390 lines
16 KiB
C#
390 lines
16 KiB
C#
namespace LaaProductionWeb.Services
|
|
{
|
|
using LaaProductionWeb.Data.Interfaces;
|
|
using LaaProductionWeb.Services.Interfaces;
|
|
using LaaProductionWeb.Services.Models.Software;
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Security.Cryptography;
|
|
using System.Text.RegularExpressions;
|
|
|
|
public class SoftwareService : ISoftwareService
|
|
{
|
|
private readonly ISqlClient sqlClient;
|
|
|
|
public SoftwareService(ISqlClient sqlClient)
|
|
=> this.sqlClient = sqlClient;
|
|
|
|
public void AddFunction(short appId, string name)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
INSERT INTO [SoftwareFunctions] (
|
|
[AppId]
|
|
, [Function])
|
|
VALUES (@{nameof(appId)}
|
|
, @{nameof(name)})")
|
|
.AddParameter(nameof(appId), appId)
|
|
.AddParameter(nameof(name), name)
|
|
.ExecuteNonQuery();
|
|
|
|
public int ApplicationId(string name)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT TOP 1 [AppId]
|
|
FROM [VersionSoftwareAccess]
|
|
WHERE [SoftwareAccess_Program] = @{nameof(name)}")
|
|
.AddParameter(nameof(name), name)
|
|
.FirstOrDefault(x => x.GetSmallint());
|
|
|
|
public void DeleteFunction(int funcId)
|
|
{
|
|
this.sqlClient
|
|
.CreateCommand($@"
|
|
DELETE FROM [SoftwareFunctions]
|
|
WHERE [Id] = @{nameof(funcId)}")
|
|
.AddParameter(nameof(funcId), funcId)
|
|
.ExecuteNonQuery();
|
|
|
|
this.sqlClient
|
|
.CreateCommand($@"
|
|
DELETE FROM [UsersFunctions]
|
|
WHERE [SoftwareFunctionId] = @{nameof(funcId)}")
|
|
.AddParameter(nameof(funcId), funcId)
|
|
.ExecuteNonQuery();
|
|
}
|
|
|
|
public short FindAndUpdateSoftware(string name, IEnumerable<string> functions)
|
|
{
|
|
var appId = this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT TOP 1 [AppId]
|
|
, MAX([SoftwareAccess_VaildTo]) OVER (PARTITION BY [AppId])
|
|
FROM [VersionSoftwareAccess]
|
|
WHERE [SoftwareAccess_Program] = @{nameof(name)}
|
|
AND [SoftwareAccess_VaildTo] > GETDATE()")
|
|
.AddParameter(nameof(name), name)
|
|
.FirstOrDefault(x => x.GetSmallint());
|
|
|
|
if (appId > 0 && functions != null && functions.Any())
|
|
{
|
|
foreach (var function in functions)
|
|
{
|
|
if (Regex.IsMatch(function, "[a-zA-Z_]+"))
|
|
{
|
|
this.AddFunction(appId, function);
|
|
}
|
|
}
|
|
}
|
|
|
|
return appId;
|
|
}
|
|
|
|
public IEnumerable<SoftwareFunction> GetAllSoftwareFunctions()
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [Id]
|
|
, [AppId]
|
|
, [Function]
|
|
FROM [SoftwareFunctions]")
|
|
.ExecuteReader(f => new SoftwareFunction
|
|
{
|
|
Id = f.GetInt(),
|
|
AppId = f.GetSmallint(),
|
|
Function = f.GetString()
|
|
});
|
|
|
|
public IEnumerable<SoftwareFunction> GetSoftwareFunctions(short appId)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [Id]
|
|
, [AppId]
|
|
, [Function]
|
|
FROM [SoftwareFunctions]
|
|
WHERE [AppId] = @{nameof(appId)}")
|
|
.AddParameter(nameof(appId), appId)
|
|
.ExecuteReader(f => new SoftwareFunction
|
|
{
|
|
Id = f.GetInt(),
|
|
AppId = f.GetSmallint(),
|
|
Function = f.GetString()
|
|
});
|
|
|
|
public IEnumerable<string> GetSoftwareFunctions(short appId, short userId)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [SF].[Function] AS [Function]
|
|
FROM [UsersFunctions] AS [UF]
|
|
JOIN [SoftwareFunctions] AS [SF]
|
|
ON [SF].[Id] = [UF].[SoftwareFunctionId]
|
|
WHERE [UF].[UserId] = @{nameof(userId)}
|
|
AND [SF].[AppId] = @{nameof(appId)}")
|
|
.AddParameter(nameof(appId), appId)
|
|
.AddParameter(nameof(userId), userId)
|
|
.ExecuteReader(x => x.GetString());
|
|
|
|
public SoftwareOverview GetSoftwareOverview(short appId)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [vsa].[AppID]
|
|
, [vsa].[SoftwareAccess_Program]
|
|
, COUNT([vsa].[AppID])
|
|
, (SELECT COUNT(1)
|
|
FROM [SoftwareFunctions]
|
|
WHERE [AppId] = [vsa].[AppID]) AS [CountF]
|
|
FROM [VersionSoftwareAccess] AS [vsa]
|
|
WHERE [vsa].[AppID] = @{nameof(appId)}
|
|
GROUP BY [vsa].[AppID]
|
|
, [vsa].[SoftwareAccess_Program]")
|
|
.AddParameter(nameof(appId), appId)
|
|
.FirstOrDefault(x => new SoftwareOverview
|
|
{
|
|
AppId = x.GetSmallint(),
|
|
Name = x.GetString(),
|
|
Versions = x.GetInt(),
|
|
Functions = x.GetInt()
|
|
});
|
|
|
|
public IEnumerable<Software> GetSoftwareVersions(short appId)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [SoftwareAccess_ID]
|
|
, [AppID]
|
|
, [SoftwareAccess_Program]
|
|
, [SoftwareAccess_MajorVersion]
|
|
, [SoftwareAccess_MinorVersion]
|
|
, [SoftwareAccess_BuildVersion]
|
|
, [SoftwareAccess_VaildTo]
|
|
, [SoftwareAccess_Desc]
|
|
FROM [VersionSoftwareAccess]
|
|
WHERE [AppId] = @{nameof(appId)}
|
|
ORDER BY [SoftwareAccess_VaildTo] DESC
|
|
, [SoftwareAccess_MajorVersion] DESC
|
|
, [SoftwareAccess_MinorVersion] DESC
|
|
, [SoftwareAccess_BuildVersion] DESC")
|
|
.AddParameter(nameof(appId), appId)
|
|
.ExecuteReader(x => new Software
|
|
{
|
|
Id = x.GetInt(),
|
|
AppId = x.GetSmallint(),
|
|
FullName = x.GetString(),
|
|
MajorV = x.GetInt(),
|
|
MinorV = x.GetInt(),
|
|
BuildV = x.GetInt(),
|
|
ValidTo = x.GetDate(),
|
|
Description = x.GetString()
|
|
});
|
|
|
|
public IEnumerable<SoftwareOverview> GetSoftwares()
|
|
=> this.sqlClient
|
|
.CreateCommand(@"
|
|
SELECT [VSA].[AppId] AS [AppId]
|
|
, [VSA].[SoftwareAccess_Program] AS [Program]
|
|
, COUNT([VSA].[AppId]) AS [Versions]
|
|
, (SELECT COUNT(1)
|
|
FROM [SoftwareFunctions]
|
|
WHERE [AppId] = [VSA].[AppID]) AS [Functions]
|
|
FROM [VersionSoftwareAccess] AS [VSA]
|
|
GROUP BY [VSA].[AppId]
|
|
, [VSA].[SoftwareAccess_Program]")
|
|
.ExecuteReader(x => new SoftwareOverview
|
|
{
|
|
AppId = x.GetSmallint(),
|
|
Name = x.GetString(),
|
|
Versions = x.GetInt(),
|
|
Functions = x.GetInt(),
|
|
});
|
|
|
|
public IEnumerable<SoftwareUser> GetUsers(string username = null)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [U].[MitarbeiterNr]
|
|
, [U].[Vorname]
|
|
, [U].[Name]
|
|
, [U].[Benutzername]
|
|
, COUNT([UF].[UserId])
|
|
, CAST(CASE WHEN [U].[PasswordHash] IS NULL THEN 0 ELSE 1 END AS BIT)
|
|
FROM [Mitarbeiter] AS [U]
|
|
LEFT JOIN [UsersFunctions] AS [UF]
|
|
ON [UF].[UserId] = [U].[MitarbeiterNr]
|
|
WHERE [U].[Vorname] LIKE @{nameof(username)}
|
|
OR [U].[Name] LIKE @{nameof(username)}
|
|
OR [U].[Benutzername] LIKE @{nameof(username)}
|
|
GROUP BY [U].[MitarbeiterNr]
|
|
, [U].[Vorname]
|
|
, [U].[Name]
|
|
, [U].[Benutzername]
|
|
, [U].[PasswordHash]
|
|
ORDER BY [U].[Vorname]
|
|
, [U].[Name]
|
|
, [U].[Benutzername]")
|
|
.AddParameter(nameof(username), $"%{username}%")
|
|
.ExecuteReader(x => new SoftwareUser
|
|
{
|
|
Id = x.GetSmallint(),
|
|
FirstName = x.GetString(),
|
|
LastName = x.GetString(),
|
|
Username = x.GetString(),
|
|
FunctionsCount = x.GetInt(),
|
|
HasPassword = x.GetBool()
|
|
});
|
|
|
|
public IEnumerable<SoftwareUser> GetUsersWithFunctions(int userId = -1, string username = null)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [U].[MitarbeiterNr]
|
|
, [U].[Vorname]
|
|
, [U].[Name]
|
|
, [U].[Benutzername]
|
|
, COUNT([UF].[UserId])
|
|
, CAST(CASE WHEN [U].[PasswordHash] IS NULL THEN 0 ELSE 1 END AS BIT)
|
|
, (SELECT CAST([SoftwareFunctionId] * -1 AS VARCHAR(MAX))
|
|
FROM [UsersFunctions]
|
|
WHERE [UserId] = [UF].[UserId]
|
|
ORDER BY [SoftwareFunctionId]
|
|
FOR XML PATH (''))
|
|
FROM [Mitarbeiter] AS [U]
|
|
LEFT JOIN [UsersFunctions] AS [UF]
|
|
ON [UF].[UserId] = [U].[MitarbeiterNr]
|
|
WHERE [U].[Vorname] LIKE @{nameof(username)}
|
|
OR [U].[Name] LIKE @{nameof(username)}
|
|
OR [U].[Benutzername] LIKE @{nameof(username)}
|
|
OR [U].[MitarbeiterNr] = @{nameof(userId)}
|
|
GROUP BY [U].[MitarbeiterNr]
|
|
, [U].[Vorname]
|
|
, [U].[Name]
|
|
, [U].[Benutzername]
|
|
, [U].[PasswordHash]
|
|
, [UF].[UserId]
|
|
ORDER BY [U].[Vorname]
|
|
, [U].[Name]
|
|
, [U].[Benutzername]")
|
|
.AddParameter(nameof(username), $"%{username}%")
|
|
.AddParameter(nameof(userId), userId)
|
|
.ExecuteReader(x => new SoftwareUser
|
|
{
|
|
Id = x.GetSmallint(),
|
|
FirstName = x.GetString(),
|
|
LastName = x.GetString(),
|
|
Username = x.GetString(),
|
|
FunctionsCount = x.GetInt(),
|
|
HasPassword = x.GetBool(),
|
|
Functions = x.GetString()
|
|
});
|
|
|
|
public void UpdateFunction(int funcId, string name)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
UPDATE [SoftwareFunctions]
|
|
SET [Function] = @{nameof(name)}
|
|
WHERE [Id] = @{nameof(funcId)}")
|
|
.AddParameter(nameof(funcId), funcId)
|
|
.AddParameter(nameof(name), name)
|
|
.ExecuteNonQuery();
|
|
|
|
public void UpdatePasswordHashes()
|
|
{
|
|
var pwdUsers = this.sqlClient
|
|
.CreateCommand($@"
|
|
SELECT [MitarbeiterNr]
|
|
, [Kennwort]
|
|
FROM [Mitarbeiter]
|
|
WHERE [Kennwort] IS NOT NULL
|
|
AND [PasswordHash] IS NULL")
|
|
.ExecuteReader(x => new KeyValuePair<short, string>(
|
|
key: x.GetSmallint(),
|
|
value: x.GetString()));
|
|
var sha256 = SHA256.Create();
|
|
|
|
foreach (var kvp in pwdUsers)
|
|
{
|
|
var userId = kvp.Key;
|
|
var password = sha256.ComputeHash(kvp.Value);
|
|
|
|
this.sqlClient
|
|
.CreateCommand($@"
|
|
UPDATE [Mitarbeiter]
|
|
SET [PasswordHash] = @{nameof(password)}
|
|
WHERE [MitarbeiterNr] = @{nameof(userId)}")
|
|
.AddParameter(nameof(userId), userId)
|
|
.AddParameter(nameof(password), password)
|
|
.ExecuteNonQuery();
|
|
}
|
|
}
|
|
|
|
public int ResetPassword(short userId)
|
|
=> this.sqlClient
|
|
.CreateCommand($@"
|
|
UPDATE [Mitarbeiter]
|
|
SET [PasswordHash] = NULL
|
|
WHERE [MitarbeiterNr] = @{nameof(userId)}")
|
|
.AddParameter(nameof(userId), userId)
|
|
.ExecuteNonQuery();
|
|
|
|
public int ResetPassword(short userId, string password)
|
|
{
|
|
password = SHA256.Create().ComputeHash(password);
|
|
|
|
return this.sqlClient
|
|
.CreateCommand($@"
|
|
UPDATE [Mitarbeiter]
|
|
SET [PasswordHash] = @{nameof(password)}
|
|
WHERE [MitarbeiterNr] = @{nameof(userId)}")
|
|
.AddParameter(nameof(userId), userId)
|
|
.AddParameter(nameof(password), password)
|
|
.ExecuteNonQuery();
|
|
}
|
|
|
|
public void UpdateUsersFunctions(Action<UserFunctions> mapper)
|
|
{
|
|
var model = new UserFunctions();
|
|
mapper(model);
|
|
|
|
var userId = model.UserId;
|
|
|
|
this.sqlClient
|
|
.CreateCommand($@"DELETE FROM [UsersFunctions] WHERE [UserId] = @{nameof(userId)}")
|
|
.AddParameter(nameof(userId), userId)
|
|
.ExecuteNonQuery();
|
|
|
|
foreach (var funcId in model.Functions ?? Array.Empty<int>())
|
|
{
|
|
this.sqlClient
|
|
.CreateCommand($@"
|
|
INSERT
|
|
INTO [UsersFunctions] ([UserId] ,[SoftwareFunctionId])
|
|
VALUES (@{nameof(userId)}, @{nameof(funcId)})")
|
|
.AddParameter(nameof(userId), userId)
|
|
.AddParameter(nameof(funcId), funcId)
|
|
.ExecuteNonQuery();
|
|
}
|
|
}
|
|
|
|
public void UpdateUsersFunctions(Action<FunctionUsers> mapper)
|
|
{
|
|
var model = new FunctionUsers();
|
|
mapper(model);
|
|
|
|
var funcId = model.FunctionId;
|
|
|
|
this.sqlClient
|
|
.CreateCommand($@"DELETE FROM [UsersFunctions] WHERE [SoftwareFunctionId] = @{nameof(funcId)}")
|
|
.AddParameter(nameof(funcId), funcId)
|
|
.ExecuteNonQuery();
|
|
|
|
foreach (var userId in model.Users ?? Array.Empty<short>())
|
|
{
|
|
this.sqlClient
|
|
.CreateCommand($@"
|
|
INSERT
|
|
INTO [UsersFunctions] ([UserId] ,[SoftwareFunctionId])
|
|
VALUES (@{nameof(userId)}, @{nameof(funcId)})")
|
|
.AddParameter(nameof(userId), userId)
|
|
.AddParameter(nameof(funcId), funcId)
|
|
.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|
|
}
|