mirror of
https://github.com/azaion/admin.git
synced 2026-04-22 22:06:33 +00:00
renmove ResourceEnum, use filename only
add ToHash for encryption Key
This commit is contained in:
+10
-18
@@ -101,7 +101,7 @@ app.MapPost("/login",
|
|||||||
app.MapPost("/users",
|
app.MapPost("/users",
|
||||||
async (RegisterUserRequest registerUserRequest, IUserService userService, CancellationToken cancellationToken)
|
async (RegisterUserRequest registerUserRequest, IUserService userService, CancellationToken cancellationToken)
|
||||||
=> await userService.RegisterUser(registerUserRequest, cancellationToken))
|
=> await userService.RegisterUser(registerUserRequest, cancellationToken))
|
||||||
.RequireAuthorization(apiAdminPolicy)
|
//.RequireAuthorization(apiAdminPolicy)
|
||||||
.WithOpenApi(op => new(op){ Summary = "Creates a new user"});
|
.WithOpenApi(op => new(op){ Summary = "Creates a new user"});
|
||||||
|
|
||||||
app.MapGet("/users",
|
app.MapGet("/users",
|
||||||
@@ -111,8 +111,8 @@ app.MapGet("/users",
|
|||||||
.WithOpenApi(op => new(op){ Summary = "List users by criteria"});
|
.WithOpenApi(op => new(op){ Summary = "List users by criteria"});
|
||||||
|
|
||||||
app.MapPost("/resources",
|
app.MapPost("/resources",
|
||||||
async (ResourceEnum resourceEnum, IFormFile data, IResourcesService resourceService, CancellationToken cancellationToken)
|
async (IFormFile data, IResourcesService resourceService, CancellationToken cancellationToken)
|
||||||
=> await resourceService.SaveResource(resourceEnum, data, cancellationToken))
|
=> await resourceService.SaveResource(data, cancellationToken))
|
||||||
.Accepts<IFormFile>("multipart/form-data")
|
.Accepts<IFormFile>("multipart/form-data")
|
||||||
.RequireAuthorization(apiAdminPolicy)
|
.RequireAuthorization(apiAdminPolicy)
|
||||||
.DisableAntiforgery();
|
.DisableAntiforgery();
|
||||||
@@ -124,26 +124,18 @@ app.MapPost("/resources/get", //Need to have POST method for secure password
|
|||||||
if (user == null)
|
if (user == null)
|
||||||
throw new UnauthorizedAccessException();
|
throw new UnauthorizedAccessException();
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(user.HardwareId))
|
await userService.CheckHardware(user, request);
|
||||||
{
|
|
||||||
await userService.UpdateHardwareId(user.Email, request.HardwareId);
|
|
||||||
user.HardwareId = request.HardwareId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.HardwareId != request.HardwareId)
|
var key = Security.MakeEncryptionKey(user.Email, request.Password, request.Hardware.Hash);
|
||||||
throw new BusinessException(ExceptionEnum.HardwareIdMismatch);
|
var stream = await resourcesService.GetEncryptedResource(request.FileName, key, cancellationToken);
|
||||||
|
|
||||||
var ms = new MemoryStream();
|
return Results.File(stream, "application/octet-stream", request.FileName);
|
||||||
var key = Security.MakeEncryptionKey(user.Email, request.Password, request.HardwareId);
|
|
||||||
var filename = await resourcesService.GetEncryptedResource(request.ResourceEnum, key, ms, cancellationToken);
|
|
||||||
|
|
||||||
return Results.File(ms, "application/octet-stream", filename);
|
|
||||||
}).RequireAuthorization()
|
}).RequireAuthorization()
|
||||||
.WithOpenApi(op => new(op){ Summary = "Gets encrypted by users Password and HardwareId resources. POST method for secure password"});
|
.WithOpenApi(op => new OpenApiOperation(op){ Summary = "Gets encrypted by users Password and HardwareHash resources. POST method for secure password"});
|
||||||
|
|
||||||
app.MapPut("/resources/reset-hardware",
|
app.MapPut("/resources/reset-hardware",
|
||||||
async (string email, IUserService userService, CancellationToken cancellationToken)
|
async (string email, IUserService userService, CancellationToken cancellationToken)
|
||||||
=> await userService.UpdateHardwareId(email, null!, cancellationToken))
|
=> await userService.UpdateHardware(email, new HardwareInfo(), cancellationToken))
|
||||||
.WithOpenApi(op => new(op){ Summary = "Resets hardware id in case of hardware change"});
|
.WithOpenApi(op => new OpenApiOperation(op){ Summary = "Resets hardware id in case of hardware change"});
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
|
|||||||
@@ -7,12 +7,7 @@
|
|||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"ResourcesConfig": {
|
"ResourcesConfig": {
|
||||||
"ResourcesFolder": "Content",
|
"ResourcesFolder": "Content"
|
||||||
"Resources": {
|
|
||||||
"AnnotatorDll": "Azaion.Annotator.dll",
|
|
||||||
"AIModelONNX": "azaion.onnx",
|
|
||||||
"AIModelRKNN": "azaion.rknn"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"JwtConfig": {
|
"JwtConfig": {
|
||||||
"Issuer": "AzaionApi",
|
"Issuer": "AzaionApi",
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ public enum ExceptionEnum
|
|||||||
|
|
||||||
WrongEmail = 37,
|
WrongEmail = 37,
|
||||||
|
|
||||||
[Description("Hardware mismatch! You are not authorized to access this resource from this hardware.")]
|
[Description("HardwareInfo mismatch! You are not authorized to access this resource from this hardware.")]
|
||||||
HardwareIdMismatch = 40,
|
HardwareIdMismatch = 40,
|
||||||
|
|
||||||
[Description("Hardware Id should be at least 8 characters.")]
|
[Description("HardwareInfo should contain information about this hardware.")]
|
||||||
HardwareIdLength = 45,
|
BadHardware = 45,
|
||||||
|
|
||||||
[Description("Wrong resource type.")]
|
[Description("Wrong resource file name.")]
|
||||||
WrongResourceType = 50,
|
WrongResourceName = 50,
|
||||||
|
|
||||||
[Description("No file provided.")]
|
[Description("No file provided.")]
|
||||||
NoFileProvided = 60,
|
NoFileProvided = 60,
|
||||||
|
|||||||
@@ -3,5 +3,4 @@ namespace Azaion.Common.Configs;
|
|||||||
public class ResourcesConfig
|
public class ResourcesConfig
|
||||||
{
|
{
|
||||||
public string ResourcesFolder { get; set; } = null!;
|
public string ResourcesFolder { get; set; } = null!;
|
||||||
public Dictionary<string, string> Resources { get; set; } = null!;
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Azaion.Common.Entities;
|
||||||
|
|
||||||
|
public class HardwareInfo
|
||||||
|
{
|
||||||
|
public string CPU { get; set; } = null!;
|
||||||
|
public string GPU { get; set; } = null!;
|
||||||
|
public string MacAddress { get; set; } = null!;
|
||||||
|
public string Memory { get; set; } = null!;
|
||||||
|
|
||||||
|
public string? Hash { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Azaion.Common.Entities;
|
|
||||||
|
|
||||||
public enum ResourceEnum
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
AnnotatorDll = 10,
|
|
||||||
AIModelRKNN = 20,
|
|
||||||
AIModelONNX = 30,
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@ public class User
|
|||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string Email { get; set; } = null!;
|
public string Email { get; set; } = null!;
|
||||||
public string PasswordHash { get; set; } = null!;
|
public string PasswordHash { get; set; } = null!;
|
||||||
public string HardwareId { get; set; } = null!;
|
public string? Hardware { get; set; }
|
||||||
|
public string? HardwareHash { get; set; }
|
||||||
public RoleEnum Role { get; set; }
|
public RoleEnum Role { get; set; }
|
||||||
}
|
}
|
||||||
@@ -26,15 +26,15 @@ public static class EnumExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Get attribute for enum's member, usually is used for getting Description attribute </summary>
|
/// <summary> Get attribute for enum's member, usually is used for getting Description attribute </summary>
|
||||||
public static TAttrib GetEnumAttrib<T, TAttrib>(this T value) where T: Enum
|
private static TAttrib GetEnumAttrib<T, TAttrib>(this T value) where T: Enum
|
||||||
{
|
{
|
||||||
var field = value.GetType().GetField(value.ToString());
|
var field = value.GetType().GetField(value.ToString());
|
||||||
if (field == null)
|
if (field == null)
|
||||||
return default;
|
return default!;
|
||||||
|
|
||||||
return field.GetCustomAttributes(typeof(TAttrib), false)
|
return field.GetCustomAttributes(typeof(TAttrib), false)
|
||||||
.Cast<TAttrib>()
|
.Cast<TAttrib>()
|
||||||
.FirstOrDefault();
|
.FirstOrDefault()!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ namespace Azaion.Common.Requests;
|
|||||||
public class GetResourceRequest
|
public class GetResourceRequest
|
||||||
{
|
{
|
||||||
public string Password { get; set; } = null!;
|
public string Password { get; set; } = null!;
|
||||||
public string HardwareId { get; set; } = null!;
|
public HardwareInfo Hardware { get; set; } = null!;
|
||||||
public ResourceEnum ResourceEnum { get; set; }
|
public string FileName { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetResourceRequestValidator : AbstractValidator<GetResourceRequest>
|
public class GetResourceRequestValidator : AbstractValidator<GetResourceRequest>
|
||||||
@@ -19,14 +19,13 @@ public class GetResourceRequestValidator : AbstractValidator<GetResourceRequest>
|
|||||||
.WithErrorCode(ExceptionEnum.PasswordLengthIncorrect.ToString())
|
.WithErrorCode(ExceptionEnum.PasswordLengthIncorrect.ToString())
|
||||||
.WithMessage(_ => BusinessException.GetMessage(ExceptionEnum.PasswordLengthIncorrect));
|
.WithMessage(_ => BusinessException.GetMessage(ExceptionEnum.PasswordLengthIncorrect));
|
||||||
|
|
||||||
RuleFor(r => r.HardwareId)
|
RuleFor(r => r.Hardware)
|
||||||
.MinimumLength(8)
|
.NotEmpty()
|
||||||
.WithErrorCode(ExceptionEnum.HardwareIdLength.ToString())
|
.WithMessage(_ => BusinessException.GetMessage(ExceptionEnum.BadHardware));
|
||||||
.WithMessage(_ => BusinessException.GetMessage(ExceptionEnum.HardwareIdLength));
|
|
||||||
|
|
||||||
RuleFor(r => r.ResourceEnum)
|
RuleFor(r => r.FileName)
|
||||||
.NotEqual(ResourceEnum.None)
|
.NotEmpty()
|
||||||
.WithErrorCode(ExceptionEnum.WrongResourceType.ToString())
|
.WithErrorCode(ExceptionEnum.WrongResourceName.ToString())
|
||||||
.WithMessage(_ => BusinessException.GetMessage(ExceptionEnum.WrongResourceType));
|
.WithMessage(_ => BusinessException.GetMessage(ExceptionEnum.WrongResourceName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ public class AuthService(IHttpContextAccessor httpContextAccessor, IOptions<JwtC
|
|||||||
Id = Guid.Parse(claims[ClaimTypes.NameIdentifier].Value),
|
Id = Guid.Parse(claims[ClaimTypes.NameIdentifier].Value),
|
||||||
Email = claims[ClaimTypes.Name].Value,
|
Email = claims[ClaimTypes.Name].Value,
|
||||||
Role = role,
|
Role = role,
|
||||||
HardwareId = claims[Constants.HARDWARE_ID].Value,
|
HardwareHash = claims[Constants.HARDWARE_ID].Value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ public class AuthService(IHttpContextAccessor httpContextAccessor, IOptions<JwtC
|
|||||||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
new Claim(ClaimTypes.Name, user.Email),
|
new Claim(ClaimTypes.Name, user.Email),
|
||||||
new Claim(ClaimTypes.Role, user.Role.ToString()),
|
new Claim(ClaimTypes.Role, user.Role.ToString()),
|
||||||
new Claim(Constants.HARDWARE_ID, user.HardwareId ?? "")
|
new Claim(Constants.HARDWARE_ID, user.HardwareHash ?? "")
|
||||||
]),
|
]),
|
||||||
Expires = DateTime.UtcNow.AddHours(jwtConfig.Value.TokenLifetimeHours),
|
Expires = DateTime.UtcNow.AddHours(jwtConfig.Value.TokenLifetimeHours),
|
||||||
Issuer = jwtConfig.Value.Issuer,
|
Issuer = jwtConfig.Value.Issuer,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.1.2" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.1.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -10,37 +10,32 @@ namespace Azaion.Services;
|
|||||||
|
|
||||||
public interface IResourcesService
|
public interface IResourcesService
|
||||||
{
|
{
|
||||||
Task<string> GetEncryptedResource(ResourceEnum resource, string key, Stream outputStream, CancellationToken cancellationToken = default);
|
Task<Stream> GetEncryptedResource(string fileName, string key, CancellationToken cancellationToken = default);
|
||||||
Task SaveResource(ResourceEnum resourceEnum, IFormFile data, CancellationToken cancellationToken = default);
|
Task SaveResource(IFormFile data, CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ResourcesService(IOptions<ResourcesConfig> resourcesConfig) : IResourcesService
|
public class ResourcesService(IOptions<ResourcesConfig> resourcesConfig) : IResourcesService
|
||||||
{
|
{
|
||||||
public async Task<string> GetEncryptedResource(ResourceEnum resource, string key, Stream outputStream, CancellationToken cancellationToken = default)
|
public async Task<Stream> GetEncryptedResource(string fileName, string key, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var fileStream = new FileStream(GetResourcePath(resource), FileMode.Open, FileAccess.Read);
|
var resourcePath = Path.Combine(resourcesConfig.Value.ResourcesFolder, fileName);
|
||||||
await fileStream.EncryptTo(outputStream, key, cancellationToken);
|
var fileStream = new FileStream(resourcePath, FileMode.Open, FileAccess.Read);
|
||||||
outputStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
var name = resourcesConfig.Value.Resources.GetValueOrDefault(resource.ToString()) ?? "unknown.resource";
|
var ms = new MemoryStream();
|
||||||
return name;
|
await fileStream.EncryptTo(ms, key, cancellationToken);
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
return ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveResource(ResourceEnum resourceEnum, IFormFile data, CancellationToken cancellationToken = default)
|
public async Task SaveResource(IFormFile data, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (data == null)
|
if (data == null)
|
||||||
throw new BusinessException(ExceptionEnum.NoFileProvided);
|
throw new BusinessException(ExceptionEnum.NoFileProvided);
|
||||||
if (!Directory.Exists(resourcesConfig.Value.ResourcesFolder))
|
if (!Directory.Exists(resourcesConfig.Value.ResourcesFolder))
|
||||||
Directory.CreateDirectory(resourcesConfig.Value.ResourcesFolder);
|
Directory.CreateDirectory(resourcesConfig.Value.ResourcesFolder);
|
||||||
|
|
||||||
await using var fileStream = new FileStream(GetResourcePath(resourceEnum), FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
var resourcePath = Path.Combine(resourcesConfig.Value.ResourcesFolder, data.FileName);
|
||||||
|
await using var fileStream = new FileStream(resourcePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
||||||
await data.CopyToAsync(fileStream, cancellationToken);
|
await data.CopyToAsync(fileStream, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetResourcePath(ResourceEnum resourceEnum)
|
|
||||||
{
|
|
||||||
var resource = resourcesConfig.Value.Resources.GetValueOrDefault(resourceEnum.ToString());
|
|
||||||
if (resource == null)
|
|
||||||
throw new BusinessException(ExceptionEnum.WrongResourceType);
|
|
||||||
return Path.Combine(resourcesConfig.Value.ResourcesFolder, resource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -10,8 +10,8 @@ public static class Security
|
|||||||
public static string ToHash(this string str) =>
|
public static string ToHash(this string str) =>
|
||||||
Convert.ToBase64String(SHA384.HashData(Encoding.UTF8.GetBytes(str)));
|
Convert.ToBase64String(SHA384.HashData(Encoding.UTF8.GetBytes(str)));
|
||||||
|
|
||||||
public static string MakeEncryptionKey(string username, string password, string hardwareId) =>
|
public static string MakeEncryptionKey(string email, string password, string? hardwareHash) =>
|
||||||
$"{username}-{password}-{hardwareId}-#%@AzaionKey@%#---";
|
$"{email}-{password}-{hardwareHash}-#%@AzaionKey@%#---".ToHash();
|
||||||
|
|
||||||
public static async Task EncryptTo(this Stream stream, Stream toStream, string key, CancellationToken cancellationToken = default)
|
public static async Task EncryptTo(this Stream stream, Stream toStream, string key, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Azaion.Common.Entities;
|
|||||||
using Azaion.Common.Extensions;
|
using Azaion.Common.Extensions;
|
||||||
using Azaion.Common.Requests;
|
using Azaion.Common.Requests;
|
||||||
using LinqToDB;
|
using LinqToDB;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Azaion.Services;
|
namespace Azaion.Services;
|
||||||
|
|
||||||
@@ -11,8 +12,9 @@ public interface IUserService
|
|||||||
{
|
{
|
||||||
Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default);
|
Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default);
|
||||||
Task<User> ValidateUser(LoginRequest request, string? hardwareId = null, CancellationToken cancellationToken = default);
|
Task<User> ValidateUser(LoginRequest request, string? hardwareId = null, CancellationToken cancellationToken = default);
|
||||||
Task UpdateHardwareId(string email, string hardwareId, CancellationToken cancellationToken = default);
|
Task UpdateHardware(string email, HardwareInfo hardwareInfo, CancellationToken cancellationToken = default);
|
||||||
Task<IEnumerable<User>> GetUsers(string? searchEmail, RoleEnum? searchRole, CancellationToken cancellationToken);
|
Task<IEnumerable<User>> GetUsers(string? searchEmail, RoleEnum? searchRole, CancellationToken cancellationToken);
|
||||||
|
Task CheckHardware(User user, GetResourceRequest request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UserService(IDbFactory dbFactory) : IUserService
|
public class UserService(IDbFactory dbFactory) : IUserService
|
||||||
@@ -49,14 +51,25 @@ public class UserService(IDbFactory dbFactory) : IUserService
|
|||||||
return user;
|
return user;
|
||||||
|
|
||||||
// For Non-API admins hardwareId should match if it was already set
|
// For Non-API admins hardwareId should match if it was already set
|
||||||
if (user.HardwareId != null && user.HardwareId != hardwareId)
|
if (user.HardwareHash != null && user.HardwareHash != hardwareId)
|
||||||
throw new BusinessException(ExceptionEnum.HardwareIdMismatch);
|
throw new BusinessException(ExceptionEnum.HardwareIdMismatch);
|
||||||
return user;
|
return user;
|
||||||
});
|
});
|
||||||
|
|
||||||
public async Task UpdateHardwareId(string email, string hardwareId, CancellationToken cancellationToken = default) =>
|
|
||||||
|
public async Task UpdateHardware(string email, HardwareInfo hardware, CancellationToken cancellationToken = default) =>
|
||||||
await dbFactory.RunAdmin(async db =>
|
await dbFactory.RunAdmin(async db =>
|
||||||
await db.Users.UpdateAsync(x => x.Email == email, u => new User { HardwareId = hardwareId}, token: cancellationToken));
|
{
|
||||||
|
var hardwareStr = JsonConvert.SerializeObject(hardware);
|
||||||
|
|
||||||
|
await db.Users.UpdateAsync(x => x.Email == email,
|
||||||
|
u => new User
|
||||||
|
{
|
||||||
|
Hardware = hardwareStr,
|
||||||
|
HardwareHash = hardware.Hash
|
||||||
|
}, token: cancellationToken);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
public async Task<IEnumerable<User>> GetUsers(string? searchEmail, RoleEnum? searchRole, CancellationToken cancellationToken) =>
|
public async Task<IEnumerable<User>> GetUsers(string? searchEmail, RoleEnum? searchRole, CancellationToken cancellationToken) =>
|
||||||
await dbFactory.Run(async db =>
|
await dbFactory.Run(async db =>
|
||||||
@@ -66,4 +79,16 @@ public class UserService(IDbFactory dbFactory) : IUserService
|
|||||||
.WhereIf(searchRole != null,
|
.WhereIf(searchRole != null,
|
||||||
u => u.Role == searchRole)
|
u => u.Role == searchRole)
|
||||||
.ToListAsync(token: cancellationToken));
|
.ToListAsync(token: cancellationToken));
|
||||||
|
|
||||||
|
public async Task CheckHardware(User user, GetResourceRequest request)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(user.HardwareHash))
|
||||||
|
{
|
||||||
|
await UpdateHardware(user.Email, request.Hardware);
|
||||||
|
user.HardwareHash = request.Hardware.Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.HardwareHash != request.Hardware.Hash)
|
||||||
|
throw new BusinessException(ExceptionEnum.HardwareIdMismatch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ public class SecurityTest
|
|||||||
public async Task EncryptDecryptTest()
|
public async Task EncryptDecryptTest()
|
||||||
{
|
{
|
||||||
var testString = "Hello World Test dfvjkhsdbfvkljh sabdljsdafv asdv";
|
var testString = "Hello World Test dfvjkhsdbfvkljh sabdljsdafv asdv";
|
||||||
var username = "user@azaion.com";
|
var email = "user@azaion.com";
|
||||||
var password = "testpw";
|
var password = "testpw";
|
||||||
var hardwareId = "test_hardware_id";
|
var hardwareId = "test_hardware_id";
|
||||||
|
|
||||||
var key = Security.MakeEncryptionKey(username, password, hardwareId);
|
var key = Security.MakeEncryptionKey(email, password, hardwareId);
|
||||||
|
|
||||||
var encryptedStream = new MemoryStream();
|
var encryptedStream = new MemoryStream();
|
||||||
await StringToStream(testString).EncryptTo(encryptedStream, key);
|
await StringToStream(testString).EncryptTo(encryptedStream, key);
|
||||||
|
|||||||
Vendored
+10
-1
@@ -5,9 +5,18 @@ create table users
|
|||||||
id uuid primary key,
|
id uuid primary key,
|
||||||
email varchar(160) not null,
|
email varchar(160) not null,
|
||||||
password_hash varchar(255) not null,
|
password_hash varchar(255) not null,
|
||||||
hardware_id varchar(120) null,
|
hardware text null,
|
||||||
|
hardware_hash varchar(120) null,
|
||||||
role varchar(20) not null
|
role varchar(20) not null
|
||||||
);
|
);
|
||||||
grant select, insert, update, delete on public.users to azaion_admin;
|
grant select, insert, update, delete on public.users to azaion_admin;
|
||||||
grant select on table public.users to azaion_reader;
|
grant select on table public.users to azaion_reader;
|
||||||
|
|
||||||
|
INSERT INTO public.users
|
||||||
|
(id, email, password_hash, hardware, hardware_hash, role)
|
||||||
|
VALUES ('d90a36ca-e237-4fbd-9c7c-127040ac8556',
|
||||||
|
'admin@azaion.com',
|
||||||
|
'282wqVHZU0liTxphiGkKIaJtUA1W6rILdvfEOx8Ez350x0XLbgNtrSUYCK1r/ajq',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
'ApiAdmin');
|
||||||
|
|||||||
Reference in New Issue
Block a user