fix login

add logging
add scripts for server
This commit is contained in:
Alex Bezdieniezhnykh
2024-12-04 12:40:56 +02:00
parent 0914c8c39e
commit 6d8ea6c74f
9 changed files with 43 additions and 18 deletions
+5
View File
@@ -11,6 +11,11 @@
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" /> <PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8"/>
<PackageReference Include="Serilog" Version="4.1.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/>
</ItemGroup> </ItemGroup>
+11
View File
@@ -11,6 +11,16 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using Serilog;
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File(
path: "logs/log.txt",
rollingInterval: RollingInterval.Day)
.CreateLogger();
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel(o => o.Limits.MaxRequestBodySize = 209715200); //increase upload limit up to 200mb builder.WebHost.ConfigureKestrel(o => o.Limits.MaxRequestBodySize = 209715200); //increase upload limit up to 200mb
@@ -20,6 +30,7 @@ if (jwtConfig == null || string.IsNullOrEmpty(jwtConfig.Secret))
throw new Exception("Missing configuration section: JwtConfig"); throw new Exception("Missing configuration section: JwtConfig");
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.Secret)); var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtConfig.Secret));
builder.Services.AddSerilog();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(o => .AddJwtBearer(o =>
{ {
+5 -5
View File
@@ -3,10 +3,10 @@
public enum RoleEnum public enum RoleEnum
{ {
None = 0, None = 0,
Operator = 10, Operator = 10, //only annotator is available. Could send annotations to queue.
Validator = 20, Validator = 20, //annotator + dataset explorer. This role allows to receive annotations from the queue.
CompanionPC = 30, CompanionPC = 30,
Admin = 40, Admin = 40, //
ResourceUploader = 50, ResourceUploader = 50, //Uploading dll and ai models
ApiAdmin = 1000 ApiAdmin = 1000 //everything
} }
+3 -1
View File
@@ -4,6 +4,7 @@ using Azaion.Common.Database;
using Azaion.Common.Entities; using Azaion.Common.Entities;
using LinqToDB; using LinqToDB;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace Azaion.Services; namespace Azaion.Services;
@@ -14,7 +15,7 @@ public interface IResourcesService
Task SaveResource(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, ILogger<ResourcesService> logger) : IResourcesService
{ {
public async Task<Stream> GetEncryptedResource(string fileName, string key, CancellationToken cancellationToken = default) public async Task<Stream> GetEncryptedResource(string fileName, string key, CancellationToken cancellationToken = default)
{ {
@@ -37,5 +38,6 @@ public class ResourcesService(IOptions<ResourcesConfig> resourcesConfig) : IReso
var resourcePath = Path.Combine(resourcesConfig.Value.ResourcesFolder, data.FileName); var resourcePath = Path.Combine(resourcesConfig.Value.ResourcesFolder, data.FileName);
await using var fileStream = new FileStream(resourcePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); await using var fileStream = new FileStream(resourcePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
await data.CopyToAsync(fileStream, cancellationToken); await data.CopyToAsync(fileStream, cancellationToken);
logger.LogInformation($"Resource {data.FileName} Saved Successfully");
} }
} }
+2 -8
View File
@@ -11,7 +11,7 @@ namespace Azaion.Services;
public interface IUserService 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, CancellationToken cancellationToken = default);
Task UpdateHardware(string email, HardwareInfo hardwareInfo, 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); Task CheckHardware(User user, GetResourceRequest request);
@@ -37,7 +37,7 @@ public class UserService(IDbFactory dbFactory) : IUserService
}); });
} }
public async Task<User> ValidateUser(LoginRequest request, string? hardwareId = null, CancellationToken cancellationToken = default) => public async Task<User> ValidateUser(LoginRequest request, CancellationToken cancellationToken = default) =>
await dbFactory.Run(async db => await dbFactory.Run(async db =>
{ {
var user = await db.Users.FirstOrDefaultAsync(x => x.Email == request.Email, token: cancellationToken); var user = await db.Users.FirstOrDefaultAsync(x => x.Email == request.Email, token: cancellationToken);
@@ -47,12 +47,6 @@ public class UserService(IDbFactory dbFactory) : IUserService
if (request.Password.ToHash() != user.PasswordHash) if (request.Password.ToHash() != user.PasswordHash)
throw new BusinessException(ExceptionEnum.WrongPassword); throw new BusinessException(ExceptionEnum.WrongPassword);
if (user.Role == RoleEnum.ApiAdmin)
return user;
// For Non-API admins hardwareId should match if it was already set
if (user.HardwareHash != null && user.HardwareHash != hardwareId)
throw new BusinessException(ExceptionEnum.HardwareIdMismatch);
return user; return user;
}); });
+4 -4
View File
@@ -12,8 +12,8 @@ chmod 640 .htpasswd
chown root:www-data .htpasswd chown root:www-data .htpasswd
# create certs # create certs
certbot --nginx -d api.mywebsite.com certbot --nginx -d api.azaion.com
certbot --nginx -d docker.mywebsite.com certbot --nginx -d docker.azaion.com
cd /etc/nginx/sites-available cd /etc/nginx/sites-available
tee -a docker.azaion.com << END tee -a docker.azaion.com << END
@@ -23,7 +23,6 @@ server {
ssl_certificate /etc/letsencrypt/live/docker.azaion.com/fullchain.pem; ssl_certificate /etc/letsencrypt/live/docker.azaion.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/docker.azaion.com/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/docker.azaion.com/privkey.pem;
client_max_body_size 200M;
location / { location / {
auth_basic "Registry"; auth_basic "Registry";
@@ -40,7 +39,6 @@ server {
server { server {
listen 80; listen 80;
server_name docker.azaion.com; server_name docker.azaion.com;
client_max_body_size 200M;
location / { location / {
auth_basic "Registry"; auth_basic "Registry";
@@ -60,6 +58,7 @@ tee -a api.azaion.com << END
server { server {
listen 443 ssl; listen 443 ssl;
server_name api.azaion.com; server_name api.azaion.com;
client_max_body_size 200M;
ssl_certificate /etc/letsencrypt/live/api.azaion.com/fullchain.pem; ssl_certificate /etc/letsencrypt/live/api.azaion.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.azaion.com/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/api.azaion.com/privkey.pem;
@@ -77,6 +76,7 @@ server {
server { server {
listen 80; listen 80;
server_name api.azaion.com; server_name api.azaion.com;
client_max_body_size 200M;
# Redirect all HTTP requests to HTTPS # Redirect all HTTP requests to HTTPS
return 301 https://\$host\$request_uri; return 301 https://\$host\$request_uri;
+2
View File
@@ -0,0 +1,2 @@
docker rm azaion.api
sh start-container.sh
+5
View File
@@ -0,0 +1,5 @@
docker run \
--env-file .env \
-p 4000:8080 \
-v /root/content:/app/Content \
--name azaion.api docker.azaion.com/api
+6
View File
@@ -0,0 +1,6 @@
docker stop azaion.api
docker rm azaion.api
docker login docker.azaion.com
docker pull docker.azaion.com/api:latest
sh start-container.sh