From 1d482a4ec2cf24dbe7cc6cb02e192e1b9545f796 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Mon, 14 Feb 2022 19:02:54 +0100 Subject: feat: Experiment with tailwind --- src/server/Api/V1/ApiSpecV1.cs | 2 +- src/server/Api/V1/BaseV1Route.cs | 2 +- src/server/Api/V1/Entries/CreateEntryRoute.cs | 2 +- src/server/Api/V1/Entries/DeleteEntryRoute.cs | 2 +- src/server/Api/V1/Entries/GetEntriesRoute.cs | 5 +-- src/server/Api/V1/Entries/UpdateEntryRoute.cs | 2 +- src/server/Startup.cs | 4 +-- src/server/StaticData/AppEnvironmentVariables.cs | 6 ++++ src/server/TODO.txt | 2 +- .../Utilities/BasicAuthenticationAttribute.cs | 39 ++++++++++++++++++++++ src/server/Utilities/BasicAuthenticationHandler.cs | 14 ++++---- 11 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 src/server/StaticData/AppEnvironmentVariables.cs create mode 100644 src/server/Utilities/BasicAuthenticationAttribute.cs (limited to 'src/server') diff --git a/src/server/Api/V1/ApiSpecV1.cs b/src/server/Api/V1/ApiSpecV1.cs index c1d1cbf..2b96842 100644 --- a/src/server/Api/V1/ApiSpecV1.cs +++ b/src/server/Api/V1/ApiSpecV1.cs @@ -11,7 +11,7 @@ public static class ApiSpecV1 VersionName = VERSION_STRING, SwaggerPath = $"/swagger/{VERSION_STRING}/swagger.json", OpenApiInfo = new OpenApiInfo { - Title = Constants.API_NAME, + Title = AppConstants.API_NAME, Version = VERSION_STRING } }; diff --git a/src/server/Api/V1/BaseV1Route.cs b/src/server/Api/V1/BaseV1Route.cs index 766291e..bbccae6 100644 --- a/src/server/Api/V1/BaseV1Route.cs +++ b/src/server/Api/V1/BaseV1Route.cs @@ -7,7 +7,7 @@ namespace IOL.BookmarkThing.Server.Api.V1; [ApiController] public class BaseV1Route : ControllerBase { - private const string AuthSchemes = CookieAuthenticationDefaults.AuthenticationScheme + "," + Constants.BASIC_AUTH_SCHEME; + private const string AuthSchemes = CookieAuthenticationDefaults.AuthenticationScheme + "," + AppConstants.BASIC_AUTH_SCHEME; /// /// User data for the currently logged on user. diff --git a/src/server/Api/V1/Entries/CreateEntryRoute.cs b/src/server/Api/V1/Entries/CreateEntryRoute.cs index b502e4a..e0ee2c1 100644 --- a/src/server/Api/V1/Entries/CreateEntryRoute.cs +++ b/src/server/Api/V1/Entries/CreateEntryRoute.cs @@ -21,7 +21,7 @@ public class CreateEntryRoute : RouteBaseV1Sync.WithRequest. [ApiVersion(ApiSpecV1.VERSION_STRING)] [HttpPost("~/v{version:apiVersion}/entries/create")] public override ActionResult Handle(CreateEntryRequest entry) { - if (IsApiCall() && !HasApiPermission(Constants.TOKEN_ALLOW_CREATE)) { + if (IsApiCall() && !HasApiPermission(AppConstants.TOKEN_ALLOW_CREATE)) { return StatusCode(403, "Your token does not permit access to this resource"); } diff --git a/src/server/Api/V1/Entries/DeleteEntryRoute.cs b/src/server/Api/V1/Entries/DeleteEntryRoute.cs index c979c1f..8b8b75c 100644 --- a/src/server/Api/V1/Entries/DeleteEntryRoute.cs +++ b/src/server/Api/V1/Entries/DeleteEntryRoute.cs @@ -18,7 +18,7 @@ public class DeleteEntryRoute : RouteBaseV1Sync.WithRequest.WithActionResu [ApiVersion(ApiSpecV1.VERSION_STRING)] [HttpDelete("~/v{version:apiVersion}/entries/{entryId:guid}")] public override ActionResult Handle(Guid entryId) { - if (IsApiCall() && !HasApiPermission(Constants.TOKEN_ALLOW_DELETE)) { + if (IsApiCall() && !HasApiPermission(AppConstants.TOKEN_ALLOW_DELETE)) { return StatusCode(403, "Your token does not permit access to this resource"); } diff --git a/src/server/Api/V1/Entries/GetEntriesRoute.cs b/src/server/Api/V1/Entries/GetEntriesRoute.cs index 27905a2..6b1d87e 100644 --- a/src/server/Api/V1/Entries/GetEntriesRoute.cs +++ b/src/server/Api/V1/Entries/GetEntriesRoute.cs @@ -14,12 +14,9 @@ public class GetEntriesRoute : RouteBaseV1Sync.WithoutRequest.WithActionResult [ApiVersion(ApiSpecV1.VERSION_STRING)] + [BasicAuthentication(AppConstants.TOKEN_ALLOW_READ)] [HttpGet("~/v{version:apiVersion}/entries")] public override ActionResult> Handle() { - if (IsApiCall() && !HasApiPermission(Constants.TOKEN_ALLOW_READ)) { - return StatusCode(403, "Your token does not permit access to this resource"); - } - return Ok(_context.Entries.Where(c => c.UserId == LoggedInUser.Id).Select(c => new EntryDto(c))); } } diff --git a/src/server/Api/V1/Entries/UpdateEntryRoute.cs b/src/server/Api/V1/Entries/UpdateEntryRoute.cs index 919364d..98e99c6 100644 --- a/src/server/Api/V1/Entries/UpdateEntryRoute.cs +++ b/src/server/Api/V1/Entries/UpdateEntryRoute.cs @@ -23,7 +23,7 @@ public class UpdateEntryRoute : RouteBaseV1Sync.WithRequest. [ApiVersion(ApiSpecV1.VERSION_STRING)] [HttpPost("~/v{version:apiVersion}/entries/update")] public override ActionResult Handle(UpdateEntryRequest entryToUpdate) { - if (IsApiCall() && !HasApiPermission(Constants.TOKEN_ALLOW_UPDATE)) { + if (IsApiCall() && !HasApiPermission(AppConstants.TOKEN_ALLOW_UPDATE)) { return StatusCode(403, "Your token does not permit access to this resource"); } diff --git a/src/server/Startup.cs b/src/server/Startup.cs index 8b831c1..0d7c05f 100644 --- a/src/server/Startup.cs +++ b/src/server/Startup.cs @@ -79,7 +79,7 @@ public class Startup }; options.Events.OnCreatingTicket = context => HandleGithubCreatingTicket.Handle(context, Configuration); }) - .AddScheme(Constants.BASIC_AUTH_SCHEME, default); + .AddScheme(AppConstants.BASIC_AUTH_SCHEME, default); services.AddLogging(); services.AddHttpClient(); @@ -157,7 +157,7 @@ public class Startup app.UseSwagger(); app.UseSwaggerUI(options => { options.SwaggerEndpoint(ApiSpecV1.Document.SwaggerPath, ApiSpecV1.Document.VersionName); - options.DocumentTitle = Constants.API_NAME; + options.DocumentTitle = AppConstants.API_NAME; }); } } diff --git a/src/server/StaticData/AppEnvironmentVariables.cs b/src/server/StaticData/AppEnvironmentVariables.cs new file mode 100644 index 0000000..a879614 --- /dev/null +++ b/src/server/StaticData/AppEnvironmentVariables.cs @@ -0,0 +1,6 @@ +namespace IOL.BookmarkThing.Server.StaticData; + +public static class AppEnvironmentVariables +{ + public const string TOKEN_ENTROPY = "TOKEN_ENTROPY"; +} diff --git a/src/server/TODO.txt b/src/server/TODO.txt index bbbffd4..69da9d3 100644 --- a/src/server/TODO.txt +++ b/src/server/TODO.txt @@ -1 +1 @@ --- API calls using Basic auth with an invalid or expired token should reflect so in the response, currently the response is always 'Your token does not grant you access to this resource' +TODO: API calls using Basic auth with an invalid or expired token should reflect so in the response, currently the response is always 'Your token does not grant you access to this resource' diff --git a/src/server/Utilities/BasicAuthenticationAttribute.cs b/src/server/Utilities/BasicAuthenticationAttribute.cs new file mode 100644 index 0000000..81467cd --- /dev/null +++ b/src/server/Utilities/BasicAuthenticationAttribute.cs @@ -0,0 +1,39 @@ +using System.Net.Http.Headers; +using Microsoft.AspNetCore.Mvc.Filters; + +namespace IOL.BookmarkThing.Server.Utilities; + +public class BasicAuthenticationAttribute : TypeFilterAttribute +{ + public BasicAuthenticationAttribute(string claimPermission) : base(typeof(BasicAuthenticationFilter)) { + Arguments = new object[] { + new Claim(claimPermission, "True") + }; + } +} + +public class BasicAuthenticationFilter : IAuthorizationFilter +{ + private readonly Claim _claim; + + public BasicAuthenticationFilter(Claim claim) { + _claim = claim; + } + + public void OnAuthorization(AuthorizationFilterContext context) { + if (!context.HttpContext.Request.Headers.ContainsKey("Authorization")) return; + try { + var authHeader = AuthenticationHeaderValue.Parse(context.HttpContext.Request.Headers["Authorization"]); + if (authHeader.Parameter is null) { + context.Result = new ForbidResult(AppConstants.BASIC_AUTH_SCHEME); + } + + var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type && c.Value == _claim.Value); + if (!hasClaim) { + context.Result = new ForbidResult(AppConstants.BASIC_AUTH_SCHEME); + } + } catch { + // ignore + } + } +} diff --git a/src/server/Utilities/BasicAuthenticationHandler.cs b/src/server/Utilities/BasicAuthenticationHandler.cs index c4124e8..fada122 100644 --- a/src/server/Utilities/BasicAuthenticationHandler.cs +++ b/src/server/Utilities/BasicAuthenticationHandler.cs @@ -60,19 +60,19 @@ public class BasicAuthenticationHandler : AuthenticationHandler() { - new(Constants.TOKEN_ALLOW_READ, token.AllowRead.ToString()), - new(Constants.TOKEN_ALLOW_UPDATE, token.AllowUpdate.ToString()), - new(Constants.TOKEN_ALLOW_CREATE, token.AllowCreate.ToString()), - new(Constants.TOKEN_ALLOW_DELETE, token.AllowDelete.ToString()), + new(AppConstants.TOKEN_ALLOW_READ, token.AllowRead.ToString()), + new(AppConstants.TOKEN_ALLOW_UPDATE, token.AllowUpdate.ToString()), + new(AppConstants.TOKEN_ALLOW_CREATE, token.AllowCreate.ToString()), + new(AppConstants.TOKEN_ALLOW_DELETE, token.AllowDelete.ToString()), }; var claims = token.User.DefaultClaims().Concat(permissions); - var identity = new ClaimsIdentity(claims, Constants.BASIC_AUTH_SCHEME); + var identity = new ClaimsIdentity(claims, AppConstants.BASIC_AUTH_SCHEME); var principal = new ClaimsPrincipal(identity); - var ticket = new AuthenticationTicket(principal, Constants.BASIC_AUTH_SCHEME); + var ticket = new AuthenticationTicket(principal, AppConstants.BASIC_AUTH_SCHEME); return Task.FromResult(AuthenticateResult.Success(ticket)); } catch (Exception e) { - _logger.LogError(e, $"An exception occured when challenging {Constants.BASIC_AUTH_SCHEME}"); + _logger.LogError(e, $"An exception occured when challenging {AppConstants.BASIC_AUTH_SCHEME}"); return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header")); } } -- cgit v1.3