From 8bbcbfab090612b0c9c600e102809f99f18b95c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szab=C3=B3=20Iv=C3=A1n?= Date: Tue, 17 Dec 2024 19:23:15 +0100 Subject: [PATCH] INIT vol 1. --- src/WorkFlowCheck.API/ApiKeyMiddleware.cs | 36 ++++++++ .../Controllers/UserController.cs | 17 ++++ src/WorkFlowCheck.API/Program.cs | 85 ++++++++++++++----- .../WorkFlowCheck.API.csproj | 9 ++ src/WorkFlowCheck.API/appsettings.json | 4 + src/WorkFlowCheck.BL/DTO/ResponseDTO.cs | 10 +++ src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj | 9 ++ src/WorkFlowCheck.DL/AppDbContext.cs | 19 +++++ src/WorkFlowCheck.DL/Entities/User.cs | 9 ++ src/WorkFlowCheck.DL/WorkFlowCheck.DL.csproj | 19 +++++ src/WorkFlowCheck.sln | 12 +++ 11 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 src/WorkFlowCheck.API/ApiKeyMiddleware.cs create mode 100644 src/WorkFlowCheck.API/Controllers/UserController.cs create mode 100644 src/WorkFlowCheck.BL/DTO/ResponseDTO.cs create mode 100644 src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj create mode 100644 src/WorkFlowCheck.DL/AppDbContext.cs create mode 100644 src/WorkFlowCheck.DL/Entities/User.cs create mode 100644 src/WorkFlowCheck.DL/WorkFlowCheck.DL.csproj diff --git a/src/WorkFlowCheck.API/ApiKeyMiddleware.cs b/src/WorkFlowCheck.API/ApiKeyMiddleware.cs new file mode 100644 index 0000000..1420a9d --- /dev/null +++ b/src/WorkFlowCheck.API/ApiKeyMiddleware.cs @@ -0,0 +1,36 @@ +namespace WorkFlowCheck.API +{ + public class ApiKeyMiddleware + { + private readonly RequestDelegate _next; + private const string ApiKeyHeaderName = "X-Api-Key"; + + public ApiKeyMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context) + { + if (!context.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey)) + { + context.Response.StatusCode = 401; // Unauthorized + await context.Response.WriteAsync("API Key hiányzik."); + return; + } + + var appSettings = context.RequestServices.GetRequiredService(); + var apiKey = appSettings.GetValue("ApiKey"); + + if (!apiKey.Equals(extractedApiKey)) + { + context.Response.StatusCode = 403; // Forbidden + await context.Response.WriteAsync("Helytelen API Key."); + return; + } + + await _next(context); + } + } + +} diff --git a/src/WorkFlowCheck.API/Controllers/UserController.cs b/src/WorkFlowCheck.API/Controllers/UserController.cs new file mode 100644 index 0000000..3de56b2 --- /dev/null +++ b/src/WorkFlowCheck.API/Controllers/UserController.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using WorkFlowCheck.BL.DTO; + +namespace WorkFlowCheck.API.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class UserController : ControllerBase + { + [HttpGet] + public ActionResult Get() + { + return new ResponseDTO { Message = "Success" }; + } + } +} diff --git a/src/WorkFlowCheck.API/Program.cs b/src/WorkFlowCheck.API/Program.cs index 98d7619..a2e9be8 100644 --- a/src/WorkFlowCheck.API/Program.cs +++ b/src/WorkFlowCheck.API/Program.cs @@ -1,36 +1,75 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.OpenApi.Models; +using System.Text.Json; using System.Text.Json.Serialization; +using WorkFlowCheck.API; +using WorkFlowCheck.DL; -var builder = WebApplication.CreateSlimBuilder(args); +var builder = WebApplication.CreateBuilder(args); -builder.Services.ConfigureHttpJsonOptions(options => +builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); + +// SWAGGER !!! +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(c => { - options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default); + c.SwaggerDoc("v1", new OpenApiInfo { Title = "WorkFlowCheck API", Version = "v1" }); + + // API Key Auth definíció + c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme + { + Description = "API Key szükséges. Használat: 'ApiKey: {kulcs}'", + Name = "X-Api-Key", // A fejlécek között keresendõ + In = ParameterLocation.Header, + Type = SecuritySchemeType.ApiKey, + Scheme = "ApiKey" + }); + + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "ApiKey" + }, + Scheme = "ApiKey", + Name = "ApiKey", + In = ParameterLocation.Header, + }, + Array.Empty() + } + }); }); +// Szolgáltatások hozzáadása +builder.Services.AddControllers().AddJsonOptions(options => +{ + options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; + options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; +}); ; + var app = builder.Build(); +// Swagger middleware +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(c => + { + c.SwaggerEndpoint("/swagger/v1/swagger.json", "WorkFlowCheck API v1"); + }); +} +// Routing és endpointok +app.UseHttpsRedirection(); +app.UseAuthorization(); -var sampleTodos = new Todo[] { - new(1, "Walk the dog"), - new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)), - new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))), - new(4, "Clean the bathroom"), - new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2))) -}; +app.MapControllers(); -var todosApi = app.MapGroup("/todos"); -todosApi.MapGet("/", () => sampleTodos); -todosApi.MapGet("/{id}", (int id) => - sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo - ? Results.Ok(todo) - : Results.NotFound()); +app.UseMiddleware(); app.Run(); -public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false); - -[JsonSerializable(typeof(Todo[]))] -internal partial class AppJsonSerializerContext : JsonSerializerContext -{ - -} diff --git a/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj b/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj index 8186e5b..625b164 100644 --- a/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj +++ b/src/WorkFlowCheck.API/WorkFlowCheck.API.csproj @@ -8,4 +8,13 @@ true + + + + + + + + + diff --git a/src/WorkFlowCheck.API/appsettings.json b/src/WorkFlowCheck.API/appsettings.json index 10f68b8..e753dd1 100644 --- a/src/WorkFlowCheck.API/appsettings.json +++ b/src/WorkFlowCheck.API/appsettings.json @@ -1,4 +1,8 @@ { + "DefaultConnection": { + "ConnectionString": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WorkFlowCheckDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False" + }, + "ApiKey": "YOUR_SECRET_API_KEY", "Logging": { "LogLevel": { "Default": "Information", diff --git a/src/WorkFlowCheck.BL/DTO/ResponseDTO.cs b/src/WorkFlowCheck.BL/DTO/ResponseDTO.cs new file mode 100644 index 0000000..1c81727 --- /dev/null +++ b/src/WorkFlowCheck.BL/DTO/ResponseDTO.cs @@ -0,0 +1,10 @@ +using System.Text.Json.Serialization; + +namespace WorkFlowCheck.BL.DTO +{ + [JsonSerializable(typeof(ResponseDTO))] + public class ResponseDTO + { + public string Message { get; set; } = null!; + } +} diff --git a/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj b/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/src/WorkFlowCheck.BL/WorkFlowCheck.BL.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/src/WorkFlowCheck.DL/AppDbContext.cs b/src/WorkFlowCheck.DL/AppDbContext.cs new file mode 100644 index 0000000..5319fa3 --- /dev/null +++ b/src/WorkFlowCheck.DL/AppDbContext.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WorkFlowCheck.DL +{ + public class AppDbContext : DbContext + { + public AppDbContext(DbContextOptions options) + : base(options) + { + } + + public DbSet Users { get; set; } = null!; + } +} diff --git a/src/WorkFlowCheck.DL/Entities/User.cs b/src/WorkFlowCheck.DL/Entities/User.cs new file mode 100644 index 0000000..6092e0a --- /dev/null +++ b/src/WorkFlowCheck.DL/Entities/User.cs @@ -0,0 +1,9 @@ +namespace WorkFlowCheck.DL.Entities +{ + public class User + { + public int Id { get; set; } + public string Name { get; set; } = null!; + public string Email { get; set; } = null!; + } +} diff --git a/src/WorkFlowCheck.DL/WorkFlowCheck.DL.csproj b/src/WorkFlowCheck.DL/WorkFlowCheck.DL.csproj new file mode 100644 index 0000000..e6a1636 --- /dev/null +++ b/src/WorkFlowCheck.DL/WorkFlowCheck.DL.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + enable + enable + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + diff --git a/src/WorkFlowCheck.sln b/src/WorkFlowCheck.sln index 0e28b64..0782e62 100644 --- a/src/WorkFlowCheck.sln +++ b/src/WorkFlowCheck.sln @@ -9,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plugin.NFC", "Plugin.NFC\Pl EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlowCheck.MAUI", "WorkFlowCheck.MAUI\WorkFlowCheck.MAUI.csproj", "{0E2BD120-EE91-4A24-A78A-CE7CA87E09AE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlowCheck.DL", "WorkFlowCheck.DL\WorkFlowCheck.DL.csproj", "{25A8C0E7-18C7-4672-ABE8-29596E7E9B72}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkFlowCheck.BL", "WorkFlowCheck.BL\WorkFlowCheck.BL.csproj", "{73049F81-7A5D-4819-ADB8-A9926672365E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -29,6 +33,14 @@ Global {0E2BD120-EE91-4A24-A78A-CE7CA87E09AE}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E2BD120-EE91-4A24-A78A-CE7CA87E09AE}.Release|Any CPU.Build.0 = Release|Any CPU {0E2BD120-EE91-4A24-A78A-CE7CA87E09AE}.Release|Any CPU.Deploy.0 = Release|Any CPU + {25A8C0E7-18C7-4672-ABE8-29596E7E9B72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25A8C0E7-18C7-4672-ABE8-29596E7E9B72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25A8C0E7-18C7-4672-ABE8-29596E7E9B72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25A8C0E7-18C7-4672-ABE8-29596E7E9B72}.Release|Any CPU.Build.0 = Release|Any CPU + {73049F81-7A5D-4819-ADB8-A9926672365E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73049F81-7A5D-4819-ADB8-A9926672365E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73049F81-7A5D-4819-ADB8-A9926672365E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73049F81-7A5D-4819-ADB8-A9926672365E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE