namespace LaaProduction.Personalization.Repositories { using LaaPackages.SqlClient; using LaaProduction.Personalization.Models; using LaaProduction.Personalization.Repositories.Interfaces; using System; using System.Collections.Generic; using System.Linq; public class EmployeesRepository : IEmployeesRepository { private readonly SqlConnection sqlConnection; public EmployeesRepository(SqlConnection sqlConnection) => this.sqlConnection = sqlConnection; public IEnumerable All() => this.sqlConnection .CreateCommand($@" SELECT [M].[MitarbeiterNr] AS [EmployeeId] , [M].[Vorname] + ' ' + [M].[Name] AS [FullName] , [M].[Benutzername] AS [Username] , [M].[PasswordHash] AS [Password] , [MR].[Recht] AS [Role] , [SF].[Function] AS [Function] FROM [Mitarbeiter] AS [M] LEFT JOIN [MitarbeiterRechte] AS [MR] ON [MR].[MitarbeiterNr] = [M].[MitarbeiterNr] LEFT JOIN [UsersFunctions] AS [UF] ON [UF].[UserId] = [M].[MitarbeiterNr] LEFT JOIN [SoftwareFunctions] AS [SF] ON [SF].[Id] = [UF].[SoftwareFunctionId] ORDER BY [FullName], [Username]") .ExecuteReader(x => new { EmployeeId = x.GetValue(0), FullName = x.GetValue(1), Username = x.GetValue(2), HasPassword = !String.IsNullOrWhiteSpace(x.GetValue(3)), Role = x.GetValue(4), Function = x.GetValue(5) }) .GroupBy(x => new Employee { EmployeeId = x.EmployeeId, FullName = x.FullName, Username = x.Username, HasPassword = x.HasPassword, }, new EmployeeComparer()) .Select(x => { x.Key.Roles = x.Select(r => r.Role).Distinct().Where(r => !String.IsNullOrWhiteSpace(r)); x.Key.RolesCount = x.Key.Roles.Count(); x.Key.Functions = x.Select(f => f.Function).Distinct().Where(r => !String.IsNullOrWhiteSpace(r)); x.Key.FunctionsCount = x.Key.Functions.Count(); return x.Key; }) .ToList(); public void CreateToken(Int16 appId, Int16 userId) => this.sqlConnection .CreateCommand($@" INSERT INTO [MitarbeiterTokens] ( [AppId] , [UserId]) VALUES (@{nameof(appId)} , @{nameof(userId)})") .SetParameter(nameof(appId), appId) .SetParameter(nameof(userId), userId) .ExecuteNonQuery(); public Int16 FindEmployeeNr(Int32 employeeId) => this.sqlConnection .CreateCommand($@" SELECT [MitarbeiterNr] FROM [Mitarbeiter] WHERE [EmployeeId] = @{nameof(employeeId)}") .SetParameter(nameof(employeeId), employeeId) .FirstOrDefault(x => x.GetValue(0)); public Int16 FindEmployeeNr(String username, String password) => this.sqlConnection .CreateCommand($@" SELECT [MitarbeiterNr] FROM [Mitarbeiter] WHERE ([Benutzername] = @{nameof(username)} OR [DomainUser] = @{nameof(username)}) AND [PasswordHash] = @{nameof(password)}") .SetParameter(nameof(username), username) .SetParameter(nameof(password), password) .FirstOrDefault(x => x.GetValue(0)); public Employee Find(Int16 employeeId) => this.sqlConnection .CreateCommand($@" SELECT [M].[MitarbeiterNr] AS [EmployeeId] , [M].[Vorname] + ' ' + [M].[Name] AS [FullName] , [M].[Benutzername] AS [Username] , [M].[PasswordHash] AS [Password] FROM [Mitarbeiter] AS [M] WHERE [M].[MitarbeiterNr] = @{nameof(employeeId)}") .SetParameter(nameof(employeeId), employeeId) .FirstOrDefault(x => new Employee { EmployeeId = x.GetValue(0), FullName = x.GetValue(1), Username = x.GetValue(2), HasPassword = !String.IsNullOrWhiteSpace(x.GetValue(3)) }); public Employee GetEmployee(String token) => this.sqlConnection .CreateCommand($@" SELECT [M].[MitarbeiterNr] , [M].[Vorname] + ' ' + [M].[Name] , [M].[Benutzername] FROM [MitarbeiterTokens] AS [MT] JOIN [Mitarbeiter] AS [M] ON [M].[MitarbeiterNr] = [MT].[UserId] WHERE [MT].[Token] = @{nameof(token)}") .SetParameter(nameof(token), token) .FirstOrDefault(x => new Employee { EmployeeId = x.GetValue(0), FullName = x.GetValue(1), Username = x.GetValue(2) }); public String GetToken(Int16 appId, Int16 userId) => this.sqlConnection .CreateCommand($@" SELECT [Token] FROM [MitarbeiterTokens] WHERE [AppId] = @{nameof(appId)} AND [UserId] = @{nameof(userId)}") .SetParameter(nameof(appId), appId) .SetParameter(nameof(userId), userId) .FirstOrDefault(x => x.GetValue(0)); public EmployeeToken GetTokenData(String token) => this.sqlConnection .CreateCommand($@" SELECT [AppId] , [UserId] FROM [MitarbeiterTokens] WHERE [Token] = @{nameof(token)}") .SetParameter(nameof(token), token) .FirstOrDefault(x => new EmployeeToken { AppId = x.GetValue(0), EmployeeId = x.GetValue(1) }); public IEnumerable GetUserRoles(String token) => this.sqlConnection .CreateCommand($@" SELECT [MR].[Recht] FROM [MitarbeiterTokens] AS [MT] JOIN [MitarbeiterRechte] AS [MR] ON [MR].[MitarbeiterNr] = [MT].[UserId] WHERE [MT].[Token] = @{nameof(token)}") .SetParameter(nameof(token), token) .ExecuteReader(x => x.GetValue(0)); public Int16 Insert(Int32 employeeId, String firstName, String lastName, String phone, String email, String username, String domainname, String password) => this.sqlConnection .CreateCommand($@" INSERT INTO [Mitarbeiter] ( [MitarbeiterNr] , [EmployeeId] , [Vorname] , [Name] , [Telefon] , [Benutzername] , [AnlageDatum] , [eMail] , [DomainUser] , [PasswordHash]) OUTPUT [inserted].[MitarbeiterNr] VALUES ((SELECT MAX([MitarbeiterNr]) + 1 FROM [Mitarbeiter]) , @{nameof(employeeId)} , @{nameof(firstName)} , @{nameof(lastName)} , @{nameof(phone)} , @{nameof(username)} , GETDATE() , @{nameof(email)} , @{nameof(domainname)} , @{nameof(password)})") .SetParameter(nameof(employeeId), employeeId) .SetParameter(nameof(firstName), firstName) .SetParameter(nameof(lastName), lastName) .SetParameter(nameof(phone), phone) .SetParameter(nameof(email), email) .SetParameter(nameof(username), username) .SetParameter(nameof(domainname), domainname) .SetParameter(nameof(password), password) .ExecuteScalar(x => x.GetValue(0)); public void ResetPassword(Int16 employeeId) => this.sqlConnection .CreateCommand($@" UPDATE [Mitarbeiter] SET [PasswordHash] = NULL WHERE [MitarbeiterNr] = @{nameof(employeeId)}") .SetParameter(nameof(employeeId), employeeId) .ExecuteNonQuery(); public void ResetTokens(Int16 employeeId) => this.sqlConnection .CreateCommand($@" DELETE FROM [MitarbeiterTokens] WHERE [UserId] = @{nameof(employeeId)}") .SetParameter(nameof(employeeId), employeeId) .ExecuteNonQuery(); public Boolean SetPassword(Int16 employeeId, String password) => this.sqlConnection .CreateCommand($@" UPDATE [Mitarbeiter] SET [PasswordHash] = @{nameof(password)} WHERE [MitarbeiterNr] = @{nameof(employeeId)}") .SetParameter(nameof(employeeId), employeeId) .SetParameter(nameof(password), password) .ExecuteNonQuery() == 1; public Int16 Update(Int32 employeeId, String firstName, String lastName, String phone, String email, String username, String domainname, String password) { var employeeNr = this.FindEmployeeNr(firstName, lastName, email, domainname); if (employeeNr > 0) { this.sqlConnection .CreateCommand($@" UPDATE [Mitarbeiter] SET [EmployeeId] = @{nameof(employeeId)} , [eMail] = @{nameof(email)} , [Telefon] = @{nameof(phone)} , [Benutzername] = @{nameof(username)} , [DomainUser] = @{nameof(domainname)} , [PasswordHash] = @{nameof(password)} WHERE [MitarbeiterNr] = @{nameof(employeeNr)}") .SetParameter(nameof(employeeNr), employeeNr) .SetParameter(nameof(employeeId), employeeId) .SetParameter(nameof(firstName), firstName) .SetParameter(nameof(lastName), lastName) .SetParameter(nameof(phone), phone) .SetParameter(nameof(email), email) .SetParameter(nameof(username), username) .SetParameter(nameof(domainname), domainname) .SetParameter(nameof(password), password) .ExecuteNonQuery(); return employeeNr.Value; } if (employeeNr is null) { return -1; } else { return default(Int16); } } private Int16? FindEmployeeNr(String firstName, String lastName, String email, String domainname) { var employeeNumbers = this.sqlConnection .CreateCommand($@" SELECT [MitarbeiterNr] FROM [Mitarbeiter] WHERE [Name] = @{nameof(lastName)} AND [Vorname] = @{nameof(firstName)}") .SetParameter(nameof(lastName), lastName) .SetParameter(nameof(firstName), firstName) .ExecuteReader(x => x.GetValue(0)) .ToList(); if (employeeNumbers.Count != 1) { employeeNumbers = this.sqlConnection .CreateCommand($@" SELECT [MitarbeiterNr] FROM [Mitarbeiter] WHERE [eMail] = @{nameof(email)}") .SetParameter(nameof(email), email) .ExecuteReader(x => x.GetValue(0)) .ToList(); if (employeeNumbers.Count != 1) { employeeNumbers = this.sqlConnection .CreateCommand($@" SELECT [MitarbeiterNr] FROM [Mitarbeiter] WHERE [DomainUser] = @{nameof(domainname)}") .SetParameter(nameof(domainname), domainname) .ExecuteReader(x => x.GetValue(0)) .ToList(); } } if (employeeNumbers.Count == 0) { return null; } else if (employeeNumbers.Count > 1) { return default(Int16); } else { return employeeNumbers.First(); } } } }