diff options
-rw-r--r-- | cspell.yaml | 16 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs | 17 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs | 10 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs | 5 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/Error.cs | 19 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpContextExtensions.cs (renamed from docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs) | 52 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpResponseAction.cs | 3 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Commons/ISecretService.cs | 6 | ||||
-rw-r--r-- | docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs | 14 |
9 files changed, 94 insertions, 48 deletions
diff --git a/cspell.yaml b/cspell.yaml new file mode 100644 index 0000000..772a7a2 --- /dev/null +++ b/cspell.yaml @@ -0,0 +1,16 @@ +version: "0.2" +language: en +dictionaries: + - en_US + - softwareTerms + - node + - typescript + - python + - html + - css + - bash + - fonts + - filetypes + - npm +words: + - crupest diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs index d371c84..184ac0a 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudService.cs @@ -20,15 +20,20 @@ public class CrudService<TEntity> : IDisposable where TEntity : class _jsonHelper = jsonHelper; _logger = loggerFactory.CreateLogger<CrudService<TEntity>>(); - if (!_table.CheckExistence(_dbConnection)) - { - DoInitializeDatabase(_dbConnection); - } + CheckDatabase(_dbConnection); } public EntityJsonHelper<TEntity> JsonHelper => _jsonHelper; - public virtual void DoInitializeDatabase(IDbConnection connection) + protected virtual void CheckDatabase(IDbConnection dbConnection) + { + if (!_table.CheckExistence(dbConnection)) + { + DoInitializeDatabase(dbConnection); + } + } + + private void DoInitializeDatabase(IDbConnection connection) { using var transaction = connection.BeginTransaction(); connection.Execute(_table.GenerateCreateTableSql(), transaction: transaction); @@ -59,7 +64,7 @@ public class CrudService<TEntity> : IDisposable where TEntity : class return (string)key; } - public void Update(object key, JsonElement jsonElement) + public void UpdateByKey(object key, JsonElement jsonElement) { var updateClauses = _jsonHelper.ConvertJsonElementToUpdateClause(jsonElement); _table.Update(_dbConnection, WhereClause.Create().Eq(_table.KeyColumn.ColumnName, key), updateClauses); diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs index 8854976..d51c0a1 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudServiceCollectionExtensions.cs @@ -12,13 +12,19 @@ public static class CrudServiceCollectionExtensions return services; } - public static IServiceCollection AddCrud<TEntity>(this IServiceCollection services) where TEntity : class + public static IServiceCollection AddCrud<TEntity, TCrudService>(this IServiceCollection services) where TEntity : class where TCrudService : CrudService<TEntity> { AddCrudCore(services); - services.TryAddScoped<CrudService<TEntity>>(); + services.TryAddScoped<CrudService<TEntity>, TCrudService>(); services.TryAddScoped<EntityJsonHelper<TEntity>>(); return services; } + + public static IServiceCollection AddCrud<TEntity>(this IServiceCollection services) where TEntity : class + { + return services.AddCrud<TEntity, CrudService<TEntity>>(); + } + } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs index 7331273..9e85c68 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Crud/CrudWebApplicationExtensions.cs @@ -2,10 +2,11 @@ namespace CrupestApi.Commons.Crud; public static class CrudWebApplicationExtensions { - public static WebApplication UseCrud<TEntity>(this WebApplication app, string path) where TEntity : class + public static WebApplication UseCrud<TEntity>(this WebApplication app, string path, string? key) where TEntity : class { app.MapGet(path, async (context) => { + var crudService = context.RequestServices.GetRequiredService<CrudService<TEntity>>(); var allEntities = crudService.GetAll(); await context.ResponseJsonAsync(allEntities.Select(e => crudService.JsonHelper.ConvertEntityToDictionary(e))); @@ -44,7 +45,7 @@ public static class CrudWebApplicationExtensions } var jsonDocument = await context.Request.ReadJsonAsync(); - crudService.Update(key, jsonDocument.RootElement); + crudService.UpdateByKey(key, jsonDocument.RootElement); await context.ResponseJsonAsync(crudService.JsonHelper.ConvertEntityToDictionary(crudService.GetByKey(key))); }); diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Error.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Error.cs deleted file mode 100644 index b298f7a..0000000 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Error.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace CrupestApi.Commons; - -public class ErrorBody -{ - public ErrorBody(string message) - { - Message = message; - } - - public string Message { get; set; } -} - -public static class CrupestApiErrorExtensions -{ - public static async Task WriteErrorMessageAsync(this HttpResponse response, string message, int statusCode = 400, HttpResponseAction? beforeWriteBody = null, CancellationToken cancellationToken = default) - { - await response.WriteJsonAsync(new ErrorBody(message), statusCode: statusCode, beforeWriteBody, cancellationToken); - } -} diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpContextExtensions.cs index 61bcc61..1d7d858 100644 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Json.cs +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpContextExtensions.cs @@ -1,9 +1,20 @@ using System.Text.Json; using Microsoft.Extensions.Options; -using Microsoft.Net.Http.Headers; namespace CrupestApi.Commons; +public delegate void HttpResponseAction(HttpResponse response); + +public class MessageBody +{ + public MessageBody(string message) + { + Message = message; + } + + public string Message { get; set; } +} + public static class CrupestApiJsonExtensions { public static IServiceCollection AddJsonOptions(this IServiceCollection services) @@ -46,7 +57,7 @@ public static class CrupestApiJsonExtensions public static async Task WriteMessageAsync(this HttpResponse response, string message, int statusCode = 400, HttpResponseAction? beforeWriteBody = null, CancellationToken cancellationToken = default) { - await response.WriteJsonAsync(new ErrorBody(message), statusCode: statusCode, beforeWriteBody, cancellationToken); + await response.WriteJsonAsync(new MessageBody(message), statusCode: statusCode, beforeWriteBody, cancellationToken); } public static Task ResponseJsonAsync<T>(this HttpContext context, T bodyObject, int statusCode = 200, HttpResponseAction? beforeWriteBody = null, CancellationToken cancellationToken = default) @@ -59,4 +70,41 @@ public static class CrupestApiJsonExtensions return context.Response.WriteMessageAsync(message, statusCode, beforeWriteBody, cancellationToken); } + public static string? GetToken(this HttpRequest request) + { + var token = request.Headers["Authorization"].ToString(); + if (token.StartsWith("Bearer ")) + { + token = token.Substring("Bearer ".Length); + return token; + } + + if (request.Query.TryGetValue("token", out var tokenValues)) + { + return tokenValues.Last(); + } + + return null; + } + + public static bool RequirePermission(this HttpContext context, string? permission) + { + if (permission is null) return true; + + var token = context.Request.GetToken(); + if (token is null) + { + context.ResponseMessageAsync("Unauthorized", 401); + return false; + } + + var secretService = context.RequestServices.GetRequiredService<ISecretService>(); + var permissions = secretService.GetPermissions(token); + if (!permissions.Contains(permission)) + { + context.ResponseMessageAsync("Forbidden", 403); + return false; + } + return true; + } } diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpResponseAction.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpResponseAction.cs deleted file mode 100644 index 9023f4e..0000000 --- a/docker/crupest-api/CrupestApi/CrupestApi.Commons/HttpResponseAction.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace CrupestApi.Commons; - -public delegate void HttpResponseAction(HttpResponse response); diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/ISecretService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/ISecretService.cs new file mode 100644 index 0000000..eeabb0d --- /dev/null +++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/ISecretService.cs @@ -0,0 +1,6 @@ +namespace CrupestApi.Commons; + +interface ISecretService +{ + List<string> GetPermissions(string secret); +} diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs deleted file mode 100644 index 7051602..0000000 --- a/docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using CrupestApi.Commons.Crud; - -namespace CrupestApi.Secrets; - -public class SecretsService : CrudService<SecretInfo> -{ - private readonly ILogger<SecretsService> _logger; - - public SecretsService(ITableInfoFactory tableInfoFactory, IDbConnectionFactory dbConnectionFactory, ILoggerFactory loggerFactory) - : base("secrets", tableInfoFactory, dbConnectionFactory, loggerFactory) - { - _logger = loggerFactory.CreateLogger<SecretsService>(); - } -} |