mirror of
https://github.com/azaion/admin.git
synced 2026-04-22 07:06:34 +00:00
add authorization
This commit is contained in:
@@ -11,6 +11,9 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNetCore.Http.Abstractions">
|
||||
<HintPath>C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.8\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Extensions.Options">
|
||||
<HintPath>C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\8.0.8\Microsoft.Extensions.Options.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
@@ -8,16 +8,15 @@ namespace Azaion.Services;
|
||||
|
||||
public interface IResourcesService
|
||||
{
|
||||
Task GetEncryptedResource(GetResourceRequest request, Stream outputStream, CancellationToken cancellationToken = default);
|
||||
Task GetEncryptedResource(ResourceEnum resource, string key, Stream outputStream, CancellationToken cancellationToken = default);
|
||||
Task SaveResource(UploadResourceRequest request, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
public class ResourcesService(IOptions<ResourcesConfig> resourcesConfig) : IResourcesService
|
||||
{
|
||||
public async Task GetEncryptedResource(GetResourceRequest request, Stream outputStream, CancellationToken cancellationToken = default)
|
||||
public async Task GetEncryptedResource(ResourceEnum resource, string key, Stream outputStream, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var fileStream = new FileStream(GetResourcePath(request.ResourceEnum), FileMode.Open, FileAccess.Read);
|
||||
var key = Security.MakeEncryptionKey(request.Username, request.Password);
|
||||
var fileStream = new FileStream(GetResourcePath(resource), FileMode.Open, FileAccess.Read);
|
||||
await fileStream.EncryptTo(outputStream, key, cancellationToken);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,56 +1,80 @@
|
||||
using Azaion.Common;
|
||||
using System.Security.Claims;
|
||||
using Azaion.Common;
|
||||
using Azaion.Common.Configs;
|
||||
using Azaion.Common.Database;
|
||||
using Azaion.Common.Entities;
|
||||
using Azaion.Common.Requests;
|
||||
using LinqToDB;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Azaion.Services;
|
||||
|
||||
public interface IUserService
|
||||
{
|
||||
User? CurrentUser { get; }
|
||||
Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default);
|
||||
Task<User?> ValidateUser(GetResourceRequest request, CancellationToken cancellationToken = default);
|
||||
Task<User> ValidateUser(string username, string password, string? hardwareId = null, CancellationToken cancellationToken = default);
|
||||
Task UpdateHardwareId(string username, string hardwareId, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
public class UserService(IDbFactory dbFactory) : IUserService
|
||||
public class UserService(IDbFactory dbFactory, IHttpContextAccessor httpContextAccessor) : IUserService
|
||||
{
|
||||
public User? CurrentUser
|
||||
{
|
||||
get
|
||||
{
|
||||
var claims = httpContextAccessor.HttpContext?.User.Claims.ToDictionary(x => x.Type);
|
||||
if (claims == null)
|
||||
return null;
|
||||
|
||||
Enum.TryParse(claims[ClaimTypes.Role].Value, out RoleEnum role);
|
||||
return new User
|
||||
{
|
||||
Id = claims[ClaimTypes.NameIdentifier].Value,
|
||||
Email = claims[ClaimTypes.Name].Value,
|
||||
Role = role,
|
||||
HardwareId = claims[Constants.HARDWARE_ID].Value,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
await dbFactory.Run(async db =>
|
||||
{
|
||||
var existingUser = await db.Users.FirstOrDefaultAsync(u => u.Username == request.Email, token: cancellationToken);
|
||||
var existingUser = await db.Users.FirstOrDefaultAsync(u => u.Email == request.Email, token: cancellationToken);
|
||||
if (existingUser != null)
|
||||
throw new BusinessException(ExceptionEnum.UserExists, "User already exists");
|
||||
|
||||
await db.InsertAsync(new User
|
||||
{
|
||||
Username = request.Email,
|
||||
Email = request.Email,
|
||||
PasswordHash = request.Password.ToHash(),
|
||||
Role = request.Role
|
||||
}, token: cancellationToken);
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<User?> ValidateUser(GetResourceRequest request, CancellationToken cancellationToken = default) =>
|
||||
public async Task<User> ValidateUser(string username, string password, string? hardwareId = null, CancellationToken cancellationToken = default) =>
|
||||
await dbFactory.Run(async db =>
|
||||
{
|
||||
var user = await db.Users.FirstOrDefaultAsync(x => x.Username == request.Username, token: cancellationToken);
|
||||
var user = await db.Users.FirstOrDefaultAsync(x => x.Email == username, token: cancellationToken);
|
||||
if (user == null)
|
||||
throw new BusinessException(ExceptionEnum.NoUserFound, "No user found");
|
||||
|
||||
if (request.Password.ToHash() != user.PasswordHash)
|
||||
if (password.ToHash() != user.PasswordHash)
|
||||
throw new BusinessException(ExceptionEnum.PasswordIncorrect, "Passwords do not match");
|
||||
|
||||
//If user's hardware Id is empty (usually on the first time login), then write down user
|
||||
if (string.IsNullOrEmpty(user.HardwareId))
|
||||
await db.Users.UpdateAsync(x => x.Username == request.Username, u => new User{HardwareId = request.HardwareId}, token: cancellationToken);
|
||||
else
|
||||
{
|
||||
//But if hardware Id exists, it should match with request
|
||||
if (user.HardwareId != request.HardwareId)
|
||||
throw new BusinessException(ExceptionEnum.HardwareIdMismatch, "Hardware id mismatch");
|
||||
}
|
||||
if (user.Role == RoleEnum.ApiAdmin)
|
||||
return user;
|
||||
|
||||
// For Non-API admins hardwareId should match if it was already set
|
||||
if (user.HardwareId != null && user.HardwareId != hardwareId)
|
||||
throw new BusinessException(ExceptionEnum.HardwareIdMismatch, "Hardware id mismatch");
|
||||
return user;
|
||||
});
|
||||
|
||||
public async Task UpdateHardwareId(string username, string hardwareId, CancellationToken cancellationToken = default) =>
|
||||
await dbFactory.Run(async db =>
|
||||
await db.Users.UpdateAsync(x => x.Email == username, u => new User { HardwareId = hardwareId}, token: cancellationToken));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user