added login via mysql

added getselfuser from mysql
This commit is contained in:
Tim G. | SnapixLP 2025-06-06 01:41:45 +02:00
parent 57e8f64095
commit 2645d698d7
3 changed files with 164 additions and 50 deletions

View File

@ -5,7 +5,7 @@ namespace Library;
public class Employee public class Employee
{ {
public string Id { get; set; } public int Id { get; set; }
public string Code { get; set; } public string Code { get; set; }
public string Surname { get; set; } public string Surname { get; set; }
public string Forename { get; set; } public string Forename { get; set; }
@ -23,7 +23,6 @@ public class Employee
public Employee(string code, string surname, string forename, string email) public Employee(string code, string surname, string forename, string email)
{ {
Id = Guid.NewGuid().ToString();
Code = code; Code = code;
Surname = surname; Surname = surname;
Forename = forename; Forename = forename;

View File

@ -1,4 +1,5 @@
using System.Net.Sockets; using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Text.Json; using System.Text.Json;
using DX86; using DX86;
using Library; using Library;
@ -30,27 +31,73 @@ public class CommandLibrary
[Command("login")] [Command("login")]
public static string LoginCommand(string[] args, TcpClient? client, TcpServer? socket) public static string LoginCommand(string[] args, TcpClient? client, TcpServer? socket)
{ {
// 1) Argument check
if (args.Length < 2) if (args.Length < 2)
throw new CommandException("Missing arguments: usage is login <username> <password>"); throw new CommandException("Missing arguments: usage is login <employeeCode> <4-digit PIN>");
string username = args[0]; string employeeCode = args[0];
string password = args[1]; string pinCode = args[1];
if (socket?.LoggedInClients.ContainsKey(client) == true) // 2) Prevent doublelogin
if (client != null && socket?.LoggedInClients.ContainsKey(client) == true)
throw new CommandException("User already logged in."); throw new CommandException("User already logged in.");
if (username == "TEST" && password == "1234") // 3) Look up the employee by Code
var empParams = new Dictionary<string, object> { { "Code", employeeCode } };
string empResultJson = Program.mySql.Get("employees", empParams);
using var empDoc = JsonDocument.Parse(empResultJson);
bool empError = empDoc.RootElement.GetProperty("error").GetBoolean();
if (empError)
{ {
if (client != null) string dbMsg = empDoc.RootElement.GetProperty("data").GetString() ?? "Unknown DB error";
{ Program.messageSender.Error($"[LoginCommand] DB error when looking up employee: {dbMsg}");
socket?.LoggedInClients.Add(client, username); throw new CommandException("Internal error while checking credentials.");
return "success";
} }
var empArray = empDoc.RootElement.GetProperty("data");
if (empArray.GetArrayLength() == 0)
{
// No employee with that Code
throw new CommandException("Invalid employee code or PIN.");
}
// 4) Extract Id from the first row
var empRow = empArray[0];
int employeeId = empRow.GetProperty("Id").GetInt32();
// 5) Check PIN for that employeeId
var pinParams = new Dictionary<string, object>
{
{ "EmployeeId", employeeId },
{ "PinCode", pinCode }
};
string pinResultJson = Program.mySql.Get("employee_pins", pinParams);
using var pinDoc = JsonDocument.Parse(pinResultJson);
bool pinError = pinDoc.RootElement.GetProperty("error").GetBoolean();
if (pinError)
{
string dbMsg = pinDoc.RootElement.GetProperty("data").GetString() ?? "Unknown DB error";
Program.messageSender.Error($"[LoginCommand] DB error when checking PIN: {dbMsg}");
throw new CommandException("Internal error while checking credentials.");
}
var pinArray = pinDoc.RootElement.GetProperty("data");
if (pinArray.GetArrayLength() == 0)
{
// No matching PIN entry
throw new CommandException("Invalid employee code or PIN.");
}
// 6) Successful login → add client to LoggedInClients
if (client == null)
throw new CommandException("No client connection detected."); throw new CommandException("No client connection detected.");
}
throw new CommandException("Invalid username or password."); socket!.LoggedInClients.Add(client, employeeCode);
// 7) Return “success” (instead of full Employee JSON)
return "success";
} }
[Command("logout")] [Command("logout")]
@ -67,15 +114,60 @@ public class CommandLibrary
[Command("getSelfUser")] [Command("getSelfUser")]
public static string GetSelfUserCommand(TcpClient? client, TcpServer? socket) public static string GetSelfUserCommand(TcpClient? client, TcpServer? socket)
{ {
// 1) Check for a valid client/socket
if (client == null || socket == null) if (client == null || socket == null)
throw new CommandException("No client connection detected."); throw new CommandException("No client connection detected.");
if (socket.LoggedInClients.TryGetValue(client, out var username)) // 2) See if this client is logged in
if (!socket.LoggedInClients.TryGetValue(client, out var employeeCode))
throw new CommandException("User not logged in.");
// 3) Query the database for that employeeCode
var empParams = new Dictionary<string, object>
{ {
return GenerateTestEmployee().ToJson(); { "Code", employeeCode }
};
string empResultJson = Program.mySql.Get("employees", empParams);
using var empDoc = JsonDocument.Parse(empResultJson);
bool empError = empDoc.RootElement.GetProperty("error").GetBoolean();
if (empError)
{
// Extract the “data” field as the DBside error message, if any
string dbMsg = empDoc.RootElement.GetProperty("data").GetString()
?? "Unknown DB error";
Program.messageSender.Error($"[GetSelfUser] DB error when looking up employee: {dbMsg}");
throw new CommandException("Internal error while fetching user data.");
} }
throw new CommandException("User not logged in."); var dataArray = empDoc.RootElement.GetProperty("data");
if (dataArray.GetArrayLength() == 0)
{
// No employee row found for this code
throw new CommandException("Loggedin user not found in database.");
}
// 4) We expect exactly one row. Take the first element:
var firstRow = dataArray[0];
// 5) Deserialize it into an Employee object.
// This requires that Employee.Id is an int (matching the DB schema),
// or you map fields manually if Id remains a string.
Employee self;
try
{
string employeeJson = firstRow.GetRawText();
self = JsonSerializer.Deserialize<Employee>(employeeJson)
?? throw new InvalidOperationException("Deserialized Employee was null.");
}
catch (Exception ex)
{
Program.messageSender.Error($"[GetSelfUser] Failed to deserialize Employee: {ex.Message}");
throw new CommandException("Internal error while parsing user data.");
}
// 6) Return the Employees JSON via the ToJson() helper you already wrote:
return self.ToJson();
} }
#endregion #endregion
@ -86,6 +178,7 @@ public class CommandLibrary
public static string GetCommand(string[] args, TcpClient? client, TcpServer? socket) => public static string GetCommand(string[] args, TcpClient? client, TcpServer? socket) =>
$"not implemented yet, args: {string.Join(", ", args)}"; $"not implemented yet, args: {string.Join(", ", args)}";
#endregion #endregion
#region DEV-TEST #region DEV-TEST

View File

@ -38,7 +38,7 @@ namespace Server;
{ {
messageSender.Log("[Program] Loaded existing database configuration."); messageSender.Log("[Program] Loaded existing database configuration.");
// Use existing credentials to connect (including cfg.Port) // Use existing credentials to connect (including cfg.Port)
return new MySQL(cfg.Username, cfg.Password, cfg.Server, cfg.Port, cfg.Database, messageSender); return InitializeDatabase(cfg.Username, cfg.Password, cfg.Server, cfg.Port, cfg.Database);
} }
else else
{ {
@ -69,11 +69,9 @@ private static MySQL InitializeDatabase(
{ {
// 1) Instantiate MySQL (will exit on failure) // 1) Instantiate MySQL (will exit on failure)
var db = new MySQL(username, password, server, port, database, messageSender); var db = new MySQL(username, password, server, port, database, messageSender);
// 2) Create the 'employees' table if it does not exist:
string createEmployeesTable = @" string createEmployeesTable = @"
CREATE TABLE IF NOT EXISTS `employees` ( CREATE TABLE IF NOT EXISTS `employees` (
`Id` VARCHAR(36) NOT NULL PRIMARY KEY, `Id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`Code` VARCHAR(50) NOT NULL, `Code` VARCHAR(50) NOT NULL,
`Surname` VARCHAR(100) NOT NULL, `Surname` VARCHAR(100) NOT NULL,
`Forename` VARCHAR(100) NOT NULL, `Forename` VARCHAR(100) NOT NULL,
@ -89,35 +87,59 @@ private static MySQL InitializeDatabase(
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"; ";
messageSender.Log("[Program] Creating 'employees' table if not present…"); messageSender.Log("[Program] Creating or verifying 'employees' table…");
var resultJson = db.ExecuteNonQuery(createEmployeesTable); var employeesResult = db.ExecuteNonQuery(createEmployeesTable);
// Parse resultJson safely using JsonDocument
try try
{ {
using var doc = JsonDocument.Parse(resultJson); using var doc = JsonDocument.Parse(employeesResult);
var root = doc.RootElement; bool empError = doc.RootElement.GetProperty("error").GetBoolean();
if (empError)
// Expecting { "error": bool, "data": ... }
bool isError = root.GetProperty("error").GetBoolean();
if (isError)
{ {
// You can inspect root.GetProperty("data").GetString() if needed messageSender.Error("[Program] Failed to create/verify 'employees' table: " + employeesResult);
messageSender.Error("[Program] Failed to create 'employees' table: " + resultJson);
Environment.Exit(1); Environment.Exit(1);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
// If something went wrong parsing JSON, treat it as a fatal error messageSender.Error("[Program] Could not parse employees CREATE TABLE response: " + ex.Message);
messageSender.Error($"[Program] Could not parse CREATE TABLE response: {ex.Message}"); messageSender.Error("[Program] Raw response: " + employeesResult);
messageSender.Error("[Program] Raw response: " + resultJson);
Environment.Exit(1); Environment.Exit(1);
} }
messageSender.Log("[Program] 'employees' table is ready."); messageSender.Log("[Program] 'employees' table is ready.");
// TODO: repeat db.ExecuteNonQuery(...) for any other tables you need // 2b) Create a new table for storing 4-digit PINs linked to EmployeeId
string createPinsTable = @"
CREATE TABLE IF NOT EXISTS `employee_pins` (
`PinId` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`EmployeeId` INT NOT NULL,
`PinCode` CHAR(4) NOT NULL,
FOREIGN KEY (`EmployeeId`) REFERENCES `employees`(`Id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
";
messageSender.Log("[Program] Creating or verifying 'employee_pins' table…");
var pinsResult = db.ExecuteNonQuery(createPinsTable);
try
{
using var doc2 = JsonDocument.Parse(pinsResult);
bool pinError = doc2.RootElement.GetProperty("error").GetBoolean();
if (pinError)
{
messageSender.Error("[Program] Failed to create/verify 'employee_pins' table: " + pinsResult);
Environment.Exit(1);
}
}
catch (Exception ex)
{
messageSender.Error("[Program] Could not parse employee_pins CREATE TABLE response: " + ex.Message);
messageSender.Error("[Program] Raw response: " + pinsResult);
Environment.Exit(1);
}
messageSender.Log("[Program] 'employee_pins' table is ready.");
// … (any further tables) …
// 3) Save the new credentials (including port) into config.json: // 3) Save the new credentials (including port) into config.json:
var newCfg = new DbConfig var newCfg = new DbConfig