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;
|
2026-02-02 16:13:40 +08:00
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using Sys = Cosmos.System;
|
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-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;
|
|
|
|
|
|
private List<User> users;
|
2026-01-31 20:50:07 +08:00
|
|
|
|
public bool fixmode = Kernel.FixMode;
|
2026-02-01 15:21:17 +08:00
|
|
|
|
private User currentLoggedInUser;
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
2026-02-05 20:42:16 +08:00
|
|
|
|
public User CurrentLoggedInUser
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return currentLoggedInUser; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
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());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
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-01-31 19:14:13 +08:00
|
|
|
|
LoadUsers();
|
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
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
if (File.Exists(userFilePath))
|
|
|
|
|
|
{
|
|
|
|
|
|
string[] lines = File.ReadAllLines(userFilePath);
|
|
|
|
|
|
users = new List<User>();
|
|
|
|
|
|
|
|
|
|
|
|
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-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
|
|
|
|
|
|
{
|
|
|
|
|
|
users = new List<User>();
|
|
|
|
|
|
}
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
users = new List<User>();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-03 02:04:43 +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-01-31 19:14:13 +08:00
|
|
|
|
public void FirstTimeSetup()
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("====================================");
|
|
|
|
|
|
Console.WriteLine(" First Time Setup");
|
|
|
|
|
|
Console.WriteLine("====================================");
|
2026-02-06 20:30:20 +08:00
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("User Terms and Conditions:");
|
|
|
|
|
|
Console.WriteLine("====================================");
|
|
|
|
|
|
Console.WriteLine("1. This operating system is provided as-is without warranty");
|
|
|
|
|
|
Console.WriteLine("2. You are responsible for your data and backups");
|
|
|
|
|
|
Console.WriteLine("3. Unauthorized access attempts may be logged");
|
|
|
|
|
|
Console.WriteLine("4. System administrators have full access to all data");
|
|
|
|
|
|
Console.WriteLine("5. By using this system, you agree to these terms");
|
|
|
|
|
|
Console.WriteLine("6. Data privacy: Your personal data is stored locally");
|
|
|
|
|
|
Console.WriteLine("7. System updates may be installed automatically");
|
|
|
|
|
|
Console.WriteLine("8. No liability for data loss or corruption");
|
|
|
|
|
|
Console.WriteLine("9. Support available at: leonmmcoset@outlook.com");
|
|
|
|
|
|
Console.WriteLine("10. This license is for personal use only");
|
|
|
|
|
|
Console.WriteLine("====================================");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
|
|
|
|
|
|
bool termsAccepted = false;
|
|
|
|
|
|
while (!termsAccepted)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.Write("Do you accept the User Terms? (yes/no): ");
|
|
|
|
|
|
string response = Console.ReadLine()?.ToLower();
|
|
|
|
|
|
|
|
|
|
|
|
if (response == "yes" || response == "y")
|
|
|
|
|
|
{
|
|
|
|
|
|
termsAccepted = true;
|
|
|
|
|
|
Console.WriteLine("Terms accepted.");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (response == "no" || response == "n")
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("You must accept the User Terms to continue.");
|
|
|
|
|
|
Console.WriteLine("Please restart the setup process.");
|
|
|
|
|
|
Thread.Sleep(2000);
|
|
|
|
|
|
Sys.Power.Reboot();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("Invalid response. Please enter 'yes' or 'no'.");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
Console.WriteLine("Please set admin username and password:");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
Console.Write("Username: ");
|
|
|
|
|
|
string username = Console.ReadLine();
|
|
|
|
|
|
|
|
|
|
|
|
while (string.IsNullOrWhiteSpace(username))
|
|
|
|
|
|
{
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError("Username cannot be empty.");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
Console.Write("Username: ");
|
|
|
|
|
|
username = Console.ReadLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Password: ");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
string password = ReadPassword();
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Please confirm your password:");
|
|
|
|
|
|
string confirmPassword = ReadPassword();
|
|
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
while (password != confirmPassword)
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError("Passwords do not match. Please try again.");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
|
|
|
|
|
Console.Write("Username: ");
|
|
|
|
|
|
username = Console.ReadLine();
|
|
|
|
|
|
|
|
|
|
|
|
while (string.IsNullOrWhiteSpace(username))
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError("Username cannot be empty.");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
Console.Write("Username: ");
|
|
|
|
|
|
username = Console.ReadLine();
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Password: ");
|
|
|
|
|
|
password = ReadPassword();
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Please confirm your password:");
|
|
|
|
|
|
confirmPassword = ReadPassword();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
User adminUser = new User
|
|
|
|
|
|
{
|
|
|
|
|
|
Username = username,
|
|
|
|
|
|
Password = password,
|
|
|
|
|
|
IsAdmin = true
|
|
|
|
|
|
};
|
|
|
|
|
|
users.Add(adminUser);
|
|
|
|
|
|
SaveUsers();
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowSuccess("Admin user created successfully!");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
2026-02-03 23:26:43 +08:00
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("Please set system hostname:");
|
|
|
|
|
|
Console.Write("Hostname: ");
|
|
|
|
|
|
string hostname = Console.ReadLine();
|
|
|
|
|
|
|
|
|
|
|
|
while (string.IsNullOrWhiteSpace(hostname))
|
|
|
|
|
|
{
|
|
|
|
|
|
ShowError("Hostname cannot be empty.");
|
|
|
|
|
|
Console.Write("Hostname: ");
|
|
|
|
|
|
hostname = Console.ReadLine();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (users.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
users[0].Hostname = hostname;
|
|
|
|
|
|
SaveHostname();
|
|
|
|
|
|
ShowSuccess($"Hostname set to: {hostname}");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-02 16:13:40 +08:00
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("System will restart in 3 seconds...");
|
|
|
|
|
|
Console.WriteLine("Please wait...");
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 3; i > 0; i--)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.Write($"\rRestarting in {i} seconds... ");
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-02 18:08:24 +08:00
|
|
|
|
Console.WriteLine("\rRestarting now!");
|
2026-02-02 16:13:40 +08:00
|
|
|
|
Sys.Power.Reboot();
|
2026-01-31 19:14:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError($"Error creating admin user: {ex.Message}");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void CreateUserFolder(string username)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"Creating user folder for {username}...");
|
|
|
|
|
|
|
|
|
|
|
|
// 在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);
|
|
|
|
|
|
Console.WriteLine($"Created user folder for {username}.");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine($"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-02 02:34:42 +08:00
|
|
|
|
ShowError($"Error creating user folder: {ex.Message}");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool Login()
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("====================================");
|
|
|
|
|
|
Console.WriteLine(" System Login");
|
|
|
|
|
|
Console.WriteLine("====================================");
|
2026-01-31 20:50:07 +08:00
|
|
|
|
// Console.ReadKey(true);
|
2026-01-30 21:55:35 +08:00
|
|
|
|
|
2026-01-30 23:36:08 +08:00
|
|
|
|
// 检测ALT+Space按键
|
|
|
|
|
|
bool useFixMode = false;
|
|
|
|
|
|
ConsoleKeyInfo keyInfo;
|
2026-01-30 21:55:35 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2026-01-31 20:50:07 +08:00
|
|
|
|
if (fixmode == true) {
|
|
|
|
|
|
keyInfo = Console.ReadKey(true);
|
|
|
|
|
|
if (keyInfo.Key == ConsoleKey.Spacebar && (keyInfo.Modifiers & ConsoleModifiers.Alt) != 0)
|
2026-01-30 23:36:08 +08:00
|
|
|
|
{
|
2026-01-31 20:50:07 +08:00
|
|
|
|
// 检测到ALT+Space,进入修复模式
|
|
|
|
|
|
useFixMode = true;
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
Console.WriteLine("Fix Mode Activated");
|
|
|
|
|
|
Console.Write("Enter fix code: ");
|
|
|
|
|
|
|
|
|
|
|
|
string fixCode = "";
|
|
|
|
|
|
while (true)
|
2026-01-30 23:36:08 +08:00
|
|
|
|
{
|
2026-01-31 20:50:07 +08:00
|
|
|
|
var codeKey = Console.ReadKey(true);
|
|
|
|
|
|
if (codeKey.Key == ConsoleKey.Enter)
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (codeKey.Key == ConsoleKey.Backspace)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (fixCode.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
fixCode = fixCode.Substring(0, fixCode.Length - 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2026-01-30 23:36:08 +08:00
|
|
|
|
{
|
2026-01-31 20:50:07 +08:00
|
|
|
|
fixCode += codeKey.KeyChar;
|
|
|
|
|
|
Console.Write(codeKey.KeyChar);
|
2026-01-30 23:36:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-31 20:50:07 +08:00
|
|
|
|
|
|
|
|
|
|
if (fixCode == "FixMyComputer")
|
|
|
|
|
|
{
|
|
|
|
|
|
Console.WriteLine("Fix mode enabled!");
|
|
|
|
|
|
}
|
2026-01-30 23:36:08 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2026-01-31 20:50:07 +08:00
|
|
|
|
Console.WriteLine("Invalid fix code. Exiting fix mode.");
|
|
|
|
|
|
useFixMode = false;
|
2026-01-30 23:36:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
// 正常登录流程
|
|
|
|
|
|
Console.Write("Username: ");
|
|
|
|
|
|
string username = Console.ReadLine();
|
2026-01-30 23:36:08 +08:00
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
if (string.IsNullOrWhiteSpace(username))
|
2026-01-30 23:36:08 +08:00
|
|
|
|
{
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError("Username cannot be empty.");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Console.Write("Password: ");
|
|
|
|
|
|
string password = ReadPassword();
|
|
|
|
|
|
|
|
|
|
|
|
// 查找用户
|
|
|
|
|
|
User foundUser = null;
|
|
|
|
|
|
foreach (User user in users)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (user.Username.ToLower() == username.ToLower())
|
2026-01-30 23:36:08 +08:00
|
|
|
|
{
|
2026-01-31 19:14:13 +08:00
|
|
|
|
foundUser = user;
|
2026-01-30 23:36:08 +08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-31 19:14:13 +08:00
|
|
|
|
if (foundUser == null)
|
2026-01-30 23:36:08 +08:00
|
|
|
|
{
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError("User not found.");
|
2026-01-31 19:14:13 +08:00
|
|
|
|
return false;
|
2026-01-30 23:36:08 +08:00
|
|
|
|
}
|
2026-01-31 19:14:13 +08:00
|
|
|
|
|
2026-02-02 04:40:47 +08:00
|
|
|
|
// 使用SHA256加密输入的密码后比较
|
|
|
|
|
|
string hashedInputPassword = HashPasswordSha256(password);
|
|
|
|
|
|
// Console.WriteLine($"Hashed Input Password: {hashedInputPassword}");
|
|
|
|
|
|
// Console.WriteLine($"Stored Password: {foundUser.Password}");
|
|
|
|
|
|
|
|
|
|
|
|
if (foundUser.Password != hashedInputPassword)
|
2026-01-31 19:14:13 +08:00
|
|
|
|
{
|
2026-02-02 04:40:47 +08:00
|
|
|
|
ShowError("Invalid password.");
|
2026-01-30 23:36:08 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2026-02-02 04:40:47 +08:00
|
|
|
|
|
|
|
|
|
|
ShowSuccess("Login successful!");
|
|
|
|
|
|
Console.Beep();
|
|
|
|
|
|
|
|
|
|
|
|
// 设置当前登录用户
|
|
|
|
|
|
currentLoggedInUser = foundUser;
|
|
|
|
|
|
|
|
|
|
|
|
// 创建用户文件夹
|
|
|
|
|
|
CreateUserFolder(foundUser.Username);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
2026-01-30 21:55:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-30 23:36:08 +08:00
|
|
|
|
catch
|
2026-01-30 21:55:35 +08:00
|
|
|
|
{
|
2026-01-30 23:36:08 +08:00
|
|
|
|
// 如果读取按键失败,使用普通登录
|
2026-02-02 02:34:42 +08:00
|
|
|
|
ShowError("Error reading key input. Using normal login.");
|
2026-01-30 21:55:35 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2026-01-30 23:36:08 +08:00
|
|
|
|
|
|
|
|
|
|
// 如果使用了修复模式,返回true
|
|
|
|
|
|
if (useFixMode)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
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);
|
2026-02-02 20:53:49 +08:00
|
|
|
|
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
|
|
|
|
}
|