mirror of
https://github.com/azaion/admin.git
synced 2026-04-22 09:06:33 +00:00
renmove ResourceEnum, use filename only
add ToHash for encryption Key
This commit is contained in:
@@ -33,7 +33,7 @@ public class AuthService(IHttpContextAccessor httpContextAccessor, IOptions<JwtC
|
||||
Id = Guid.Parse(claims[ClaimTypes.NameIdentifier].Value),
|
||||
Email = claims[ClaimTypes.Name].Value,
|
||||
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.Name, user.Email),
|
||||
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),
|
||||
Issuer = jwtConfig.Value.Issuer,
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -10,37 +10,32 @@ namespace Azaion.Services;
|
||||
|
||||
public interface IResourcesService
|
||||
{
|
||||
Task<string> GetEncryptedResource(ResourceEnum resource, string key, Stream outputStream, CancellationToken cancellationToken = default);
|
||||
Task SaveResource(ResourceEnum resourceEnum, IFormFile data, CancellationToken cancellationToken = default);
|
||||
Task<Stream> GetEncryptedResource(string fileName, string key, CancellationToken cancellationToken = default);
|
||||
Task SaveResource(IFormFile data, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
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);
|
||||
await fileStream.EncryptTo(outputStream, key, cancellationToken);
|
||||
outputStream.Seek(0, SeekOrigin.Begin);
|
||||
var name = resourcesConfig.Value.Resources.GetValueOrDefault(resource.ToString()) ?? "unknown.resource";
|
||||
return name;
|
||||
var resourcePath = Path.Combine(resourcesConfig.Value.ResourcesFolder, fileName);
|
||||
var fileStream = new FileStream(resourcePath, FileMode.Open, FileAccess.Read);
|
||||
|
||||
var ms = new MemoryStream();
|
||||
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)
|
||||
throw new BusinessException(ExceptionEnum.NoFileProvided);
|
||||
if (!Directory.Exists(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);
|
||||
}
|
||||
|
||||
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) =>
|
||||
Convert.ToBase64String(SHA384.HashData(Encoding.UTF8.GetBytes(str)));
|
||||
|
||||
public static string MakeEncryptionKey(string username, string password, string hardwareId) =>
|
||||
$"{username}-{password}-{hardwareId}-#%@AzaionKey@%#---";
|
||||
public static string MakeEncryptionKey(string email, string password, string? hardwareHash) =>
|
||||
$"{email}-{password}-{hardwareHash}-#%@AzaionKey@%#---".ToHash();
|
||||
|
||||
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.Requests;
|
||||
using LinqToDB;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Azaion.Services;
|
||||
|
||||
@@ -11,8 +12,9 @@ public interface IUserService
|
||||
{
|
||||
Task RegisterUser(RegisterUserRequest request, 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 CheckHardware(User user, GetResourceRequest request);
|
||||
}
|
||||
|
||||
public class UserService(IDbFactory dbFactory) : IUserService
|
||||
@@ -49,14 +51,25 @@ public class UserService(IDbFactory dbFactory) : IUserService
|
||||
return user;
|
||||
|
||||
// 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);
|
||||
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 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) =>
|
||||
await dbFactory.Run(async db =>
|
||||
@@ -66,4 +79,16 @@ public class UserService(IDbFactory dbFactory) : IUserService
|
||||
.WhereIf(searchRole != null,
|
||||
u => u.Role == searchRole)
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user