diff --git a/EasyWay.sln b/EasyWay.sln index b7cba65..5dcc16b 100644 --- a/EasyWay.sln +++ b/EasyWay.sln @@ -21,12 +21,6 @@ Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "easy-way-samples-compose", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EasyWay.WebApi", "source\EasyWay.WebApi\EasyWay.WebApi.csproj", "{39B268A4-26E1-4609-9228-845E836C26FC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyWay.Auth", "source\EasyWay.Auth\EasyWay.Auth.csproj", "{AE66C586-5C48-4A23-9186-63D90F0BC4A1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyWay.Auth.WebApi", "source\EasyWay.Auth.WebApi\EasyWay.Auth.WebApi.csproj", "{2CF71C5B-0A95-416A-AB6A-6DB3545DCCF5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyWay.AuthSamples", "samples\EasyWay.AuthSamples\EasyWay.AuthSamples.csproj", "{04307081-E971-4A1A-ACF2-D709EA7F8AD3}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyWay.FluentValidation", "source\EasyWay.FluentValidation\EasyWay.FluentValidation.csproj", "{16C0EBA2-2E35-40E1-B655-70D6C16B2ECC}" EndProject Global @@ -59,18 +53,6 @@ Global {39B268A4-26E1-4609-9228-845E836C26FC}.Debug|Any CPU.Build.0 = Debug|Any CPU {39B268A4-26E1-4609-9228-845E836C26FC}.Release|Any CPU.ActiveCfg = Release|Any CPU {39B268A4-26E1-4609-9228-845E836C26FC}.Release|Any CPU.Build.0 = Release|Any CPU - {AE66C586-5C48-4A23-9186-63D90F0BC4A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AE66C586-5C48-4A23-9186-63D90F0BC4A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE66C586-5C48-4A23-9186-63D90F0BC4A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AE66C586-5C48-4A23-9186-63D90F0BC4A1}.Release|Any CPU.Build.0 = Release|Any CPU - {2CF71C5B-0A95-416A-AB6A-6DB3545DCCF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2CF71C5B-0A95-416A-AB6A-6DB3545DCCF5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2CF71C5B-0A95-416A-AB6A-6DB3545DCCF5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2CF71C5B-0A95-416A-AB6A-6DB3545DCCF5}.Release|Any CPU.Build.0 = Release|Any CPU - {04307081-E971-4A1A-ACF2-D709EA7F8AD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {04307081-E971-4A1A-ACF2-D709EA7F8AD3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04307081-E971-4A1A-ACF2-D709EA7F8AD3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {04307081-E971-4A1A-ACF2-D709EA7F8AD3}.Release|Any CPU.Build.0 = Release|Any CPU {16C0EBA2-2E35-40E1-B655-70D6C16B2ECC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {16C0EBA2-2E35-40E1-B655-70D6C16B2ECC}.Debug|Any CPU.Build.0 = Debug|Any CPU {16C0EBA2-2E35-40E1-B655-70D6C16B2ECC}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -86,9 +68,6 @@ Global {CA7B1CA4-2576-4E40-8C89-1B2DC0F9B898} = {AA2BD30D-EDA1-4DED-B94B-896F6A6666C3} {92E6AA1A-C91A-491E-B5FF-72ADAAEA8C80} = {B403E9EE-655A-481E-889B-F292845AE5BF} {39B268A4-26E1-4609-9228-845E836C26FC} = {92D4A304-6772-4482-83CC-68FDF54087C4} - {AE66C586-5C48-4A23-9186-63D90F0BC4A1} = {92D4A304-6772-4482-83CC-68FDF54087C4} - {2CF71C5B-0A95-416A-AB6A-6DB3545DCCF5} = {92D4A304-6772-4482-83CC-68FDF54087C4} - {04307081-E971-4A1A-ACF2-D709EA7F8AD3} = {B403E9EE-655A-481E-889B-F292845AE5BF} {16C0EBA2-2E35-40E1-B655-70D6C16B2ECC} = {92D4A304-6772-4482-83CC-68FDF54087C4} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/samples/EasyWay.AuthSamples/EasyWay.AuthSamples.csproj b/samples/EasyWay.AuthSamples/EasyWay.AuthSamples.csproj deleted file mode 100644 index 0432d3e..0000000 --- a/samples/EasyWay.AuthSamples/EasyWay.AuthSamples.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net9.0 - enable - enable - - - - - - - - - - - diff --git a/samples/EasyWay.AuthSamples/EasyWay.AuthSamples.http b/samples/EasyWay.AuthSamples/EasyWay.AuthSamples.http deleted file mode 100644 index b26fd89..0000000 --- a/samples/EasyWay.AuthSamples/EasyWay.AuthSamples.http +++ /dev/null @@ -1,6 +0,0 @@ -@EasyWay.AuthSamples_HostAddress = http://localhost:5229 - -GET {{EasyWay.AuthSamples_HostAddress}}/weatherforecast/ -Accept: application/json - -### diff --git a/samples/EasyWay.AuthSamples/Program.cs b/samples/EasyWay.AuthSamples/Program.cs deleted file mode 100644 index b06288b..0000000 --- a/samples/EasyWay.AuthSamples/Program.cs +++ /dev/null @@ -1,3 +0,0 @@ -using EasyWay; - -await AuthServer.RunAsync(args); \ No newline at end of file diff --git a/samples/EasyWay.AuthSamples/Properties/launchSettings.json b/samples/EasyWay.AuthSamples/Properties/launchSettings.json deleted file mode 100644 index b038ea7..0000000 --- a/samples/EasyWay.AuthSamples/Properties/launchSettings.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/launchsettings.json", - "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "https://localhost:7221;http://localhost:5229", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": false, - "applicationUrl": "https://localhost:7221;http://localhost:5229", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/samples/EasyWay.AuthSamples/appsettings.Development.json b/samples/EasyWay.AuthSamples/appsettings.Development.json deleted file mode 100644 index 0c208ae..0000000 --- a/samples/EasyWay.AuthSamples/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/samples/EasyWay.AuthSamples/appsettings.json b/samples/EasyWay.AuthSamples/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/samples/EasyWay.AuthSamples/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/samples/EasyWay.Samples/Program.cs b/samples/EasyWay.Samples/Program.cs index b305b98..b9034df 100644 --- a/samples/EasyWay.Samples/Program.cs +++ b/samples/EasyWay.Samples/Program.cs @@ -2,7 +2,7 @@ using EasyWay.Samples.Commands; using EasyWay.Samples.Commands.WithResult; using EasyWay.Samples.Queries; - +/* var webKernelBuilder = WebKernelBuilder.Create(args); var builder = webKernelBuilder.AppBuilder; @@ -28,4 +28,9 @@ webKernel.MapCommand(); webKernel.MapQuery(); -await webKernel.RunAsync(); \ No newline at end of file + + +await webKernel.RunAsync(); +*/ + +Console.WriteLine("TEST"); \ No newline at end of file diff --git a/source/EasyWay.Auth.WebApi/AuthServer.cs b/source/EasyWay.Auth.WebApi/AuthServer.cs deleted file mode 100644 index f0e5655..0000000 --- a/source/EasyWay.Auth.WebApi/AuthServer.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using EasyWay.Internals; -using EasyWay.Internals.Middlewares; - -namespace EasyWay -{ - public static class AuthServer - { - public static async Task RunAsync(string[] args) - { - var builder = WebApplication.CreateBuilder(args); - - builder.WebHost.UseKestrel(option => option.AddServerHeader = false); - - builder.Services.AddAuth(); - builder.Services.AddAuthWebApi(); - - var app = builder.Build(); - - app.UseMiddleware(); - - app.MapIssueEndpoint(); - app.MapRefreshEndpoint(); - app.MapCancelEndpoint(); - - await app.RunAsync(); - } - } -} diff --git a/source/EasyWay.Auth.WebApi/EasyWay.Auth.WebApi.csproj b/source/EasyWay.Auth.WebApi/EasyWay.Auth.WebApi.csproj deleted file mode 100644 index 5b916da..0000000 --- a/source/EasyWay.Auth.WebApi/EasyWay.Auth.WebApi.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net9.0 - enable - enable - - - - - - - - diff --git a/source/EasyWay.Auth.WebApi/Internals/AccessTokenResponse.cs b/source/EasyWay.Auth.WebApi/Internals/AccessTokenResponse.cs deleted file mode 100644 index 9948849..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/AccessTokenResponse.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace EasyWay.Internals -{ - internal sealed class AccessTokenResponse - { - public string AccessToken { get; } - - internal AccessTokenResponse(string accessToken) - { - AccessToken = accessToken; - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/Cookies/IRefreshTokenCookie.cs b/source/EasyWay.Auth.WebApi/Internals/Cookies/IRefreshTokenCookie.cs deleted file mode 100644 index 671be8a..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/Cookies/IRefreshTokenCookie.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Microsoft.AspNetCore.Http; - -namespace EasyWay.Internals.Cookies -{ - internal interface IRefreshTokenCookie - { - string? Get(HttpContext httpContext); - - void Add(HttpContext httpContext, string refreshToken, DateTime expires); - - void Remove(HttpContext httpContext); - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/Cookies/RefreshTokenCookie.cs b/source/EasyWay.Auth.WebApi/Internals/Cookies/RefreshTokenCookie.cs deleted file mode 100644 index ccbfc18..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/Cookies/RefreshTokenCookie.cs +++ /dev/null @@ -1,56 +0,0 @@ -using EasyWay.Internals.Settings; -using Microsoft.AspNetCore.Http; - -namespace EasyWay.Internals.Cookies -{ - internal sealed class RefreshTokenCookie : IRefreshTokenCookie - { - private const string _refreshTokenCookieName = "X-Refresh-Token"; - - private const string _cookiePath = "/tokens/"; - - private readonly IAuthServerSettings _authServerSettings; - - public RefreshTokenCookie(IAuthServerSettings authServerSettings) - { - _authServerSettings = authServerSettings; - } - - public void Add(HttpContext httpContext, string refreshToken, DateTime expires) - { - var cookieOptions = new CookieOptions() - { - HttpOnly = true, - Secure = true, - IsEssential = true, - SameSite = SameSiteMode.Strict, - Expires = expires, - Path = _cookiePath, - Domain = _authServerSettings.Domain, - }; - - httpContext.Response.Cookies.Append(_refreshTokenCookieName, refreshToken, cookieOptions); - } - - public string? Get(HttpContext httpContext) - { - return httpContext.Request.Cookies.SingleOrDefault(x => x.Key == _refreshTokenCookieName).Value; - } - - public void Remove(HttpContext httpContext) - { - var cookieOptions = new CookieOptions() - { - HttpOnly = true, - Secure = true, - IsEssential = true, - SameSite = SameSiteMode.Strict, - Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), - Path = _cookiePath, - Domain = _authServerSettings.Domain, - }; - - httpContext.Response.Cookies.Append(_refreshTokenCookieName, string.Empty, cookieOptions); - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/EasyWayAuthApiRoutes.cs b/source/EasyWay.Auth.WebApi/Internals/EasyWayAuthApiRoutes.cs deleted file mode 100644 index 84510c5..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/EasyWayAuthApiRoutes.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace EasyWay.Internals -{ - internal static class EasyWayAuthApiRoutes - { - internal const string ISSUE_TOKENS = "/issue"; - - internal const string REFRESH_TOKENS = "/tokens/refresh"; - - internal const string CANCEL_TOKENS = "/tokens/cancel"; - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/Extensions.cs b/source/EasyWay.Auth.WebApi/Internals/Extensions.cs deleted file mode 100644 index 0368f2a..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/Extensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using EasyWay.Internals.Cookies; -using EasyWay.Internals.Settings; -using EasyWay.Settings; -using Microsoft.Extensions.DependencyInjection; - -namespace EasyWay.Internals -{ - internal static class Extensions - { - internal static IServiceCollection AddAuthWebApi(this IServiceCollection services) - { - services.AddSingleton(); - - var settings = new AuthServerSettings(); - - services.AddSingleton(settings); - services.AddSingleton(settings); - - return services; - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/MapCancelExtension.cs b/source/EasyWay.Auth.WebApi/Internals/MapCancelExtension.cs deleted file mode 100644 index b1b41be..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/MapCancelExtension.cs +++ /dev/null @@ -1,31 +0,0 @@ -using EasyWay.Internals.Application.Cancel; -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Cookies; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; - -namespace EasyWay.Internals -{ - internal static class MapCancelExtension - { - internal static IEndpointRouteBuilder MapCancelEndpoint(this IEndpointRouteBuilder endpoints) - { - endpoints.MapPost(EasyWayAuthApiRoutes.CANCEL_TOKENS, async ( - ISecurityActionExecutor executor, - IRefreshTokenCookie refreshTokenCookie, - HttpContext httpContext) => - { - var refreshToken = refreshTokenCookie.Get(httpContext); - - var tokensResult = await executor.Execute(new CancelRefreshTokenAction(refreshToken)); - - refreshTokenCookie.Remove(httpContext); - - return tokensResult.IsSuccess ? Results.StatusCode(200) : Results.StatusCode(401); - }); - - return endpoints; - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/MapIssueExtension.cs b/source/EasyWay.Auth.WebApi/Internals/MapIssueExtension.cs deleted file mode 100644 index 0fa5934..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/MapIssueExtension.cs +++ /dev/null @@ -1,42 +0,0 @@ -using EasyWay.Internals.Application; -using EasyWay.Internals.Application.Issue; -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Cookies; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Logging; - -namespace EasyWay.Internals -{ - internal static class MapIssueExtension - { - internal static IEndpointRouteBuilder MapIssueEndpoint(this IEndpointRouteBuilder endpoints) - { - endpoints.MapPost(EasyWayAuthApiRoutes.ISSUE_TOKENS, async ( - ISecurityActionExecutor executor, - IRefreshTokenCookie cookie, - HttpContext httpContext) => - { - //TODO Authentication (return userID) - var userId = new Guid("ca1af613-987b-41df-b82e-ebb6d76a44b8"); - - var issueTokensResult = await executor.Execute(new IssueTokensAction(userId)); - - if (issueTokensResult.IsFailure) - { - cookie.Remove(httpContext); - - return Results.StatusCode(401); - } - - cookie.Add(httpContext, issueTokensResult.Value.RefreshToken, issueTokensResult.Value.RefreshTokenExpires); - - return Results.Ok(new AccessTokenResponse(issueTokensResult.Value.AccessToken)); - }); - - - return endpoints; - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/MapRefreshExtension.cs b/source/EasyWay.Auth.WebApi/Internals/MapRefreshExtension.cs deleted file mode 100644 index 11ae51e..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/MapRefreshExtension.cs +++ /dev/null @@ -1,36 +0,0 @@ -using EasyWay.Internals.Application; -using EasyWay.Internals.Application.Refresh; -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Cookies; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; - -namespace EasyWay.Internals -{ - internal static class MapRefreshExtension - { - internal static IEndpointRouteBuilder MapRefreshEndpoint(this IEndpointRouteBuilder endpoints) - { - endpoints.MapPost(EasyWayAuthApiRoutes.REFRESH_TOKENS, async (ISecurityActionExecutor executor, IRefreshTokenCookie cookie, HttpContext httpContext) => - { - var oldRefreshToken = cookie.Get(httpContext); - - var tokensResult = await executor.Execute(new RefreshTokensAction(oldRefreshToken)); - - if (tokensResult.IsFailure) - { - cookie.Remove(httpContext); - - return Results.StatusCode(401); - } - - cookie.Add(httpContext, tokensResult.Value.RefreshToken, tokensResult.Value.RefreshTokenExpires); - - return Results.Ok(new AccessTokenResponse(tokensResult.Value.AccessToken)); - }); - - return endpoints; - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/Middlewares/ExceptionHandlerMiddleware.cs b/source/EasyWay.Auth.WebApi/Internals/Middlewares/ExceptionHandlerMiddleware.cs deleted file mode 100644 index f6720bb..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/Middlewares/ExceptionHandlerMiddleware.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.AspNetCore.Http; -using System.Net; -using EasyWay.Internals.Cookies; -using Microsoft.Extensions.Logging; - -namespace EasyWay.Internals.Middlewares -{ - internal sealed class ExceptionHandlerMiddleware - { - private readonly RequestDelegate _next; - - private readonly IRefreshTokenCookie _refreshTokenCookie; - - private readonly ILogger _logger; - - public ExceptionHandlerMiddleware( - RequestDelegate next, - IRefreshTokenCookie refreshTokenCookie, - ILogger logger) - { - _next = next; - _refreshTokenCookie = refreshTokenCookie; - _logger = logger; - } - - public async Task Invoke(HttpContext httpContext) - { - try - { - await _next(httpContext); - } - catch (Exception exception) - { - _logger.LogError("Exception {@exception}", exception); - - httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; - } - } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/Settings/AuthServerSettings.cs b/source/EasyWay.Auth.WebApi/Internals/Settings/AuthServerSettings.cs deleted file mode 100644 index 713d58d..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/Settings/AuthServerSettings.cs +++ /dev/null @@ -1,23 +0,0 @@ -using EasyWay.Settings; - -namespace EasyWay.Internals.Settings -{ - internal sealed class AuthServerSettings : IAuthServerSettings, IAuthSettings - { - public string Domain { get; set; } = "localhost"; - - public TimeSpan RefreshTokenLifetime { get; set; } = TimeSpan.FromDays(1); - - public TimeSpan? RefreshTokenMaxIdleTime { get; set; } = null; - - public TimeSpan AccessTokenLifetime { get; set; } = TimeSpan.FromSeconds(3); - - public string SecretKey { get; set; } = "XN32ifS0ZumZ0QZTAFyY86GdQRPnTHjwzh42KpflDemEZ+Ewlzpgb3N5l8u9/jWV"; - - public int RefreshTokenSize { get; set; } = 32; - - public string RefreshTokenSalt { get; set; } = "wdxWsh+ZRpRhe4MByN2RzTESn4XbVE8xn/cKg5jp450="; - - internal AuthServerSettings() { } - } -} diff --git a/source/EasyWay.Auth.WebApi/Internals/Settings/IAuthServerSettings.cs b/source/EasyWay.Auth.WebApi/Internals/Settings/IAuthServerSettings.cs deleted file mode 100644 index 5004fa8..0000000 --- a/source/EasyWay.Auth.WebApi/Internals/Settings/IAuthServerSettings.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace EasyWay.Internals.Settings -{ - internal interface IAuthServerSettings - { - string Domain { get; } - } -} diff --git a/source/EasyWay.Auth/EasyWay.Auth.csproj b/source/EasyWay.Auth/EasyWay.Auth.csproj deleted file mode 100644 index cc1f7f8..0000000 --- a/source/EasyWay.Auth/EasyWay.Auth.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/source/EasyWay.Auth/Internals/AccessTokenCreators/AccessToken.cs b/source/EasyWay.Auth/Internals/AccessTokenCreators/AccessToken.cs deleted file mode 100644 index aa2bbaf..0000000 --- a/source/EasyWay.Auth/Internals/AccessTokenCreators/AccessToken.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace EasyWay.Internals.AccessTokenCreators -{ - internal sealed class AccessToken - { - internal string Token { get; } - - internal DateTime Expires { get; } - - internal AccessToken( - string token, - DateTime expires) - { - Token = token; - Expires = expires; - } - } -} diff --git a/source/EasyWay.Auth/Internals/AccessTokenCreators/AccessTokensCreator.cs b/source/EasyWay.Auth/Internals/AccessTokenCreators/AccessTokensCreator.cs deleted file mode 100644 index 1a113f4..0000000 --- a/source/EasyWay.Auth/Internals/AccessTokenCreators/AccessTokensCreator.cs +++ /dev/null @@ -1,46 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Clocks; -using EasyWay.Settings; -using Microsoft.IdentityModel.Tokens; -using System.IdentityModel.Tokens.Jwt; -using System.Security.Claims; -using System.Text; - -namespace EasyWay.Internals.AccessTokenCreators -{ - internal sealed class AccessTokensCreator : IAccessTokensCreator - { - private readonly IAuthSettings _settings; - - public AccessTokensCreator(IAuthSettings settings) - { - _settings = settings; - } - - public AccessToken Create(Guid userId) - { - var tokenHandler = new JwtSecurityTokenHandler(); - - var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(_settings.SecretKey)); - - var expires = SecurityClock.UtcNow.Add(_settings.AccessTokenLifetime); - - var tokenDescriptor = new SecurityTokenDescriptor - { - Subject = new ClaimsIdentity(new[] -{ - new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()), - new Claim(JwtRegisteredClaimNames.UniqueName, Guid.NewGuid().ToString()), - new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) - }), - Expires = expires, - SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature), - }; - - var accessToken = tokenHandler.CreateToken(tokenDescriptor); - - var stringToken = tokenHandler.WriteToken(accessToken); - - return new AccessToken(stringToken, expires); - } - } -} diff --git a/source/EasyWay.Auth/Internals/AccessTokenCreators/IAccessTokensCreator.cs b/source/EasyWay.Auth/Internals/AccessTokenCreators/IAccessTokensCreator.cs deleted file mode 100644 index 590388d..0000000 --- a/source/EasyWay.Auth/Internals/AccessTokenCreators/IAccessTokensCreator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace EasyWay.Internals.AccessTokenCreators -{ - internal interface IAccessTokensCreator - { - AccessToken Create(Guid userId); - } -} diff --git a/source/EasyWay.Auth/Internals/Application/Cancel/CancelRefreshTokenAction.cs b/source/EasyWay.Auth/Internals/Application/Cancel/CancelRefreshTokenAction.cs deleted file mode 100644 index 30b8c2f..0000000 --- a/source/EasyWay.Auth/Internals/Application/Cancel/CancelRefreshTokenAction.cs +++ /dev/null @@ -1,14 +0,0 @@ -using EasyWay.Internals.Contracts; - -namespace EasyWay.Internals.Application.Cancel -{ - internal sealed class CancelRefreshTokenAction : ISecurityAction - { - internal string? RefreshToken { get; } - - internal CancelRefreshTokenAction(string? refreshToken) - { - RefreshToken = refreshToken; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Application/Cancel/CancelRefreshTokenActionHandler.cs b/source/EasyWay.Auth/Internals/Application/Cancel/CancelRefreshTokenActionHandler.cs deleted file mode 100644 index 0c16c9b..0000000 --- a/source/EasyWay.Auth/Internals/Application/Cancel/CancelRefreshTokenActionHandler.cs +++ /dev/null @@ -1,39 +0,0 @@ -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Domain; -using EasyWay.Internals.Domain.SeedWorks.Results; -using EasyWay.Internals.RefreshTokenCreators; - -namespace EasyWay.Internals.Application.Cancel -{ - internal sealed class CancelRefreshTokenActionHandler : ISecurityActionHandler - { - private readonly ISecurityTokensRepository _repository; - - private readonly IRefreshTokenHasher _refreshTokenHasher; - - public CancelRefreshTokenActionHandler( - ISecurityTokensRepository repository, - IRefreshTokenHasher refreshTokenHasher) - { - _repository = repository; - _refreshTokenHasher = refreshTokenHasher; - } - - public async Task Handle(CancelRefreshTokenAction action) - { - if (string.IsNullOrEmpty(action.RefreshToken)) - { - return SecurityResult.Failure(new RefreshTokenIsNotProvidedSecurityError()); - } - - var hashedRefreshToken = _refreshTokenHasher.Hash(action.RefreshToken); - - if (!await _repository.IfExistsRemove(hashedRefreshToken)) - { - return SecurityResult.Failure(new RefreshTokenDoesNotExistSecurityError()); - } - - return SecurityResult.Success; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Application/Issue/IssueTokensAction.cs b/source/EasyWay.Auth/Internals/Application/Issue/IssueTokensAction.cs deleted file mode 100644 index 4decf1f..0000000 --- a/source/EasyWay.Auth/Internals/Application/Issue/IssueTokensAction.cs +++ /dev/null @@ -1,14 +0,0 @@ -using EasyWay.Internals.Contracts; - -namespace EasyWay.Internals.Application.Issue -{ - internal sealed class IssueTokensAction : ISecurityAction - { - internal Guid UserId { get; } - - internal IssueTokensAction(Guid userId) - { - UserId = userId; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Application/Issue/IssueTokensActionHandler.cs b/source/EasyWay.Auth/Internals/Application/Issue/IssueTokensActionHandler.cs deleted file mode 100644 index 24a8fe9..0000000 --- a/source/EasyWay.Auth/Internals/Application/Issue/IssueTokensActionHandler.cs +++ /dev/null @@ -1,62 +0,0 @@ -using EasyWay.Internals.AccessTokenCreators; -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Domain; -using EasyWay.Internals.Domain.SeedWorks.Results; -using EasyWay.Internals.RefreshTokenCreators; -using EasyWay.Settings; -using Microsoft.Extensions.Logging; - -namespace EasyWay.Internals.Application.Issue -{ - internal sealed class IssueTokensActionHandler : ISecurityActionHandler - { - private readonly IAccessTokensCreator _accessTokensCreator; - - private readonly IRefreshTokenCreator _refreshTokenCreator; - - private readonly ISecurityTokensRepository _storage; - - private readonly IAuthSettings _authSettings; - - private readonly IRefreshTokenHasher _refreshTokenHasher; - - private readonly ILogger _logger; - - public IssueTokensActionHandler( - IAccessTokensCreator accessTokensCreator, - IRefreshTokenCreator refreshTokenCreator, - ISecurityTokensRepository storage, - IAuthSettings authSettings, - IRefreshTokenHasher refreshTokenHasher, - ILogger logger) - { - _accessTokensCreator = accessTokensCreator; - _refreshTokenCreator = refreshTokenCreator; - _storage = storage; - _authSettings = authSettings; - _refreshTokenHasher = refreshTokenHasher; - _logger = logger; - } - - public async Task> Handle(IssueTokensAction action) - { - if (await _storage.IfExistsRemove(action.UserId)) - { - _logger.LogInformation("Overwritten refresh token for user {@userId}", action.UserId); - } - - //TODO hash - var refreshToken = _refreshTokenCreator.Create(); - var accessToken = _accessTokensCreator.Create(action.UserId); - - var hashedRefreshToken = _refreshTokenHasher.Hash(refreshToken); - - //TODO hash after check rules - var storageToken = SecurityTokens.Issue(action.UserId, hashedRefreshToken, _authSettings.RefreshTokenLifetime, _authSettings.RefreshTokenMaxIdleTime, accessToken.Expires); - - await _storage.Add(storageToken); - - return SecurityResult.Success(new TokensDto(refreshToken, storageToken.RefreshTokenExpires, accessToken.Token)); - } - } -} diff --git a/source/EasyWay.Auth/Internals/Application/Refresh/RefreshTokensAction.cs b/source/EasyWay.Auth/Internals/Application/Refresh/RefreshTokensAction.cs deleted file mode 100644 index b54e294..0000000 --- a/source/EasyWay.Auth/Internals/Application/Refresh/RefreshTokensAction.cs +++ /dev/null @@ -1,14 +0,0 @@ -using EasyWay.Internals.Contracts; - -namespace EasyWay.Internals.Application.Refresh -{ - internal sealed class RefreshTokensAction : ISecurityAction - { - internal string? OldRefreshToken { get; } - - internal RefreshTokensAction(string? oldRefreshToken) - { - OldRefreshToken = oldRefreshToken; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Application/Refresh/RefreshTokensActionHandler.cs b/source/EasyWay.Auth/Internals/Application/Refresh/RefreshTokensActionHandler.cs deleted file mode 100644 index 24a6349..0000000 --- a/source/EasyWay.Auth/Internals/Application/Refresh/RefreshTokensActionHandler.cs +++ /dev/null @@ -1,66 +0,0 @@ -using EasyWay.Internals.AccessTokenCreators; -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Domain; -using EasyWay.Internals.Domain.SeedWorks.Results; -using EasyWay.Internals.RefreshTokenCreators; -using EasyWay.Settings; - -namespace EasyWay.Internals.Application.Refresh -{ - internal sealed class RefreshTokensActionHandler : ISecurityActionHandler - { - private readonly IAccessTokensCreator _accessTokensCreator; - - private readonly IRefreshTokenCreator _refreshTokenCreator; - - private readonly ISecurityTokensRepository _storage; - - private readonly IRefreshTokenHasher _refreshTokenHasher; - - private readonly IAuthSettings _authSettings; - - public RefreshTokensActionHandler( - IAccessTokensCreator accessTokensCreator, - IRefreshTokenCreator refreshTokenCreator, - ISecurityTokensRepository storage, - IRefreshTokenHasher refreshTokenHasher, - IAuthSettings authSettings) - { - _accessTokensCreator = accessTokensCreator; - _refreshTokenCreator = refreshTokenCreator; - _storage = storage; - _refreshTokenHasher = refreshTokenHasher; - _authSettings = authSettings; - } - - public async Task> Handle(RefreshTokensAction action) - { - if (string.IsNullOrEmpty(action.OldRefreshToken)) - { - return SecurityResult.Failure(new RefreshTokenIsNotProvidedSecurityError()); - } - - var hashedOldRefreshToken = _refreshTokenHasher.Hash(action.OldRefreshToken); - - var storageTokens = await _storage.Get(hashedOldRefreshToken); - - if (storageTokens is null) - { - return SecurityResult.Failure(new RefreshTokenDoesNotExistSecurityError()); - } - - var accessToken = _accessTokensCreator.Create(storageTokens.UserId); - - var newRefreshToken = _refreshTokenCreator.Create(); - - var refreshResult = storageTokens.Refresh(newRefreshToken, accessToken.Expires, _refreshTokenHasher, _authSettings.RefreshTokenMaxIdleTime); - - if (refreshResult.IsFailure) - { - return SecurityResult.Failure(refreshResult.Error); - } - - return SecurityResult.Success(new TokensDto(newRefreshToken, storageTokens.RefreshTokenExpires, accessToken.Token)); - } - } -} diff --git a/source/EasyWay.Auth/Internals/Application/RefreshTokenDoesNotExistSecurityError.cs b/source/EasyWay.Auth/Internals/Application/RefreshTokenDoesNotExistSecurityError.cs deleted file mode 100644 index 9f1eea1..0000000 --- a/source/EasyWay.Auth/Internals/Application/RefreshTokenDoesNotExistSecurityError.cs +++ /dev/null @@ -1,6 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Application -{ - internal sealed class RefreshTokenDoesNotExistSecurityError : SecurityError; -} diff --git a/source/EasyWay.Auth/Internals/Application/RefreshTokenIsNotProvidedSecurityError.cs b/source/EasyWay.Auth/Internals/Application/RefreshTokenIsNotProvidedSecurityError.cs deleted file mode 100644 index bfb7c05..0000000 --- a/source/EasyWay.Auth/Internals/Application/RefreshTokenIsNotProvidedSecurityError.cs +++ /dev/null @@ -1,6 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Application -{ - internal sealed class RefreshTokenIsNotProvidedSecurityError : SecurityError; -} diff --git a/source/EasyWay.Auth/Internals/Application/TokensDto.cs b/source/EasyWay.Auth/Internals/Application/TokensDto.cs deleted file mode 100644 index 65948e7..0000000 --- a/source/EasyWay.Auth/Internals/Application/TokensDto.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace EasyWay.Internals.Application -{ - internal sealed class TokensDto - { - public string RefreshToken { get; } - - public DateTime RefreshTokenExpires { get; } - - public string AccessToken { get; } - - internal TokensDto(string refreshToken, DateTime refreshTokenExpires, string accessToken) - { - RefreshToken = refreshToken; - RefreshTokenExpires = refreshTokenExpires; - AccessToken = accessToken; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Contracts/Extensions.cs b/source/EasyWay.Auth/Internals/Contracts/Extensions.cs deleted file mode 100644 index 29d3df4..0000000 --- a/source/EasyWay.Auth/Internals/Contracts/Extensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using EasyWay.Internals.Application.Refresh; -using EasyWay.Internals.Application; -using Microsoft.Extensions.DependencyInjection; -using EasyWay.Internals.Application.Issue; -using EasyWay.Internals.Application.Cancel; - -namespace EasyWay.Internals.Contracts -{ - internal static class Extensions - { - internal static IServiceCollection AddSecurityActions(this IServiceCollection services) - { - services.AddScoped(); - - services.AddScoped, RefreshTokensActionHandler>(); - services.AddScoped, IssueTokensActionHandler>(); - services.AddScoped, CancelRefreshTokenActionHandler>(); - - return services; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Contracts/ISecurityAction.cs b/source/EasyWay.Auth/Internals/Contracts/ISecurityAction.cs deleted file mode 100644 index 54e1cd1..0000000 --- a/source/EasyWay.Auth/Internals/Contracts/ISecurityAction.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace EasyWay.Internals.Contracts -{ - internal interface ISecurityAction; - - internal interface ISecurityAction; -} diff --git a/source/EasyWay.Auth/Internals/Contracts/ISecurityActionExecutor.cs b/source/EasyWay.Auth/Internals/Contracts/ISecurityActionExecutor.cs deleted file mode 100644 index c2fb471..0000000 --- a/source/EasyWay.Auth/Internals/Contracts/ISecurityActionExecutor.cs +++ /dev/null @@ -1,13 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Contracts -{ - internal interface ISecurityActionExecutor - { - Task Execute(TAction action) - where TAction : class, ISecurityAction; - - Task> Execute(TAction action) - where TAction : class, ISecurityAction; - } -} diff --git a/source/EasyWay.Auth/Internals/Contracts/ISecurityActionHandler.cs b/source/EasyWay.Auth/Internals/Contracts/ISecurityActionHandler.cs deleted file mode 100644 index d4c3c16..0000000 --- a/source/EasyWay.Auth/Internals/Contracts/ISecurityActionHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Contracts -{ - internal interface ISecurityActionHandler - where TAction : class, ISecurityAction - { - Task Handle(TAction action); - } - - internal interface ISecurityActionHandler - where TAction : class, ISecurityAction - { - Task> Handle(TAction action); - } -} diff --git a/source/EasyWay.Auth/Internals/Contracts/SecurityActionExecutor.cs b/source/EasyWay.Auth/Internals/Contracts/SecurityActionExecutor.cs deleted file mode 100644 index a02a03d..0000000 --- a/source/EasyWay.Auth/Internals/Contracts/SecurityActionExecutor.cs +++ /dev/null @@ -1,46 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace EasyWay.Internals.Contracts -{ - internal sealed class SecurityActionExecutor : ISecurityActionExecutor - { - private readonly IServiceProvider _serviceProvider; - - public SecurityActionExecutor(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public async Task Execute(TAction action) - where TAction : class, ISecurityAction - { - var result = await _serviceProvider.GetRequiredService>().Handle(action); - - if (result.IsFailure) - { - var logger = _serviceProvider.GetRequiredService>(); - - logger.LogWarning(result.Error.Code); - } - - return result; - } - - public async Task> Execute(TAction action) - where TAction : class, ISecurityAction - { - var result = await _serviceProvider.GetRequiredService>().Handle(action); - - if (result.IsFailure) - { - var logger = _serviceProvider.GetRequiredService>(); - - logger.LogWarning(result.Error.Code); - } - - return result; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Domain/Errors/AccessTokenIsNotExpiredSecurityError.cs b/source/EasyWay.Auth/Internals/Domain/Errors/AccessTokenIsNotExpiredSecurityError.cs deleted file mode 100644 index ad65601..0000000 --- a/source/EasyWay.Auth/Internals/Domain/Errors/AccessTokenIsNotExpiredSecurityError.cs +++ /dev/null @@ -1,6 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Domain.Errors -{ - internal sealed class AccessTokenIsNotExpiredSecurityError : SecurityError; -} diff --git a/source/EasyWay.Auth/Internals/Domain/Errors/RefreshTokenIsExpiredSecurityError.cs b/source/EasyWay.Auth/Internals/Domain/Errors/RefreshTokenIsExpiredSecurityError.cs deleted file mode 100644 index 046b5e2..0000000 --- a/source/EasyWay.Auth/Internals/Domain/Errors/RefreshTokenIsExpiredSecurityError.cs +++ /dev/null @@ -1,6 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Domain.Errors -{ - internal sealed class RefreshTokenIsExpiredSecurityError : SecurityError; -} diff --git a/source/EasyWay.Auth/Internals/Domain/Errors/RefreshTokenTimeoutExceededSecurityError.cs b/source/EasyWay.Auth/Internals/Domain/Errors/RefreshTokenTimeoutExceededSecurityError.cs deleted file mode 100644 index 0093fe2..0000000 --- a/source/EasyWay.Auth/Internals/Domain/Errors/RefreshTokenTimeoutExceededSecurityError.cs +++ /dev/null @@ -1,6 +0,0 @@ -using EasyWay.Internals.Domain.SeedWorks.Results; - -namespace EasyWay.Internals.Domain.Errors -{ - internal sealed class RefreshTokenTimeoutExceededSecurityError : SecurityError; -} diff --git a/source/EasyWay.Auth/Internals/Domain/ISecurityTokensRepository.cs b/source/EasyWay.Auth/Internals/Domain/ISecurityTokensRepository.cs deleted file mode 100644 index 39db8a6..0000000 --- a/source/EasyWay.Auth/Internals/Domain/ISecurityTokensRepository.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace EasyWay.Internals.Domain -{ - internal interface ISecurityTokensRepository - { - Task Get(string refreshToken); - - Task IfExistsRemove(Guid userId); - - Task IfExistsRemove(string refreshToken); - - Task Remove(string refreshToken); - - Task Add(SecurityTokens storageTokens); - } -} diff --git a/source/EasyWay.Auth/Internals/Domain/SecurityTokens.cs b/source/EasyWay.Auth/Internals/Domain/SecurityTokens.cs deleted file mode 100644 index ec05d4f..0000000 --- a/source/EasyWay.Auth/Internals/Domain/SecurityTokens.cs +++ /dev/null @@ -1,93 +0,0 @@ -using EasyWay.Internals.Domain.Errors; -using EasyWay.Internals.Domain.SeedWorks.Clocks; -using EasyWay.Internals.Domain.SeedWorks.Results; -using EasyWay.Internals.RefreshTokenCreators; - -namespace EasyWay.Internals.Domain -{ - internal sealed class SecurityTokens - { - public Guid UserId { get; private set; } - - public string HashedRefreshToken { get; private set; } - - public DateTime RefreshTokenExpires { get; private set; } - - public DateTime? RefreshTokenTimeout { get; private set; } - - public DateTime AccessTokenExpires { get; private set; } - - private SecurityTokens( - Guid userId, - string hashedRefreshToken, - DateTime refreshTokenExpires, - DateTime? refreshTokenTimeout, - DateTime accessTokenExpires) - { - UserId = userId; - HashedRefreshToken = hashedRefreshToken; - RefreshTokenExpires = refreshTokenExpires; - RefreshTokenTimeout = refreshTokenTimeout; - AccessTokenExpires = accessTokenExpires; - } - - internal static SecurityTokens Issue( - Guid userId, - string hashedRefreshToken, - TimeSpan refreshTokenLifetime, - TimeSpan? refreshTokenMaxIdleTime, - DateTime accessTokenExpires) - { - var refreshTokenExpires = SecurityClock.UtcNow.Add(refreshTokenLifetime); - var refreshTokenTimeout = CalculateRefreshTokenTimeout(refreshTokenMaxIdleTime, refreshTokenExpires); - - return new SecurityTokens(userId, hashedRefreshToken, refreshTokenExpires, refreshTokenTimeout, accessTokenExpires); - } - - internal SecurityResult Refresh( - string refreshToken, - DateTime accessTokenExpires, - IRefreshTokenHasher refreshTokenHasher, - TimeSpan? refreshTokenMaxIdleTime) - { - if (!IsAccessTokenExpired()) - { - return SecurityResult.Failure(new AccessTokenIsNotExpiredSecurityError()); - } - - if (IsRefreshTokenExpired()) - { - return SecurityResult.Failure(new RefreshTokenIsExpiredSecurityError()); - } - - if (IsRefreshTokenIdleTimeExceeded()) - { - return SecurityResult.Failure(new RefreshTokenTimeoutExceededSecurityError()); - } - - RefreshTokenTimeout = CalculateRefreshTokenTimeout(refreshTokenMaxIdleTime, RefreshTokenExpires); - HashedRefreshToken = refreshTokenHasher.Hash(refreshToken); - AccessTokenExpires = accessTokenExpires; - - return SecurityResult.Success; - } - - private bool IsAccessTokenExpired() => SecurityClock.UtcNow >= AccessTokenExpires; - - private bool IsRefreshTokenExpired() => SecurityClock.UtcNow >= RefreshTokenExpires; - - private bool IsRefreshTokenIdleTimeExceeded() => RefreshTokenTimeout is not null ? SecurityClock.UtcNow >= RefreshTokenTimeout : false; - - private static DateTime? CalculateRefreshTokenTimeout(TimeSpan? refreshTokenMaxIdleTime, DateTime refreshTokenExpires) - { - DateTime? refreshTokenTimeout = refreshTokenMaxIdleTime.HasValue ? SecurityClock.UtcNow + refreshTokenMaxIdleTime.Value : null; - - if (refreshTokenTimeout.HasValue) - { - return refreshTokenTimeout > refreshTokenExpires ? refreshTokenExpires : refreshTokenTimeout; - } - - return refreshTokenTimeout; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Clocks/CustomDateTimeMustBeUtcException.cs b/source/EasyWay.Auth/Internals/Domain/SeedWorks/Clocks/CustomDateTimeMustBeUtcException.cs deleted file mode 100644 index 2fac967..0000000 --- a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Clocks/CustomDateTimeMustBeUtcException.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace EasyWay.Internals.Domain.SeedWorks.Clocks -{ - internal sealed class CustomDateTimeMustBeUtcException : Exception - { - internal CustomDateTimeMustBeUtcException() : base() { } - } -} diff --git a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Clocks/SecurityClock.cs b/source/EasyWay.Auth/Internals/Domain/SeedWorks/Clocks/SecurityClock.cs deleted file mode 100644 index fdd42ad..0000000 --- a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Clocks/SecurityClock.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace EasyWay.Internals.Domain.SeedWorks.Clocks -{ - internal static class SecurityClock - { - [ThreadStatic] private static DateTime? _customDateTime; - - public static DateTime UtcNow - { - get - { - if (_customDateTime.HasValue) - { - return _customDateTime.Value; - } - - return DateTime.UtcNow; - } - } - - internal static void Set(DateTime customDateTime) - { - if (customDateTime.Kind != DateTimeKind.Utc) - { - throw new CustomDateTimeMustBeUtcException(); - } - - _customDateTime = customDateTime; - } - - internal static void Reset() => _customDateTime = null; - } -} diff --git a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/NoneSecurityError.cs b/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/NoneSecurityError.cs deleted file mode 100644 index 499630b..0000000 --- a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/NoneSecurityError.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace EasyWay.Internals.Domain.SeedWorks.Results -{ - internal sealed class NoneSecurityError : SecurityError; -} diff --git a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/SecurityError.cs b/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/SecurityError.cs deleted file mode 100644 index e22121b..0000000 --- a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/SecurityError.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace EasyWay.Internals.Domain.SeedWorks.Results -{ - internal abstract class SecurityError - { - internal string Code => GetType().Name; - - internal SecurityError() { } - } -} diff --git a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/SecurityResult.cs b/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/SecurityResult.cs deleted file mode 100644 index e8ee330..0000000 --- a/source/EasyWay.Auth/Internals/Domain/SeedWorks/Results/SecurityResult.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace EasyWay.Internals.Domain.SeedWorks.Results -{ - internal sealed class SecurityResult - { - internal bool IsSuccess { get; } - - internal bool IsFailure => !IsSuccess; - - internal SecurityError Error { get; } - - private SecurityResult() - { - IsSuccess = true; - Error = new NoneSecurityError(); - } - - private SecurityResult(SecurityError securityError) - { - IsSuccess = false; - Error = securityError; - } - - internal static SecurityResult Success => new(); - - internal static SecurityResult Failure(TSecurityResult error) - where TSecurityResult : SecurityError => new(error); - } - - internal sealed class SecurityResult - { - internal TValue Value { get; } - - internal bool IsSuccess { get; } - - internal bool IsFailure => !IsSuccess; - - internal SecurityError Error { get; } - - private SecurityResult(TValue value) - { - Value = value; - IsSuccess = true; - Error = new NoneSecurityError(); - } - - private SecurityResult(SecurityError securityError) - { - IsSuccess = false; - Error = securityError; - } - - internal static SecurityResult Success(TValue value) => new(value); - - internal static SecurityResult Failure(TSecurityResult error) - where TSecurityResult : SecurityError => new(error); - } -} - - diff --git a/source/EasyWay.Auth/Internals/Extensions.cs b/source/EasyWay.Auth/Internals/Extensions.cs deleted file mode 100644 index da2509c..0000000 --- a/source/EasyWay.Auth/Internals/Extensions.cs +++ /dev/null @@ -1,28 +0,0 @@ -using EasyWay.Internals.AccessTokenCreators; -using EasyWay.Internals.Application.Cancel; -using EasyWay.Internals.Application.Issue; -using EasyWay.Internals.Application.Refresh; -using EasyWay.Internals.Contracts; -using EasyWay.Internals.Domain; -using EasyWay.Internals.Infrastructure; -using EasyWay.Internals.RefreshTokenCreators; -using Microsoft.Extensions.DependencyInjection; - -namespace EasyWay.Internals -{ - internal static class Extensions - { - internal static IServiceCollection AddAuth(this IServiceCollection services) - { - services.AddSecurityActions(); - - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - - services.AddScoped(); - - return services; - } - } -} diff --git a/source/EasyWay.Auth/Internals/Infrastructure/SecurityTokensRepository.cs b/source/EasyWay.Auth/Internals/Infrastructure/SecurityTokensRepository.cs deleted file mode 100644 index 9580313..0000000 --- a/source/EasyWay.Auth/Internals/Infrastructure/SecurityTokensRepository.cs +++ /dev/null @@ -1,59 +0,0 @@ -using EasyWay.Internals.Domain; - -namespace EasyWay.Internals.Infrastructure -{ - internal sealed class SecurityTokensRepository : ISecurityTokensRepository - { - private static List tokens = new List(); - - public Task Add(SecurityTokens storageTokens) - { - tokens.Add(storageTokens); - - return Task.CompletedTask; - } - - public Task Get(string refreshToken) - { - var token = tokens.SingleOrDefault(x => x.HashedRefreshToken == refreshToken); - - return Task.FromResult(token); - } - - public Task IfExistsRemove(Guid userId) - { - var token = tokens.SingleOrDefault(x => x.UserId == userId); - - if (token != null) - { - return Task.FromResult(tokens.Remove(token)); - } - - return Task.FromResult(false); - } - - public Task IfExistsRemove(string refreshToken) - { - var token = tokens.SingleOrDefault(x => x.HashedRefreshToken == refreshToken); - - if (token != null) - { - return Task.FromResult(tokens.Remove(token)); - } - - return Task.FromResult(false); - } - - public Task Remove(string refreshToken) - { - var token = tokens.SingleOrDefault(x => x.HashedRefreshToken == refreshToken); - - if (token != null) - { - tokens.Remove(token); - } - - return Task.CompletedTask; - } - } -} diff --git a/source/EasyWay.Auth/Internals/RefreshTokenCreators/IRefreshTokenCreator.cs b/source/EasyWay.Auth/Internals/RefreshTokenCreators/IRefreshTokenCreator.cs deleted file mode 100644 index 7a2b638..0000000 --- a/source/EasyWay.Auth/Internals/RefreshTokenCreators/IRefreshTokenCreator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace EasyWay.Internals.RefreshTokenCreators -{ - internal interface IRefreshTokenCreator - { - string Create(); - } -} diff --git a/source/EasyWay.Auth/Internals/RefreshTokenCreators/IRefreshTokenHasher.cs b/source/EasyWay.Auth/Internals/RefreshTokenCreators/IRefreshTokenHasher.cs deleted file mode 100644 index 8cba135..0000000 --- a/source/EasyWay.Auth/Internals/RefreshTokenCreators/IRefreshTokenHasher.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace EasyWay.Internals.RefreshTokenCreators -{ - internal interface IRefreshTokenHasher - { - string Hash(string refreshToken); - - bool Verify(string refreshToken, string hashedRefreshToken); - } -} diff --git a/source/EasyWay.Auth/Internals/RefreshTokenCreators/RefreshTokenCreator.cs b/source/EasyWay.Auth/Internals/RefreshTokenCreators/RefreshTokenCreator.cs deleted file mode 100644 index 8e17ada..0000000 --- a/source/EasyWay.Auth/Internals/RefreshTokenCreators/RefreshTokenCreator.cs +++ /dev/null @@ -1,26 +0,0 @@ -using EasyWay.Settings; -using System.Security.Cryptography; - -namespace EasyWay.Internals.RefreshTokenCreators -{ - internal sealed class RefreshTokenCreator : IRefreshTokenCreator - { - private readonly IAuthSettings _settings; - - public RefreshTokenCreator(IAuthSettings settings) - { - _settings = settings; - } - - public string Create() - { - var randomNumber = new byte[_settings.RefreshTokenSize]; - - var rng = RandomNumberGenerator.Create(); - - rng.GetBytes(randomNumber); - - return Convert.ToBase64String(randomNumber); - } - } -} diff --git a/source/EasyWay.Auth/Internals/RefreshTokenCreators/RefreshTokenHasher.cs b/source/EasyWay.Auth/Internals/RefreshTokenCreators/RefreshTokenHasher.cs deleted file mode 100644 index 30c32c3..0000000 --- a/source/EasyWay.Auth/Internals/RefreshTokenCreators/RefreshTokenHasher.cs +++ /dev/null @@ -1,33 +0,0 @@ -using EasyWay.Settings; -using System.Security.Cryptography; - -namespace EasyWay.Internals.RefreshTokenCreators -{ - internal sealed class RefreshTokenHasher : IRefreshTokenHasher - { - private const int KeySize = 256 / 8; - - private const int Iterations = 3; - - private readonly HashAlgorithmName AlgorithmName = HashAlgorithmName.SHA256; - - private readonly byte[] _salt; - - public RefreshTokenHasher(IAuthSettings settings) - { - _salt = Convert.FromBase64String(settings.RefreshTokenSalt); - } - - public string Hash(string refreshToken) - { - var key = Rfc2898DeriveBytes.Pbkdf2(refreshToken, _salt, Iterations, AlgorithmName, KeySize); - - return Convert.ToBase64String(key); - } - - public bool Verify(string refreshToken, string hashedRefreshToken) - { - return Convert.FromBase64String(hashedRefreshToken) == Rfc2898DeriveBytes.Pbkdf2(refreshToken, _salt, Iterations, AlgorithmName, KeySize); - } - } -} diff --git a/source/EasyWay.Auth/Settings/IAuthSettings.cs b/source/EasyWay.Auth/Settings/IAuthSettings.cs deleted file mode 100644 index c30247f..0000000 --- a/source/EasyWay.Auth/Settings/IAuthSettings.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace EasyWay.Settings -{ - internal interface IAuthSettings - { - string SecretKey { get; } - - TimeSpan RefreshTokenLifetime { get; } - - TimeSpan? RefreshTokenMaxIdleTime { get; } - - int RefreshTokenSize { get; } - - string RefreshTokenSalt { get; } - - TimeSpan AccessTokenLifetime { get; } - } -} diff --git a/source/EasyWay.WebApi/Internals/Extensions.cs b/source/EasyWay.WebApi/Extensions.cs similarity index 56% rename from source/EasyWay.WebApi/Internals/Extensions.cs rename to source/EasyWay.WebApi/Extensions.cs index 4b1fd36..1725877 100644 --- a/source/EasyWay.WebApi/Internals/Extensions.cs +++ b/source/EasyWay.WebApi/Extensions.cs @@ -1,23 +1,25 @@ -using EasyWay.Internals.Contexts; +using EasyWay.Internals; +using EasyWay.Internals.Contexts; using EasyWay.Internals.Exceptions; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; -namespace EasyWay.Internals +namespace EasyWay { - internal static class Extensions + public static class Extensions { - internal static void AddEasyWayWebApi( + public static void AddEasyWayWebApi( this IServiceCollection services) { services.AddHttpContextAccessor(); + services.AddSingleton(); + services.AddScoped(); } - internal static void UseEasyWay(this IApplicationBuilder app) + public static void UseEasyWay(this IApplicationBuilder app) { - app.UseHttpsRedirection(); app.UseMiddleware(); } } diff --git a/source/EasyWay.WebApi/IWebApiResultMapper.cs b/source/EasyWay.WebApi/IWebApiResultMapper.cs new file mode 100644 index 0000000..a69f96d --- /dev/null +++ b/source/EasyWay.WebApi/IWebApiResultMapper.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Http; + +namespace EasyWay +{ + public interface IWebApiResultMapper + { + IResult Map(CommandResult commandResult); + + IResult Map(CommandResult commandResult) + where TOperationResult : OperationResult; + + IResult Map(QueryResult queryResult) + where TReadModel : ReadModel; + } +} diff --git a/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs b/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs new file mode 100644 index 0000000..de35d49 --- /dev/null +++ b/source/EasyWay.WebApi/Internals/WebApiResultMapper.cs @@ -0,0 +1,41 @@ +using EasyWay.Internals.Commands.Results; +using EasyWay.Internals.Queries.Results; +using Microsoft.AspNetCore.Http; + +namespace EasyWay.Internals +{ + internal sealed class WebApiResultMapper : IWebApiResultMapper + { + public IResult Map(CommandResult commandResult) + { + return commandResult.Error switch + { + CommandErrorEnum.None => Results.Ok(), + CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), + _ => Results.StatusCode(500), + }; + } + + public IResult Map(CommandResult commandResult) where TOperationResult : OperationResult + { + return commandResult.Error switch + { + CommandErrorEnum.None => Results.Ok(), + CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), + _ => Results.StatusCode(500), + }; + } + + public IResult Map(QueryResult queryResult) where TReadModel : ReadModel + { + return queryResult.Error switch + { + QueryErrorEnum.None => Results.Ok(queryResult.ReadModel), + QueryErrorEnum.Validation => Results.BadRequest(queryResult.ValidationErrors), + QueryErrorEnum.NotFound => Results.StatusCode(404), + QueryErrorEnum.Forbidden => Results.StatusCode(403), + _ => Results.StatusCode(500), + }; + } + } +} diff --git a/source/EasyWay.WebApi/RcpStyleExtensions.cs b/source/EasyWay.WebApi/RcpStyleExtensions.cs deleted file mode 100644 index a7ee2db..0000000 --- a/source/EasyWay.WebApi/RcpStyleExtensions.cs +++ /dev/null @@ -1,73 +0,0 @@ -using EasyWay.Internals.Commands.Results; -using EasyWay.Internals.Queries.Results; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; - -namespace EasyWay -{ - public static class RcpStyleExtensions - { - public static WebKernel MapQuery(this WebKernel webKernel) - where TModule : EasyWayModule - where TQuery : Query - where TReadModel : ReadModel - { - webKernel.App.MapGet("api/" + typeof(TModule).Name + "/" + typeof(TQuery).Name, async ([AsParameters] TQuery query, IModuleExecutor executor, CancellationToken cancellationToken) => - { - var queryResult = await executor.Execute(query, cancellationToken); - - return queryResult.Error switch - { - QueryErrorEnum.None => Results.Ok(queryResult.ReadModel), - QueryErrorEnum.Validation => Results.BadRequest(queryResult.ValidationErrors), - QueryErrorEnum.NotFound => Results.StatusCode(404), - QueryErrorEnum.Forbidden => Results.StatusCode(403), - _ => Results.StatusCode(500), - }; - }); - - return webKernel; - } - - public static WebKernel MapCommand(this WebKernel webKernel) - where TModule : EasyWayModule - where TCommand : Command - { - webKernel.App.MapPost("api/" + typeof(TModule).Name + "/" + typeof(TCommand).Name, async ([FromBody] TCommand command, IModuleExecutor executor, CancellationToken cancellationToken) => - { - var commandResult = await executor.Execute(command, cancellationToken); - - return commandResult.Error switch - { - CommandErrorEnum.None => Results.Ok(), - CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), - _ => Results.StatusCode(500), - }; - }); - - return webKernel; - } - - public static WebKernel MapCommand(this WebKernel webKernel) - where TModule : EasyWayModule - where TCommand : Command - where TCommandResult : OperationResult - { - webKernel.App.MapPost("api/" + typeof(TModule).Name + "/" + typeof(TCommand).Name, async ([FromBody] TCommand command, IModuleExecutor executor, CancellationToken cancellationToken) => - { - var commandResult = await executor.Execute(command, cancellationToken); - - return commandResult.Error switch - { - CommandErrorEnum.None => Results.Ok(), - CommandErrorEnum.Validation => Results.BadRequest(commandResult.ValidationErrors), - _ => Results.StatusCode(500), - }; - }); - - return webKernel; - } - } -} diff --git a/source/EasyWay.WebApi/WebKernel.cs b/source/EasyWay.WebApi/WebKernel.cs deleted file mode 100644 index ac366ea..0000000 --- a/source/EasyWay.WebApi/WebKernel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using EasyWay.Internals; -using Microsoft.AspNetCore.Builder; - -namespace EasyWay -{ - public sealed class WebKernel - { - public readonly WebApplication App; - - internal WebKernel(WebApplication webApplication) - { - App = webApplication; - - App.UseEasyWay(); - } - - public async Task RunAsync() - { - await App.RunAsync(); - } - } -} diff --git a/source/EasyWay.WebApi/WebKernelBuilder.cs b/source/EasyWay.WebApi/WebKernelBuilder.cs deleted file mode 100644 index 010eaab..0000000 --- a/source/EasyWay.WebApi/WebKernelBuilder.cs +++ /dev/null @@ -1,43 +0,0 @@ -using EasyWay.Internals; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; - -namespace EasyWay -{ - public sealed class WebKernelBuilder - { - public readonly WebApplicationBuilder AppBuilder; - - private readonly Kernel _kernel; - - private WebKernelBuilder(WebApplicationBuilder webApplicationBuilder) - { - AppBuilder = webApplicationBuilder; - _kernel = Kernel.Create(); - } - - public static WebKernelBuilder Create(string[] args) - { - var builder = WebApplication.CreateBuilder(args); - - builder.WebHost.UseKestrel(option => option.AddServerHeader = false); - - return new WebKernelBuilder(builder); - } - - public void AddModule() - where TModule : EasyWayModule, new() - { - _kernel.AddModule(); - } - - public async Task BuildAsync() - { - await _kernel.BuildAsync(AppBuilder.Services); - AppBuilder.Services.AddEasyWayWebApi(); - - - return new WebKernel(AppBuilder.Build()); - } - } -}