Files
CMLeonOS/System/UserSystem.cs

937 lines
36 KiB
C#
Raw Normal View History

2026-01-30 21:55:35 +08:00
using System;
2026-01-31 19:14:13 +08:00
using System.Collections.Generic;
2026-01-30 21:55:35 +08:00
using System.IO;
2026-02-02 04:40:47 +08:00
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Sys = Cosmos.System;
2026-02-26 13:33:53 +08:00
using CMLeonOS.Logger;
using CMLeonOS.Settings;
2026-01-30 21:55:35 +08:00
namespace CMLeonOS
{
2026-01-31 19:14:13 +08:00
public class User
{
public string Username { get; set; }
public string Password { get; set; }
public bool IsAdmin { get; set; }
2026-02-03 23:26:43 +08:00
public string Hostname { get; set; }
2026-03-01 17:03:49 +08:00
public List<string> Messages { get; set; }
public bool Admin
{
get { return IsAdmin; }
}
public bool LockedOut { get; set; }
public DateTime LockoutEnd { get; set; }
public bool Authenticate(string password)
{
string hashedInputPassword = UserSystem.HashPasswordSha256(password);
return Password == hashedInputPassword;
}
2026-01-31 19:14:13 +08:00
}
2026-01-30 21:55:35 +08:00
public class UserSystem
{
2026-01-31 19:14:13 +08:00
private string sysDirectory = @"0:\system";
private string userFilePath;
2026-03-01 17:03:49 +08:00
private static List<User> users;
2026-01-31 20:50:07 +08:00
public bool fixmode = Kernel.FixMode;
2026-03-01 17:03:49 +08:00
private static User currentLoggedInUser;
2026-02-26 13:33:53 +08:00
private static CMLeonOS.Logger.Logger _logger = CMLeonOS.Logger.Logger.Instance;
private Dictionary<string, int> loginAttempts = new Dictionary<string, int>();
2026-03-01 17:03:49 +08:00
private static bool initialized = false;
2026-01-30 21:55:35 +08:00
2026-03-01 17:03:49 +08:00
public static List<User> GetUsers()
{
return users;
}
public static User CurrentLoggedInUser
{
get { return currentLoggedInUser; }
}
2026-03-01 17:03:49 +08:00
public static void Initialize()
{
// 清空用户列表并重新加载
users = null;
var tempUserSystem = new UserSystem();
tempUserSystem.LoadUsers();
initialized = true;
_logger.Info("UserSystem", $"User system initialized. Loaded {users?.Count ?? 0} users.");
}
public static void ReloadUsers()
{
// 清空用户列表并重新加载
users = null;
var tempUserSystem = new UserSystem();
tempUserSystem.LoadUsers();
_logger.Info("UserSystem", $"User data reloaded. Total users: {users?.Count ?? 0}");
}
2026-02-02 02:34:42 +08:00
public void ShowError(string error)
{
2026-02-05 11:20:09 +08:00
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"{error}");
Console.ResetColor();
2026-02-02 02:34:42 +08:00
}
public void ShowSuccess(string message)
{
2026-02-05 11:20:09 +08:00
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"{message}");
Console.ResetColor();
2026-02-02 02:34:42 +08:00
}
2026-02-04 02:36:07 +08:00
public static string HashPasswordSha256(string password)
2026-02-02 04:40:47 +08:00
{
Sha256 sha256 = new Sha256();
byte[] passwordBytesUnhashed = Encoding.Unicode.GetBytes(password);
sha256.AddData(passwordBytesUnhashed, 0, (uint)passwordBytesUnhashed.Length);
return Convert.ToBase64String(sha256.GetHash());
}
private static bool ContainsInvalidChars(string input)
{
char[] invalidChars = { '<', '>', ':', '"', '|', '?', '*', '/', '\\', ' ' };
foreach (char c in invalidChars)
{
if (input.Contains(c.ToString()))
{
return true;
}
}
return false;
}
2026-01-30 21:55:35 +08:00
public UserSystem()
{
2026-01-30 23:36:08 +08:00
EnsureSysDirectoryExists();
2026-01-31 19:14:13 +08:00
userFilePath = Path.Combine(sysDirectory, "user.dat");
2026-01-30 23:36:08 +08:00
2026-02-01 15:21:17 +08:00
currentLoggedInUser = null;
2026-03-01 17:03:49 +08:00
// 不在构造函数中调用 LoadUsers(),避免重复初始化
// LoadUsers() 会在 UserSystem.Initialize() 中调用
2026-02-03 23:26:43 +08:00
LoadHostname();
2026-01-30 21:55:35 +08:00
}
2026-01-30 23:36:08 +08:00
private void EnsureSysDirectoryExists()
{
try
{
if (!Directory.Exists(sysDirectory))
{
Directory.CreateDirectory(sysDirectory);
}
}
catch
{
// 忽略目录创建错误
}
}
2026-02-03 23:26:43 +08:00
private void LoadHostname()
{
string hostnameFilePath = Path.Combine(sysDirectory, "hostname.dat");
try
{
if (File.Exists(hostnameFilePath))
{
string hostname = File.ReadAllText(hostnameFilePath);
if (!string.IsNullOrWhiteSpace(hostname))
{
if (users.Count > 0)
{
users[0].Hostname = hostname;
}
}
}
}
catch
{
}
}
private void SaveHostname()
{
string hostnameFilePath = Path.Combine(sysDirectory, "hostname.dat");
try
{
if (users.Count > 0)
{
string hostname = users[0].Hostname;
File.WriteAllText(hostnameFilePath, hostname);
}
}
catch (Exception ex)
{
ShowError($"Error saving hostname: {ex.Message}");
}
}
public string GetHostname()
{
if (users.Count > 0)
{
return users[0].Hostname;
}
return "Not set";
}
public void SetHostname(string hostname)
{
if (string.IsNullOrWhiteSpace(hostname))
{
ShowError("Hostname cannot be empty");
return;
}
if (users.Count > 0)
{
users[0].Hostname = hostname;
SaveHostname();
ShowSuccess($"Hostname set to: {hostname}");
}
else
{
ShowError("No users found. Please create a user first.");
}
}
public void ProcessHostnameCommand(string args)
{
if (string.IsNullOrEmpty(args))
{
ShowError("Usage: hostname <new_hostname>");
return;
}
SetHostname(args);
}
2026-01-31 19:14:13 +08:00
private void LoadUsers()
2026-01-30 21:55:35 +08:00
{
2026-03-01 17:03:49 +08:00
_logger.Info("UserSystem", "LoadUsers() called");
_logger.Info("UserSystem", $" - userFilePath: {userFilePath}");
_logger.Info("UserSystem", $" - File.Exists: {File.Exists(userFilePath)}");
_logger.Info("UserSystem", $" - users is null: {users == null}");
_logger.Info("UserSystem", $" - users.Count: {users?.Count ?? 0}");
2026-01-30 21:55:35 +08:00
try
{
2026-01-31 19:14:13 +08:00
if (File.Exists(userFilePath))
{
2026-03-01 17:03:49 +08:00
_logger.Info("UserSystem", " - Reading user file...");
2026-01-31 19:14:13 +08:00
string[] lines = File.ReadAllLines(userFilePath);
2026-03-01 17:03:49 +08:00
_logger.Info("UserSystem", $" - Total lines in file: {lines.Length}");
// 只在第一次加载时创建列表,后续加载不清空
if (users == null)
{
users = new List<User>();
_logger.Info("UserSystem", " - Created new users list");
}
2026-01-31 19:14:13 +08:00
2026-03-01 17:03:49 +08:00
int userCount = 0;
2026-01-31 19:14:13 +08:00
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#"))
{
continue;
}
string[] parts = line.Split('|');
if (parts.Length >= 2)
{
User user = new User
{
Username = parts[0].Trim(),
Password = parts[1].Trim(),
2026-02-03 23:26:43 +08:00
IsAdmin = parts.Length >= 3 && parts[2].Trim().ToLower() == "admin",
Hostname = parts.Length >= 4 ? parts[3].Trim() : ""
2026-01-31 19:14:13 +08:00
};
users.Add(user);
2026-03-01 17:03:49 +08:00
userCount++;
_logger.Info("UserSystem", $" - Loaded user: {user.Username}, Admin: {user.Admin}");
2026-01-31 19:14:13 +08:00
}
}
2026-02-02 04:40:47 +08:00
2026-03-01 17:03:49 +08:00
_logger.Info("UserSystem", $" - Total users loaded: {userCount}");
2026-02-02 04:40:47 +08:00
// Note: Passwords are stored as SHA256 hashes in the file
// When comparing passwords during login, hash the input password first
2026-01-31 19:14:13 +08:00
}
else
{
2026-03-01 17:03:49 +08:00
// 只在第一次加载时创建列表
if (users == null)
{
users = new List<User>();
_logger.Info("UserSystem", " - Created empty users list (file not found)");
}
else
{
_logger.Info("UserSystem", $" - Using existing users list (count: {users.Count})");
}
2026-01-31 19:14:13 +08:00
}
2026-01-30 21:55:35 +08:00
}
2026-03-01 17:03:49 +08:00
catch (Exception ex)
2026-01-30 21:55:35 +08:00
{
2026-03-01 17:03:49 +08:00
_logger.Error("UserSystem", $"Error loading users: {ex.Message}");
// 只在第一次加载时创建列表
if (users == null)
{
users = new List<User>();
}
2026-01-31 19:14:13 +08:00
}
}
private void SaveUsers()
{
try
{
List<string> lines = new List<string>();
foreach (User user in users)
{
2026-02-06 16:15:24 +08:00
string passwordToSave;
if (IsPasswordAlreadyHashed(user.Password))
{
passwordToSave = user.Password;
}
else
{
passwordToSave = HashPasswordSha256(user.Password);
}
string line = $"{user.Username}|{passwordToSave}|{(user.IsAdmin ? "admin" : "user")}|{user.Hostname}";
2026-01-31 19:14:13 +08:00
lines.Add(line);
}
File.WriteAllLines(userFilePath, lines.ToArray());
2026-01-30 21:55:35 +08:00
}
2026-01-31 19:14:13 +08:00
catch (Exception ex)
{
2026-02-02 02:34:42 +08:00
ShowError($"Error saving users: {ex.Message}");
2026-01-31 19:14:13 +08:00
}
}
2026-02-06 16:15:24 +08:00
private bool IsPasswordAlreadyHashed(string password)
{
if (string.IsNullOrWhiteSpace(password))
{
return false;
}
string trimmedPassword = password.Trim();
if (trimmedPassword.Length < 32)
{
return false;
}
foreach (char c in trimmedPassword)
{
if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '='))
{
return false;
}
}
return true;
}
2026-01-31 19:14:13 +08:00
public bool HasUsers
{
get { return users.Count > 0; }
2026-01-30 21:55:35 +08:00
}
2026-01-31 19:14:13 +08:00
public bool IsAdminSet
2026-01-30 21:55:35 +08:00
{
2026-01-31 19:14:13 +08:00
get
{
foreach (User user in users)
{
if (user.IsAdmin)
{
return true;
}
}
return false;
}
2026-01-30 21:55:35 +08:00
}
public string CurrentUsername
{
get
{
if (currentLoggedInUser != null)
{
return currentLoggedInUser.Username;
}
return "Not logged in";
}
}
2026-02-04 01:55:14 +08:00
public bool CurrentUserIsAdmin
{
get
{
if (currentLoggedInUser != null)
{
return currentLoggedInUser.IsAdmin;
}
return false;
}
}
2026-03-01 17:03:49 +08:00
public static void SetCurrentLoggedInUser(User user)
{
currentLoggedInUser = user;
}
2026-01-31 19:14:13 +08:00
public void FirstTimeSetup()
2026-01-30 21:55:35 +08:00
{
2026-02-07 13:25:15 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear();
2026-02-11 14:18:13 +08:00
var termsBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 18), "User Terms and Conditions", () => { }, true);
2026-02-07 13:25:15 +08:00
termsBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Gray, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.WriteLine("1. This operating system is provided as-is without warranty");
global::System.Console.SetCursorPosition(7, 8);
global::System.Console.WriteLine("2. You are responsible for your data and backups");
global::System.Console.SetCursorPosition(7, 9);
global::System.Console.WriteLine("3. Unauthorized access attempts may be logged");
global::System.Console.SetCursorPosition(7, 10);
global::System.Console.WriteLine("4. System administrators have full access to all data");
global::System.Console.SetCursorPosition(7, 11);
global::System.Console.WriteLine("5. By using this system, you agree to these terms");
global::System.Console.SetCursorPosition(7, 12);
global::System.Console.WriteLine("6. Data privacy: Your personal data is stored locally");
global::System.Console.SetCursorPosition(7, 13);
global::System.Console.WriteLine("7. System updates may be installed automatically");
global::System.Console.SetCursorPosition(7, 14);
global::System.Console.WriteLine("8. No liability for data loss or corruption");
global::System.Console.SetCursorPosition(7, 15);
2026-02-09 21:33:21 +08:00
global::System.Console.WriteLine("9. Support available at: https://lbbs.ecuil.com/#/thread/category/10");
2026-02-07 13:25:15 +08:00
global::System.Console.SetCursorPosition(7, 16);
global::System.Console.WriteLine("10. This license is for personal use only");
2026-02-07 17:26:43 +08:00
global::System.Console.SetCursorPosition(7, 17);
2026-02-09 21:33:21 +08:00
global::System.Console.WriteLine("11. Use of this OS requires recognition of the one-China principle");
2026-02-07 13:25:15 +08:00
bool termsAccepted = false;
while (!termsAccepted)
{
2026-02-07 13:25:15 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("Do you accept the User Terms? (yes/no): ");
string response = global::System.Console.ReadLine()?.ToLower();
if (response == "yes" || response == "y")
{
termsAccepted = true;
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("Terms accepted. ");
}
else if (response == "no" || response == "n")
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("You must accept the User Terms to continue.");
global::System.Threading.Thread.Sleep(2000);
Sys.Power.Reboot();
}
else
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(5, 24);
global::System.Console.Write("Invalid response. Please enter 'yes' or 'no'.");
}
}
2026-02-07 13:25:15 +08:00
global::System.Console.Clear();
var setupBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 12), "Admin Account Setup", () => { }, true);
setupBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
string username = global::System.Console.ReadLine();
2026-01-31 19:14:13 +08:00
while (string.IsNullOrWhiteSpace(username))
2026-01-30 21:55:35 +08:00
{
2026-02-07 13:25:15 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Username cannot be empty. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
username = global::System.Console.ReadLine();
}
while (ContainsInvalidChars(username))
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Username contains invalid characters: < > : \" | ? * / \\ space");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
2026-02-07 13:25:15 +08:00
username = global::System.Console.ReadLine();
2026-01-30 21:55:35 +08:00
}
2026-02-07 13:25:15 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 8);
global::System.Console.Write("Password: ");
string password = ReadPassword();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 9);
global::System.Console.Write("Confirm Password: ");
string confirmPassword = ReadPassword();
while (password != confirmPassword)
2026-02-03 23:26:43 +08:00
{
2026-02-07 13:25:15 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Passwords do not match. Please try again. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
username = global::System.Console.ReadLine();
while (string.IsNullOrWhiteSpace(username))
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Username cannot be empty. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Username: ");
username = global::System.Console.ReadLine();
}
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 8);
global::System.Console.Write("Password: ");
password = ReadPassword();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 9);
global::System.Console.Write("Confirm Password: ");
confirmPassword = ReadPassword();
2026-02-03 23:26:43 +08:00
}
2026-02-07 13:25:15 +08:00
try
2026-02-03 23:26:43 +08:00
{
2026-02-07 13:25:15 +08:00
User adminUser = new User
{
Username = username,
Password = password,
IsAdmin = true
};
users.Add(adminUser);
SaveUsers();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Admin user created successfully! ");
global::System.Console.Clear();
var hostnameBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(5, 5, 70, 8), "Hostname Setup", () => { }, true);
hostnameBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Hostname: ");
string hostname = global::System.Console.ReadLine();
while (string.IsNullOrWhiteSpace(hostname))
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Hostname cannot be empty. ");
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 7);
global::System.Console.Write("Hostname: ");
hostname = global::System.Console.ReadLine();
}
if (users.Count > 0)
{
users[0].Hostname = hostname;
SaveUsers();
}
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(7, 24);
global::System.Console.Write("Hostname set successfully! ");
global::System.Threading.Thread.Sleep(2000);
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear();
global::System.Console.SetCursorPosition(30, 12);
global::System.Console.Write("Setup completed!");
global::System.Console.SetCursorPosition(20, 13);
global::System.Console.Write("System will restart in 3 seconds...");
global::System.Threading.Thread.Sleep(3000);
Sys.Power.Reboot();
2026-02-03 23:26:43 +08:00
}
2026-02-07 13:25:15 +08:00
catch (Exception ex)
{
2026-02-07 13:25:15 +08:00
ShowError($"Error creating admin user: {ex.Message}");
}
2026-01-31 19:14:13 +08:00
}
private void CreateUserFolder(string username)
{
try
{
2026-02-26 13:33:53 +08:00
_logger.Info("UserSystem", $"Creating user folder for {username}...");
2026-01-31 19:14:13 +08:00
// 在user文件夹下创建用户文件夹
string userFolderPath = Path.Combine(@"0:\user", username);
// 检查用户文件夹是否存在
if (!Directory.Exists(userFolderPath))
2026-01-30 21:55:35 +08:00
{
2026-01-31 19:14:13 +08:00
Directory.CreateDirectory(userFolderPath);
2026-02-26 13:33:53 +08:00
_logger.Info("UserSystem", $"Created user folder for {username}.");
2026-01-31 19:14:13 +08:00
}
else
{
2026-02-26 13:33:53 +08:00
_logger.Info("UserSystem", $"User folder for {username} already exists.");
2026-01-30 21:55:35 +08:00
}
}
2026-01-31 19:14:13 +08:00
catch (Exception ex)
2026-01-30 21:55:35 +08:00
{
2026-02-26 13:33:53 +08:00
_logger.Error("UserSystem", $"Error creating user folder for {username}: {ex.Message}");
2026-01-30 21:55:35 +08:00
}
}
public bool Login()
{
2026-02-07 14:50:39 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.Clear();
var loginBox = new CMLeonOS.UI.Window(new CMLeonOS.UI.Rect(15, 8, 50, 10), "Login", () => { }, true);
loginBox.Render();
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 10);
global::System.Console.Write("Username: ");
string username = global::System.Console.ReadLine();
if (string.IsNullOrWhiteSpace(username))
2026-01-30 21:55:35 +08:00
{
2026-02-07 14:50:39 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("Username cannot be empty. ");
global::System.Threading.Thread.Sleep(1000);
return false;
}
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.White, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 11);
global::System.Console.Write("Password: ");
string password = ReadPassword();
User foundUser = null;
foreach (User user in users)
{
if (user.Username.ToLower() == username.ToLower())
2026-01-30 21:55:35 +08:00
{
2026-02-07 14:50:39 +08:00
foundUser = user;
break;
2026-01-30 21:55:35 +08:00
}
}
2026-02-07 14:50:39 +08:00
if (foundUser == null)
2026-01-30 21:55:35 +08:00
{
2026-02-07 14:50:39 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("User not found. ");
global::System.Threading.Thread.Sleep(1000);
2026-01-30 21:55:35 +08:00
return false;
}
2026-02-07 14:50:39 +08:00
string hashedInputPassword = HashPasswordSha256(password);
if (foundUser.Password != hashedInputPassword)
2026-01-30 23:36:08 +08:00
{
string usernameLower = username.ToLower();
if (!loginAttempts.ContainsKey(usernameLower))
{
loginAttempts[usernameLower] = 0;
}
loginAttempts[usernameLower]++;
int attempts = loginAttempts[usernameLower];
int maxAttempts = Settings.SettingsManager.MaxLoginAttempts;
if (attempts >= maxAttempts)
{
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write($"Maximum login attempts ({maxAttempts}) reached. ");
global::System.Console.SetCursorPosition(17, 25);
global::System.Console.Write("Please restart to enter password again. ");
global::System.Threading.Thread.Sleep(3000);
Sys.Power.Reboot();
}
2026-02-07 14:50:39 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Red, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write($"Invalid password. Attempts: {attempts}/{maxAttempts} ");
2026-02-07 14:50:39 +08:00
global::System.Threading.Thread.Sleep(1000);
return false;
2026-01-30 23:36:08 +08:00
}
2026-02-07 14:50:39 +08:00
loginAttempts.Remove(username.ToLower());
2026-02-07 14:50:39 +08:00
CMLeonOS.UI.TUIHelper.SetColors(global::System.ConsoleColor.Green, global::System.ConsoleColor.Black);
global::System.Console.SetCursorPosition(17, 24);
global::System.Console.Write("Login successful! ");
// global::System.Console.WriteLine("Please wait... ");
global::System.Threading.Thread.Sleep(1500);
global::System.Console.ResetColor();
global::System.Console.Clear();
global::System.Console.Beep();
currentLoggedInUser = foundUser;
CreateUserFolder(foundUser.Username);
return true;
2026-01-30 21:55:35 +08:00
}
2026-01-31 19:14:13 +08:00
public bool AddUser(string args, bool isAdmin)
2026-01-30 21:55:35 +08:00
{
2026-01-31 19:14:13 +08:00
Console.WriteLine("====================================");
Console.WriteLine($" Add {(isAdmin ? "Admin" : "User")}");
Console.WriteLine("====================================");
string[] parts = args.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length < 2)
2026-01-30 21:55:35 +08:00
{
2026-02-02 02:34:42 +08:00
ShowError("Error: Please specify username and password");
ShowError($"Usage: user add {(isAdmin ? "admin" : "user")} <username> <password>");
2026-01-31 19:14:13 +08:00
return false;
}
string username = parts[0];
string password = parts[1];
// 检查用户名是否已存在
foreach (User user in users)
{
if (user.Username.ToLower() == username.ToLower())
2026-01-30 21:55:35 +08:00
{
2026-02-02 02:34:42 +08:00
ShowError($"Error: User '{username}' already exists.");
2026-01-31 19:14:13 +08:00
return false;
2026-01-30 21:55:35 +08:00
}
2026-01-31 19:14:13 +08:00
}
try
{
User newUser = new User
2026-01-30 21:55:35 +08:00
{
2026-01-31 19:14:13 +08:00
Username = username,
2026-02-06 02:04:51 +08:00
Password = password,
2026-01-31 19:14:13 +08:00
IsAdmin = isAdmin
};
users.Add(newUser);
SaveUsers();
// 创建用户文件夹
CreateUserFolder(username);
2026-02-02 02:34:42 +08:00
ShowSuccess($"{(isAdmin ? "Admin" : "User")} '{username}' created successfully!");
ShowSuccess("You shall restart the system to apply the changes.");
2026-01-31 19:14:13 +08:00
return true;
}
catch (Exception ex)
{
2026-02-02 02:34:42 +08:00
ShowError($"Error adding user: {ex.Message}");
2026-01-31 19:14:13 +08:00
return false;
}
}
public bool DeleteUser(string username)
{
Console.WriteLine("====================================");
Console.WriteLine(" Delete User");
Console.WriteLine("====================================");
if (string.IsNullOrWhiteSpace(username))
{
2026-02-02 02:34:42 +08:00
ShowError("Error: Please specify username");
ShowError("Usage: user delete <username>");
2026-01-31 19:14:13 +08:00
return false;
}
// 查找用户
User foundUser = null;
foreach (User user in users)
{
if (user.Username.ToLower() == username.ToLower())
{
foundUser = user;
break;
2026-01-30 21:55:35 +08:00
}
2026-01-31 19:14:13 +08:00
}
if (foundUser == null)
{
2026-02-02 02:34:42 +08:00
ShowError($"Error: User '{username}' not found.");
2026-01-31 19:14:13 +08:00
return false;
}
// 检查是否是最后一个管理员
int adminCount = 0;
foreach (User user in users)
{
if (user.IsAdmin)
2026-01-30 21:55:35 +08:00
{
2026-01-31 19:14:13 +08:00
adminCount++;
2026-01-30 21:55:35 +08:00
}
}
2026-01-31 19:14:13 +08:00
if (foundUser.IsAdmin && adminCount <= 1)
{
2026-02-02 02:34:42 +08:00
ShowError("Error: Cannot delete the last admin user.");
2026-01-31 19:14:13 +08:00
return false;
}
try
{
users.Remove(foundUser);
SaveUsers();
2026-02-02 02:34:42 +08:00
ShowSuccess($"User '{username}' deleted successfully!");
2026-01-31 19:14:13 +08:00
return true;
}
catch (Exception ex)
{
2026-02-02 02:34:42 +08:00
ShowError($"Error deleting user: {ex.Message}");
2026-01-31 19:14:13 +08:00
return false;
}
}
public void ListUsers()
{
Console.WriteLine("====================================");
Console.WriteLine(" User List");
Console.WriteLine("====================================");
if (users.Count == 0)
{
Console.WriteLine("No users found.");
return;
}
Console.WriteLine();
foreach (User user in users)
{
string userType = user.IsAdmin ? "[ADMIN]" : "[USER]";
Console.WriteLine($"{userType} {user.Username}");
}
2026-01-30 21:55:35 +08:00
}
public bool ChangePassword()
{
Console.WriteLine("====================================");
Console.WriteLine(" Change Password");
Console.WriteLine("====================================");
2026-01-31 19:14:13 +08:00
Console.Write("Please enter your current password: ");
2026-01-30 21:55:35 +08:00
string currentPassword = ReadPassword();
2026-02-01 15:21:17 +08:00
// 检查是否有用户登录
if (currentLoggedInUser == null)
2026-01-31 19:14:13 +08:00
{
2026-02-02 02:34:42 +08:00
ShowError("Error: No user logged in.");
2026-01-31 19:14:13 +08:00
return false;
}
Console.Write("Please enter your new password: ");
string newPassword = ReadPassword();
Console.WriteLine("Please confirm your new password: ");
string confirmPassword = ReadPassword();
if (newPassword == confirmPassword)
{
try
2026-01-30 21:55:35 +08:00
{
2026-02-01 15:21:17 +08:00
currentLoggedInUser.Password = newPassword;
2026-01-31 19:14:13 +08:00
SaveUsers();
2026-02-02 02:34:42 +08:00
ShowSuccess("Password changed successfully!");
2026-01-30 21:55:35 +08:00
return true;
}
2026-01-31 19:14:13 +08:00
catch (Exception ex)
2026-01-30 21:55:35 +08:00
{
2026-02-02 02:34:42 +08:00
ShowError($"Error changing password: {ex.Message}");
2026-01-30 21:55:35 +08:00
return false;
}
}
2026-01-31 19:14:13 +08:00
else
2026-01-30 21:55:35 +08:00
{
2026-02-02 02:34:42 +08:00
ShowError("New passwords do not match.");
2026-01-30 21:55:35 +08:00
return false;
}
}
2026-01-31 19:14:13 +08:00
private string ReadPassword()
{
string password = "";
while (true)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
if (keyInfo.Key == ConsoleKey.Enter)
{
Console.WriteLine();
break;
}
else if (keyInfo.Key == ConsoleKey.Backspace)
{
if (password.Length > 0)
{
password = password.Substring(0, password.Length - 1);
int cursorLeft = Console.CursorLeft;
int cursorTop = Console.CursorTop;
if (cursorLeft > 0)
{
Console.SetCursorPosition(cursorLeft - 1, cursorTop);
Console.Write(" ");
Console.SetCursorPosition(cursorLeft - 1, cursorTop);
}
2026-01-31 19:14:13 +08:00
}
}
else
{
password += keyInfo.KeyChar;
Console.Write("*");
}
}
return password;
}
2026-01-30 21:55:35 +08:00
}
2026-01-31 19:14:13 +08:00
}