| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- using System;
- using System.Configuration;
- using System.Windows.Forms;
- using Npgsql;
- using NpgsqlTypes;
- namespace SimpleDBViewer
- {
- public partial class LoginForm : Form
- {
- public LoginForm()
- {
- InitializeComponent();
- }
- private void TxtPassword_KeyDown(object sender, KeyEventArgs e)
- {
- if (e.KeyCode == Keys.Enter)
- {
- e.SuppressKeyPress = true;
- BtnLogin_Click(sender, EventArgs.Empty);
- }
- }
- private void BtnLogin_Click(object sender, EventArgs e)
- {
- string login = txtLogin.Text.Trim();
- string password = txtPassword.Text;
- lblError.Text = "";
- if (string.IsNullOrWhiteSpace(login))
- {
- lblError.Text = "Введите логин.";
- txtLogin.Focus();
- return;
- }
- if (string.IsNullOrWhiteSpace(password))
- {
- lblError.Text = "Введите пароль.";
- txtPassword.Focus();
- return;
- }
- try
- {
- btnLogin.Enabled = false;
- btnLogin.Text = "Проверка...";
- Application.DoEvents();
- using (NpgsqlConnection connection = new NpgsqlConnection(DbSettings.ConnectionString))
- {
- connection.Open();
- const string sql = @"
- select user_id, login, role::text as role, instructor_id, driver_id
- from akulova_vs.fn_authenticate_user(cast(@login as text), cast(@password as text))";
- using (NpgsqlCommand command = new NpgsqlCommand(sql, connection))
- {
- command.Parameters.AddWithValue("@login", login);
- command.Parameters.AddWithValue("@password", password);
- using (NpgsqlDataReader reader = command.ExecuteReader())
- {
- if (!reader.Read())
- {
- lblError.Text = "Неверный логин или пароль.";
- return;
- }
- UserSession.CurrentUser = new UserInfo
- {
- UserId = Convert.ToInt32(reader["user_id"]),
- Login = reader["login"].ToString(),
- Role = reader["role"].ToString(),
- InstructorId = reader["instructor_id"] == DBNull.Value
- ? (int?)null
- : Convert.ToInt32(reader["instructor_id"]),
- DriverId = reader["driver_id"] == DBNull.Value
- ? (int?)null
- : Convert.ToInt32(reader["driver_id"])
- };
- }
- }
- }
- using (MainForm mainForm = new MainForm())
- {
- Hide();
- mainForm.ShowDialog();
- txtPassword.Clear();
- Show();
- txtPassword.Focus();
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(AppError.ToUserMessage(ex, "Не удалось выполнить вход."),
- "Ошибка подключения или авторизации", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- finally
- {
- btnLogin.Enabled = true;
- btnLogin.Text = "Войти";
- }
- }
- private void BtnExit_Click(object sender, EventArgs e)
- {
- Application.Exit();
- }
- private void lblInfo_Click(object sender, EventArgs e)
- {
- }
- }
- public static class DbSettings
- {
- public static string ConnectionString
- {
- get
- {
- ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings["AutoschoolDb"];
- return settings.ConnectionString;
- }
- }
- }
- public class UserInfo
- {
- public int UserId { get; set; }
- public string Login { get; set; }
- public string Role { get; set; }
- public int? InstructorId { get; set; }
- public int? DriverId { get; set; }
- }
- public static class DbAppContext
- {
- public static void Apply(NpgsqlConnection connection)
- {
- if (connection == null || !UserSession.IsLoggedIn)
- return;
- using (NpgsqlCommand command = new NpgsqlCommand(@"
- select set_config('app.user_login', cast(@login as text), false);", connection))
- {
- command.Parameters.AddWithValue("@login", UserSession.CurrentUser.Login ?? "system");
- command.ExecuteNonQuery();
- }
- }
- public static void MarkLatestAuditLogin(NpgsqlConnection connection, string tableName)
- {
- MarkLatestAuditLogin(connection, tableName, null);
- }
- public static void MarkLatestAuditLogin(NpgsqlConnection connection, string tableName, object recordId)
- {
- if (connection == null || !UserSession.IsLoggedIn || string.IsNullOrWhiteSpace(tableName))
- return;
- int parsedRecordId;
- object recordIdValue = DBNull.Value;
- if (recordId != null && recordId != DBNull.Value && int.TryParse(recordId.ToString(), out parsedRecordId))
- recordIdValue = parsedRecordId;
- using (NpgsqlCommand command = new NpgsqlCommand(@"
- update akulova_vs.audit_log
- set changed_by = cast(@login as varchar)
- where log_id = (
- select log_id
- from akulova_vs.audit_log
- where table_name = cast(@table_name as text)
- and (cast(@record_id as integer) is null or record_id = cast(@record_id as integer))
- and changed_at >= now() - interval '5 minutes'
- order by log_id desc
- limit 1
- );", connection))
- {
- command.Parameters.AddWithValue("@login", UserSession.CurrentUser.Login ?? "system");
- command.Parameters.AddWithValue("@table_name", tableName);
- NpgsqlParameter recordParameter = command.Parameters.Add("@record_id", NpgsqlDbType.Integer);
- recordParameter.Value = recordIdValue;
- command.ExecuteNonQuery();
- }
- }
- }
- public static class UserSession
- {
- public static UserInfo CurrentUser { get; set; }
- public static bool IsLoggedIn
- {
- get { return CurrentUser != null; }
- }
- public static bool IsAdmin
- {
- get { return IsLoggedIn && CurrentUser.Role == "admin"; }
- }
- public static void Logout()
- {
- CurrentUser = null;
- }
- }
- public static class AppError
- {
- public static string ToUserMessage(Exception ex, string actionText)
- {
- if (ex is ArgumentException)
- return ex.Message;
- PostgresException pg = ex as PostgresException;
- if (pg != null)
- {
- switch (pg.SqlState)
- {
- case "23505":
- return actionText + "\n\nТакая запись уже существует. Проверьте уникальные поля: логин, номер удостоверения или номер водительских прав.";
- case "23503":
- return actionText + "\n\nЗапись нельзя сохранить или удалить, потому что она связана с другими данными. Сначала проверьте связанные таблицы.";
- case "23502":
- return actionText + "\n\nНе заполнено обязательное поле. Проверьте форму и заполните все обязательные данные.";
- case "23514":
- return actionText + "\n\nЗначение не проходит проверку базы данных. Проверьте выбранный результат экзамена, сложность маршрута, категорию прав или дату рождения.";
- case "22P02":
- case "22007":
- case "22008":
- return actionText + "\n\nНекорректный формат данных. Проверьте числа и даты.";
- case "42P01":
- return actionText + "\n\nТаблица или представление не найдено. Проверьте, что объекты созданы в схеме akulova_vs и в строке подключения указан Search Path=akulova_vs,public.";
- case "42883":
- return actionText + "\n\nФункция базы данных не найдена. Проверьте, что функции fn_authenticate_user и fn_hash_password созданы в схеме akulova_vs.";
- case "42703":
- return actionText + "\n\nВ базе данных не найден нужный столбец. Проверьте, что структура таблиц соответствует ТЗ.";
- case "42501":
- return actionText + "\n\nНедостаточно прав для выполнения операции в базе данных.";
- case "3D000":
- return actionText + "\n\nБаза данных не найдена. Проверьте имя базы в App.config.";
- case "28P01":
- return actionText + "\n\nНеверный логин или пароль подключения к PostgreSQL. Проверьте Username и Password в App.config.";
- default:
- return actionText + "\n\nБаза данных вернула ошибку. Код: " + pg.SqlState + ".";
- }
- }
- if (ex is NpgsqlException)
- {
- return actionText + "\n\nНе удалось подключиться к PostgreSQL. Проверьте сервер, порт, базу данных и строку подключения в App.config.";
- }
- if (ex is FormatException || ex is InvalidCastException)
- {
- return actionText + "\n\nНекорректный формат данных. Проверьте, что числовые поля заполнены числами, а даты выбраны через календарь.";
- }
- return actionText + "\n\nПроизошла ошибка при выполнении операции. Проверьте введённые данные и попробуйте ещё раз.";
- }
- }
- }
|