Files
CodingSandbox/UserPermissionTest_CS_WinForms/UserSettings.cs
T
2026-05-31 15:54:46 +03:00

386 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace UserPermissionTest_CS_WinForms
{
public partial class UserSettings : Form
{
private string? _editingUsername = null; // null means we are adding a new user, otherwise contains the original username of the user being edited.
private bool _isPopulatingFields = false;
public UserSettings()
{
InitializeComponent();
}
private void UserSettings_Load(object sender, EventArgs e)
{
RefreshUserList();
// Register to updates to keep UI synchronized in real-time
SessionManager.UsersUpdated += SessionManager_UsersUpdated;
if (lstUsers.Items.Count > 0)
{
lstUsers.SelectedIndex = 0;
}
else
{
ClearDetailsForm();
}
}
private void SessionManager_UsersUpdated()
{
// Safeguard for cross-thread calls, though in WinForms it's usually on the UI thread
if (this.InvokeRequired)
{
this.Invoke(new Action(RefreshUserList));
}
else
{
RefreshUserList();
}
}
private void RefreshUserList()
{
_isPopulatingFields = true;
string? currentSelection = lstUsers.SelectedItem?.ToString();
lstUsers.Items.Clear();
foreach (var user in SessionManager.Users)
{
lstUsers.Items.Add(user.Username);
}
// Restore selection if possible
if (currentSelection != null && lstUsers.Items.Contains(currentSelection))
{
lstUsers.SelectedItem = currentSelection;
}
else if (lstUsers.Items.Count > 0)
{
lstUsers.SelectedIndex = 0;
}
else
{
ClearDetailsForm();
}
_isPopulatingFields = false;
RefreshPermissionList();
}
private void RefreshPermissionList()
{
// Save currently checked permission IDs
var checkedPermIds = new HashSet<int>();
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
if (chkPermissions.GetItemChecked(i))
{
var permission = chkPermissions.Items[i] as Permission;
if (permission != null)
{
checkedPermIds.Add(permission.Id);
}
}
}
chkPermissions.Items.Clear();
foreach (var permission in SessionManager.AvailablePermissions)
{
chkPermissions.Items.Add(permission);
}
// If we are editing a user, check their specific permissions
if (_editingUsername != null)
{
var user = SessionManager.Users.FirstOrDefault(u => u.Username.Equals(_editingUsername, StringComparison.OrdinalIgnoreCase));
if (user != null)
{
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
var permission = chkPermissions.Items[i] as Permission;
if (permission != null && user.Permissions.Contains(permission.Id))
{
chkPermissions.SetItemChecked(i, true);
}
}
}
}
else
{
// Otherwise, restore the checks that the administrator was in the middle of selecting
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
var permission = chkPermissions.Items[i] as Permission;
if (permission != null && checkedPermIds.Contains(permission.Id))
{
chkPermissions.SetItemChecked(i, true);
}
}
}
}
private void lstUsers_SelectedIndexChanged(object sender, EventArgs e)
{
if (_isPopulatingFields) return;
string? selectedUsername = lstUsers.SelectedItem?.ToString();
if (selectedUsername != null)
{
var user = SessionManager.Users.FirstOrDefault(u => u.Username.Equals(selectedUsername, StringComparison.OrdinalIgnoreCase));
if (user != null)
{
PopulateUserDetails(user);
}
}
else
{
ClearDetailsForm();
}
}
private void PopulateUserDetails(User user)
{
_isPopulatingFields = true;
_editingUsername = user.Username;
txtUsername.Text = user.Username;
txtFullName.Text = user.FullName;
// Mask the actual password on display with a special visual placeholder
txtPassword.Text = "●●●●●●●●";
txtPassword.PasswordChar = '•';
btnTogglePassword.Text = "👁";
// Update permissions CheckedListBox
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
var permission = chkPermissions.Items[i] as Permission;
bool hasPermission = permission != null && user.Permissions.Contains(permission.Id);
chkPermissions.SetItemChecked(i, hasPermission);
}
lblDetailsHeader.Text = $"User Profile: {user.Username}";
btnDeleteUser.Enabled = true;
_isPopulatingFields = false;
}
private void ClearDetailsForm()
{
_isPopulatingFields = true;
_editingUsername = null;
txtUsername.Text = string.Empty;
txtFullName.Text = string.Empty;
txtPassword.Text = string.Empty;
txtPassword.PasswordChar = '•';
btnTogglePassword.Text = "👁";
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
chkPermissions.SetItemChecked(i, false);
}
lblDetailsHeader.Text = "New User Profile Setup";
btnDeleteUser.Enabled = false;
_isPopulatingFields = false;
}
private void btnAddUser_Click(object sender, EventArgs e)
{
lstUsers.ClearSelected();
ClearDetailsForm();
txtUsername.Focus();
}
private void btnDeleteUser_Click(object sender, EventArgs e)
{
if (_editingUsername == null) return;
var result = MessageBox.Show(
$"Are you sure you want to delete the user '{_editingUsername}'?",
"Confirm Deletion",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning);
if (result == DialogResult.Yes)
{
SessionManager.DeleteUser(_editingUsername);
}
}
private void btnSaveUser_Click(object sender, EventArgs e)
{
string username = txtUsername.Text.Trim();
string fullName = txtFullName.Text.Trim();
string password = txtPassword.Text;
if (string.IsNullOrEmpty(username))
{
MessageBox.Show("Username cannot be empty.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtUsername.Focus();
return;
}
if (string.IsNullOrEmpty(fullName))
{
MessageBox.Show("Full Name cannot be empty.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtFullName.Focus();
return;
}
if (string.IsNullOrEmpty(password))
{
MessageBox.Show("Password cannot be empty.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtPassword.Focus();
return;
}
// Check duplicate username
bool isNewUser = _editingUsername == null;
bool usernameExists = SessionManager.Users.Any(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
// Determine final password hash to save
string finalPasswordHash;
if (isNewUser)
{
if (usernameExists)
{
MessageBox.Show($"A user with username '{username}' already exists.", "Duplicate Username", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtUsername.Focus();
return;
}
if (password == "●●●●●●●●")
{
MessageBox.Show("Please enter a valid password for the new user.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtPassword.Focus();
return;
}
finalPasswordHash = PasswordHasher.HashPassword(password);
var newUser = new User
{
Username = username,
FullName = fullName,
Password = finalPasswordHash,
Permissions = GetCheckedPermissions()
};
SessionManager.AddUser(newUser);
MessageBox.Show($"User '{username}' created successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
// Select the newly created user
lstUsers.SelectedItem = username;
}
else
{
// Editing existing user
if (!username.Equals(_editingUsername, StringComparison.OrdinalIgnoreCase) && usernameExists)
{
MessageBox.Show($"A user with username '{username}' already exists.", "Duplicate Username", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtUsername.Focus();
return;
}
var existingUser = SessionManager.Users.FirstOrDefault(u => u.Username.Equals(_editingUsername, StringComparison.OrdinalIgnoreCase));
if (password == "●●●●●●●●" || string.IsNullOrEmpty(password))
{
// Keep existing hashed password
finalPasswordHash = existingUser != null ? existingUser.Password : PasswordHasher.HashPassword("admin");
}
else
{
// Hash new password
finalPasswordHash = PasswordHasher.HashPassword(password);
}
var updatedUser = new User
{
Username = username,
FullName = fullName,
Password = finalPasswordHash,
Permissions = GetCheckedPermissions()
};
string originalName = _editingUsername!;
SessionManager.UpdateUser(originalName, updatedUser);
MessageBox.Show($"User details for '{username}' updated successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
// Keep the selection updated
lstUsers.SelectedItem = username;
}
}
private void btnTogglePassword_Click(object sender, EventArgs e)
{
if (txtPassword.PasswordChar == '•')
{
txtPassword.PasswordChar = '\0'; // Show password
btnTogglePassword.Text = "🙈";
}
else
{
txtPassword.PasswordChar = '•'; // Mask password
btnTogglePassword.Text = "👁";
}
}
private List<int> GetCheckedPermissions()
{
var list = new List<int>();
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
if (chkPermissions.GetItemChecked(i))
{
var permission = chkPermissions.Items[i] as Permission;
if (permission != null)
{
list.Add(permission.Id);
}
}
}
return list;
}
private void btnAddNewPermission_Click(object sender, EventArgs e)
{
string newPerm = txtNewPermission.Text.Trim();
if (string.IsNullOrEmpty(newPerm))
{
MessageBox.Show("Please enter a permission name.", "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtNewPermission.Focus();
return;
}
if (SessionManager.AvailablePermissions.Any(p => p.Name.Equals(newPerm, StringComparison.OrdinalIgnoreCase)))
{
MessageBox.Show($"Permission '{newPerm}' already exists in the system.", "Duplicate Permission", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtNewPermission.Focus();
return;
}
SessionManager.AddPermission(newPerm);
txtNewPermission.Clear();
RefreshPermissionList();
MessageBox.Show($"New permission '{newPerm}' registered. You can now assign it to users.", "Permission Registered", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
// Unsubscribe to prevent memory leaks
SessionManager.UsersUpdated -= SessionManager_UsersUpdated;
base.OnFormClosing(e);
}
}
}