added "UserPermissionTesting_CS_WinForms" project

This commit is contained in:
Atakan Kayman
2026-05-31 15:08:26 +03:00
parent 1ea9de0042
commit 374067dd2e
26 changed files with 2213 additions and 427 deletions
@@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace UserPermissionTest_CS_WinForms
{
public interface IUserRepository
{
List<User> LoadUsers();
void SaveUsers(List<User> users);
List<string> LoadPermissions();
void SavePermissions(List<string> permissions);
}
}
@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace UserPermissionTest_CS_WinForms
{
public class JsonUserRepository : IUserRepository
{
private const string UsersFile = "users.json";
private const string PermissionsFile = "permissions.json";
public List<User> LoadUsers()
{
if (!File.Exists(UsersFile))
{
var defaults = GetDefaultUsers();
SaveUsers(defaults);
return defaults;
}
try
{
string json = File.ReadAllText(UsersFile);
var users = JsonConvert.DeserializeObject<List<User>>(json);
if (users == null) return GetDefaultUsers();
// Dynamic Migration: If any loaded user has a plain text password, hash it and re-save
bool modified = false;
foreach (var user in users)
{
if (user.Password.Length != 64 || !IsHexString(user.Password))
{
user.Password = PasswordHasher.HashPassword(user.Password);
modified = true;
}
}
if (modified)
{
SaveUsers(users);
}
return users;
}
catch (Exception ex)
{
Console.WriteLine("Error reading users JSON, falling back to defaults: " + ex.Message);
return GetDefaultUsers();
}
}
private bool IsHexString(string str)
{
if (string.IsNullOrEmpty(str)) return false;
foreach (char c in str)
{
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))
return false;
}
return true;
}
public void SaveUsers(List<User> users)
{
try
{
string json = JsonConvert.SerializeObject(users, Formatting.Indented);
File.WriteAllText(UsersFile, json);
}
catch (Exception ex)
{
Console.WriteLine("Error writing users JSON: " + ex.Message);
}
}
public List<string> LoadPermissions()
{
if (!File.Exists(PermissionsFile))
{
var defaults = GetDefaultPermissions();
SavePermissions(defaults);
return defaults;
}
try
{
string json = File.ReadAllText(PermissionsFile);
var permissions = JsonConvert.DeserializeObject<List<string>>(json);
return permissions ?? GetDefaultPermissions();
}
catch (Exception ex)
{
Console.WriteLine("Error reading permissions JSON, falling back to defaults: " + ex.Message);
return GetDefaultPermissions();
}
}
public void SavePermissions(List<string> permissions)
{
try
{
string json = JsonConvert.SerializeObject(permissions, Formatting.Indented);
File.WriteAllText(PermissionsFile, json);
}
catch (Exception ex)
{
Console.WriteLine("Error writing permissions JSON: " + ex.Message);
}
}
private List<User> GetDefaultUsers()
{
return new List<User>
{
new User
{
Username = "admin",
FullName = "System Administrator",
Password = PasswordHasher.HashPassword("admin"),
Permissions = GetDefaultPermissions()
},
new User
{
Username = "user",
FullName = "Standard User",
Password = PasswordHasher.HashPassword("user"),
Permissions = new List<string> { "View Dashboard" }
}
};
}
private List<string> GetDefaultPermissions()
{
return new List<string>
{
"View Dashboard",
"Edit Settings",
"Manage Users",
"Full Control",
"Delete Transactions"
};
}
}
}
+218
View File
@@ -0,0 +1,218 @@
namespace UserPermissionTest_CS_WinForms
{
partial class LoginDialog
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.pnlHeader = new System.Windows.Forms.Panel();
this.lblTitle = new System.Windows.Forms.Label();
this.lblSubtitle = new System.Windows.Forms.Label();
this.lblUsername = new System.Windows.Forms.Label();
this.txtUsername = new System.Windows.Forms.TextBox();
this.lblPassword = new System.Windows.Forms.Label();
this.txtPassword = new System.Windows.Forms.TextBox();
this.btnTogglePassword = new System.Windows.Forms.Button();
this.btnLogin = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.lblError = new System.Windows.Forms.Label();
this.pnlHeader.SuspendLayout();
this.SuspendLayout();
//
// pnlHeader
//
this.pnlHeader.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(41)))), ((int)(((byte)(59)))));
this.pnlHeader.Controls.Add(this.lblTitle);
this.pnlHeader.Controls.Add(this.lblSubtitle);
this.pnlHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlHeader.Location = new System.Drawing.Point(0, 0);
this.pnlHeader.Name = "pnlHeader";
this.pnlHeader.Size = new System.Drawing.Size(380, 80);
this.pnlHeader.TabIndex = 0;
//
// lblTitle
//
this.lblTitle.AutoSize = true;
this.lblTitle.Font = new System.Drawing.Font("Segoe UI Semibold", 16F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTitle.ForeColor = System.Drawing.Color.White;
this.lblTitle.Location = new System.Drawing.Point(20, 15);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(126, 30);
this.lblTitle.TabIndex = 0;
this.lblTitle.Text = "User Sign In";
//
// lblSubtitle
//
this.lblSubtitle.AutoSize = true;
this.lblSubtitle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblSubtitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(148)))), ((int)(((byte)(163)))), ((int)(((byte)(184)))));
this.lblSubtitle.Location = new System.Drawing.Point(22, 45);
this.lblSubtitle.Name = "lblSubtitle";
this.lblSubtitle.Size = new System.Drawing.Size(189, 15);
this.lblSubtitle.TabIndex = 1;
this.lblSubtitle.Text = "Please enter your credentials to login";
//
// lblUsername
//
this.lblUsername.AutoSize = true;
this.lblUsername.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblUsername.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.lblUsername.Location = new System.Drawing.Point(30, 100);
this.lblUsername.Name = "lblUsername";
this.lblUsername.Size = new System.Drawing.Size(69, 17);
this.lblUsername.TabIndex = 1;
this.lblUsername.Text = "Username";
//
// txtUsername
//
this.txtUsername.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.txtUsername.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtUsername.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.txtUsername.Location = new System.Drawing.Point(30, 122);
this.txtUsername.Name = "txtUsername";
this.txtUsername.Size = new System.Drawing.Size(320, 27);
this.txtUsername.TabIndex = 2;
//
// lblPassword
//
this.lblPassword.AutoSize = true;
this.lblPassword.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblPassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.lblPassword.Location = new System.Drawing.Point(30, 160);
this.lblPassword.Name = "lblPassword";
this.lblPassword.Size = new System.Drawing.Size(66, 17);
this.lblPassword.TabIndex = 3;
this.lblPassword.Text = "Password";
//
// txtPassword
//
this.txtPassword.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.txtPassword.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtPassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.txtPassword.Location = new System.Drawing.Point(30, 182);
this.txtPassword.Name = "txtPassword";
this.txtPassword.PasswordChar = '•';
this.txtPassword.Size = new System.Drawing.Size(285, 27);
this.txtPassword.TabIndex = 4;
//
// btnTogglePassword
//
this.btnTogglePassword.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(245)))), ((int)(((byte)(249)))));
this.btnTogglePassword.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnTogglePassword.FlatAppearance.BorderSize = 0;
this.btnTogglePassword.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnTogglePassword.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnTogglePassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.btnTogglePassword.Location = new System.Drawing.Point(320, 182);
this.btnTogglePassword.Name = "btnTogglePassword";
this.btnTogglePassword.Size = new System.Drawing.Size(30, 27);
this.btnTogglePassword.TabIndex = 8;
this.btnTogglePassword.Text = "👁";
this.btnTogglePassword.UseVisualStyleBackColor = false;
this.btnTogglePassword.Click += new System.EventHandler(this.btnTogglePassword_Click);
//
// btnLogin
//
this.btnLogin.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(99)))), ((int)(((byte)(102)))), ((int)(((byte)(241)))));
this.btnLogin.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnLogin.FlatAppearance.BorderSize = 0;
this.btnLogin.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnLogin.Font = new System.Drawing.Font("Segoe UI Semibold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnLogin.ForeColor = System.Drawing.Color.White;
this.btnLogin.Location = new System.Drawing.Point(230, 245);
this.btnLogin.Name = "btnLogin";
this.btnLogin.Size = new System.Drawing.Size(120, 36);
this.btnLogin.TabIndex = 5;
this.btnLogin.Text = "Login";
this.btnLogin.UseVisualStyleBackColor = false;
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// btnCancel
//
this.btnCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(245)))), ((int)(((byte)(249)))));
this.btnCancel.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.FlatAppearance.BorderSize = 0;
this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnCancel.Font = new System.Drawing.Font("Segoe UI Semibold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.btnCancel.Location = new System.Drawing.Point(100, 245);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(120, 36);
this.btnCancel.TabIndex = 6;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = false;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// lblError
//
this.lblError.AutoSize = true;
this.lblError.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblError.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(239)))), ((int)(((byte)(68)))), ((int)(((byte)(68)))));
this.lblError.Location = new System.Drawing.Point(30, 215);
this.lblError.Name = "lblError";
this.lblError.Size = new System.Drawing.Size(167, 15);
this.lblError.TabIndex = 7;
this.lblError.Text = "Invalid username or password!";
this.lblError.Visible = false;
//
// LoginDialog
//
this.AcceptButton = this.btnLogin;
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(380, 305);
this.Controls.Add(this.lblError);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnLogin);
this.Controls.Add(this.txtPassword);
this.Controls.Add(this.btnTogglePassword);
this.Controls.Add(this.lblPassword);
this.Controls.Add(this.txtUsername);
this.Controls.Add(this.lblUsername);
this.Controls.Add(this.pnlHeader);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "LoginDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Sign In";
this.pnlHeader.ResumeLayout(false);
this.pnlHeader.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel pnlHeader;
private System.Windows.Forms.Label lblTitle;
private System.Windows.Forms.Label lblSubtitle;
private System.Windows.Forms.Label lblUsername;
private System.Windows.Forms.TextBox txtUsername;
private System.Windows.Forms.Label lblPassword;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.Button btnTogglePassword;
private System.Windows.Forms.Button btnLogin;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Label lblError;
}
}
@@ -0,0 +1,60 @@
using System;
using System.Windows.Forms;
namespace UserPermissionTest_CS_WinForms
{
public partial class LoginDialog : Form
{
public LoginDialog()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
lblError.Visible = false;
string username = txtUsername.Text.Trim();
string password = txtPassword.Text;
if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
{
lblError.Text = "Please fill in all fields.";
lblError.Visible = true;
return;
}
if (SessionManager.Login(username, password))
{
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
lblError.Text = "Invalid username or password!";
lblError.Visible = true;
txtPassword.Clear();
txtPassword.Focus();
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
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 = "👁";
}
}
}
}
+319
View File
@@ -0,0 +1,319 @@
namespace UserPermissionTest_CS_WinForms
{
partial class MainForm
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.pnlHeader = new System.Windows.Forms.Panel();
this.lblTitle = new System.Windows.Forms.Label();
this.lblSubtitle = new System.Windows.Forms.Label();
this.pnlSidebar = new System.Windows.Forms.Panel();
this.btnUsers = new System.Windows.Forms.Button();
this.btnLogout = new System.Windows.Forms.Button();
this.btnLogin = new System.Windows.Forms.Button();
this.pnlContent = new System.Windows.Forms.Panel();
this.pnlSessionCard = new System.Windows.Forms.Panel();
this.lstUserPermissions = new System.Windows.Forms.ListBox();
this.lblPermissionsHeader = new System.Windows.Forms.Label();
this.pnlDivider = new System.Windows.Forms.Panel();
this.lblFullNameValue = new System.Windows.Forms.Label();
this.lblFullNameLabel = new System.Windows.Forms.Label();
this.lblUsernameValue = new System.Windows.Forms.Label();
this.lblUsernameLabel = new System.Windows.Forms.Label();
this.lblStatusBadge = new System.Windows.Forms.Label();
this.lblSessionHeader = new System.Windows.Forms.Label();
this.pnlHeader.SuspendLayout();
this.pnlSidebar.SuspendLayout();
this.pnlContent.SuspendLayout();
this.pnlSessionCard.SuspendLayout();
this.SuspendLayout();
//
// pnlHeader
//
this.pnlHeader.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(41)))), ((int)(((byte)(59)))));
this.pnlHeader.Controls.Add(this.lblTitle);
this.pnlHeader.Controls.Add(this.lblSubtitle);
this.pnlHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlHeader.Location = new System.Drawing.Point(0, 0);
this.pnlHeader.Name = "pnlHeader";
this.pnlHeader.Size = new System.Drawing.Size(684, 80);
this.pnlHeader.TabIndex = 0;
//
// lblTitle
//
this.lblTitle.AutoSize = true;
this.lblTitle.Font = new System.Drawing.Font("Segoe UI Semibold", 16F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTitle.ForeColor = System.Drawing.Color.White;
this.lblTitle.Location = new System.Drawing.Point(20, 15);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(325, 30);
this.lblTitle.TabIndex = 0;
this.lblTitle.Text = "Authentication && Security Portal";
//
// lblSubtitle
//
this.lblSubtitle.AutoSize = true;
this.lblSubtitle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblSubtitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(148)))), ((int)(((byte)(163)))), ((int)(((byte)(184)))));
this.lblSubtitle.Location = new System.Drawing.Point(22, 45);
this.lblSubtitle.Name = "lblSubtitle";
this.lblSubtitle.Size = new System.Drawing.Size(342, 15);
this.lblSubtitle.TabIndex = 1;
this.lblSubtitle.Text = "Secure WinForms Session Sandbox - Target Framework .NET 4.8.1";
//
// pnlSidebar
//
this.pnlSidebar.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.pnlSidebar.Controls.Add(this.btnUsers);
this.pnlSidebar.Controls.Add(this.btnLogout);
this.pnlSidebar.Controls.Add(this.btnLogin);
this.pnlSidebar.Dock = System.Windows.Forms.DockStyle.Left;
this.pnlSidebar.Location = new System.Drawing.Point(0, 80);
this.pnlSidebar.Name = "pnlSidebar";
this.pnlSidebar.Padding = new System.Windows.Forms.Padding(15);
this.pnlSidebar.Size = new System.Drawing.Size(180, 301);
this.pnlSidebar.TabIndex = 1;
//
// btnUsers
//
this.btnUsers.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(245)))), ((int)(((byte)(249)))));
this.btnUsers.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnUsers.Dock = System.Windows.Forms.DockStyle.Top;
this.btnUsers.FlatAppearance.BorderSize = 0;
this.btnUsers.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnUsers.Font = new System.Drawing.Font("Segoe UI Semibold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnUsers.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(65)))), ((int)(((byte)(85)))));
this.btnUsers.Location = new System.Drawing.Point(15, 107);
this.btnUsers.Name = "btnUsers";
this.btnUsers.Size = new System.Drawing.Size(150, 46);
this.btnUsers.TabIndex = 2;
this.btnUsers.Text = "👥 Manage Users";
this.btnUsers.UseVisualStyleBackColor = false;
this.btnUsers.Click += new System.EventHandler(this.btnUsers_Click);
//
// btnLogout
//
this.btnLogout.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(254)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.btnLogout.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnLogout.Dock = System.Windows.Forms.DockStyle.Top;
this.btnLogout.FlatAppearance.BorderSize = 0;
this.btnLogout.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnLogout.Font = new System.Drawing.Font("Segoe UI Semibold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnLogout.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(239)))), ((int)(((byte)(68)))), ((int)(((byte)(68)))));
this.btnLogout.Location = new System.Drawing.Point(15, 61);
this.btnLogout.Name = "btnLogout";
this.btnLogout.Size = new System.Drawing.Size(150, 46);
this.btnLogout.TabIndex = 1;
this.btnLogout.Text = "🚪 Logout";
this.btnLogout.UseVisualStyleBackColor = false;
this.btnLogout.Click += new System.EventHandler(this.btnLogout_Click);
//
// btnLogin
//
this.btnLogin.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(99)))), ((int)(((byte)(102)))), ((int)(((byte)(241)))));
this.btnLogin.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnLogin.Dock = System.Windows.Forms.DockStyle.Top;
this.btnLogin.FlatAppearance.BorderSize = 0;
this.btnLogin.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnLogin.Font = new System.Drawing.Font("Segoe UI Semibold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnLogin.ForeColor = System.Drawing.Color.White;
this.btnLogin.Location = new System.Drawing.Point(15, 15);
this.btnLogin.Name = "btnLogin";
this.btnLogin.Size = new System.Drawing.Size(150, 46);
this.btnLogin.TabIndex = 0;
this.btnLogin.Text = "🔑 Login";
this.btnLogin.UseVisualStyleBackColor = false;
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// pnlContent
//
this.pnlContent.BackColor = System.Drawing.Color.White;
this.pnlContent.Controls.Add(this.pnlSessionCard);
this.pnlContent.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlContent.Location = new System.Drawing.Point(180, 80);
this.pnlContent.Name = "pnlContent";
this.pnlContent.Padding = new System.Windows.Forms.Padding(20);
this.pnlContent.Size = new System.Drawing.Size(504, 301);
this.pnlContent.TabIndex = 2;
//
// pnlSessionCard
//
this.pnlSessionCard.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.pnlSessionCard.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pnlSessionCard.Controls.Add(this.lstUserPermissions);
this.pnlSessionCard.Controls.Add(this.lblPermissionsHeader);
this.pnlSessionCard.Controls.Add(this.pnlDivider);
this.pnlSessionCard.Controls.Add(this.lblFullNameValue);
this.pnlSessionCard.Controls.Add(this.lblFullNameLabel);
this.pnlSessionCard.Controls.Add(this.lblUsernameValue);
this.pnlSessionCard.Controls.Add(this.lblUsernameLabel);
this.pnlSessionCard.Controls.Add(this.lblStatusBadge);
this.pnlSessionCard.Controls.Add(this.lblSessionHeader);
this.pnlSessionCard.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlSessionCard.Location = new System.Drawing.Point(20, 20);
this.pnlSessionCard.Name = "pnlSessionCard";
this.pnlSessionCard.Padding = new System.Windows.Forms.Padding(15);
this.pnlSessionCard.Size = new System.Drawing.Size(464, 261);
this.pnlSessionCard.TabIndex = 0;
//
// lstUserPermissions
//
this.lstUserPermissions.BackColor = System.Drawing.Color.White;
this.lstUserPermissions.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lstUserPermissions.Font = new System.Drawing.Font("Segoe UI", 9.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lstUserPermissions.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(65)))), ((int)(((byte)(85)))));
this.lstUserPermissions.FormattingEnabled = true;
this.lstUserPermissions.ItemHeight = 17;
this.lstUserPermissions.Location = new System.Drawing.Point(200, 75);
this.lstUserPermissions.Name = "lstUserPermissions";
this.lstUserPermissions.SelectionMode = System.Windows.Forms.SelectionMode.None;
this.lstUserPermissions.Size = new System.Drawing.Size(240, 155);
this.lstUserPermissions.TabIndex = 8;
//
// lblPermissionsHeader
//
this.lblPermissionsHeader.AutoSize = true;
this.lblPermissionsHeader.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblPermissionsHeader.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(116)))), ((int)(((byte)(139)))));
this.lblPermissionsHeader.Location = new System.Drawing.Point(200, 55);
this.lblPermissionsHeader.Name = "lblPermissionsHeader";
this.lblPermissionsHeader.Size = new System.Drawing.Size(121, 15);
this.lblPermissionsHeader.TabIndex = 7;
this.lblPermissionsHeader.Text = "ASSIGNED PRIVILEGES";
//
// pnlDivider
//
this.pnlDivider.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(226)))), ((int)(((byte)(232)))), ((int)(((byte)(240)))));
this.pnlDivider.Location = new System.Drawing.Point(180, 50);
this.pnlDivider.Name = "pnlDivider";
this.pnlDivider.Size = new System.Drawing.Size(1, 180);
this.pnlDivider.TabIndex = 6;
//
// lblFullNameValue
//
this.lblFullNameValue.AutoSize = true;
this.lblFullNameValue.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblFullNameValue.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.lblFullNameValue.Location = new System.Drawing.Point(15, 160);
this.lblFullNameValue.Name = "lblFullNameValue";
this.lblFullNameValue.Size = new System.Drawing.Size(14, 19);
this.lblFullNameValue.TabIndex = 5;
this.lblFullNameValue.Text = "-";
//
// lblFullNameLabel
//
this.lblFullNameLabel.AutoSize = true;
this.lblFullNameLabel.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblFullNameLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(116)))), ((int)(((byte)(139)))));
this.lblFullNameLabel.Location = new System.Drawing.Point(15, 140);
this.lblFullNameLabel.Name = "lblFullNameLabel";
this.lblFullNameLabel.Size = new System.Drawing.Size(68, 15);
this.lblFullNameLabel.TabIndex = 4;
this.lblFullNameLabel.Text = "FULL NAME";
//
// lblUsernameValue
//
this.lblUsernameValue.AutoSize = true;
this.lblUsernameValue.Font = new System.Drawing.Font("Segoe UI Semibold", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblUsernameValue.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.lblUsernameValue.Location = new System.Drawing.Point(15, 100);
this.lblUsernameValue.Name = "lblUsernameValue";
this.lblUsernameValue.Size = new System.Drawing.Size(95, 19);
this.lblUsernameValue.TabIndex = 3;
this.lblUsernameValue.Text = "Not Logged In";
//
// lblUsernameLabel
//
this.lblUsernameLabel.AutoSize = true;
this.lblUsernameLabel.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblUsernameLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(116)))), ((int)(((byte)(139)))));
this.lblUsernameLabel.Location = new System.Drawing.Point(15, 80);
this.lblUsernameLabel.Name = "lblUsernameLabel";
this.lblUsernameLabel.Size = new System.Drawing.Size(68, 15);
this.lblUsernameLabel.TabIndex = 2;
this.lblUsernameLabel.Text = "USERNAME";
//
// lblStatusBadge
//
this.lblStatusBadge.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(239)))), ((int)(((byte)(68)))), ((int)(((byte)(68)))));
this.lblStatusBadge.Font = new System.Drawing.Font("Segoe UI Semibold", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblStatusBadge.ForeColor = System.Drawing.Color.White;
this.lblStatusBadge.Location = new System.Drawing.Point(15, 45);
this.lblStatusBadge.Name = "lblStatusBadge";
this.lblStatusBadge.Size = new System.Drawing.Size(95, 22);
this.lblStatusBadge.TabIndex = 1;
this.lblStatusBadge.Text = "SIGNED OUT";
this.lblStatusBadge.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lblSessionHeader
//
this.lblSessionHeader.AutoSize = true;
this.lblSessionHeader.Font = new System.Drawing.Font("Segoe UI Semibold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblSessionHeader.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(41)))), ((int)(((byte)(59)))));
this.lblSessionHeader.Location = new System.Drawing.Point(12, 12);
this.lblSessionHeader.Name = "lblSessionHeader";
this.lblSessionHeader.Size = new System.Drawing.Size(183, 21);
this.lblSessionHeader.TabIndex = 0;
this.lblSessionHeader.Text = "Active Session Statistics";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(684, 381);
this.Controls.Add(this.pnlContent);
this.Controls.Add(this.pnlSidebar);
this.Controls.Add(this.pnlHeader);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "MainForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Authentication & Directory Sandbox";
this.Load += new System.EventHandler(this.MainForm_Load);
this.pnlHeader.ResumeLayout(false);
this.pnlHeader.PerformLayout();
this.pnlSidebar.ResumeLayout(false);
this.pnlContent.ResumeLayout(false);
this.pnlSessionCard.ResumeLayout(false);
this.pnlSessionCard.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel pnlHeader;
private System.Windows.Forms.Label lblTitle;
private System.Windows.Forms.Label lblSubtitle;
private System.Windows.Forms.Panel pnlSidebar;
private System.Windows.Forms.Button btnLogin;
private System.Windows.Forms.Button btnLogout;
private System.Windows.Forms.Button btnUsers;
private System.Windows.Forms.Panel pnlContent;
private System.Windows.Forms.Panel pnlSessionCard;
private System.Windows.Forms.Label lblSessionHeader;
private System.Windows.Forms.Label lblStatusBadge;
private System.Windows.Forms.Label lblUsernameValue;
private System.Windows.Forms.Label lblUsernameLabel;
private System.Windows.Forms.Label lblFullNameValue;
private System.Windows.Forms.Label lblFullNameLabel;
private System.Windows.Forms.Panel pnlDivider;
private System.Windows.Forms.ListBox lstUserPermissions;
private System.Windows.Forms.Label lblPermissionsHeader;
}
}
+153
View File
@@ -0,0 +1,153 @@
using System;
using System.Drawing;
using System.Windows.Forms;
namespace UserPermissionTest_CS_WinForms
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
// Subscribe to session state change notifications
SessionManager.SessionStateChanged += UpdateSessionUi;
// Trigger initial UI update
UpdateSessionUi();
}
private void UpdateSessionUi()
{
if (this.InvokeRequired)
{
this.Invoke(new Action(UpdateSessionUi));
return;
}
var user = SessionManager.CurrentUser;
if (user == null)
{
// Signed Out State
lblStatusBadge.Text = "SIGNED OUT";
lblStatusBadge.BackColor = Color.FromArgb(239, 68, 68); // Red
lblUsernameValue.Text = "Not Logged In";
lblUsernameValue.ForeColor = Color.FromArgb(100, 116, 139); // Slate-400
lblFullNameValue.Text = "-";
lstUserPermissions.Items.Clear();
lstUserPermissions.Items.Add("(Sign in to view permissions)");
btnLogin.Enabled = true;
btnLogout.Enabled = false;
// Authorization: Lock directory when not logged in
btnUsers.Enabled = false;
btnUsers.Text = "🔒 Manage Users";
btnUsers.BackColor = Color.FromArgb(241, 245, 249);
}
else
{
// Signed In State
lblStatusBadge.Text = "SIGNED IN";
lblStatusBadge.BackColor = Color.FromArgb(16, 185, 129); // Green
lblUsernameValue.Text = user.Username;
lblUsernameValue.ForeColor = Color.FromArgb(15, 23, 42); // Navy-900
lblFullNameValue.Text = user.FullName;
lstUserPermissions.Items.Clear();
if (user.Permissions.Count == 0)
{
lstUserPermissions.Items.Add("(No permissions assigned)");
}
else
{
foreach (var permission in user.Permissions)
{
lstUserPermissions.Items.Add("✓ " + permission);
}
}
btnLogin.Enabled = false;
btnLogout.Enabled = true;
// Authorization: Check if user has 'Manage Users' or 'Full Control'
bool hasAccess = user.Permissions.Contains("Manage Users") || user.Permissions.Contains("Full Control");
if (hasAccess)
{
btnUsers.Enabled = true;
btnUsers.Text = "👥 Manage Users";
btnUsers.BackColor = Color.FromArgb(241, 245, 249);
}
else
{
btnUsers.Enabled = false;
btnUsers.Text = "🔒 Manage Users (Locked)";
btnUsers.BackColor = Color.FromArgb(241, 245, 249);
}
}
}
private void btnLogin_Click(object sender, EventArgs e)
{
using (var loginDialog = new LoginDialog())
{
if (loginDialog.ShowDialog(this) == DialogResult.OK)
{
MessageBox.Show(
$"Welcome back, {SessionManager.CurrentUser?.FullName}!",
"Sign In Successful",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
}
private void btnLogout_Click(object sender, EventArgs e)
{
if (SessionManager.CurrentUser != null)
{
string username = SessionManager.CurrentUser.Username;
SessionManager.Logout();
MessageBox.Show(
$"User '{username}' has been successfully logged out.",
"Signed Out",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
private void btnUsers_Click(object sender, EventArgs e)
{
var user = SessionManager.CurrentUser;
if (user == null || (!user.Permissions.Contains("Manage Users") && !user.Permissions.Contains("Full Control")))
{
MessageBox.Show(
"Security Exception: You do not possess the required credentials ('Manage Users' or 'Full Control') to access directory configuration.",
"Access Denied",
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
return;
}
using (var userSettings = new UserSettings())
{
userSettings.ShowDialog(this);
}
// After closing settings, refresh the session UI (in case the current user's profile was changed)
UpdateSessionUi();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
// Unsubscribe to prevent reference leaks
SessionManager.SessionStateChanged -= UpdateSessionUi;
base.OnFormClosing(e);
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.Security.Cryptography;
using System.Text;
namespace UserPermissionTest_CS_WinForms
{
public static class PasswordHasher
{
/// <summary>
/// Hashes the plain-text password using SHA-256.
/// </summary>
public static string HashPassword(string password)
{
if (password == null) throw new ArgumentNullException(nameof(password));
using (SHA256 sha256 = SHA256.Create())
{
byte[] bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString();
}
}
/// <summary>
/// Verifies whether the entered plain-text password matches the stored SHA-256 hash.
/// </summary>
public static bool VerifyPassword(string enteredPassword, string storedHash)
{
if (enteredPassword == null || storedHash == null) return false;
string hashedInput = HashPassword(enteredPassword);
return hashedInput.Equals(storedHash, StringComparison.OrdinalIgnoreCase);
}
}
}
+16
View File
@@ -0,0 +1,16 @@
using System;
using System.Windows.Forms;
namespace UserPermissionTest_CS_WinForms
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace UserPermissionTest_CS_WinForms
{
public static class SessionManager
{
private static readonly IUserRepository UserRepository = new JsonUserRepository();
public static User? CurrentUser { get; private set; }
public static List<User> Users { get; private set; } = new List<User>();
public static List<string> AvailablePermissions { get; private set; } = new List<string>();
public static event Action? SessionStateChanged;
public static event Action? UsersUpdated;
static SessionManager()
{
// Load state from repository
Users = UserRepository.LoadUsers();
AvailablePermissions = UserRepository.LoadPermissions();
}
public static bool Login(string username, string password)
{
var user = Users.FirstOrDefault(u =>
u.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
if (user != null && PasswordHasher.VerifyPassword(password, user.Password))
{
CurrentUser = user;
SessionStateChanged?.Invoke();
return true;
}
return false;
}
public static void Logout()
{
if (CurrentUser != null)
{
CurrentUser = null;
SessionStateChanged?.Invoke();
}
}
public static void AddUser(User user)
{
Users.Add(user);
UserRepository.SaveUsers(Users);
UsersUpdated?.Invoke();
}
public static void UpdateUser(string oldUsername, User updatedUser)
{
var index = Users.FindIndex(u => u.Username.Equals(oldUsername, StringComparison.OrdinalIgnoreCase));
if (index >= 0)
{
Users[index] = updatedUser;
// If updated user is currently logged in, update current user too
if (CurrentUser != null && CurrentUser.Username.Equals(oldUsername, StringComparison.OrdinalIgnoreCase))
{
CurrentUser = updatedUser;
SessionStateChanged?.Invoke();
}
UserRepository.SaveUsers(Users);
UsersUpdated?.Invoke();
}
}
public static void DeleteUser(string username)
{
var user = Users.FirstOrDefault(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
if (user != null)
{
Users.Remove(user);
// If deleted user is logged in, log out
if (CurrentUser != null && CurrentUser.Username.Equals(username, StringComparison.OrdinalIgnoreCase))
{
CurrentUser = null;
SessionStateChanged?.Invoke();
}
UserRepository.SaveUsers(Users);
UsersUpdated?.Invoke();
}
}
public static void AddPermission(string permission)
{
if (!AvailablePermissions.Contains(permission))
{
AvailablePermissions.Add(permission);
UserRepository.SavePermissions(AvailablePermissions);
UsersUpdated?.Invoke();
}
}
}
}
+24
View File
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
namespace UserPermissionTest_CS_WinForms
{
public class User
{
public string Username { get; set; } = string.Empty;
public string FullName { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public List<string> Permissions { get; set; } = new List<string>();
public User Clone()
{
return new User
{
Username = this.Username,
FullName = this.FullName,
Password = this.Password,
Permissions = new List<string>(this.Permissions)
};
}
}
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net481</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
</Project>
+402
View File
@@ -0,0 +1,402 @@
namespace UserPermissionTest_CS_WinForms
{
partial class UserSettings
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.pnlHeader = new System.Windows.Forms.Panel();
this.lblTitle = new System.Windows.Forms.Label();
this.lblSubtitle = new System.Windows.Forms.Label();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.btnDeleteUser = new System.Windows.Forms.Button();
this.btnAddUser = new System.Windows.Forms.Button();
this.lstUsers = new System.Windows.Forms.ListBox();
this.lblUsersList = new System.Windows.Forms.Label();
this.grpPermissions = new System.Windows.Forms.GroupBox();
this.btnAddNewPermission = new System.Windows.Forms.Button();
this.txtNewPermission = new System.Windows.Forms.TextBox();
this.lblNewPermission = new System.Windows.Forms.Label();
this.chkPermissions = new System.Windows.Forms.CheckedListBox();
this.btnSaveUser = new System.Windows.Forms.Button();
this.txtPassword = new System.Windows.Forms.TextBox();
this.btnTogglePassword = new System.Windows.Forms.Button();
this.lblPassword = new System.Windows.Forms.Label();
this.txtFullName = new System.Windows.Forms.TextBox();
this.lblFullName = new System.Windows.Forms.Label();
this.txtUsername = new System.Windows.Forms.TextBox();
this.lblUsername = new System.Windows.Forms.Label();
this.lblDetailsHeader = new System.Windows.Forms.Label();
this.pnlHeader.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.grpPermissions.SuspendLayout();
this.SuspendLayout();
//
// pnlHeader
//
this.pnlHeader.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(41)))), ((int)(((byte)(59)))));
this.pnlHeader.Controls.Add(this.lblTitle);
this.pnlHeader.Controls.Add(this.lblSubtitle);
this.pnlHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.pnlHeader.Location = new System.Drawing.Point(0, 0);
this.pnlHeader.Name = "pnlHeader";
this.pnlHeader.Size = new System.Drawing.Size(834, 80);
this.pnlHeader.TabIndex = 0;
//
// lblTitle
//
this.lblTitle.AutoSize = true;
this.lblTitle.Font = new System.Drawing.Font("Segoe UI Semibold", 16F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTitle.ForeColor = System.Drawing.Color.White;
this.lblTitle.Location = new System.Drawing.Point(20, 15);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(262, 30);
this.lblTitle.TabIndex = 0;
this.lblTitle.Text = "UserSettings && Directory";
//
// lblSubtitle
//
this.lblSubtitle.AutoSize = true;
this.lblSubtitle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblSubtitle.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(148)))), ((int)(((byte)(163)))), ((int)(((byte)(184)))));
this.lblSubtitle.Location = new System.Drawing.Point(22, 45);
this.lblSubtitle.Name = "lblSubtitle";
this.lblSubtitle.Size = new System.Drawing.Size(325, 15);
this.lblSubtitle.TabIndex = 1;
this.lblSubtitle.Text = "Manage user credentials, personal details, and security roles.";
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.Location = new System.Drawing.Point(0, 80);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.splitContainer.Panel1.Controls.Add(this.btnDeleteUser);
this.splitContainer.Panel1.Controls.Add(this.btnAddUser);
this.splitContainer.Panel1.Controls.Add(this.lstUsers);
this.splitContainer.Panel1.Controls.Add(this.lblUsersList);
this.splitContainer.Panel1.Padding = new System.Windows.Forms.Padding(15);
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.BackColor = System.Drawing.Color.White;
this.splitContainer.Panel2.Controls.Add(this.grpPermissions);
this.splitContainer.Panel2.Controls.Add(this.btnSaveUser);
this.splitContainer.Panel2.Controls.Add(this.txtPassword);
this.splitContainer.Panel2.Controls.Add(this.btnTogglePassword);
this.splitContainer.Panel2.Controls.Add(this.lblPassword);
this.splitContainer.Panel2.Controls.Add(this.txtFullName);
this.splitContainer.Panel2.Controls.Add(this.lblFullName);
this.splitContainer.Panel2.Controls.Add(this.txtUsername);
this.splitContainer.Panel2.Controls.Add(this.lblUsername);
this.splitContainer.Panel2.Controls.Add(this.lblDetailsHeader);
this.splitContainer.Panel2.Padding = new System.Windows.Forms.Padding(20);
this.splitContainer.Size = new System.Drawing.Size(834, 461);
this.splitContainer.SplitterDistance = 250;
this.splitContainer.TabIndex = 1;
//
// btnDeleteUser
//
this.btnDeleteUser.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(254)))), ((int)(((byte)(242)))), ((int)(((byte)(242)))));
this.btnDeleteUser.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnDeleteUser.FlatAppearance.BorderSize = 0;
this.btnDeleteUser.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnDeleteUser.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnDeleteUser.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(239)))), ((int)(((byte)(68)))), ((int)(((byte)(68)))));
this.btnDeleteUser.Location = new System.Drawing.Point(130, 410);
this.btnDeleteUser.Name = "btnDeleteUser";
this.btnDeleteUser.Size = new System.Drawing.Size(105, 36);
this.btnDeleteUser.TabIndex = 3;
this.btnDeleteUser.Text = "Delete User";
this.btnDeleteUser.UseVisualStyleBackColor = false;
this.btnDeleteUser.Click += new System.EventHandler(this.btnDeleteUser_Click);
//
// btnAddUser
//
this.btnAddUser.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(99)))), ((int)(((byte)(102)))), ((int)(((byte)(241)))));
this.btnAddUser.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnAddUser.FlatAppearance.BorderSize = 0;
this.btnAddUser.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnAddUser.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnAddUser.ForeColor = System.Drawing.Color.White;
this.btnAddUser.Location = new System.Drawing.Point(15, 410);
this.btnAddUser.Name = "btnAddUser";
this.btnAddUser.Size = new System.Drawing.Size(105, 36);
this.btnAddUser.TabIndex = 2;
this.btnAddUser.Text = "+ Add User";
this.btnAddUser.UseVisualStyleBackColor = false;
this.btnAddUser.Click += new System.EventHandler(this.btnAddUser_Click);
//
// lstUsers
//
this.lstUsers.BackColor = System.Drawing.Color.White;
this.lstUsers.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.lstUsers.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lstUsers.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.lstUsers.FormattingEnabled = true;
this.lstUsers.ItemHeight = 17;
this.lstUsers.Location = new System.Drawing.Point(15, 40);
this.lstUsers.Name = "lstUsers";
this.lstUsers.Size = new System.Drawing.Size(220, 359);
this.lstUsers.TabIndex = 1;
this.lstUsers.SelectedIndexChanged += new System.EventHandler(this.lstUsers_SelectedIndexChanged);
//
// lblUsersList
//
this.lblUsersList.AutoSize = true;
this.lblUsersList.Font = new System.Drawing.Font("Segoe UI Semibold", 11F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblUsersList.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(65)))), ((int)(((byte)(85)))));
this.lblUsersList.Location = new System.Drawing.Point(15, 12);
this.lblUsersList.Name = "lblUsersList";
this.lblUsersList.Size = new System.Drawing.Size(114, 20);
this.lblUsersList.TabIndex = 0;
this.lblUsersList.Text = "Users Directory";
//
// grpPermissions
//
this.grpPermissions.Controls.Add(this.btnAddNewPermission);
this.grpPermissions.Controls.Add(this.txtNewPermission);
this.grpPermissions.Controls.Add(this.lblNewPermission);
this.grpPermissions.Controls.Add(this.chkPermissions);
this.grpPermissions.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.grpPermissions.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(65)))), ((int)(((byte)(85)))));
this.grpPermissions.Location = new System.Drawing.Point(240, 50);
this.grpPermissions.Name = "grpPermissions";
this.grpPermissions.Size = new System.Drawing.Size(320, 335);
this.grpPermissions.TabIndex = 8;
this.grpPermissions.TabStop = false;
this.grpPermissions.Text = "User Permissions";
//
// btnAddNewPermission
//
this.btnAddNewPermission.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(245)))), ((int)(((byte)(249)))));
this.btnAddNewPermission.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnAddNewPermission.FlatAppearance.BorderSize = 0;
this.btnAddNewPermission.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnAddNewPermission.Font = new System.Drawing.Font("Segoe UI Semibold", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnAddNewPermission.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.btnAddNewPermission.Location = new System.Drawing.Point(240, 292);
this.btnAddNewPermission.Name = "btnAddNewPermission";
this.btnAddNewPermission.Size = new System.Drawing.Size(65, 27);
this.btnAddNewPermission.TabIndex = 3;
this.btnAddNewPermission.Text = "Add";
this.btnAddNewPermission.UseVisualStyleBackColor = false;
this.btnAddNewPermission.Click += new System.EventHandler(this.btnAddNewPermission_Click);
//
// txtNewPermission
//
this.txtNewPermission.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.txtNewPermission.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtNewPermission.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.txtNewPermission.Location = new System.Drawing.Point(15, 293);
this.txtNewPermission.Name = "txtNewPermission";
this.txtNewPermission.Size = new System.Drawing.Size(220, 25);
this.txtNewPermission.TabIndex = 2;
//
// lblNewPermission
//
this.lblNewPermission.AutoSize = true;
this.lblNewPermission.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblNewPermission.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(116)))), ((int)(((byte)(139)))));
this.lblNewPermission.Location = new System.Drawing.Point(15, 275);
this.lblNewPermission.Name = "lblNewPermission";
this.lblNewPermission.Size = new System.Drawing.Size(127, 13);
this.lblNewPermission.TabIndex = 1;
this.lblNewPermission.Text = "Define New Permission:";
//
// chkPermissions
//
this.chkPermissions.BackColor = System.Drawing.Color.White;
this.chkPermissions.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.chkPermissions.CheckOnClick = true;
this.chkPermissions.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.chkPermissions.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.chkPermissions.FormattingEnabled = true;
this.chkPermissions.Location = new System.Drawing.Point(15, 25);
this.chkPermissions.Name = "chkPermissions";
this.chkPermissions.Size = new System.Drawing.Size(290, 240);
this.chkPermissions.TabIndex = 0;
//
// btnSaveUser
//
this.btnSaveUser.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(16)))), ((int)(((byte)(185)))), ((int)(((byte)(129)))));
this.btnSaveUser.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnSaveUser.FlatAppearance.BorderSize = 0;
this.btnSaveUser.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnSaveUser.Font = new System.Drawing.Font("Segoe UI Semibold", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnSaveUser.ForeColor = System.Drawing.Color.White;
this.btnSaveUser.Location = new System.Drawing.Point(20, 395);
this.btnSaveUser.Name = "btnSaveUser";
this.btnSaveUser.Size = new System.Drawing.Size(540, 40);
this.btnSaveUser.TabIndex = 7;
this.btnSaveUser.Text = "Save Profile Changes";
this.btnSaveUser.UseVisualStyleBackColor = false;
this.btnSaveUser.Click += new System.EventHandler(this.btnSaveUser_Click);
//
// txtPassword
//
this.txtPassword.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.txtPassword.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtPassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.txtPassword.Location = new System.Drawing.Point(20, 205);
this.txtPassword.Name = "txtPassword";
this.txtPassword.PasswordChar = '•';
this.txtPassword.Size = new System.Drawing.Size(165, 25);
this.txtPassword.TabIndex = 6;
//
// btnTogglePassword
//
this.btnTogglePassword.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(245)))), ((int)(((byte)(249)))));
this.btnTogglePassword.Cursor = System.Windows.Forms.Cursors.Hand;
this.btnTogglePassword.FlatAppearance.BorderSize = 0;
this.btnTogglePassword.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.btnTogglePassword.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnTogglePassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.btnTogglePassword.Location = new System.Drawing.Point(190, 205);
this.btnTogglePassword.Name = "btnTogglePassword";
this.btnTogglePassword.Size = new System.Drawing.Size(30, 25);
this.btnTogglePassword.TabIndex = 9;
this.btnTogglePassword.Text = "👁";
this.btnTogglePassword.UseVisualStyleBackColor = false;
this.btnTogglePassword.Click += new System.EventHandler(this.btnTogglePassword_Click);
//
// lblPassword
//
this.lblPassword.AutoSize = true;
this.lblPassword.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblPassword.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.lblPassword.Location = new System.Drawing.Point(20, 185);
this.lblPassword.Name = "lblPassword";
this.lblPassword.Size = new System.Drawing.Size(66, 17);
this.lblPassword.TabIndex = 5;
this.lblPassword.Text = "Password";
//
// txtFullName
//
this.txtFullName.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.txtFullName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtFullName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.txtFullName.Location = new System.Drawing.Point(20, 145);
this.txtFullName.Name = "txtFullName";
this.txtFullName.Size = new System.Drawing.Size(200, 25);
this.txtFullName.TabIndex = 4;
//
// lblFullName
//
this.lblFullName.AutoSize = true;
this.lblFullName.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblFullName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.lblFullName.Location = new System.Drawing.Point(20, 125);
this.lblFullName.Name = "lblFullName";
this.lblFullName.Size = new System.Drawing.Size(69, 17);
this.lblFullName.TabIndex = 3;
this.lblFullName.Text = "Full Name";
//
// txtUsername
//
this.txtUsername.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(250)))), ((int)(((byte)(252)))));
this.txtUsername.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.txtUsername.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(23)))), ((int)(((byte)(42)))));
this.txtUsername.Location = new System.Drawing.Point(20, 85);
this.txtUsername.Name = "txtUsername";
this.txtUsername.Size = new System.Drawing.Size(200, 25);
this.txtUsername.TabIndex = 2;
//
// lblUsername
//
this.lblUsername.AutoSize = true;
this.lblUsername.Font = new System.Drawing.Font("Segoe UI Semibold", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblUsername.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(71)))), ((int)(((byte)(85)))), ((int)(((byte)(105)))));
this.lblUsername.Location = new System.Drawing.Point(20, 65);
this.lblUsername.Name = "lblUsername";
this.lblUsername.Size = new System.Drawing.Size(75, 17);
this.lblUsername.TabIndex = 1;
this.lblUsername.Text = "User Name";
//
// lblDetailsHeader
//
this.lblDetailsHeader.AutoSize = true;
this.lblDetailsHeader.Font = new System.Drawing.Font("Segoe UI Semibold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblDetailsHeader.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(41)))), ((int)(((byte)(59)))));
this.lblDetailsHeader.Location = new System.Drawing.Point(16, 12);
this.lblDetailsHeader.Name = "lblDetailsHeader";
this.lblDetailsHeader.Size = new System.Drawing.Size(150, 21);
this.lblDetailsHeader.TabIndex = 0;
this.lblDetailsHeader.Text = "User Profile Details";
//
// UserSettings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(834, 541);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.pnlHeader);
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "UserSettings";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Directory & Security Manager";
this.Load += new System.EventHandler(this.UserSettings_Load);
this.pnlHeader.ResumeLayout(false);
this.pnlHeader.PerformLayout();
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel1.PerformLayout();
this.splitContainer.Panel2.ResumeLayout(false);
this.splitContainer.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
this.splitContainer.ResumeLayout(false);
this.grpPermissions.ResumeLayout(false);
this.grpPermissions.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel pnlHeader;
private System.Windows.Forms.Label lblTitle;
private System.Windows.Forms.Label lblSubtitle;
private System.Windows.Forms.SplitContainer splitContainer;
private System.Windows.Forms.Label lblUsersList;
private System.Windows.Forms.ListBox lstUsers;
private System.Windows.Forms.Button btnDeleteUser;
private System.Windows.Forms.Button btnAddUser;
private System.Windows.Forms.Label lblDetailsHeader;
private System.Windows.Forms.TextBox txtUsername;
private System.Windows.Forms.Label lblUsername;
private System.Windows.Forms.TextBox txtPassword;
private System.Windows.Forms.Label lblPassword;
private System.Windows.Forms.TextBox txtFullName;
private System.Windows.Forms.Label lblFullName;
private System.Windows.Forms.Button btnSaveUser;
private System.Windows.Forms.GroupBox grpPermissions;
private System.Windows.Forms.CheckedListBox chkPermissions;
private System.Windows.Forms.Button btnAddNewPermission;
private System.Windows.Forms.TextBox txtNewPermission;
private System.Windows.Forms.Label lblNewPermission;
private System.Windows.Forms.Button btnTogglePassword;
}
}
@@ -0,0 +1,385 @@
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 permissions
var checkedPerms = new HashSet<string>();
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
if (chkPermissions.GetItemChecked(i))
{
string? itemText = chkPermissions.Items[i]?.ToString();
if (itemText != null)
{
checkedPerms.Add(itemText);
}
}
}
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++)
{
string? permissionName = chkPermissions.Items[i].ToString();
if (permissionName != null && user.Permissions.Contains(permissionName))
{
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++)
{
string? permissionName = chkPermissions.Items[i].ToString();
if (permissionName != null && checkedPerms.Contains(permissionName))
{
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++)
{
string? permissionName = chkPermissions.Items[i].ToString();
bool hasPermission = permissionName != null && user.Permissions.Contains(permissionName);
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<string> GetCheckedPermissions()
{
var list = new List<string>();
for (int i = 0; i < chkPermissions.Items.Count; i++)
{
if (chkPermissions.GetItemChecked(i))
{
string? permissionName = chkPermissions.Items[i].ToString();
if (permissionName != null)
{
list.Add(permissionName);
}
}
}
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.Contains(newPerm, StringComparer.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);
}
}
}