From 27088f8217c2632da92ab213edc440e477ac6e0a Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 26 Sep 2024 10:20:30 +0200 Subject: [PATCH 1/4] Reorganized folder structure --- FrontendTest/appsettings.Development.json | 8 -------- HopFrame.sln | 16 ++++++---------- .../Controller/SecurityController.cs | 5 +++-- .../HopFrame.Api}/Extensions/MvcExtensions.cs | 0 .../Extensions/ServiceCollectionExtensions.cs | 0 .../HopFrame.Api}/HopFrame.Api.csproj | 0 .../HopFrame.Api}/Logic/ILogicResult.cs | 0 .../HopFrame.Api}/Logic/LogicResult.cs | 0 .../HopFrame.Api}/Models/SingleValueResult.cs | 0 .../Models/UserPasswordValidation.cs | 0 {HopFrame.Api => src/HopFrame.Api}/README.md | 0 .../HopFrame.Database}/HopDbContextBase.cs | 0 .../HopFrame.Database}/HopFrame.Database.csproj | 0 .../Models/Entries/GroupEntry.cs | 0 .../Models/Entries/PermissionEntry.cs | 0 .../Models/Entries/TokenEntry.cs | 0 .../Models/Entries/UserEntry.cs | 0 .../Models/ModelExtensions.cs | 0 .../HopFrame.Database}/Models/Permission.cs | 0 .../Models/PermissionGroup.cs | 0 .../HopFrame.Database}/Models/User.cs | 0 .../HopFrame.Database}/README.md | 0 .../HopFrame.Security}/AdminPermissions.cs | 0 .../Authentication/HopFrameAuthentication.cs | 0 .../HopFrameAuthenticationExtensions.cs | 0 .../Authorization/AuthorizedAttribute.cs | 0 .../Authorization/AuthorizedFilter.cs | 0 .../Authorization/PermissionValidator.cs | 0 .../Claims/HopFrameClaimTypes.cs | 0 .../HopFrame.Security}/Claims/ITokenContext.cs | 0 .../Claims/TokenContextImplementor.cs | 0 .../HopFrame.Security}/EncryptionManager.cs | 0 .../HopFrame.Security}/HopFrame.Security.csproj | 0 .../HopFrame.Security}/Models/UserLogin.cs | 0 .../HopFrame.Security}/Models/UserRegister.cs | 0 .../HopFrame.Security}/README.md | 0 .../Services/IPermissionService.cs | 0 .../HopFrame.Security}/Services/IUserService.cs | 0 .../Implementation/PermissionService.cs | 0 .../Services/Implementation/UserService.cs | 0 .../HopFrame.Web}/AdminPermissions.cs | 0 .../HopFrame.Web}/AuthMiddleware.cs | 0 .../Administration/GroupAddModal.razor | 0 .../Administration/HopIconDisplay.razor | 0 .../Administration/UserAddModal.razor | 0 .../Administration/UserEditModal.razor | 0 .../Components/AuthorizedView.razor | 0 .../HopFrame.Web}/HopFrame.Web.csproj | 0 .../HopFrame.Web}/Model/NavigationItem.cs | 0 .../HopFrame.Web}/Model/PermissionGroupAdd.cs | 0 .../HopFrame.Web}/Model/RegisterData.cs | 0 .../HopFrame.Web}/Model/UserAdd.cs | 0 .../Pages/Administration/AdminDashboard.razor | 0 .../Pages/Administration/AdminLogin.razor | 0 .../Pages/Administration/AdminLogin.razor.css | 0 .../Pages/Administration/GroupsPage.razor | 0 .../Pages/Administration/GroupsPage.razor.css | 0 .../Administration/Layout/AdminLayout.razor | 0 .../Pages/Administration/Layout/AdminMenu.razor | 0 .../Administration/Layout/EmptyLayout.razor | 0 .../Pages/Administration/UsersPage.razor | 0 .../Pages/Administration/UsersPage.razor.css | 0 {HopFrame.Web => src/HopFrame.Web}/README.md | 0 .../ServiceCollectionExtensions.cs | 2 -- .../HopFrame.Web}/Services/IAuthService.cs | 0 .../Services/Implementation/AuthService.cs | 0 {FrontendTest => test/FrontendTest}/.gitignore | 0 .../FrontendTest}/Components/App.razor | 0 .../Components/Layout/MainLayout.razor | 0 .../Components/Layout/MainLayout.razor.css | 0 .../Components/Layout/NavMenu.razor | 0 .../Components/Layout/NavMenu.razor.css | 0 .../Components/Pages/Counter.razor | 0 .../FrontendTest}/Components/Pages/Error.razor | 0 .../FrontendTest}/Components/Pages/Home.razor | 0 .../Components/Pages/Weather.razor | 0 .../FrontendTest}/Components/Routes.razor | 0 .../FrontendTest}/Components/_Imports.razor | 0 .../FrontendTest}/DatabaseContext.cs | 2 +- .../FrontendTest}/FrontendTest.csproj | 8 ++++---- {FrontendTest => test/FrontendTest}/Program.cs | 0 .../Properties/launchSettings.json | 0 .../FrontendTest}/appsettings.json | 0 .../FrontendTest}/wwwroot/app.css | 0 .../FrontendTest}/wwwroot/favicon.png | Bin {RestApiTest => test/RestApiTest}/.gitignore | 0 .../RestApiTest}/Controllers/TestController.cs | 0 .../RestApiTest}/DatabaseContext.cs | 2 +- {RestApiTest => test/RestApiTest}/Program.cs | 0 .../RestApiTest}/Properties/launchSettings.json | 0 .../RestApiTest}/RestApiTest.csproj | 4 +--- .../RestApiTest}/appsettings.json | 0 92 files changed, 16 insertions(+), 31 deletions(-) delete mode 100644 FrontendTest/appsettings.Development.json rename {HopFrame.Api => src/HopFrame.Api}/Controller/SecurityController.cs (97%) rename {HopFrame.Api => src/HopFrame.Api}/Extensions/MvcExtensions.cs (100%) rename {HopFrame.Api => src/HopFrame.Api}/Extensions/ServiceCollectionExtensions.cs (100%) rename {HopFrame.Api => src/HopFrame.Api}/HopFrame.Api.csproj (100%) rename {HopFrame.Api => src/HopFrame.Api}/Logic/ILogicResult.cs (100%) rename {HopFrame.Api => src/HopFrame.Api}/Logic/LogicResult.cs (100%) rename {HopFrame.Api => src/HopFrame.Api}/Models/SingleValueResult.cs (100%) rename {HopFrame.Api => src/HopFrame.Api}/Models/UserPasswordValidation.cs (100%) rename {HopFrame.Api => src/HopFrame.Api}/README.md (100%) rename {HopFrame.Database => src/HopFrame.Database}/HopDbContextBase.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/HopFrame.Database.csproj (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/Entries/GroupEntry.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/Entries/PermissionEntry.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/Entries/TokenEntry.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/Entries/UserEntry.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/ModelExtensions.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/Permission.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/PermissionGroup.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/Models/User.cs (100%) rename {HopFrame.Database => src/HopFrame.Database}/README.md (100%) rename {HopFrame.Security => src/HopFrame.Security}/AdminPermissions.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Authentication/HopFrameAuthentication.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Authentication/HopFrameAuthenticationExtensions.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Authorization/AuthorizedAttribute.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Authorization/AuthorizedFilter.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Authorization/PermissionValidator.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Claims/HopFrameClaimTypes.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Claims/ITokenContext.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Claims/TokenContextImplementor.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/EncryptionManager.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/HopFrame.Security.csproj (100%) rename {HopFrame.Security => src/HopFrame.Security}/Models/UserLogin.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Models/UserRegister.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/README.md (100%) rename {HopFrame.Security => src/HopFrame.Security}/Services/IPermissionService.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Services/IUserService.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Services/Implementation/PermissionService.cs (100%) rename {HopFrame.Security => src/HopFrame.Security}/Services/Implementation/UserService.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/AdminPermissions.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/AuthMiddleware.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/Components/Administration/GroupAddModal.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Components/Administration/HopIconDisplay.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Components/Administration/UserAddModal.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Components/Administration/UserEditModal.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Components/AuthorizedView.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/HopFrame.Web.csproj (100%) rename {HopFrame.Web => src/HopFrame.Web}/Model/NavigationItem.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/Model/PermissionGroupAdd.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/Model/RegisterData.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/Model/UserAdd.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/AdminDashboard.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/AdminLogin.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/AdminLogin.razor.css (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/GroupsPage.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/GroupsPage.razor.css (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/Layout/AdminLayout.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/Layout/AdminMenu.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/Layout/EmptyLayout.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/UsersPage.razor (100%) rename {HopFrame.Web => src/HopFrame.Web}/Pages/Administration/UsersPage.razor.css (100%) rename {HopFrame.Web => src/HopFrame.Web}/README.md (100%) rename {HopFrame.Web => src/HopFrame.Web}/ServiceCollectionExtensions.cs (95%) rename {HopFrame.Web => src/HopFrame.Web}/Services/IAuthService.cs (100%) rename {HopFrame.Web => src/HopFrame.Web}/Services/Implementation/AuthService.cs (100%) rename {FrontendTest => test/FrontendTest}/.gitignore (100%) rename {FrontendTest => test/FrontendTest}/Components/App.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Layout/MainLayout.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Layout/MainLayout.razor.css (100%) rename {FrontendTest => test/FrontendTest}/Components/Layout/NavMenu.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Layout/NavMenu.razor.css (100%) rename {FrontendTest => test/FrontendTest}/Components/Pages/Counter.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Pages/Error.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Pages/Home.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Pages/Weather.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/Routes.razor (100%) rename {FrontendTest => test/FrontendTest}/Components/_Imports.razor (100%) rename {FrontendTest => test/FrontendTest}/DatabaseContext.cs (77%) rename {FrontendTest => test/FrontendTest}/FrontendTest.csproj (87%) rename {FrontendTest => test/FrontendTest}/Program.cs (100%) rename {FrontendTest => test/FrontendTest}/Properties/launchSettings.json (100%) rename {FrontendTest => test/FrontendTest}/appsettings.json (100%) rename {FrontendTest => test/FrontendTest}/wwwroot/app.css (100%) rename {FrontendTest => test/FrontendTest}/wwwroot/favicon.png (100%) rename {RestApiTest => test/RestApiTest}/.gitignore (100%) rename {RestApiTest => test/RestApiTest}/Controllers/TestController.cs (100%) rename {RestApiTest => test/RestApiTest}/DatabaseContext.cs (77%) rename {RestApiTest => test/RestApiTest}/Program.cs (100%) rename {RestApiTest => test/RestApiTest}/Properties/launchSettings.json (100%) rename {RestApiTest => test/RestApiTest}/RestApiTest.csproj (77%) rename {RestApiTest => test/RestApiTest}/appsettings.json (100%) diff --git a/FrontendTest/appsettings.Development.json b/FrontendTest/appsettings.Development.json deleted file mode 100644 index 0c208ae..0000000 --- a/FrontendTest/appsettings.Development.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - } -} diff --git a/HopFrame.sln b/HopFrame.sln index 453dbcf..f9217e8 100644 --- a/HopFrame.sln +++ b/HopFrame.sln @@ -1,18 +1,16 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Database", "HopFrame.Database\HopFrame.Database.csproj", "{003120AE-F38B-4632-8497-BE4505189627}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Database", "src\HopFrame.Database\HopFrame.Database.csproj", "{003120AE-F38B-4632-8497-BE4505189627}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{58703056-8DAD-4221-BBE3-42425D2F4929}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestApiTest", "test\RestApiTest\RestApiTest.csproj", "{921159CE-AF75-44C3-A3F9-6B9B1A4E85CF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestApiTest", "RestApiTest\RestApiTest.csproj", "{921159CE-AF75-44C3-A3F9-6B9B1A4E85CF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Security", "src\HopFrame.Security\HopFrame.Security.csproj", "{7F82E1C6-4A42-4337-9E03-2EE6429D004F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Security", "HopFrame.Security\HopFrame.Security.csproj", "{7F82E1C6-4A42-4337-9E03-2EE6429D004F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Api", "src\HopFrame.Api\HopFrame.Api.csproj", "{1E821490-AEDC-4F55-B758-52F4FADAB53A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Api", "HopFrame.Api\HopFrame.Api.csproj", "{1E821490-AEDC-4F55-B758-52F4FADAB53A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Web", "src\HopFrame.Web\HopFrame.Web.csproj", "{3BE585BC-13A5-4BE4-A806-E9EC2D825956}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Web", "HopFrame.Web\HopFrame.Web.csproj", "{3BE585BC-13A5-4BE4-A806-E9EC2D825956}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FrontendTest", "FrontendTest\FrontendTest.csproj", "{8F983A37-63CF-48D5-988D-58B78EF8AECD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FrontendTest", "test\FrontendTest\FrontendTest.csproj", "{8F983A37-63CF-48D5-988D-58B78EF8AECD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -46,7 +44,5 @@ Global {8F983A37-63CF-48D5-988D-58B78EF8AECD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution - {921159CE-AF75-44C3-A3F9-6B9B1A4E85CF} = {58703056-8DAD-4221-BBE3-42425D2F4929} - {8F983A37-63CF-48D5-988D-58B78EF8AECD} = {58703056-8DAD-4221-BBE3-42425D2F4929} EndGlobalSection EndGlobal diff --git a/HopFrame.Api/Controller/SecurityController.cs b/src/HopFrame.Api/Controller/SecurityController.cs similarity index 97% rename from HopFrame.Api/Controller/SecurityController.cs rename to src/HopFrame.Api/Controller/SecurityController.cs index fe6ea8e..de9a50a 100644 --- a/HopFrame.Api/Controller/SecurityController.cs +++ b/src/HopFrame.Api/Controller/SecurityController.cs @@ -24,7 +24,7 @@ public class SecurityController(TDbContext context, IUserService use if (user is null) return LogicResult>.NotFound("The provided email address was not found"); - if (await users.CheckUserPassword(user, login.Password)) + if (!await users.CheckUserPassword(user, login.Password)) return LogicResult>.Forbidden("The provided password is not correct"); var refreshToken = new TokenEntry { @@ -162,12 +162,13 @@ public class SecurityController(TDbContext context, IUserService use public async Task Delete([FromBody] UserPasswordValidation validation) { var user = tokenContext.User; - if (await users.CheckUserPassword(user, validation.Password)) + if (!await users.CheckUserPassword(user, validation.Password)) return LogicResult.Forbidden("The provided password is not correct"); await users.DeleteUser(user); HttpContext.Response.Cookies.Delete(ITokenContext.RefreshTokenType); + HttpContext.Response.Cookies.Delete(ITokenContext.AccessTokenType); return LogicResult.Ok(); } diff --git a/HopFrame.Api/Extensions/MvcExtensions.cs b/src/HopFrame.Api/Extensions/MvcExtensions.cs similarity index 100% rename from HopFrame.Api/Extensions/MvcExtensions.cs rename to src/HopFrame.Api/Extensions/MvcExtensions.cs diff --git a/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs b/src/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs similarity index 100% rename from HopFrame.Api/Extensions/ServiceCollectionExtensions.cs rename to src/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs diff --git a/HopFrame.Api/HopFrame.Api.csproj b/src/HopFrame.Api/HopFrame.Api.csproj similarity index 100% rename from HopFrame.Api/HopFrame.Api.csproj rename to src/HopFrame.Api/HopFrame.Api.csproj diff --git a/HopFrame.Api/Logic/ILogicResult.cs b/src/HopFrame.Api/Logic/ILogicResult.cs similarity index 100% rename from HopFrame.Api/Logic/ILogicResult.cs rename to src/HopFrame.Api/Logic/ILogicResult.cs diff --git a/HopFrame.Api/Logic/LogicResult.cs b/src/HopFrame.Api/Logic/LogicResult.cs similarity index 100% rename from HopFrame.Api/Logic/LogicResult.cs rename to src/HopFrame.Api/Logic/LogicResult.cs diff --git a/HopFrame.Api/Models/SingleValueResult.cs b/src/HopFrame.Api/Models/SingleValueResult.cs similarity index 100% rename from HopFrame.Api/Models/SingleValueResult.cs rename to src/HopFrame.Api/Models/SingleValueResult.cs diff --git a/HopFrame.Api/Models/UserPasswordValidation.cs b/src/HopFrame.Api/Models/UserPasswordValidation.cs similarity index 100% rename from HopFrame.Api/Models/UserPasswordValidation.cs rename to src/HopFrame.Api/Models/UserPasswordValidation.cs diff --git a/HopFrame.Api/README.md b/src/HopFrame.Api/README.md similarity index 100% rename from HopFrame.Api/README.md rename to src/HopFrame.Api/README.md diff --git a/HopFrame.Database/HopDbContextBase.cs b/src/HopFrame.Database/HopDbContextBase.cs similarity index 100% rename from HopFrame.Database/HopDbContextBase.cs rename to src/HopFrame.Database/HopDbContextBase.cs diff --git a/HopFrame.Database/HopFrame.Database.csproj b/src/HopFrame.Database/HopFrame.Database.csproj similarity index 100% rename from HopFrame.Database/HopFrame.Database.csproj rename to src/HopFrame.Database/HopFrame.Database.csproj diff --git a/HopFrame.Database/Models/Entries/GroupEntry.cs b/src/HopFrame.Database/Models/Entries/GroupEntry.cs similarity index 100% rename from HopFrame.Database/Models/Entries/GroupEntry.cs rename to src/HopFrame.Database/Models/Entries/GroupEntry.cs diff --git a/HopFrame.Database/Models/Entries/PermissionEntry.cs b/src/HopFrame.Database/Models/Entries/PermissionEntry.cs similarity index 100% rename from HopFrame.Database/Models/Entries/PermissionEntry.cs rename to src/HopFrame.Database/Models/Entries/PermissionEntry.cs diff --git a/HopFrame.Database/Models/Entries/TokenEntry.cs b/src/HopFrame.Database/Models/Entries/TokenEntry.cs similarity index 100% rename from HopFrame.Database/Models/Entries/TokenEntry.cs rename to src/HopFrame.Database/Models/Entries/TokenEntry.cs diff --git a/HopFrame.Database/Models/Entries/UserEntry.cs b/src/HopFrame.Database/Models/Entries/UserEntry.cs similarity index 100% rename from HopFrame.Database/Models/Entries/UserEntry.cs rename to src/HopFrame.Database/Models/Entries/UserEntry.cs diff --git a/HopFrame.Database/Models/ModelExtensions.cs b/src/HopFrame.Database/Models/ModelExtensions.cs similarity index 100% rename from HopFrame.Database/Models/ModelExtensions.cs rename to src/HopFrame.Database/Models/ModelExtensions.cs diff --git a/HopFrame.Database/Models/Permission.cs b/src/HopFrame.Database/Models/Permission.cs similarity index 100% rename from HopFrame.Database/Models/Permission.cs rename to src/HopFrame.Database/Models/Permission.cs diff --git a/HopFrame.Database/Models/PermissionGroup.cs b/src/HopFrame.Database/Models/PermissionGroup.cs similarity index 100% rename from HopFrame.Database/Models/PermissionGroup.cs rename to src/HopFrame.Database/Models/PermissionGroup.cs diff --git a/HopFrame.Database/Models/User.cs b/src/HopFrame.Database/Models/User.cs similarity index 100% rename from HopFrame.Database/Models/User.cs rename to src/HopFrame.Database/Models/User.cs diff --git a/HopFrame.Database/README.md b/src/HopFrame.Database/README.md similarity index 100% rename from HopFrame.Database/README.md rename to src/HopFrame.Database/README.md diff --git a/HopFrame.Security/AdminPermissions.cs b/src/HopFrame.Security/AdminPermissions.cs similarity index 100% rename from HopFrame.Security/AdminPermissions.cs rename to src/HopFrame.Security/AdminPermissions.cs diff --git a/HopFrame.Security/Authentication/HopFrameAuthentication.cs b/src/HopFrame.Security/Authentication/HopFrameAuthentication.cs similarity index 100% rename from HopFrame.Security/Authentication/HopFrameAuthentication.cs rename to src/HopFrame.Security/Authentication/HopFrameAuthentication.cs diff --git a/HopFrame.Security/Authentication/HopFrameAuthenticationExtensions.cs b/src/HopFrame.Security/Authentication/HopFrameAuthenticationExtensions.cs similarity index 100% rename from HopFrame.Security/Authentication/HopFrameAuthenticationExtensions.cs rename to src/HopFrame.Security/Authentication/HopFrameAuthenticationExtensions.cs diff --git a/HopFrame.Security/Authorization/AuthorizedAttribute.cs b/src/HopFrame.Security/Authorization/AuthorizedAttribute.cs similarity index 100% rename from HopFrame.Security/Authorization/AuthorizedAttribute.cs rename to src/HopFrame.Security/Authorization/AuthorizedAttribute.cs diff --git a/HopFrame.Security/Authorization/AuthorizedFilter.cs b/src/HopFrame.Security/Authorization/AuthorizedFilter.cs similarity index 100% rename from HopFrame.Security/Authorization/AuthorizedFilter.cs rename to src/HopFrame.Security/Authorization/AuthorizedFilter.cs diff --git a/HopFrame.Security/Authorization/PermissionValidator.cs b/src/HopFrame.Security/Authorization/PermissionValidator.cs similarity index 100% rename from HopFrame.Security/Authorization/PermissionValidator.cs rename to src/HopFrame.Security/Authorization/PermissionValidator.cs diff --git a/HopFrame.Security/Claims/HopFrameClaimTypes.cs b/src/HopFrame.Security/Claims/HopFrameClaimTypes.cs similarity index 100% rename from HopFrame.Security/Claims/HopFrameClaimTypes.cs rename to src/HopFrame.Security/Claims/HopFrameClaimTypes.cs diff --git a/HopFrame.Security/Claims/ITokenContext.cs b/src/HopFrame.Security/Claims/ITokenContext.cs similarity index 100% rename from HopFrame.Security/Claims/ITokenContext.cs rename to src/HopFrame.Security/Claims/ITokenContext.cs diff --git a/HopFrame.Security/Claims/TokenContextImplementor.cs b/src/HopFrame.Security/Claims/TokenContextImplementor.cs similarity index 100% rename from HopFrame.Security/Claims/TokenContextImplementor.cs rename to src/HopFrame.Security/Claims/TokenContextImplementor.cs diff --git a/HopFrame.Security/EncryptionManager.cs b/src/HopFrame.Security/EncryptionManager.cs similarity index 100% rename from HopFrame.Security/EncryptionManager.cs rename to src/HopFrame.Security/EncryptionManager.cs diff --git a/HopFrame.Security/HopFrame.Security.csproj b/src/HopFrame.Security/HopFrame.Security.csproj similarity index 100% rename from HopFrame.Security/HopFrame.Security.csproj rename to src/HopFrame.Security/HopFrame.Security.csproj diff --git a/HopFrame.Security/Models/UserLogin.cs b/src/HopFrame.Security/Models/UserLogin.cs similarity index 100% rename from HopFrame.Security/Models/UserLogin.cs rename to src/HopFrame.Security/Models/UserLogin.cs diff --git a/HopFrame.Security/Models/UserRegister.cs b/src/HopFrame.Security/Models/UserRegister.cs similarity index 100% rename from HopFrame.Security/Models/UserRegister.cs rename to src/HopFrame.Security/Models/UserRegister.cs diff --git a/HopFrame.Security/README.md b/src/HopFrame.Security/README.md similarity index 100% rename from HopFrame.Security/README.md rename to src/HopFrame.Security/README.md diff --git a/HopFrame.Security/Services/IPermissionService.cs b/src/HopFrame.Security/Services/IPermissionService.cs similarity index 100% rename from HopFrame.Security/Services/IPermissionService.cs rename to src/HopFrame.Security/Services/IPermissionService.cs diff --git a/HopFrame.Security/Services/IUserService.cs b/src/HopFrame.Security/Services/IUserService.cs similarity index 100% rename from HopFrame.Security/Services/IUserService.cs rename to src/HopFrame.Security/Services/IUserService.cs diff --git a/HopFrame.Security/Services/Implementation/PermissionService.cs b/src/HopFrame.Security/Services/Implementation/PermissionService.cs similarity index 100% rename from HopFrame.Security/Services/Implementation/PermissionService.cs rename to src/HopFrame.Security/Services/Implementation/PermissionService.cs diff --git a/HopFrame.Security/Services/Implementation/UserService.cs b/src/HopFrame.Security/Services/Implementation/UserService.cs similarity index 100% rename from HopFrame.Security/Services/Implementation/UserService.cs rename to src/HopFrame.Security/Services/Implementation/UserService.cs diff --git a/HopFrame.Web/AdminPermissions.cs b/src/HopFrame.Web/AdminPermissions.cs similarity index 100% rename from HopFrame.Web/AdminPermissions.cs rename to src/HopFrame.Web/AdminPermissions.cs diff --git a/HopFrame.Web/AuthMiddleware.cs b/src/HopFrame.Web/AuthMiddleware.cs similarity index 100% rename from HopFrame.Web/AuthMiddleware.cs rename to src/HopFrame.Web/AuthMiddleware.cs diff --git a/HopFrame.Web/Components/Administration/GroupAddModal.razor b/src/HopFrame.Web/Components/Administration/GroupAddModal.razor similarity index 100% rename from HopFrame.Web/Components/Administration/GroupAddModal.razor rename to src/HopFrame.Web/Components/Administration/GroupAddModal.razor diff --git a/HopFrame.Web/Components/Administration/HopIconDisplay.razor b/src/HopFrame.Web/Components/Administration/HopIconDisplay.razor similarity index 100% rename from HopFrame.Web/Components/Administration/HopIconDisplay.razor rename to src/HopFrame.Web/Components/Administration/HopIconDisplay.razor diff --git a/HopFrame.Web/Components/Administration/UserAddModal.razor b/src/HopFrame.Web/Components/Administration/UserAddModal.razor similarity index 100% rename from HopFrame.Web/Components/Administration/UserAddModal.razor rename to src/HopFrame.Web/Components/Administration/UserAddModal.razor diff --git a/HopFrame.Web/Components/Administration/UserEditModal.razor b/src/HopFrame.Web/Components/Administration/UserEditModal.razor similarity index 100% rename from HopFrame.Web/Components/Administration/UserEditModal.razor rename to src/HopFrame.Web/Components/Administration/UserEditModal.razor diff --git a/HopFrame.Web/Components/AuthorizedView.razor b/src/HopFrame.Web/Components/AuthorizedView.razor similarity index 100% rename from HopFrame.Web/Components/AuthorizedView.razor rename to src/HopFrame.Web/Components/AuthorizedView.razor diff --git a/HopFrame.Web/HopFrame.Web.csproj b/src/HopFrame.Web/HopFrame.Web.csproj similarity index 100% rename from HopFrame.Web/HopFrame.Web.csproj rename to src/HopFrame.Web/HopFrame.Web.csproj diff --git a/HopFrame.Web/Model/NavigationItem.cs b/src/HopFrame.Web/Model/NavigationItem.cs similarity index 100% rename from HopFrame.Web/Model/NavigationItem.cs rename to src/HopFrame.Web/Model/NavigationItem.cs diff --git a/HopFrame.Web/Model/PermissionGroupAdd.cs b/src/HopFrame.Web/Model/PermissionGroupAdd.cs similarity index 100% rename from HopFrame.Web/Model/PermissionGroupAdd.cs rename to src/HopFrame.Web/Model/PermissionGroupAdd.cs diff --git a/HopFrame.Web/Model/RegisterData.cs b/src/HopFrame.Web/Model/RegisterData.cs similarity index 100% rename from HopFrame.Web/Model/RegisterData.cs rename to src/HopFrame.Web/Model/RegisterData.cs diff --git a/HopFrame.Web/Model/UserAdd.cs b/src/HopFrame.Web/Model/UserAdd.cs similarity index 100% rename from HopFrame.Web/Model/UserAdd.cs rename to src/HopFrame.Web/Model/UserAdd.cs diff --git a/HopFrame.Web/Pages/Administration/AdminDashboard.razor b/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/AdminDashboard.razor rename to src/HopFrame.Web/Pages/Administration/AdminDashboard.razor diff --git a/HopFrame.Web/Pages/Administration/AdminLogin.razor b/src/HopFrame.Web/Pages/Administration/AdminLogin.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/AdminLogin.razor rename to src/HopFrame.Web/Pages/Administration/AdminLogin.razor diff --git a/HopFrame.Web/Pages/Administration/AdminLogin.razor.css b/src/HopFrame.Web/Pages/Administration/AdminLogin.razor.css similarity index 100% rename from HopFrame.Web/Pages/Administration/AdminLogin.razor.css rename to src/HopFrame.Web/Pages/Administration/AdminLogin.razor.css diff --git a/HopFrame.Web/Pages/Administration/GroupsPage.razor b/src/HopFrame.Web/Pages/Administration/GroupsPage.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/GroupsPage.razor rename to src/HopFrame.Web/Pages/Administration/GroupsPage.razor diff --git a/HopFrame.Web/Pages/Administration/GroupsPage.razor.css b/src/HopFrame.Web/Pages/Administration/GroupsPage.razor.css similarity index 100% rename from HopFrame.Web/Pages/Administration/GroupsPage.razor.css rename to src/HopFrame.Web/Pages/Administration/GroupsPage.razor.css diff --git a/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor b/src/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor rename to src/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor diff --git a/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor b/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor rename to src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor diff --git a/HopFrame.Web/Pages/Administration/Layout/EmptyLayout.razor b/src/HopFrame.Web/Pages/Administration/Layout/EmptyLayout.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/Layout/EmptyLayout.razor rename to src/HopFrame.Web/Pages/Administration/Layout/EmptyLayout.razor diff --git a/HopFrame.Web/Pages/Administration/UsersPage.razor b/src/HopFrame.Web/Pages/Administration/UsersPage.razor similarity index 100% rename from HopFrame.Web/Pages/Administration/UsersPage.razor rename to src/HopFrame.Web/Pages/Administration/UsersPage.razor diff --git a/HopFrame.Web/Pages/Administration/UsersPage.razor.css b/src/HopFrame.Web/Pages/Administration/UsersPage.razor.css similarity index 100% rename from HopFrame.Web/Pages/Administration/UsersPage.razor.css rename to src/HopFrame.Web/Pages/Administration/UsersPage.razor.css diff --git a/HopFrame.Web/README.md b/src/HopFrame.Web/README.md similarity index 100% rename from HopFrame.Web/README.md rename to src/HopFrame.Web/README.md diff --git a/HopFrame.Web/ServiceCollectionExtensions.cs b/src/HopFrame.Web/ServiceCollectionExtensions.cs similarity index 95% rename from HopFrame.Web/ServiceCollectionExtensions.cs rename to src/HopFrame.Web/ServiceCollectionExtensions.cs index c6438d5..b6770d7 100644 --- a/HopFrame.Web/ServiceCollectionExtensions.cs +++ b/src/HopFrame.Web/ServiceCollectionExtensions.cs @@ -18,8 +18,6 @@ public static class ServiceCollectionExtensions { // Component library's services.AddSweetAlert2(); services.AddBlazorStrap(); - - //TODO: Use https://blazorstrap.io/V5/V5 services.AddHopFrameAuthentication(); diff --git a/HopFrame.Web/Services/IAuthService.cs b/src/HopFrame.Web/Services/IAuthService.cs similarity index 100% rename from HopFrame.Web/Services/IAuthService.cs rename to src/HopFrame.Web/Services/IAuthService.cs diff --git a/HopFrame.Web/Services/Implementation/AuthService.cs b/src/HopFrame.Web/Services/Implementation/AuthService.cs similarity index 100% rename from HopFrame.Web/Services/Implementation/AuthService.cs rename to src/HopFrame.Web/Services/Implementation/AuthService.cs diff --git a/FrontendTest/.gitignore b/test/FrontendTest/.gitignore similarity index 100% rename from FrontendTest/.gitignore rename to test/FrontendTest/.gitignore diff --git a/FrontendTest/Components/App.razor b/test/FrontendTest/Components/App.razor similarity index 100% rename from FrontendTest/Components/App.razor rename to test/FrontendTest/Components/App.razor diff --git a/FrontendTest/Components/Layout/MainLayout.razor b/test/FrontendTest/Components/Layout/MainLayout.razor similarity index 100% rename from FrontendTest/Components/Layout/MainLayout.razor rename to test/FrontendTest/Components/Layout/MainLayout.razor diff --git a/FrontendTest/Components/Layout/MainLayout.razor.css b/test/FrontendTest/Components/Layout/MainLayout.razor.css similarity index 100% rename from FrontendTest/Components/Layout/MainLayout.razor.css rename to test/FrontendTest/Components/Layout/MainLayout.razor.css diff --git a/FrontendTest/Components/Layout/NavMenu.razor b/test/FrontendTest/Components/Layout/NavMenu.razor similarity index 100% rename from FrontendTest/Components/Layout/NavMenu.razor rename to test/FrontendTest/Components/Layout/NavMenu.razor diff --git a/FrontendTest/Components/Layout/NavMenu.razor.css b/test/FrontendTest/Components/Layout/NavMenu.razor.css similarity index 100% rename from FrontendTest/Components/Layout/NavMenu.razor.css rename to test/FrontendTest/Components/Layout/NavMenu.razor.css diff --git a/FrontendTest/Components/Pages/Counter.razor b/test/FrontendTest/Components/Pages/Counter.razor similarity index 100% rename from FrontendTest/Components/Pages/Counter.razor rename to test/FrontendTest/Components/Pages/Counter.razor diff --git a/FrontendTest/Components/Pages/Error.razor b/test/FrontendTest/Components/Pages/Error.razor similarity index 100% rename from FrontendTest/Components/Pages/Error.razor rename to test/FrontendTest/Components/Pages/Error.razor diff --git a/FrontendTest/Components/Pages/Home.razor b/test/FrontendTest/Components/Pages/Home.razor similarity index 100% rename from FrontendTest/Components/Pages/Home.razor rename to test/FrontendTest/Components/Pages/Home.razor diff --git a/FrontendTest/Components/Pages/Weather.razor b/test/FrontendTest/Components/Pages/Weather.razor similarity index 100% rename from FrontendTest/Components/Pages/Weather.razor rename to test/FrontendTest/Components/Pages/Weather.razor diff --git a/FrontendTest/Components/Routes.razor b/test/FrontendTest/Components/Routes.razor similarity index 100% rename from FrontendTest/Components/Routes.razor rename to test/FrontendTest/Components/Routes.razor diff --git a/FrontendTest/Components/_Imports.razor b/test/FrontendTest/Components/_Imports.razor similarity index 100% rename from FrontendTest/Components/_Imports.razor rename to test/FrontendTest/Components/_Imports.razor diff --git a/FrontendTest/DatabaseContext.cs b/test/FrontendTest/DatabaseContext.cs similarity index 77% rename from FrontendTest/DatabaseContext.cs rename to test/FrontendTest/DatabaseContext.cs index 20945c9..5da7d59 100644 --- a/FrontendTest/DatabaseContext.cs +++ b/test/FrontendTest/DatabaseContext.cs @@ -7,6 +7,6 @@ public class DatabaseContext : HopDbContextBase { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); - optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\RestApiTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); + optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\test\\RestApiTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); } } \ No newline at end of file diff --git a/FrontendTest/FrontendTest.csproj b/test/FrontendTest/FrontendTest.csproj similarity index 87% rename from FrontendTest/FrontendTest.csproj rename to test/FrontendTest/FrontendTest.csproj index 79d6740..312aa4b 100644 --- a/FrontendTest/FrontendTest.csproj +++ b/test/FrontendTest/FrontendTest.csproj @@ -6,10 +6,6 @@ enable - - - - @@ -19,4 +15,8 @@ <_ContentIncludedByDefault Remove="wwwroot\bootstrap\bootstrap.min.css.map" /> + + + + diff --git a/FrontendTest/Program.cs b/test/FrontendTest/Program.cs similarity index 100% rename from FrontendTest/Program.cs rename to test/FrontendTest/Program.cs diff --git a/FrontendTest/Properties/launchSettings.json b/test/FrontendTest/Properties/launchSettings.json similarity index 100% rename from FrontendTest/Properties/launchSettings.json rename to test/FrontendTest/Properties/launchSettings.json diff --git a/FrontendTest/appsettings.json b/test/FrontendTest/appsettings.json similarity index 100% rename from FrontendTest/appsettings.json rename to test/FrontendTest/appsettings.json diff --git a/FrontendTest/wwwroot/app.css b/test/FrontendTest/wwwroot/app.css similarity index 100% rename from FrontendTest/wwwroot/app.css rename to test/FrontendTest/wwwroot/app.css diff --git a/FrontendTest/wwwroot/favicon.png b/test/FrontendTest/wwwroot/favicon.png similarity index 100% rename from FrontendTest/wwwroot/favicon.png rename to test/FrontendTest/wwwroot/favicon.png diff --git a/RestApiTest/.gitignore b/test/RestApiTest/.gitignore similarity index 100% rename from RestApiTest/.gitignore rename to test/RestApiTest/.gitignore diff --git a/RestApiTest/Controllers/TestController.cs b/test/RestApiTest/Controllers/TestController.cs similarity index 100% rename from RestApiTest/Controllers/TestController.cs rename to test/RestApiTest/Controllers/TestController.cs diff --git a/RestApiTest/DatabaseContext.cs b/test/RestApiTest/DatabaseContext.cs similarity index 77% rename from RestApiTest/DatabaseContext.cs rename to test/RestApiTest/DatabaseContext.cs index fed4058..3133353 100644 --- a/RestApiTest/DatabaseContext.cs +++ b/test/RestApiTest/DatabaseContext.cs @@ -7,6 +7,6 @@ public class DatabaseContext : HopDbContextBase { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); - optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\RestApiTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); + optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\test\\RestApiTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); } } \ No newline at end of file diff --git a/RestApiTest/Program.cs b/test/RestApiTest/Program.cs similarity index 100% rename from RestApiTest/Program.cs rename to test/RestApiTest/Program.cs diff --git a/RestApiTest/Properties/launchSettings.json b/test/RestApiTest/Properties/launchSettings.json similarity index 100% rename from RestApiTest/Properties/launchSettings.json rename to test/RestApiTest/Properties/launchSettings.json diff --git a/RestApiTest/RestApiTest.csproj b/test/RestApiTest/RestApiTest.csproj similarity index 77% rename from RestApiTest/RestApiTest.csproj rename to test/RestApiTest/RestApiTest.csproj index 936e228..2549297 100644 --- a/RestApiTest/RestApiTest.csproj +++ b/test/RestApiTest/RestApiTest.csproj @@ -17,9 +17,7 @@ - - - + diff --git a/RestApiTest/appsettings.json b/test/RestApiTest/appsettings.json similarity index 100% rename from RestApiTest/appsettings.json rename to test/RestApiTest/appsettings.json From 0c3501fc68167a5b39a8dea098b9b2921efb6871 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 26 Sep 2024 10:50:13 +0200 Subject: [PATCH 2/4] Added more specific readme's + removed obsolete code --- src/HopFrame.Api/README.md | 11 +++++ src/HopFrame.Security/README.md | 72 ++++++++++++++++++++++++++++ src/HopFrame.Web/AdminPermissions.cs | 16 ------- src/HopFrame.Web/README.md | 17 +++++++ 4 files changed, 100 insertions(+), 16 deletions(-) delete mode 100644 src/HopFrame.Web/AdminPermissions.cs diff --git a/src/HopFrame.Api/README.md b/src/HopFrame.Api/README.md index 17d0ac1..994c8c5 100644 --- a/src/HopFrame.Api/README.md +++ b/src/HopFrame.Api/README.md @@ -28,3 +28,14 @@ This module contains some useful endpoints for user login / register management. builder.Services.AddHopFrame(); ``` +# Endpoints +By default, the module provides a controller for handling authentication based requests by the user. +You can explore the contoller by the build in swagger site from ASP .NET. + +## Disable the Endpoints +If you don't want to include these endpoints you need to comment out the AddHopFrame line and only add the Auth middleware: +```csharp +builder.Services.AddDbContext(); +//builder.Services.AddHopFrame(); +services.AddHopFrameAuthentication(); +``` diff --git a/src/HopFrame.Security/README.md b/src/HopFrame.Security/README.md index fec1066..cc4b5d0 100644 --- a/src/HopFrame.Security/README.md +++ b/src/HopFrame.Security/README.md @@ -1,2 +1,74 @@ # HopFrame Security module this module contains all handlers for the login and register validation. It also checks the user permissions. + +# Services added in this module +You can use these services by specifying them as a dependency. All of them are scoped dependencies. + +## ITokenContext +This service provides the information given by the current request + +```csharp +public interface ITokenContext { + bool IsAuthenticated { get; } + + User User { get; } + + Guid AccessToken { get; } +} +``` + +## IUserService +This service simplifies the data access of the user table in the database. + +```csharp +public interface IUserService { + Task> GetUsers(); + + Task GetUser(Guid userId); + + Task GetUserByEmail(string email); + + Task GetUserByUsername(string username); + + Task AddUser(UserRegister user); + + Task UpdateUser(User user); + + Task DeleteUser(User user); + + Task CheckUserPassword(User user, string password); + + Task ChangePassword(User user, string password); +} +``` + +## IPermissionService +This service handles all permission and group interactions with the data source. + +```csharp +public interface IPermissionService { + Task HasPermission(string permission, Guid user); + + Task> GetPermissionGroups(); + + Task GetPermissionGroup(string name); + + Task EditPermissionGroup(PermissionGroup group); + + Task> GetUserPermissionGroups(User user); + + Task RemoveGroupFromUser(User user, PermissionGroup group); + + Task CreatePermissionGroup(string name, bool isDefault = false, string description = null); + + Task DeletePermissionGroup(PermissionGroup group); + + Task GetPermission(string name, IPermissionOwner owner); + + Task AddPermission(IPermissionOwner owner, string permission); + + Task RemovePermission(Permission permission); + + Task GetFullPermissions(string user); +} +``` diff --git a/src/HopFrame.Web/AdminPermissions.cs b/src/HopFrame.Web/AdminPermissions.cs deleted file mode 100644 index 365ae87..0000000 --- a/src/HopFrame.Web/AdminPermissions.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace HopFrame.Web; - -[Obsolete("Use HopFrame.Security.AdminPermissions instead")] -public static class AdminPermissions { - public const string IsAdmin = Security.AdminPermissions.IsAdmin; - - public const string ViewUsers = Security.AdminPermissions.ViewUsers; - public const string EditUser = Security.AdminPermissions.EditUser; - public const string DeleteUser = Security.AdminPermissions.DeleteUser; - public const string AddUser = Security.AdminPermissions.AddUser; - - public const string ViewGroups = Security.AdminPermissions.ViewGroups; - public const string EditGroup = Security.AdminPermissions.EditGroup; - public const string DeleteGroup = Security.AdminPermissions.DeleteGroup; - public const string AddGroup = Security.AdminPermissions.AddGroup; -} \ No newline at end of file diff --git a/src/HopFrame.Web/README.md b/src/HopFrame.Web/README.md index 38d2b5d..28b55c5 100644 --- a/src/HopFrame.Web/README.md +++ b/src/HopFrame.Web/README.md @@ -41,3 +41,20 @@ This module contains useful helpers for Blazor Apps and an Admin Dashboard. .AddHopFrameAdminPages() .AddInteractiveServerRenderMode(); ``` + +# Services added in this module +You can use these services by specifying them as a dependency. All of them are scoped dependencies. + +## IAuthService +This service handles all the authentication like login or register. It properly creates all tokens so the user can be identified + +```csharp +public interface IAuthService { + Task Register(UserRegister register); + Task Login(UserLogin login); + Task Logout(); + + Task RefreshLogin(); + Task IsLoggedIn(); +} +``` From b448229d880aadb9a773af04bf28eede9e973a2a Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 26 Sep 2024 11:19:41 +0200 Subject: [PATCH 3/4] Moved Auth logic to seperate service + endpoints can be disabled --- .../Controller/SecurityController.cs | 152 +--------------- .../Extensions/ServiceCollectionExtensions.cs | 20 ++- src/HopFrame.Api/Logic/IAuthLogic.cs | 16 ++ .../Logic/Implementation/AuthLogic.cs | 166 ++++++++++++++++++ src/HopFrame.Api/README.md | 63 ++++++- 5 files changed, 268 insertions(+), 149 deletions(-) create mode 100644 src/HopFrame.Api/Logic/IAuthLogic.cs create mode 100644 src/HopFrame.Api/Logic/Implementation/AuthLogic.cs diff --git a/src/HopFrame.Api/Controller/SecurityController.cs b/src/HopFrame.Api/Controller/SecurityController.cs index de9a50a..d9c1128 100644 --- a/src/HopFrame.Api/Controller/SecurityController.cs +++ b/src/HopFrame.Api/Controller/SecurityController.cs @@ -1,176 +1,38 @@ using HopFrame.Api.Logic; using HopFrame.Api.Models; -using HopFrame.Database; -using HopFrame.Database.Models.Entries; -using HopFrame.Security.Authentication; using HopFrame.Security.Authorization; -using HopFrame.Security.Claims; using HopFrame.Security.Models; -using HopFrame.Security.Services; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; namespace HopFrame.Api.Controller; [ApiController] -[Route("authentication")] -public class SecurityController(TDbContext context, IUserService users, ITokenContext tokenContext) : ControllerBase where TDbContext : HopDbContextBase { +[Route("api/v1/authentication")] +public class SecurityController(IAuthLogic auth) : ControllerBase { [HttpPut("login")] public async Task>> Login([FromBody] UserLogin login) { - var user = await users.GetUserByEmail(login.Email); - - if (user is null) - return LogicResult>.NotFound("The provided email address was not found"); - - if (!await users.CheckUserPassword(user, login.Password)) - return LogicResult>.Forbidden("The provided password is not correct"); - - var refreshToken = new TokenEntry { - CreatedAt = DateTime.Now, - Token = Guid.NewGuid().ToString(), - Type = TokenEntry.RefreshTokenType, - UserId = user.Id.ToString() - }; - var accessToken = new TokenEntry { - CreatedAt = DateTime.Now, - Token = Guid.NewGuid().ToString(), - Type = TokenEntry.AccessTokenType, - UserId = user.Id.ToString() - }; - - HttpContext.Response.Cookies.Append(ITokenContext.RefreshTokenType, refreshToken.Token, new CookieOptions { - MaxAge = HopFrameAuthentication.RefreshTokenTime, - HttpOnly = true, - Secure = true - }); - HttpContext.Response.Cookies.Append(ITokenContext.AccessTokenType, accessToken.Token, new CookieOptions { - MaxAge = HopFrameAuthentication.AccessTokenTime, - HttpOnly = true, - Secure = true - }); - - await context.Tokens.AddRangeAsync(refreshToken, accessToken); - await context.SaveChangesAsync(); - - return LogicResult>.Ok(accessToken.Token); + return await auth.Login(login); } [HttpPost("register")] public async Task>> Register([FromBody] UserRegister register) { - if (register.Password.Length < 8) - return LogicResult>.Conflict("Password needs to be at least 8 characters long"); - - var allUsers = await users.GetUsers(); - if (allUsers.Any(user => user.Username == register.Username || user.Email == register.Email)) - return LogicResult>.Conflict("Username or Email is already registered"); - - var user = await users.AddUser(register); - - var refreshToken = new TokenEntry { - CreatedAt = DateTime.Now, - Token = Guid.NewGuid().ToString(), - Type = TokenEntry.RefreshTokenType, - UserId = user.Id.ToString() - }; - var accessToken = new TokenEntry { - CreatedAt = DateTime.Now, - Token = Guid.NewGuid().ToString(), - Type = TokenEntry.AccessTokenType, - UserId = user.Id.ToString() - }; - - await context.Tokens.AddRangeAsync(refreshToken, accessToken); - await context.SaveChangesAsync(); - - HttpContext.Response.Cookies.Append(ITokenContext.RefreshTokenType, refreshToken.Token, new CookieOptions { - MaxAge = HopFrameAuthentication.RefreshTokenTime, - HttpOnly = true, - Secure = true - }); - HttpContext.Response.Cookies.Append(ITokenContext.AccessTokenType, accessToken.Token, new CookieOptions { - MaxAge = HopFrameAuthentication.AccessTokenTime, - HttpOnly = false, - Secure = true - }); - - return LogicResult>.Ok(accessToken.Token); + return await auth.Register(register); } [HttpGet("authenticate")] public async Task>> Authenticate() { - var refreshToken = HttpContext.Request.Cookies[ITokenContext.RefreshTokenType]; - - if (string.IsNullOrEmpty(refreshToken)) - return LogicResult>.Conflict("Refresh token not provided"); - - var token = await context.Tokens.SingleOrDefaultAsync(token => token.Token == refreshToken && token.Type == TokenEntry.RefreshTokenType); - - if (token is null) - return LogicResult>.NotFound("Refresh token not valid"); - - if (token.CreatedAt + HopFrameAuthentication.RefreshTokenTime < DateTime.Now) - return LogicResult>.Conflict("Refresh token is expired"); - - var accessToken = new TokenEntry { - CreatedAt = DateTime.Now, - Token = Guid.NewGuid().ToString(), - Type = TokenEntry.AccessTokenType, - UserId = token.UserId - }; - - await context.Tokens.AddAsync(accessToken); - await context.SaveChangesAsync(); - - HttpContext.Response.Cookies.Append(ITokenContext.AccessTokenType, accessToken.Token, new CookieOptions { - MaxAge = HopFrameAuthentication.AccessTokenTime, - HttpOnly = false, - Secure = true - }); - - return LogicResult>.Ok(accessToken.Token); + return await auth.Authenticate(); } [HttpDelete("logout"), Authorized] public async Task Logout() { - var accessToken = HttpContext.User.GetAccessTokenId(); - var refreshToken = HttpContext.Request.Cookies[ITokenContext.RefreshTokenType]; - - if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(refreshToken)) - return LogicResult.Conflict("access or refresh token not provided"); - - var tokenEntries = await context.Tokens.Where(token => - (token.Token == accessToken && token.Type == TokenEntry.AccessTokenType) || - (token.Token == refreshToken && token.Type == TokenEntry.RefreshTokenType)) - .ToArrayAsync(); - - if (tokenEntries.Length != 2) - return LogicResult.NotFound("One or more of the provided tokens was not found"); - - context.Tokens.Remove(tokenEntries[0]); - context.Tokens.Remove(tokenEntries[1]); - await context.SaveChangesAsync(); - - HttpContext.Response.Cookies.Delete(ITokenContext.RefreshTokenType); - HttpContext.Response.Cookies.Delete(ITokenContext.AccessTokenType); - - return LogicResult.Ok(); + return await auth.Logout(); } [HttpDelete("delete"), Authorized] public async Task Delete([FromBody] UserPasswordValidation validation) { - var user = tokenContext.User; - - if (!await users.CheckUserPassword(user, validation.Password)) - return LogicResult.Forbidden("The provided password is not correct"); - - await users.DeleteUser(user); - - HttpContext.Response.Cookies.Delete(ITokenContext.RefreshTokenType); - HttpContext.Response.Cookies.Delete(ITokenContext.AccessTokenType); - - return LogicResult.Ok(); + return await auth.Delete(validation); } } \ No newline at end of file diff --git a/src/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs b/src/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs index 568580e..29feb38 100644 --- a/src/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs +++ b/src/HopFrame.Api/Extensions/ServiceCollectionExtensions.cs @@ -1,19 +1,35 @@ using HopFrame.Api.Controller; +using HopFrame.Api.Logic; +using HopFrame.Api.Logic.Implementation; using HopFrame.Database; using HopFrame.Security.Authentication; +using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace HopFrame.Api.Extensions; public static class ServiceCollectionExtensions { /// - /// Adds all HopFrame endpoints and the HopFrame security layer to the WebApplication + /// Adds all HopFrame endpoints and services to the application /// /// The service provider to add the services to /// The data source for all HopFrame entities public static void AddHopFrame(this IServiceCollection services) where TDbContext : HopDbContextBase { - services.AddMvcCore().UseSpecificControllers(typeof(SecurityController)); + services.AddMvcCore().UseSpecificControllers(typeof(SecurityController)); + AddHopFrameNoEndpoints(services); + } + + /// + /// Adds all HopFrame services to the application + /// + /// The service provider to add the services to + /// The data source for all HopFrame entities + public static void AddHopFrameNoEndpoints(this IServiceCollection services) where TDbContext : HopDbContextBase { + services.TryAddSingleton(); + services.AddScoped>(); + services.AddHopFrameAuthentication(); } diff --git a/src/HopFrame.Api/Logic/IAuthLogic.cs b/src/HopFrame.Api/Logic/IAuthLogic.cs new file mode 100644 index 0000000..7dc5b78 --- /dev/null +++ b/src/HopFrame.Api/Logic/IAuthLogic.cs @@ -0,0 +1,16 @@ +using HopFrame.Api.Models; +using HopFrame.Security.Models; + +namespace HopFrame.Api.Logic; + +public interface IAuthLogic { + Task>> Login(UserLogin login); + + Task>> Register(UserRegister register); + + Task>> Authenticate(); + + Task Logout(); + + Task Delete(UserPasswordValidation validation); +} \ No newline at end of file diff --git a/src/HopFrame.Api/Logic/Implementation/AuthLogic.cs b/src/HopFrame.Api/Logic/Implementation/AuthLogic.cs new file mode 100644 index 0000000..405c2cf --- /dev/null +++ b/src/HopFrame.Api/Logic/Implementation/AuthLogic.cs @@ -0,0 +1,166 @@ +using HopFrame.Api.Models; +using HopFrame.Database; +using HopFrame.Database.Models.Entries; +using HopFrame.Security.Authentication; +using HopFrame.Security.Claims; +using HopFrame.Security.Models; +using HopFrame.Security.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; + +namespace HopFrame.Api.Logic.Implementation; + +public class AuthLogic(TDbContext context, IUserService users, ITokenContext tokenContext, IHttpContextAccessor accessor) : IAuthLogic where TDbContext : HopDbContextBase { + + public async Task>> Login(UserLogin login) { + var user = await users.GetUserByEmail(login.Email); + + if (user is null) + return LogicResult>.NotFound("The provided email address was not found"); + + if (!await users.CheckUserPassword(user, login.Password)) + return LogicResult>.Forbidden("The provided password is not correct"); + + var refreshToken = new TokenEntry { + CreatedAt = DateTime.Now, + Token = Guid.NewGuid().ToString(), + Type = TokenEntry.RefreshTokenType, + UserId = user.Id.ToString() + }; + var accessToken = new TokenEntry { + CreatedAt = DateTime.Now, + Token = Guid.NewGuid().ToString(), + Type = TokenEntry.AccessTokenType, + UserId = user.Id.ToString() + }; + + accessor.HttpContext?.Response.Cookies.Append(ITokenContext.RefreshTokenType, refreshToken.Token, new CookieOptions { + MaxAge = HopFrameAuthentication.RefreshTokenTime, + HttpOnly = true, + Secure = true + }); + accessor.HttpContext?.Response.Cookies.Append(ITokenContext.AccessTokenType, accessToken.Token, new CookieOptions { + MaxAge = HopFrameAuthentication.AccessTokenTime, + HttpOnly = true, + Secure = true + }); + + await context.Tokens.AddRangeAsync(refreshToken, accessToken); + await context.SaveChangesAsync(); + + return LogicResult>.Ok(accessToken.Token); + } + + public async Task>> Register(UserRegister register) { + if (register.Password.Length < 8) + return LogicResult>.Conflict("Password needs to be at least 8 characters long"); + + var allUsers = await users.GetUsers(); + if (allUsers.Any(user => user.Username == register.Username || user.Email == register.Email)) + return LogicResult>.Conflict("Username or Email is already registered"); + + var user = await users.AddUser(register); + + var refreshToken = new TokenEntry { + CreatedAt = DateTime.Now, + Token = Guid.NewGuid().ToString(), + Type = TokenEntry.RefreshTokenType, + UserId = user.Id.ToString() + }; + var accessToken = new TokenEntry { + CreatedAt = DateTime.Now, + Token = Guid.NewGuid().ToString(), + Type = TokenEntry.AccessTokenType, + UserId = user.Id.ToString() + }; + + await context.Tokens.AddRangeAsync(refreshToken, accessToken); + await context.SaveChangesAsync(); + + accessor.HttpContext?.Response.Cookies.Append(ITokenContext.RefreshTokenType, refreshToken.Token, new CookieOptions { + MaxAge = HopFrameAuthentication.RefreshTokenTime, + HttpOnly = true, + Secure = true + }); + accessor.HttpContext?.Response.Cookies.Append(ITokenContext.AccessTokenType, accessToken.Token, new CookieOptions { + MaxAge = HopFrameAuthentication.AccessTokenTime, + HttpOnly = false, + Secure = true + }); + + return LogicResult>.Ok(accessToken.Token); + } + + public async Task>> Authenticate() { + var refreshToken = accessor.HttpContext?.Request.Cookies[ITokenContext.RefreshTokenType]; + + if (string.IsNullOrEmpty(refreshToken)) + return LogicResult>.Conflict("Refresh token not provided"); + + var token = await context.Tokens.SingleOrDefaultAsync(token => token.Token == refreshToken && token.Type == TokenEntry.RefreshTokenType); + + if (token is null) + return LogicResult>.NotFound("Refresh token not valid"); + + if (token.CreatedAt + HopFrameAuthentication.RefreshTokenTime < DateTime.Now) + return LogicResult>.Conflict("Refresh token is expired"); + + var accessToken = new TokenEntry { + CreatedAt = DateTime.Now, + Token = Guid.NewGuid().ToString(), + Type = TokenEntry.AccessTokenType, + UserId = token.UserId + }; + + await context.Tokens.AddAsync(accessToken); + await context.SaveChangesAsync(); + + accessor.HttpContext?.Response.Cookies.Append(ITokenContext.AccessTokenType, accessToken.Token, new CookieOptions { + MaxAge = HopFrameAuthentication.AccessTokenTime, + HttpOnly = false, + Secure = true + }); + + return LogicResult>.Ok(accessToken.Token); + } + + public async Task Logout() { + var accessToken = accessor.HttpContext?.User.GetAccessTokenId(); + var refreshToken = accessor.HttpContext?.Request.Cookies[ITokenContext.RefreshTokenType]; + + if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(refreshToken)) + return LogicResult.Conflict("access or refresh token not provided"); + + var tokenEntries = await context.Tokens.Where(token => + (token.Token == accessToken && token.Type == TokenEntry.AccessTokenType) || + (token.Token == refreshToken && token.Type == TokenEntry.RefreshTokenType)) + .ToArrayAsync(); + + if (tokenEntries.Length != 2) + return LogicResult.NotFound("One or more of the provided tokens was not found"); + + context.Tokens.Remove(tokenEntries[0]); + context.Tokens.Remove(tokenEntries[1]); + await context.SaveChangesAsync(); + + accessor.HttpContext?.Response.Cookies.Delete(ITokenContext.RefreshTokenType); + accessor.HttpContext?.Response.Cookies.Delete(ITokenContext.AccessTokenType); + + return LogicResult.Ok(); + } + + public async Task Delete(UserPasswordValidation validation) { + var user = tokenContext.User; + + if (!await users.CheckUserPassword(user, validation.Password)) + return LogicResult.Forbidden("The provided password is not correct"); + + await users.DeleteUser(user); + + accessor.HttpContext?.Response.Cookies.Delete(ITokenContext.RefreshTokenType); + accessor.HttpContext?.Response.Cookies.Delete(ITokenContext.AccessTokenType); + + return LogicResult.Ok(); + } + +} \ No newline at end of file diff --git a/src/HopFrame.Api/README.md b/src/HopFrame.Api/README.md index 994c8c5..67b946b 100644 --- a/src/HopFrame.Api/README.md +++ b/src/HopFrame.Api/README.md @@ -33,9 +33,68 @@ By default, the module provides a controller for handling authentication based r You can explore the contoller by the build in swagger site from ASP .NET. ## Disable the Endpoints -If you don't want to include these endpoints you need to comment out the AddHopFrame line and only add the Auth middleware: + ```csharp builder.Services.AddDbContext(); //builder.Services.AddHopFrame(); -services.AddHopFrameAuthentication(); +services.AddHopFrameNoEndpoints(); ``` + +# Services added in this module +You can use these services by specifying them as a dependency. All of them are scoped dependencies. + +## LogicResult +Logic result is an extension of the ActionResult for an ApiController. It provides simple Http status results with either a message or data by specifying the generic type. + +```csharp +public class LogicResult : ILogicResult { + public static LogicResult Ok(); + + public static LogicResult BadRequest(); + + public static LogicResult BadRequest(string message); + + public static LogicResult Forbidden(); + + public static LogicResult Forbidden(string message); + + public static LogicResult NotFound(); + + public static LogicResult NotFound(string message); + + public static LogicResult Conflict(); + + public static LogicResult Conflict(string message); + + public static LogicResult Forward(LogicResult result); + + public static LogicResult Forward(ILogicResult result); + + public static implicit operator ActionResult(LogicResult v); +} + +public class LogicResult : ILogicResult { + public static LogicResult Ok(); + + public static LogicResult Ok(T result); + + ... +} +``` + +## IAuthLogic +This service handles all logic needed to provide the authentication endpoints by using the LogicResults. + +```csharp +public interface IAuthLogic { + Task>> Login(UserLogin login); + + Task>> Register(UserRegister register); + + Task>> Authenticate(); + + Task Logout(); + + Task Delete(UserPasswordValidation validation); +} +``` \ No newline at end of file From 0c4212049cced8dff26102c32d912b65fccbee0c Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 26 Sep 2024 11:55:53 +0200 Subject: [PATCH 4/4] Updated docs --- docs/Diagrams/Models/ApiModels.puml | 8 -- docs/Diagrams/Models/DatabaseModels.puml | 3 - docs/Diagrams/Models/img/ApiModels.svg | 2 +- docs/Diagrams/Models/img/DatabaseModels.svg | 2 +- docs/README.md | 13 ++ docs/{Models/README.md => models.md} | 6 +- docs/services.md | 145 ++++++++++++++++++++ docs/usage.md | 70 ++++++++++ 8 files changed, 233 insertions(+), 16 deletions(-) create mode 100644 docs/README.md rename docs/{Models/README.md => models.md} (70%) create mode 100644 docs/services.md create mode 100644 docs/usage.md diff --git a/docs/Diagrams/Models/ApiModels.puml b/docs/Diagrams/Models/ApiModels.puml index 2019855..bb5d25a 100644 --- a/docs/Diagrams/Models/ApiModels.puml +++ b/docs/Diagrams/Models/ApiModels.puml @@ -13,12 +13,6 @@ namespace HopFrame.Security { } } -namespace HopFrame.Web { - class RegisterData { - +RepeatedPassword: string - } -} - namespace HopFrame.Api { class SingleValueResult { +Value: TValue @@ -29,6 +23,4 @@ namespace HopFrame.Api { } } -UserRegister <|-- RegisterData - @enduml \ No newline at end of file diff --git a/docs/Diagrams/Models/DatabaseModels.puml b/docs/Diagrams/Models/DatabaseModels.puml index fc3a7b9..2e47b5b 100644 --- a/docs/Diagrams/Models/DatabaseModels.puml +++ b/docs/Diagrams/Models/DatabaseModels.puml @@ -11,9 +11,6 @@ namespace HopFrame.Database { } class TokenEntry { - {static} +RefreshTokenType: int = 0 - {static} +AccessTokenType: int = 1 - +Type: int +Token: string +UserId: string diff --git a/docs/Diagrams/Models/img/ApiModels.svg b/docs/Diagrams/Models/img/ApiModels.svg index 82ff3c0..76a19b4 100644 --- a/docs/Diagrams/Models/img/ApiModels.svg +++ b/docs/Diagrams/Models/img/ApiModels.svg @@ -1 +1 @@ -HopFrameSecurityWebApiUserLoginEmail: stringPassword: stringUserRegisterUsername: stringEmail: stringPassword: stringRegisterDataRepeatedPassword: stringSingleValueResultTValueValue: TValueUserPasswordValidationPassword: string \ No newline at end of file +HopFrameSecurityApiUserLoginEmail: stringPassword: stringUserRegisterUsername: stringEmail: stringPassword: stringSingleValueResultTValueValue: TValueUserPasswordValidationPassword: string \ No newline at end of file diff --git a/docs/Diagrams/Models/img/DatabaseModels.svg b/docs/Diagrams/Models/img/DatabaseModels.svg index 06aa882..fedbd56 100644 --- a/docs/Diagrams/Models/img/DatabaseModels.svg +++ b/docs/Diagrams/Models/img/DatabaseModels.svg @@ -1 +1 @@ -HopFrame.DatabaseUserEntryId: stringUsername: stringEmail: stringPassword: stringCreatedAt: DateTimeTokenEntryRefreshTokenType: int = 0AccessTokenType: int = 1 Type: intToken: stringUserId: stringCreatedAt: DateTimePermissionEntryRecordId: longPermissionText: stringUserId: stringGrantedAt: DateTimeGroupEntryName: stringDefault: boolDescription: stringCreatedAt: DateTime \ No newline at end of file +HopFrame.DatabaseUserEntryId: stringUsername: stringEmail: stringPassword: stringCreatedAt: DateTimeTokenEntryType: intToken: stringUserId: stringCreatedAt: DateTimePermissionEntryRecordId: longPermissionText: stringUserId: stringGrantedAt: DateTimeGroupEntryName: stringDefault: boolDescription: stringCreatedAt: DateTime \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..eb4fa47 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,13 @@ +# HopFrame documentation +These sides contain all documentation available for the HopFrame modules + +## Content +| Topic | Description | Document | +|----------|------------------------------------------------|-----------------------| +| Models | All models used by the HopFrame | [link](./models.md) | +| Services | All services provided by the HopFrame | [link](./services.md) | +| Usage | How to properly implement the HopFrame modules | [link](./usage.md) | + +## Dependencies +Both the HopFrame.Api and HopFrame.Web modules are dependent on the HopFrame.Database and HopFrame.Security modules. +So all models and services provided by these modules are available in the other modules as well. diff --git a/docs/Models/README.md b/docs/models.md similarity index 70% rename from docs/Models/README.md rename to docs/models.md index 03273b6..6af77a4 100644 --- a/docs/Models/README.md +++ b/docs/models.md @@ -6,16 +6,16 @@ This page shows all models that HopFrame uses. ## Base Models These are the models used by the various database services. -![](../Diagrams/Models/img/BaseModels.svg) +![](./Diagrams/Models/img/BaseModels.svg) ## API Models These are the models used by the REST API and the Blazor API. -![](../Diagrams/Models/img/ApiModels.svg) +![](./Diagrams/Models/img/ApiModels.svg) ## Database Models These are the models that correspond to the scheme in the Database -![](../Diagrams/Models/img/DatabaseModels.svg) +![](./Diagrams/Models/img/DatabaseModels.svg) diff --git a/docs/services.md b/docs/services.md new file mode 100644 index 0000000..81a7312 --- /dev/null +++ b/docs/services.md @@ -0,0 +1,145 @@ +# HopFrame Services +This page describes all services provided by the HopFrame. +You can use these services by specifying them as a dependency. All of them are scoped dependencies. + +## HopFrame.Security +### ITokenContext +This service provides the information given by the current request + +```csharp +public interface ITokenContext { + bool IsAuthenticated { get; } + + User User { get; } + + Guid AccessToken { get; } +} +``` + +### IUserService +This service simplifies the data access of the user table in the database. + +```csharp +public interface IUserService { + Task> GetUsers(); + + Task GetUser(Guid userId); + + Task GetUserByEmail(string email); + + Task GetUserByUsername(string username); + + Task AddUser(UserRegister user); + + Task UpdateUser(User user); + + Task DeleteUser(User user); + + Task CheckUserPassword(User user, string password); + + Task ChangePassword(User user, string password); +} +``` + +### IPermissionService +This service handles all permission and group interactions with the data source. + +```csharp +public interface IPermissionService { + Task HasPermission(string permission, Guid user); + + Task> GetPermissionGroups(); + + Task GetPermissionGroup(string name); + + Task EditPermissionGroup(PermissionGroup group); + + Task> GetUserPermissionGroups(User user); + + Task RemoveGroupFromUser(User user, PermissionGroup group); + + Task CreatePermissionGroup(string name, bool isDefault = false, string description = null); + + Task DeletePermissionGroup(PermissionGroup group); + + Task GetPermission(string name, IPermissionOwner owner); + + Task AddPermission(IPermissionOwner owner, string permission); + + Task RemovePermission(Permission permission); + + Task GetFullPermissions(string user); +} +``` + +## HopFrame.Api +### LogicResult +Logic result is an extension of the ActionResult for an ApiController. It provides simple Http status results with either a message or data by specifying the generic type. + +```csharp +public class LogicResult : ILogicResult { + public static LogicResult Ok(); + + public static LogicResult BadRequest(); + + public static LogicResult BadRequest(string message); + + public static LogicResult Forbidden(); + + public static LogicResult Forbidden(string message); + + public static LogicResult NotFound(); + + public static LogicResult NotFound(string message); + + public static LogicResult Conflict(); + + public static LogicResult Conflict(string message); + + public static LogicResult Forward(LogicResult result); + + public static LogicResult Forward(ILogicResult result); + + public static implicit operator ActionResult(LogicResult v); +} + +public class LogicResult : ILogicResult { + public static LogicResult Ok(); + + public static LogicResult Ok(T result); + + ... +} +``` + +### IAuthLogic +This service handles all logic needed to provide the authentication endpoints by using the LogicResults. + +```csharp +public interface IAuthLogic { + Task>> Login(UserLogin login); + + Task>> Register(UserRegister register); + + Task>> Authenticate(); + + Task Logout(); + + Task Delete(UserPasswordValidation validation); +} +``` + +## HopFrame.Web +### IAuthService +This service handles all the authentication like login or register. It properly creates all tokens so the user can be identified + +```csharp +public interface IAuthService { + Task Register(UserRegister register); + Task Login(UserLogin login); + Task Logout(); + + Task RefreshLogin(); + Task IsLoggedIn(); +} +``` diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..2023531 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,70 @@ +# HopFrame Usage +There are two different versions of HopFrame, either the Web API version or the full Blazor web version. + +## Ho to use the Web API version + +1. Add the HopFrame.Api library to your project: + + ``` + dotnet add package HopFrame.Api + ``` + +2. Create a DbContext that inherits the ``HopDbContext`` and add a data source + + ```csharp + public class DatabaseContext : HopDbContextBase { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { + base.OnConfiguring(optionsBuilder); + + optionsBuilder.UseSqlite("..."); + } + } + ``` + +3. Add the DbContext and HopFrame to your services + + ```csharp + builder.Services.AddDbContext(); + builder.Services.AddHopFrame(); + ``` + +## How to use the Blazor API + +1. Add the HopFrame.Web library to your project + + ``` + dotnet add package HopFrame.Web + ``` + +2. Create a DbContext that inherits the ``HopDbContext`` and add a data source + + ```csharp + public class DatabaseContext : HopDbContextBase { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { + base.OnConfiguring(optionsBuilder); + + optionsBuilder.UseSqlite("..."); + } + } + ``` + +3. Add the DbContext and HopFrame to your services + + ```csharp + builder.Services.AddDbContext(); + builder.Services.AddHopFrame(); + ``` + +4. Add the authentication middleware to your app + + ```csharp + app.UseMiddleware(); + ``` + +5. Add the HopFrame pages to your Razor components + + ```csharp + app.MapRazorComponents() + .AddHopFrameAdminPages() + .AddInteractiveServerRenderMode(); + ```