| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- using Npgsql;
- using System;
- using System.Configuration;
- using System.Data;
- using System.Windows.Forms;
- namespace WindowsFormsApp4
- {
- public partial class AdminUserEditForm : Form
- {
- private readonly string connStr = ConfigurationManager.ConnectionStrings["PostgreSQL"].ConnectionString;
- private int? userId = null;
- // Конструктор: если userId передан, то редактирование, иначе – добавление нового пользователя
- public AdminUserEditForm(int? userId = null)
- {
- InitializeComponent();
- this.userId = userId;
- LoadLibraries();
- if (userId.HasValue)
- {
- LoadUserData();
- txtUserId.Text = userId.Value.ToString();
- }
- else
- {
- this.Text = "Добавление пользователя";
- labelTitle.Text = "Добавление пользователя";
- txtUserId.Text = "(новый)";
- }
- }
- private string GenerateSalt()
- {
- byte[] saltBytes = new byte[16];
- using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider())
- rng.GetBytes(saltBytes);
- return Convert.ToBase64String(saltBytes);
- }
- private string HashPassword(string password, string salt)
- {
- byte[] combined = System.Text.Encoding.UTF8.GetBytes(password + salt);
- using (var sha256 = System.Security.Cryptography.SHA256.Create())
- {
- byte[] hash = sha256.ComputeHash(combined);
- return Convert.ToBase64String(hash);
- }
- }
- private void LoadLibraries()
- {
- string query = "SELECT id, name FROM libraries ORDER BY name";
- DataTable dt = new DataTable();
- using (var conn = new NpgsqlConnection(connStr))
- using (var cmd = new NpgsqlCommand(query, conn))
- {
- conn.Open();
- using (var adapter = new NpgsqlDataAdapter(cmd))
- {
- adapter.Fill(dt);
- }
- }
- comboBoxLibrary.DisplayMember = "name";
- comboBoxLibrary.ValueMember = "id";
- comboBoxLibrary.DataSource = dt;
- comboBoxLibrary.SelectedIndex = -1;
- }
- private void LoadUserData()
- {
- string query = @"
- SELECT name, lastname, phone, email, role_name, library_id, bilet_active
- FROM users WHERE id = @id";
- using (var conn = new NpgsqlConnection(connStr))
- using (var cmd = new NpgsqlCommand(query, conn))
- {
- cmd.Parameters.AddWithValue("id", userId.Value);
- conn.Open();
- using (var reader = cmd.ExecuteReader())
- {
- if (reader.Read())
- {
- txtName.Text = reader["name"].ToString();
- txtLastname.Text = reader["lastname"].ToString();
- txtPhone.Text = reader["phone"].ToString();
- txtEmail.Text = reader["email"].ToString();
- comboBoxRole.SelectedItem = reader["role_name"].ToString();
- if (reader["library_id"] != DBNull.Value)
- comboBoxLibrary.SelectedValue = reader["library_id"];
- checkBoxActive.Checked = Convert.ToBoolean(reader["bilet_active"]);
- }
- }
- }
- }
- private void btnSave_Click(object sender, EventArgs e)
- {
- if (string.IsNullOrEmpty(txtName.Text) || string.IsNullOrEmpty(txtLastname.Text))
- {
- MessageBox.Show("Имя и фамилия обязательны", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- string role = comboBoxRole.SelectedItem?.ToString();
- if (string.IsNullOrEmpty(role))
- {
- MessageBox.Show("Выберите роль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- object libraryId = comboBoxLibrary.SelectedValue ?? DBNull.Value;
- // Обработка пароля (только если поле видимо и в нём что-то есть)
- string newPassword = txtNewPassword?.Text.Trim();
- bool updatePassword = !string.IsNullOrEmpty(newPassword);
- if (updatePassword && newPassword != txtConfirmPassword?.Text.Trim())
- {
- MessageBox.Show("Пароль и подтверждение не совпадают", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- if (updatePassword && newPassword.Length < 4)
- {
- MessageBox.Show("Пароль должен быть не менее 4 символов", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- try
- {
- using (var conn = new NpgsqlConnection(connStr))
- {
- conn.Open();
- if (userId.HasValue)
- {
- // 1. Обновление данных пользователя
- string query = @"
- UPDATE users
- SET name=@name, lastname=@lastname, phone=@phone, email=@email,
- role_name=@role::role, library_id=@libId, bilet_active=@active
- WHERE id=@id";
- using (var cmd = new NpgsqlCommand(query, conn))
- {
- cmd.Parameters.AddWithValue("name", txtName.Text);
- cmd.Parameters.AddWithValue("lastname", txtLastname.Text);
- cmd.Parameters.AddWithValue("phone", txtPhone.Text);
- cmd.Parameters.AddWithValue("email", txtEmail.Text);
- cmd.Parameters.AddWithValue("role", role);
- cmd.Parameters.AddWithValue("libId", libraryId == DBNull.Value ? DBNull.Value : libraryId);
- cmd.Parameters.AddWithValue("active", checkBoxActive.Checked);
- cmd.Parameters.AddWithValue("id", userId.Value);
- cmd.ExecuteNonQuery();
- }
- // 2. Если задан новый пароль – обновляем user_auth
- if (updatePassword)
- {
- string salt = GenerateSalt();
- string hash = HashPassword(newPassword, salt);
- string authQuery = @"
- UPDATE user_auth
- SET password = @hash, salt = @salt
- WHERE user_id = @userId";
- using (var cmd = new NpgsqlCommand(authQuery, conn))
- {
- cmd.Parameters.AddWithValue("hash", hash);
- cmd.Parameters.AddWithValue("salt", salt);
- cmd.Parameters.AddWithValue("userId", userId.Value);
- if (cmd.ExecuteNonQuery() == 0)
- {
- // Если записи ещё нет (бывает при ручной миграции), вставляем
- string insertAuth = @"
- INSERT INTO user_auth (user_id, login, password, salt)
- VALUES (@userId, @login, @hash, @salt)";
- using (var cmd2 = new NpgsqlCommand(insertAuth, conn))
- {
- cmd2.Parameters.AddWithValue("userId", userId.Value);
- cmd2.Parameters.AddWithValue("login", txtEmail.Text);
- cmd2.Parameters.AddWithValue("hash", hash);
- cmd2.Parameters.AddWithValue("salt", salt);
- cmd2.ExecuteNonQuery();
- }
- }
- }
- }
- }
- else
- {
- // Добавление нового пользователя
- if (!updatePassword)
- {
- MessageBox.Show("Для нового пользователя необходимо задать пароль", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
- return;
- }
- // Вставка в users
- string insertUser = @"
- INSERT INTO users (name, lastname, phone, email, registration_date, role_name, library_id, bilet_active)
- VALUES (@name, @lastname, @phone, @email, CURRENT_DATE, @role::role, @libId, @active)
- RETURNING id";
- int newId;
- using (var cmd = new NpgsqlCommand(insertUser, conn))
- {
- cmd.Parameters.AddWithValue("name", txtName.Text);
- cmd.Parameters.AddWithValue("lastname", txtLastname.Text);
- cmd.Parameters.AddWithValue("phone", txtPhone.Text);
- cmd.Parameters.AddWithValue("email", txtEmail.Text);
- cmd.Parameters.AddWithValue("role", role);
- cmd.Parameters.AddWithValue("libId", libraryId == DBNull.Value ? DBNull.Value : libraryId);
- cmd.Parameters.AddWithValue("active", checkBoxActive.Checked);
- newId = (int)cmd.ExecuteScalar();
- }
- // Вставка в user_auth
- string salt = GenerateSalt();
- string hash = HashPassword(newPassword, salt);
- string insertAuth = @"
- INSERT INTO user_auth (user_id, login, password, salt)
- VALUES (@userId, @login, @hash, @salt)";
- using (var cmd = new NpgsqlCommand(insertAuth, conn))
- {
- cmd.Parameters.AddWithValue("userId", newId);
- cmd.Parameters.AddWithValue("login", txtEmail.Text); // логин = email (можно изменить)
- cmd.Parameters.AddWithValue("hash", hash);
- cmd.Parameters.AddWithValue("salt", salt);
- cmd.ExecuteNonQuery();
- }
- MessageBox.Show($"Пользователь добавлен с ID {newId}", "Успех");
- }
- MessageBox.Show("Сохранено", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
- this.DialogResult = DialogResult.OK;
- this.Close();
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
-
- }
- private void btnCancel_Click(object sender, EventArgs e)
- {
- this.DialogResult = DialogResult.Cancel;
- this.Close();
- }
- private void AdminUserEditForm_Load(object sender, EventArgs e)
- {
- }
- private void labelConfirmPassword_Click(object sender, EventArgs e)
- {
- }
- }
- }
|