Init commit

add security encryption and hashing: WIP
add endpoints: register user, get and save resources
add db main operations, User entity
This commit is contained in:
Alex Bezdieniezhnykh
2024-11-09 00:37:43 +02:00
commit 121052a3ef
26 changed files with 605 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="linq2db" Version="5.4.1" />
</ItemGroup>
</Project>
+18
View File
@@ -0,0 +1,18 @@
namespace Azaion.Common;
public class BusinessException(ExceptionEnum exEnum, string message) : Exception(message)
{
private ExceptionEnum ExceptionEnum { get; set; } = exEnum;
}
public enum ExceptionEnum
{
NoUserFound = 10,
UserExists = 20,
PasswordIncorrect = 30,
UserLengthIncorrect = 33,
WrongEmail = 35,
PasswordLengthIncorrect = 37,
HardwareIdMismatch = 40,
WrongResourceType = 50
}
@@ -0,0 +1,6 @@
namespace Azaion.Common.Configs;
public class ConnectionStrings
{
public string AzaionDb { get; set; } = null!;
}
+7
View File
@@ -0,0 +1,7 @@
namespace Azaion.Common.Configs;
public class ResourcesConfig
{
public string ResourcesFolder { get; set; } = null!;
public Dictionary<string, string> Resources { get; set; } = null!;
}
+10
View File
@@ -0,0 +1,10 @@
using Azaion.Common.Entities;
using LinqToDB;
using LinqToDB.Data;
namespace Azaion.Common.Database;
public class AzaionDb(DataOptions dataOptions) : DataConnection(dataOptions)
{
public ITable<User> Users => this.GetTable<User>();
}
@@ -0,0 +1,21 @@
using Azaion.Common.Entities;
using LinqToDB.Mapping;
namespace Azaion.Common.Database;
public static class AzaionDbSchemaHolder
{
public static readonly MappingSchema MappingSchema;
static AzaionDbSchemaHolder()
{
MappingSchema = new MappingSchema();
var builder = new FluentMappingBuilder(MappingSchema);
builder.Entity<User>()
.HasTableName("users")
.HasIdentity(x => x.Id);
builder.Build();
}
}
+48
View File
@@ -0,0 +1,48 @@
using System.Diagnostics;
using LinqToDB;
namespace Azaion.Common.Database;
public interface IDbFactory
{
Task<T> Run<T>(Func<AzaionDb, Task<T>> func);
Task Run(Func<AzaionDb, Task> func);
T Run<T>(Func<AzaionDb, T> func);
}
public class DbFactory : IDbFactory
{
private readonly DataOptions _dataOptions;
public DbFactory(string connectionString, bool useTracing = true, bool msSql = false)
{
if (string.IsNullOrEmpty(connectionString))
throw new ArgumentException("Empty connectionString", nameof(connectionString));
_dataOptions = new DataOptions()
.UsePostgreSQL(connectionString)
.UseMappingSchema(AzaionDbSchemaHolder.MappingSchema);
if (useTracing)
_ = _dataOptions.UseTracing(TraceLevel.Info, t => Console.WriteLine(t.SqlText));
}
public async Task<T> Run<T>(Func<AzaionDb, Task<T>> func)
{
await using var db = new AzaionDb(_dataOptions);
return await func(db);
}
public async Task Run(Func<AzaionDb, Task> func)
{
await using var db = new AzaionDb(_dataOptions);
await func(db);
}
public T Run<T>(Func<AzaionDb, T> func)
{
using var db = new AzaionDb(_dataOptions);
return func(db);
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Azaion.Common.Entities;
public enum ResourceEnum
{
AnnotatorDll = 10,
AIModelRKNN = 20,
AIModelONNX = 20,
}
+9
View File
@@ -0,0 +1,9 @@
namespace Azaion.Common;
public enum RoleEnum
{
Operator,
Validator,
CompanionPC,
Admin
}
+12
View File
@@ -0,0 +1,12 @@
namespace Azaion.Common.Entities;
public class User
{
public string Id { get; set; } = null!;
public string Username { get; set; } = null!;
public string PasswordHash { get; set; } = null!;
public string HardwareId { get; set; } = null!;
public RoleEnum Role { get; set; }
public string UniqueKey => $"Azaion#{Username}#{PasswordHash}#{HardwareId}";
}
@@ -0,0 +1,17 @@
using Azaion.Common.Entities;
namespace Azaion.Common.Requests;
public class GetResourceRequest
{
public string Username { get; set; } = null!;
public string Password { get; set; } = null!;
public string HardwareId { get; set; } = null!;
public ResourceEnum ResourceEnum { get; set; }
}
public class UploadResourceRequest
{
public ResourceEnum ResourceEnum { get; set; }
public Stream Data { get; set; } = null!;
}
@@ -0,0 +1,22 @@
using FluentValidation;
namespace Azaion.Common.Requests;
public class RegisterUserRequest
{
public string Email { get; set; } = null!;
public string Password { get; set; } = null!;
public RoleEnum Role { get; set; }
}
public class RegisterUserValidator : AbstractValidator<RegisterUserRequest>
{
public RegisterUserValidator()
{
RuleFor(r => r.Email)
.MinimumLength(8).WithErrorCode(ExceptionEnum.UserLengthIncorrect.ToString()).WithMessage("Email address should be at least 8 characters.")
.EmailAddress().WithErrorCode(ExceptionEnum.WrongEmail.ToString()).WithMessage("Email address is not valid.");
RuleFor(r => r.Password)
.MinimumLength(8).WithErrorCode(ExceptionEnum.PasswordLengthIncorrect.ToString()).WithMessage("Password should be at least 8 characters.");
} }