From 6c5c5c9e9d3387a48595c1ed8ab9f167edf39eb4 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Wed, 20 Nov 2024 20:20:48 +0100 Subject: [PATCH 01/11] Integrated models directly into docs --- docs/Diagrams/Models/ApiModels.puml | 26 ----- docs/Diagrams/Models/BaseModels.puml | 37 -------- docs/Diagrams/Models/DatabaseModels.puml | 38 -------- docs/Diagrams/Models/img/ApiModels.svg | 1 - docs/Diagrams/Models/img/BaseModels.svg | 1 - docs/Diagrams/Models/img/DatabaseModels.svg | 1 - docs/models.md | 100 +++++++++++++++++++- 7 files changed, 97 insertions(+), 107 deletions(-) delete mode 100644 docs/Diagrams/Models/ApiModels.puml delete mode 100644 docs/Diagrams/Models/BaseModels.puml delete mode 100644 docs/Diagrams/Models/DatabaseModels.puml delete mode 100644 docs/Diagrams/Models/img/ApiModels.svg delete mode 100644 docs/Diagrams/Models/img/BaseModels.svg delete mode 100644 docs/Diagrams/Models/img/DatabaseModels.svg diff --git a/docs/Diagrams/Models/ApiModels.puml b/docs/Diagrams/Models/ApiModels.puml deleted file mode 100644 index bb5d25a..0000000 --- a/docs/Diagrams/Models/ApiModels.puml +++ /dev/null @@ -1,26 +0,0 @@ -@startuml ApiModels - -namespace HopFrame.Security { - class UserLogin { - +Email: string - +Password: string - } - - class UserRegister { - +Username: string - +Email: string - +Password: string - } -} - -namespace HopFrame.Api { - class SingleValueResult { - +Value: TValue - } - - class UserPasswordValidation { - +Password: string - } -} - -@enduml \ No newline at end of file diff --git a/docs/Diagrams/Models/BaseModels.puml b/docs/Diagrams/Models/BaseModels.puml deleted file mode 100644 index 62706fc..0000000 --- a/docs/Diagrams/Models/BaseModels.puml +++ /dev/null @@ -1,37 +0,0 @@ -@startuml BaseModels -set namespaceSeparator none - -namespace HopFrame.Database { - class User { - +Id: Guid - +Username: string - +Email: string - +CreatedAt: DateTime - +Permissions: IList - } - - class Permission { - +Id: long - +PermissionName: string - +Owner: Guid - +GrantedAt: DateTime - } - - class PermissionGroup { - +Name: string - +IsDefaultGroup: bool - +Description: string - +CreatedAt: DateTime - +Permissions: IList - } - - interface IPermissionOwner {} -} - -IPermissionOwner <|-- User -IPermissionOwner <|-- PermissionGroup - -User .. Permission -PermissionGroup .. Permission - -@enduml \ No newline at end of file diff --git a/docs/Diagrams/Models/DatabaseModels.puml b/docs/Diagrams/Models/DatabaseModels.puml deleted file mode 100644 index 2e47b5b..0000000 --- a/docs/Diagrams/Models/DatabaseModels.puml +++ /dev/null @@ -1,38 +0,0 @@ -@startuml DatabaseModels -set namespaceSeparator none - -namespace HopFrame.Database { - class UserEntry { - +Id: string - +Username: string - +Email: string - +Password: string - +CreatedAt: DateTime - } - - class TokenEntry { - +Type: int - +Token: string - +UserId: string - +CreatedAt: DateTime - } - - class PermissionEntry { - +RecordId: long - +PermissionText: string - +UserId: string - +GrantedAt: DateTime - } - - class GroupEntry { - +Name: string - +Default: bool - +Description: string - +CreatedAt: DateTime - } -} - -UserEntry *-- TokenEntry -UserEntry *-- PermissionEntry - -@enduml \ No newline at end of file diff --git a/docs/Diagrams/Models/img/ApiModels.svg b/docs/Diagrams/Models/img/ApiModels.svg deleted file mode 100644 index 76a19b4..0000000 --- a/docs/Diagrams/Models/img/ApiModels.svg +++ /dev/null @@ -1 +0,0 @@ -HopFrameSecurityApiUserLoginEmail: stringPassword: stringUserRegisterUsername: stringEmail: stringPassword: stringSingleValueResultTValueValue: TValueUserPasswordValidationPassword: string \ No newline at end of file diff --git a/docs/Diagrams/Models/img/BaseModels.svg b/docs/Diagrams/Models/img/BaseModels.svg deleted file mode 100644 index 89ed8d2..0000000 --- a/docs/Diagrams/Models/img/BaseModels.svg +++ /dev/null @@ -1 +0,0 @@ -HopFrame.DatabaseUserId: GuidUsername: stringEmail: stringCreatedAt: DateTimePermissions: IList<Permission>PermissionId: longPermissionName: stringOwner: GuidGrantedAt: DateTimePermissionGroupName: stringIsDefaultGroup: boolDescription: stringCreatedAt: DateTimePermissions: IList<Permission>IPermissionOwner \ No newline at end of file diff --git a/docs/Diagrams/Models/img/DatabaseModels.svg b/docs/Diagrams/Models/img/DatabaseModels.svg deleted file mode 100644 index fedbd56..0000000 --- a/docs/Diagrams/Models/img/DatabaseModels.svg +++ /dev/null @@ -1 +0,0 @@ -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/models.md b/docs/models.md index 6af77a4..d33a07d 100644 --- a/docs/models.md +++ b/docs/models.md @@ -6,16 +6,110 @@ 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) +```plantuml +set namespaceSeparator none + +namespace HopFrame.Database { + class User { + +Id: Guid + +Username: string + +Email: string + +CreatedAt: DateTime + +Permissions: IList + } + + class Permission { + +Id: long + +PermissionName: string + +Owner: Guid + +GrantedAt: DateTime + } + + class PermissionGroup { + +Name: string + +IsDefaultGroup: bool + +Description: string + +CreatedAt: DateTime + +Permissions: IList + } + + interface IPermissionOwner {} +} + +IPermissionOwner <|-- User +IPermissionOwner <|-- PermissionGroup + +User .. Permission +PermissionGroup .. Permission +``` ## API Models These are the models used by the REST API and the Blazor API. -![](./Diagrams/Models/img/ApiModels.svg) +```plantuml +namespace HopFrame.Security { + class UserLogin { + +Email: string + +Password: string + } + + class UserRegister { + +Username: string + +Email: string + +Password: string + } +} + +namespace HopFrame.Api { + class SingleValueResult { + +Value: TValue + } + + class UserPasswordValidation { + +Password: string + } +} +``` ## Database Models These are the models that correspond to the scheme in the Database -![](./Diagrams/Models/img/DatabaseModels.svg) +```plantuml +set namespaceSeparator none + +namespace HopFrame.Database { + class UserEntry { + +Id: string + +Username: string + +Email: string + +Password: string + +CreatedAt: DateTime + } + + class TokenEntry { + +Type: int + +Token: string + +UserId: string + +CreatedAt: DateTime + } + + class PermissionEntry { + +RecordId: long + +PermissionText: string + +UserId: string + +GrantedAt: DateTime + } + + class GroupEntry { + +Name: string + +Default: bool + +Description: string + +CreatedAt: DateTime + } +} + +UserEntry *-- TokenEntry +UserEntry *-- PermissionEntry +``` From 6d2f7051ee70306fe5e1b966a7b179866840cf29 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Wed, 20 Nov 2024 20:24:33 +0100 Subject: [PATCH 02/11] attempt to fix diagram display issue --- docs/models.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/models.md b/docs/models.md index d33a07d..b8963eb 100644 --- a/docs/models.md +++ b/docs/models.md @@ -7,6 +7,7 @@ This page shows all models that HopFrame uses. These are the models used by the various database services. ```plantuml +@startuml set namespaceSeparator none namespace HopFrame.Database { @@ -41,6 +42,7 @@ IPermissionOwner <|-- PermissionGroup User .. Permission PermissionGroup .. Permission +@enduml ``` @@ -48,6 +50,7 @@ PermissionGroup .. Permission These are the models used by the REST API and the Blazor API. ```plantuml +@startuml namespace HopFrame.Security { class UserLogin { +Email: string @@ -70,6 +73,7 @@ namespace HopFrame.Api { +Password: string } } +@enduml ``` @@ -77,6 +81,7 @@ namespace HopFrame.Api { These are the models that correspond to the scheme in the Database ```plantuml +@startuml set namespaceSeparator none namespace HopFrame.Database { @@ -112,4 +117,5 @@ namespace HopFrame.Database { UserEntry *-- TokenEntry UserEntry *-- PermissionEntry +@enduml ``` From 986c5cebdee5aa53636ec4e900e11b01a89a738f Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 21 Nov 2024 16:15:18 +0100 Subject: [PATCH 03/11] Added inline documentation + fixed small bugs --- docs/README.md | 21 ++- docs/models.md | 121 --------------- docs/services.md | 145 ------------------ docs/usage.md | 70 --------- src/HopFrame.Api/Logic/IAuthLogic.cs | 9 ++ src/HopFrame.Api/Models/SingleValueResult.cs | 5 + .../Repositories/IPermissionRepository.cs | 2 +- .../Repositories/ITokenRepository.cs | 6 +- .../Models/AdminPageProperty.cs | 2 - src/HopFrame.Web/AuthMiddleware.cs | 5 +- src/HopFrame.Web/HopAdminContext.cs | 2 +- .../Pages/Administration/AdminDashboard.razor | 3 + .../Administration/Layout/AdminMenu.razor | 5 +- 13 files changed, 37 insertions(+), 359 deletions(-) delete mode 100644 docs/models.md delete mode 100644 docs/services.md delete mode 100644 docs/usage.md diff --git a/docs/README.md b/docs/README.md index eb4fa47..582a4f0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,13 +1,10 @@ -# HopFrame documentation -These sides contain all documentation available for the HopFrame modules +# HopFrame Documentation -## 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. +- [x] In code documentation +- [ ] Installation +- [ ] Database usage +- [ ] Authentication usage +- [ ] LogicResult usage +- [ ] Repositories usage +- [ ] AuthService usage +- [ ] AdminPages usage diff --git a/docs/models.md b/docs/models.md deleted file mode 100644 index b8963eb..0000000 --- a/docs/models.md +++ /dev/null @@ -1,121 +0,0 @@ -# Models for HopFrame - -This page shows all models that HopFrame uses. - - -## Base Models -These are the models used by the various database services. - -```plantuml -@startuml -set namespaceSeparator none - -namespace HopFrame.Database { - class User { - +Id: Guid - +Username: string - +Email: string - +CreatedAt: DateTime - +Permissions: IList - } - - class Permission { - +Id: long - +PermissionName: string - +Owner: Guid - +GrantedAt: DateTime - } - - class PermissionGroup { - +Name: string - +IsDefaultGroup: bool - +Description: string - +CreatedAt: DateTime - +Permissions: IList - } - - interface IPermissionOwner {} -} - -IPermissionOwner <|-- User -IPermissionOwner <|-- PermissionGroup - -User .. Permission -PermissionGroup .. Permission -@enduml -``` - - -## API Models -These are the models used by the REST API and the Blazor API. - -```plantuml -@startuml -namespace HopFrame.Security { - class UserLogin { - +Email: string - +Password: string - } - - class UserRegister { - +Username: string - +Email: string - +Password: string - } -} - -namespace HopFrame.Api { - class SingleValueResult { - +Value: TValue - } - - class UserPasswordValidation { - +Password: string - } -} -@enduml -``` - - -## Database Models -These are the models that correspond to the scheme in the Database - -```plantuml -@startuml -set namespaceSeparator none - -namespace HopFrame.Database { - class UserEntry { - +Id: string - +Username: string - +Email: string - +Password: string - +CreatedAt: DateTime - } - - class TokenEntry { - +Type: int - +Token: string - +UserId: string - +CreatedAt: DateTime - } - - class PermissionEntry { - +RecordId: long - +PermissionText: string - +UserId: string - +GrantedAt: DateTime - } - - class GroupEntry { - +Name: string - +Default: bool - +Description: string - +CreatedAt: DateTime - } -} - -UserEntry *-- TokenEntry -UserEntry *-- PermissionEntry -@enduml -``` diff --git a/docs/services.md b/docs/services.md deleted file mode 100644 index 81a7312..0000000 --- a/docs/services.md +++ /dev/null @@ -1,145 +0,0 @@ -# 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 deleted file mode 100644 index 2023531..0000000 --- a/docs/usage.md +++ /dev/null @@ -1,70 +0,0 @@ -# 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(); - ``` diff --git a/src/HopFrame.Api/Logic/IAuthLogic.cs b/src/HopFrame.Api/Logic/IAuthLogic.cs index 7dc5b78..3dd5b5b 100644 --- a/src/HopFrame.Api/Logic/IAuthLogic.cs +++ b/src/HopFrame.Api/Logic/IAuthLogic.cs @@ -8,9 +8,18 @@ public interface IAuthLogic { Task>> Register(UserRegister register); + /// + /// Reassures that the user has a valid refresh token and generates a new access token + /// + /// The newly generated access token Task>> Authenticate(); Task Logout(); + /// + /// Deletes the user account that called the endpoint if the provided password is correct + /// + /// The password od the user + /// Task Delete(UserPasswordValidation validation); } \ No newline at end of file diff --git a/src/HopFrame.Api/Models/SingleValueResult.cs b/src/HopFrame.Api/Models/SingleValueResult.cs index c09fdb6..81cbdb4 100644 --- a/src/HopFrame.Api/Models/SingleValueResult.cs +++ b/src/HopFrame.Api/Models/SingleValueResult.cs @@ -1,5 +1,10 @@ namespace HopFrame.Api.Models; +/// +/// Useful for endpoints that only return a single int or string +/// +/// The value of the result +/// The type of the result public struct SingleValueResult(TValue value) { public TValue Value { get; set; } = value; diff --git a/src/HopFrame.Database/Repositories/IPermissionRepository.cs b/src/HopFrame.Database/Repositories/IPermissionRepository.cs index 5971e34..07680ce 100644 --- a/src/HopFrame.Database/Repositories/IPermissionRepository.cs +++ b/src/HopFrame.Database/Repositories/IPermissionRepository.cs @@ -19,5 +19,5 @@ public interface IPermissionRepository { Task RemovePermission(IPermissionOwner owner, string permission); - public Task> GetFullPermissions(IPermissionOwner owner); + Task> GetFullPermissions(IPermissionOwner owner); } \ No newline at end of file diff --git a/src/HopFrame.Database/Repositories/ITokenRepository.cs b/src/HopFrame.Database/Repositories/ITokenRepository.cs index 19b38ac..bec3963 100644 --- a/src/HopFrame.Database/Repositories/ITokenRepository.cs +++ b/src/HopFrame.Database/Repositories/ITokenRepository.cs @@ -3,7 +3,7 @@ using HopFrame.Database.Models; namespace HopFrame.Database.Repositories; public interface ITokenRepository { - public Task GetToken(string content); - public Task CreateToken(int type, User owner); - public Task DeleteUserTokens(User owner); + Task GetToken(string content); + Task CreateToken(int type, User owner); + Task DeleteUserTokens(User owner); } \ No newline at end of file diff --git a/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs b/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs index 8347e36..60cc763 100644 --- a/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs +++ b/src/HopFrame.Web.Admin/Models/AdminPageProperty.cs @@ -1,5 +1,3 @@ -using System.Text.Json.Serialization; - namespace HopFrame.Web.Admin.Models; public sealed class AdminPageProperty { diff --git a/src/HopFrame.Web/AuthMiddleware.cs b/src/HopFrame.Web/AuthMiddleware.cs index 509ad83..33e2f52 100644 --- a/src/HopFrame.Web/AuthMiddleware.cs +++ b/src/HopFrame.Web/AuthMiddleware.cs @@ -7,6 +7,9 @@ using Microsoft.AspNetCore.Http; namespace HopFrame.Web; +/// +/// Assures that the user stays logged in even if the access token is expired +/// public sealed class AuthMiddleware(IAuthService auth, IPermissionRepository perms) : IMiddleware { public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var loggedIn = await auth.IsLoggedIn(); @@ -14,7 +17,7 @@ public sealed class AuthMiddleware(IAuthService auth, IPermissionRepository perm if (!loggedIn) { var token = await auth.RefreshLogin(); if (token is null) { - await next.Invoke(context); + next?.Invoke(context); return; } diff --git a/src/HopFrame.Web/HopAdminContext.cs b/src/HopFrame.Web/HopAdminContext.cs index e0ab493..22aac7b 100644 --- a/src/HopFrame.Web/HopAdminContext.cs +++ b/src/HopFrame.Web/HopAdminContext.cs @@ -8,7 +8,7 @@ using HopFrame.Web.Repositories; namespace HopFrame.Web; -public class HopAdminContext : AdminPagesContext { +internal class HopAdminContext : AdminPagesContext { public AdminPage Users { get; set; } public AdminPage Groups { get; set; } diff --git a/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor b/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor index 71d3482..7ebb3cf 100644 --- a/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor +++ b/src/HopFrame.Web/Pages/Administration/AdminDashboard.razor @@ -5,11 +5,14 @@ @using BlazorStrap @using HopFrame.Web.Pages.Administration.Layout @using BlazorStrap.V5 +@using HopFrame.Security @using HopFrame.Web.Admin.Providers @using HopFrame.Web.Components @using Microsoft.AspNetCore.Components.Web @layout AdminLayout + + Admin Dashboard diff --git a/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor b/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor index aae2c7f..a47bafb 100644 --- a/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor +++ b/src/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor @@ -30,13 +30,12 @@ } - + logged in as @Context?.User.Username - + - logout From eef03c152d38b582dc009bb6cbf386f7779ea25a Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 21 Nov 2024 16:55:56 +0100 Subject: [PATCH 04/11] finished documentation for installation, database usage and authentication --- docs/Authentication.md | 42 +++++++++++++++++++++++++++++++++++ docs/README.md | 6 ++--- docs/installation/Blazor.md | 37 ++++++++++++++++++++++++++++++ docs/installation/Database.md | 37 ++++++++++++++++++++++++++++++ docs/installation/README.md | 2 ++ docs/installation/WebAPI.md | 17 ++++++++++++++ 6 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 docs/Authentication.md create mode 100644 docs/installation/Blazor.md create mode 100644 docs/installation/Database.md create mode 100644 docs/installation/README.md create mode 100644 docs/installation/WebAPI.md diff --git a/docs/Authentication.md b/docs/Authentication.md new file mode 100644 index 0000000..4f03292 --- /dev/null +++ b/docs/Authentication.md @@ -0,0 +1,42 @@ +# HopFrame Authentication + +With the provided HopFrame services, you can secure your endpoints and blazor pages so that only logged-in users or users with the right permissions can access the endpoint/page + +## Usage +### Secure your endpoints +You can secure your endpoints by adding the `Authorized` attribute. + +```csharp +// Everyone can access this endpoint +[HttpGet("hello")] +public ActionResult HelloWorld() { + return "Hello, World!"; +} + +// Only logged-in users can access this endpoint +[HttpGet("hello"), Authorized] +public ActionResult HelloWorld() { + return "Hello, World!"; +} + +// Only logged-in users with the specified permissions can access this endpoint +[HttpGet("hello"), Authorized("test.permission", "test.permission.another")] +public ActionResult HelloWorld() { + return "Hello, World!"; +} +``` + +### Secure your Blazor pages +You can secure your Blazor pages by using the `AuthorizedView` component. +Everything placed inside this component will only be displayed if the authorization was successful. +You can also redirect the user if the authorization fails by specifying a `RedirectIfUnauthorized` url. + +```htmlinblazor + + +

This paragraph is only visible if the user is logged-in and has the required permission

+
+ + + +``` diff --git a/docs/README.md b/docs/README.md index 582a4f0..98a41ca 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,9 @@ # HopFrame Documentation - [x] In code documentation -- [ ] Installation -- [ ] Database usage -- [ ] Authentication usage +- [x] Installation +- [x] Database usage +- [x] Authentication usage - [ ] LogicResult usage - [ ] Repositories usage - [ ] AuthService usage diff --git a/docs/installation/Blazor.md b/docs/installation/Blazor.md new file mode 100644 index 0000000..abbe172 --- /dev/null +++ b/docs/installation/Blazor.md @@ -0,0 +1,37 @@ +## How to use the Blazor API +This Installation adds all HopFrame [pages](../pages) and [services](../services) to the application. + +1. Add the HopFrame.Web library to your project + + ``` + dotnet add package HopFrame.Web + ``` + +2. Create a [DbContext](./Database.md) that inherits the ``HopDbContext`` and add a data source +

 

+ +3. Add the HopFrame services to your application, provide the previously created `DatabaseContext` that inherits from `HopDbContextBase` + + ```csharp + builder.Services.AddHopFrame(); + ``` + +4. **Optional:** You can also add your [AdminContext](../admin) + + ```csharp + builder.Services.AddAdminContext(); + ``` + +5. Add the authentication middleware to your app + + ```csharp + app.UseMiddleware(); + ``` + +6. Add the HopFrame pages to your Razor components + + ```csharp + app.MapRazorComponents() + .AddHopFrameAdminPages() + .AddInteractiveServerRenderMode(); + ``` diff --git a/docs/installation/Database.md b/docs/installation/Database.md new file mode 100644 index 0000000..2ebef13 --- /dev/null +++ b/docs/installation/Database.md @@ -0,0 +1,37 @@ +# Database initialization +You also need to initialize the data source with the tables from HopFrame + +## Create a DbContext + +1. Create a c# class that inherits from the `HopDbContextBase` and add a data source (In the example Sqlite is used) + + ```csharp + public class DatabaseContext : HopDbContextBase { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { + base.OnConfiguring(optionsBuilder); + + optionsBuilder.UseSqlite("..."); + } + } + ``` + + **IMPORTANT:** You need to leave the `base.OnConfiguring(optionsBuilder)` in place so the HopFrame model relations are set correctly. +

 

+ +2. Register the `DatabaseContext` as a service + + ```csharp + builder.Services.AddDbContext(); + ``` + +3. Create a database migration + + ```bash + dotnet ef migrations add Initial + ``` + +4. Apply the migration to the data source + + ```bash + dotnet ef database update + ``` diff --git a/docs/installation/README.md b/docs/installation/README.md new file mode 100644 index 0000000..0f3cda1 --- /dev/null +++ b/docs/installation/README.md @@ -0,0 +1,2 @@ +# HopFrame Usage +There are two different versions of HopFrame, either the [Web API](./WebAPI.md) version or the full [Blazor web version](./Blazor.md). diff --git a/docs/installation/WebAPI.md b/docs/installation/WebAPI.md new file mode 100644 index 0000000..6166db0 --- /dev/null +++ b/docs/installation/WebAPI.md @@ -0,0 +1,17 @@ +# Ho to use the Web API version +This Installation adds all HopFrame [endpoints](../endpoints) and [services](../services) to the application. + +1. Add the HopFrame.Api library to your project: + + ``` + dotnet add package HopFrame.Api + ``` + +2. Create a [DbContext](./Database.md) that inherits the ``HopDbContext`` and add a data source +

 

+ +3. Add the HopFrame services to your application, provide the previously created `DatabaseContext` that inherits from `HopDbContextBase` + + ```csharp + builder.Services.AddHopFrame(); + ``` From 01cd0e1590f6e5adbbd46ff2adf74066ee13ac07 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 21 Nov 2024 16:56:45 +0100 Subject: [PATCH 05/11] Renamed Authentication to Authorization --- docs/{Authentication.md => Authorization.md} | 0 docs/README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{Authentication.md => Authorization.md} (100%) diff --git a/docs/Authentication.md b/docs/Authorization.md similarity index 100% rename from docs/Authentication.md rename to docs/Authorization.md diff --git a/docs/README.md b/docs/README.md index 98a41ca..595d23d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,7 +3,7 @@ - [x] In code documentation - [x] Installation - [x] Database usage -- [x] Authentication usage +- [x] Authorization usage - [ ] LogicResult usage - [ ] Repositories usage - [ ] AuthService usage From e8c61dbc7f937f7ab7397db630c9b2489a89b7f5 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Thu, 21 Nov 2024 17:02:15 +0100 Subject: [PATCH 06/11] Fixed visual separation issues --- docs/Authorization.md | 10 ++++++++-- docs/installation/Blazor.md | 1 - docs/installation/Database.md | 8 +++----- docs/installation/WebAPI.md | 1 - 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/Authorization.md b/docs/Authorization.md index 4f03292..312aaa1 100644 --- a/docs/Authorization.md +++ b/docs/Authorization.md @@ -1,6 +1,6 @@ # HopFrame Authentication -With the provided HopFrame services, you can secure your endpoints and blazor pages so that only logged-in users or users with the right permissions can access the endpoint/page +With the provided HopFrame services, you can secure your endpoints and blazor pages so that only logged-in users or users with the right permissions can access the endpoint/page. ## Usage ### Secure your endpoints @@ -12,13 +12,17 @@ You can secure your endpoints by adding the `Authorized` attribute. public ActionResult HelloWorld() { return "Hello, World!"; } +``` +```csharp // Only logged-in users can access this endpoint [HttpGet("hello"), Authorized] public ActionResult HelloWorld() { return "Hello, World!"; } +``` +```csharp // Only logged-in users with the specified permissions can access this endpoint [HttpGet("hello"), Authorized("test.permission", "test.permission.another")] public ActionResult HelloWorld() { @@ -31,12 +35,14 @@ You can secure your Blazor pages by using the `AuthorizedView` component. Everything placed inside this component will only be displayed if the authorization was successful. You can also redirect the user if the authorization fails by specifying a `RedirectIfUnauthorized` url. -```htmlinblazor +```html

This paragraph is only visible if the user is logged-in and has the required permission

+``` +```html ``` diff --git a/docs/installation/Blazor.md b/docs/installation/Blazor.md index abbe172..d427551 100644 --- a/docs/installation/Blazor.md +++ b/docs/installation/Blazor.md @@ -8,7 +8,6 @@ This Installation adds all HopFrame [pages](../pages) and [services](../services ``` 2. Create a [DbContext](./Database.md) that inherits the ``HopDbContext`` and add a data source -

 

3. Add the HopFrame services to your application, provide the previously created `DatabaseContext` that inherits from `HopDbContextBase` diff --git a/docs/installation/Database.md b/docs/installation/Database.md index 2ebef13..c695a8f 100644 --- a/docs/installation/Database.md +++ b/docs/installation/Database.md @@ -1,9 +1,10 @@ # Database initialization -You also need to initialize the data source with the tables from HopFrame +You also need to initialize the data source with the tables from HopFrame. ## Create a DbContext -1. Create a c# class that inherits from the `HopDbContextBase` and add a data source (In the example Sqlite is used) +1. Create a c# class that inherits from the `HopDbContextBase` and add a data source (In the example Sqlite is used)\ + **IMPORTANT:** You need to leave the `base.OnConfiguring(optionsBuilder)` in place so the HopFrame model relations are set correctly. ```csharp public class DatabaseContext : HopDbContextBase { @@ -14,9 +15,6 @@ You also need to initialize the data source with the tables from HopFrame } } ``` - - **IMPORTANT:** You need to leave the `base.OnConfiguring(optionsBuilder)` in place so the HopFrame model relations are set correctly. -

 

2. Register the `DatabaseContext` as a service diff --git a/docs/installation/WebAPI.md b/docs/installation/WebAPI.md index 6166db0..429ee5d 100644 --- a/docs/installation/WebAPI.md +++ b/docs/installation/WebAPI.md @@ -8,7 +8,6 @@ This Installation adds all HopFrame [endpoints](../endpoints) and [services](../ ``` 2. Create a [DbContext](./Database.md) that inherits the ``HopDbContext`` and add a data source -

 

3. Add the HopFrame services to your application, provide the previously created `DatabaseContext` that inherits from `HopDbContextBase` From a531cd7a47c0fa1ae6515591dedb4fcc38a3c534 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Fri, 22 Nov 2024 10:49:48 +0100 Subject: [PATCH 07/11] Reorganized files --- docs/Authorization.md | 48 ------------------- docs/api/authorization.md | 30 ++++++++++++ .../WebAPI.md => api/installation.md} | 4 +- docs/blazor/authorization.md | 20 ++++++++ .../Blazor.md => blazor/installation.md} | 6 +-- .../{installation/Database.md => database.md} | 0 docs/installation/README.md | 2 - 7 files changed, 55 insertions(+), 55 deletions(-) delete mode 100644 docs/Authorization.md create mode 100644 docs/api/authorization.md rename docs/{installation/WebAPI.md => api/installation.md} (61%) create mode 100644 docs/blazor/authorization.md rename docs/{installation/Blazor.md => blazor/installation.md} (72%) rename docs/{installation/Database.md => database.md} (100%) delete mode 100644 docs/installation/README.md diff --git a/docs/Authorization.md b/docs/Authorization.md deleted file mode 100644 index 312aaa1..0000000 --- a/docs/Authorization.md +++ /dev/null @@ -1,48 +0,0 @@ -# HopFrame Authentication - -With the provided HopFrame services, you can secure your endpoints and blazor pages so that only logged-in users or users with the right permissions can access the endpoint/page. - -## Usage -### Secure your endpoints -You can secure your endpoints by adding the `Authorized` attribute. - -```csharp -// Everyone can access this endpoint -[HttpGet("hello")] -public ActionResult HelloWorld() { - return "Hello, World!"; -} -``` - -```csharp -// Only logged-in users can access this endpoint -[HttpGet("hello"), Authorized] -public ActionResult HelloWorld() { - return "Hello, World!"; -} -``` - -```csharp -// Only logged-in users with the specified permissions can access this endpoint -[HttpGet("hello"), Authorized("test.permission", "test.permission.another")] -public ActionResult HelloWorld() { - return "Hello, World!"; -} -``` - -### Secure your Blazor pages -You can secure your Blazor pages by using the `AuthorizedView` component. -Everything placed inside this component will only be displayed if the authorization was successful. -You can also redirect the user if the authorization fails by specifying a `RedirectIfUnauthorized` url. - -```html - - -

This paragraph is only visible if the user is logged-in and has the required permission

-
-``` - -```html - - -``` diff --git a/docs/api/authorization.md b/docs/api/authorization.md new file mode 100644 index 0000000..8fe422f --- /dev/null +++ b/docs/api/authorization.md @@ -0,0 +1,30 @@ +# HopFrame Authentication + +With the provided HopFrame services, you can secure your endpoints so that only logged-in users or users with the right permissions can access the endpoint. + +## Usage +You can secure your endpoints by adding the `Authorized` attribute. + +```csharp +// Everyone can access this endpoint +[HttpGet("hello")] +public ActionResult HelloWorld() { + return "Hello, World!"; +} +``` + +```csharp +// Only logged-in users can access this endpoint +[HttpGet("hello"), Authorized] +public ActionResult HelloWorld() { + return "Hello, World!"; +} +``` + +```csharp +// Only logged-in users with the specified permissions can access this endpoint +[HttpGet("hello"), Authorized("test.permission", "test.permission.another")] +public ActionResult HelloWorld() { + return "Hello, World!"; +} +``` diff --git a/docs/installation/WebAPI.md b/docs/api/installation.md similarity index 61% rename from docs/installation/WebAPI.md rename to docs/api/installation.md index 429ee5d..249bcd7 100644 --- a/docs/installation/WebAPI.md +++ b/docs/api/installation.md @@ -1,5 +1,5 @@ # Ho to use the Web API version -This Installation adds all HopFrame [endpoints](../endpoints) and [services](../services) to the application. +This Installation adds all HopFrame [endpoints](./endpoints.md) and [services](./services.md) to the application. 1. Add the HopFrame.Api library to your project: @@ -7,7 +7,7 @@ This Installation adds all HopFrame [endpoints](../endpoints) and [services](../ dotnet add package HopFrame.Api ``` -2. Create a [DbContext](./Database.md) that inherits the ``HopDbContext`` and add a data source +2. Create a [DbContext](../database.md) that inherits the ``HopDbContext`` and add a data source 3. Add the HopFrame services to your application, provide the previously created `DatabaseContext` that inherits from `HopDbContextBase` diff --git a/docs/blazor/authorization.md b/docs/blazor/authorization.md new file mode 100644 index 0000000..952de9c --- /dev/null +++ b/docs/blazor/authorization.md @@ -0,0 +1,20 @@ +# HopFrame Authentication + +With the provided HopFrame services, you can secure your blazor pages so that only logged-in users or users with the right permissions can access the page. + +## Usage +You can secure your Blazor pages by using the `AuthorizedView` component. +Everything placed inside this component will only be displayed if the authorization was successful. +You can also redirect the user if the authorization fails by specifying a `RedirectIfUnauthorized` url. + +```html + + +

This paragraph is only visible if the user is logged-in and has the required permission

+
+``` + +```html + + +``` diff --git a/docs/installation/Blazor.md b/docs/blazor/installation.md similarity index 72% rename from docs/installation/Blazor.md rename to docs/blazor/installation.md index d427551..91e87d7 100644 --- a/docs/installation/Blazor.md +++ b/docs/blazor/installation.md @@ -1,5 +1,5 @@ ## How to use the Blazor API -This Installation adds all HopFrame [pages](../pages) and [services](../services) to the application. +This Installation adds all HopFrame [pages](./pages.md) and [services](./services.md) to the application. 1. Add the HopFrame.Web library to your project @@ -7,7 +7,7 @@ This Installation adds all HopFrame [pages](../pages) and [services](../services dotnet add package HopFrame.Web ``` -2. Create a [DbContext](./Database.md) that inherits the ``HopDbContext`` and add a data source +2. Create a [DbContext](../database.md) that inherits the ``HopDbContext`` and add a data source 3. Add the HopFrame services to your application, provide the previously created `DatabaseContext` that inherits from `HopDbContextBase` @@ -15,7 +15,7 @@ This Installation adds all HopFrame [pages](../pages) and [services](../services builder.Services.AddHopFrame(); ``` -4. **Optional:** You can also add your [AdminContext](../admin) +4. **Optional:** You can also add your [AdminContext](./admin.md) ```csharp builder.Services.AddAdminContext(); diff --git a/docs/installation/Database.md b/docs/database.md similarity index 100% rename from docs/installation/Database.md rename to docs/database.md diff --git a/docs/installation/README.md b/docs/installation/README.md deleted file mode 100644 index 0f3cda1..0000000 --- a/docs/installation/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# HopFrame Usage -There are two different versions of HopFrame, either the [Web API](./WebAPI.md) version or the full [Blazor web version](./Blazor.md). From 2bc8a5d70b237fc3392c491559c16b119a02bfe7 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Fri, 22 Nov 2024 11:42:21 +0100 Subject: [PATCH 08/11] working on various components of the documentation --- docs/README.md | 9 +++-- docs/api/endpoints.md | 0 docs/api/installation.md | 2 +- docs/api/logicresults.md | 33 ++++++++++++++++ docs/blazor/admin.md | 2 + docs/blazor/auth.md | 20 ++++++++++ docs/blazor/installation.md | 2 +- docs/blazor/pages.md | 0 docs/repositories.md | 75 +++++++++++++++++++++++++++++++++++++ 9 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 docs/api/endpoints.md create mode 100644 docs/api/logicresults.md create mode 100644 docs/blazor/admin.md create mode 100644 docs/blazor/auth.md create mode 100644 docs/blazor/pages.md create mode 100644 docs/repositories.md diff --git a/docs/README.md b/docs/README.md index 595d23d..9b12c36 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,7 +4,10 @@ - [x] Installation - [x] Database usage - [x] Authorization usage -- [ ] LogicResult usage -- [ ] Repositories usage -- [ ] AuthService usage +- [x] LogicResult usage +- [x] Repositories usage +- [x] AuthService usage +- [x] AuthMiddleware usage - [ ] AdminPages usage +- [ ] Endpoints usage +- [ ] Blazor pages usage diff --git a/docs/api/endpoints.md b/docs/api/endpoints.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/api/installation.md b/docs/api/installation.md index 249bcd7..66021eb 100644 --- a/docs/api/installation.md +++ b/docs/api/installation.md @@ -1,5 +1,5 @@ # Ho to use the Web API version -This Installation adds all HopFrame [endpoints](./endpoints.md) and [services](./services.md) to the application. +This Installation adds all HopFrame [endpoints](./endpoints.md) and [repositories](../repositories.md) to the application. 1. Add the HopFrame.Api library to your project: diff --git a/docs/api/logicresults.md b/docs/api/logicresults.md new file mode 100644 index 0000000..aacb6e5 --- /dev/null +++ b/docs/api/logicresults.md @@ -0,0 +1,33 @@ +# LogicResults +LogicResults provide another layer of abstraction above the ActionResults. +They help you sending the right `HttpStatusCode` with the right data. + +## Usage +1. Create an endpoint that returns an `ActionResult`: + + ```csharp + [HttpGet("hello")] + public ActionResult Hello() { + return new ActionResult("Hello, World!"); + } + ``` +2. Now instead of directly returning the `ActionResult`, return a `LogicResult` + + ```csharp + [HttpGet("hello")] + public ActionResult Hello() { + return LogicResult.Ok("Hello, World!"); + } + ``` +3. This allows you to very easily change the return type by simply calling the right function + + ```csharp + [HttpGet("hello")] + public ActionResult Hello() { + if (!Auth.IsLoggedIn) + return LogicResult.Forbidden(); + + return LogicResult.Ok("Hello, World!"); + } + ``` + **Hint:** You can also provide an error message for status codes that are not in the 200 range. \ No newline at end of file diff --git a/docs/blazor/admin.md b/docs/blazor/admin.md new file mode 100644 index 0000000..4b90907 --- /dev/null +++ b/docs/blazor/admin.md @@ -0,0 +1,2 @@ +# HopFrame Admin Pages + diff --git a/docs/blazor/auth.md b/docs/blazor/auth.md new file mode 100644 index 0000000..0b15e1c --- /dev/null +++ b/docs/blazor/auth.md @@ -0,0 +1,20 @@ +# Auth Service +The `IAuthService` provides some useful methods to handle user authentication (login/register). + +## Usage +Simply define the `IAuthService` as a dependency + +```csharp +public interface IAuthService { + Task Register(UserRegister register); + Task Login(UserLogin login); + Task Logout(); + + Task RefreshLogin(); + Task IsLoggedIn(); +} +``` +## Automatically refresh user sessions +1. Make sure you have implementented the `AuthMiddleware` how it's described in step 5 of the [installation](./installation.md). + +2. After that, the access token of the user gets automatically refreshed as long as the refresh token is valid. diff --git a/docs/blazor/installation.md b/docs/blazor/installation.md index 91e87d7..f740b7b 100644 --- a/docs/blazor/installation.md +++ b/docs/blazor/installation.md @@ -1,5 +1,5 @@ ## How to use the Blazor API -This Installation adds all HopFrame [pages](./pages.md) and [services](./services.md) to the application. +This Installation adds all HopFrame [pages](./pages.md) and [repositories](../repositories.md) to the application. 1. Add the HopFrame.Web library to your project diff --git a/docs/blazor/pages.md b/docs/blazor/pages.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/repositories.md b/docs/repositories.md new file mode 100644 index 0000000..25cb4ac --- /dev/null +++ b/docs/repositories.md @@ -0,0 +1,75 @@ +# HopFrame Repositories +The HopFrame provies repositories for the various build in database models as an abstraction around the `HopDbContext` to ensure, that the data is proccessed and saved correctly. + +## Overview +The repositories can also be used by simply defining them as a dependency in your service / controller. + +### User Repository + +```csharp +public interface IUserRepository { + Task> GetUsers(); + + Task GetUser(Guid userId); + + Task GetUserByEmail(string email); + + Task GetUserByUsername(string username); + + Task AddUser(User user); + + Task UpdateUser(User user); + + Task DeleteUser(User user); + + Task CheckUserPassword(User user, string password); + + Task ChangePassword(User user, string password); +} +``` + +### Group Repository + +```csharp +public interface IGroupRepository { + Task> GetPermissionGroups(); + + Task> GetDefaultGroups(); + + Task> GetUserGroups(User user); + + Task GetPermissionGroup(string name); + + Task EditPermissionGroup(PermissionGroup group); + + Task CreatePermissionGroup(PermissionGroup group); + + Task DeletePermissionGroup(PermissionGroup group); +} +``` + +### Permission Repository + +```csharp +public interface IPermissionRepository { + Task HasPermission(IPermissionOwner owner, params string[] permissions); + + Task AddPermission(IPermissionOwner owner, string permission); + + Task RemovePermission(IPermissionOwner owner, string permission); + + Task> GetFullPermissions(IPermissionOwner owner); +} +``` + +### Token Repository + +```csharp +public interface ITokenRepository { + Task GetToken(string content); + + Task CreateToken(int type, User owner); + + Task DeleteUserTokens(User owner); +} +``` From 16ef41800d219e4ed4a55a9f202e357c4c0c5f32 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Fri, 22 Nov 2024 12:20:33 +0100 Subject: [PATCH 09/11] added endpoint documentation --- docs/README.md | 2 +- docs/api/endpoints.md | 21 +++++++++++++++++++++ docs/api/logicresults.md | 2 +- docs/api/models.md | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 docs/api/models.md diff --git a/docs/README.md b/docs/README.md index 9b12c36..3d1b031 100644 --- a/docs/README.md +++ b/docs/README.md @@ -9,5 +9,5 @@ - [x] AuthService usage - [x] AuthMiddleware usage - [ ] AdminPages usage -- [ ] Endpoints usage +- [x] Endpoints usage - [ ] Blazor pages usage diff --git a/docs/api/endpoints.md b/docs/api/endpoints.md index e69de29..f082a1d 100644 --- a/docs/api/endpoints.md +++ b/docs/api/endpoints.md @@ -0,0 +1,21 @@ +# HopFrame Endpoints +HopFrame currently only supports endpoints for authentication out of the box. + +> **Hint:** with the help of the [repositories](../repositories.md) you can very easily create missing endpoints for HopFrame components yourself. + +## All currently supported endpoints + +> **Hint:** you can use the build-in [swagger](https://swagger.io/) ui to explore and test all endpoints of your application __including__ HopFrame endpoints. + +### SecurityController +Base endpoint: `api/v1/authentication`\ +**Important:** All primitive data types (including `string`) are return as a [`SingleValueResult`](./models.md#SingleValueResult) + + +| Method | Endpoint | Payload | Returns | +| ------ | -------- | ------- | ------- | +| PUT | login | [UserLogin](./models.md#UserLogin) | access token (string) | +| POST | register | [UserRegister](./models#UserRegister) | access token (string) | +| GET | authenticate | | access token (string) | +| DELETE | logout | | | +| DELETE | delete | [UserPasswordValidation](./models.md#UserPasswordValidation) | | diff --git a/docs/api/logicresults.md b/docs/api/logicresults.md index aacb6e5..ad2fe43 100644 --- a/docs/api/logicresults.md +++ b/docs/api/logicresults.md @@ -30,4 +30,4 @@ They help you sending the right `HttpStatusCode` with the right data. return LogicResult.Ok("Hello, World!"); } ``` - **Hint:** You can also provide an error message for status codes that are not in the 200 range. \ No newline at end of file + > **Hint:** You can also provide an error message for status codes that are not in the 200 range. \ No newline at end of file diff --git a/docs/api/models.md b/docs/api/models.md new file mode 100644 index 0000000..049ea1f --- /dev/null +++ b/docs/api/models.md @@ -0,0 +1,33 @@ +# HopFrame Models +All models used by the RestAPI are listed below + +## SingleValueResult +```csharp +public struct SingleValueResult(TValue value) { + public TValue Value { get; set; } = value; +} +``` + +## UserLogin +```csharp +public class UserLogin { + public string Email { get; set; } + public string Password { get; set; } +} +``` + +## UserRegister +```csharp +public class UserRegister { + public string Username { get; set; } + public string Email { get; set; } + public string Password { get; set; } +} +``` + +## UserPasswordValidation +```csharp +public sealed class UserPasswordValidation { + public string Password { get; set; } +} +``` From 0c2c02136d2c039aec968de75c3a456c1e32df59 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Fri, 22 Nov 2024 14:04:15 +0100 Subject: [PATCH 10/11] added docs for admin pages and blazor pages + fixed typos --- docs/README.md | 4 +- docs/api/endpoints.md | 16 +++--- docs/blazor/admin.md | 131 ++++++++++++++++++++++++++++++++++++++++++ docs/blazor/auth.md | 2 +- docs/blazor/pages.md | 14 +++++ 5 files changed, 156 insertions(+), 11 deletions(-) diff --git a/docs/README.md b/docs/README.md index 3d1b031..f51bf76 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,6 +8,6 @@ - [x] Repositories usage - [x] AuthService usage - [x] AuthMiddleware usage -- [ ] AdminPages usage +- [x] AdminPages usage - [x] Endpoints usage -- [ ] Blazor pages usage +- [x] Blazor pages usage diff --git a/docs/api/endpoints.md b/docs/api/endpoints.md index f082a1d..8ed7fb0 100644 --- a/docs/api/endpoints.md +++ b/docs/api/endpoints.md @@ -8,14 +8,14 @@ HopFrame currently only supports endpoints for authentication out of the box. > **Hint:** you can use the build-in [swagger](https://swagger.io/) ui to explore and test all endpoints of your application __including__ HopFrame endpoints. ### SecurityController -Base endpoint: `api/v1/authentication`\ +Base endpoint: `/api/v1/authentication`\ **Important:** All primitive data types (including `string`) are return as a [`SingleValueResult`](./models.md#SingleValueResult) -| Method | Endpoint | Payload | Returns | -| ------ | -------- | ------- | ------- | -| PUT | login | [UserLogin](./models.md#UserLogin) | access token (string) | -| POST | register | [UserRegister](./models#UserRegister) | access token (string) | -| GET | authenticate | | access token (string) | -| DELETE | logout | | | -| DELETE | delete | [UserPasswordValidation](./models.md#UserPasswordValidation) | | +| Method | Endpoint | Payload | Returns | +|--------|---------------|--------------------------------------------------------------|-----------------------| +| PUT | /login | [UserLogin](./models.md#UserLogin) | access token (string) | +| POST | /register | [UserRegister](./models#UserRegister) | access token (string) | +| GET | /authenticate | | access token (string) | +| DELETE | /logout | | | +| DELETE | /delete | [UserPasswordValidation](./models.md#UserPasswordValidation) | | diff --git a/docs/blazor/admin.md b/docs/blazor/admin.md index 4b90907..feec095 100644 --- a/docs/blazor/admin.md +++ b/docs/blazor/admin.md @@ -1,2 +1,133 @@ # HopFrame Admin Pages +Admin pages can be defined through a `AdminContext` similar to how a `DbContext` is defined. They generate administration pages like [`/administration/users`](./pages.md) +simply by reading the structure of the provided model and optionally some additional configuration. +> **Fun fact:** The already existing pages `/administration/users` and `/administration/groups` are also generated using an internal `AdminContext`. + +## Usage +1. Create a class that inherits the `AdminPagesContext` base class + + ```csharp + public class AdminContext : AdminPagesContext { + + } + ``` + +2. Add your admin pages as properties to the class + + ```csharp + public class AdminContext : AdminPagesContext { + + public AdminPage
Addresses { get; set; } + + public AdminPage Employees { get; set; } + + } + ``` + +3. **Optionally** you can further configure your pages in the `OnModelCreating` method + + ```csharp + public class AdminContext : AdminPagesContext { + + public AdminPage
Addresses { get; set; } + public AdminPage Employees { get; set; } + + public override void OnModelCreating(IAdminContextGenerator generator) { + base.OnModelCreating(generator); + + generator.Page() + .Property(e => e.Address) + .IsSelector(); + + generator.Page
() + .Property(a => a.Employee) + .Ignore(); + + generator.Page
() + .Property(a => a.AddressId) + .IsSelector() + .Parser((model, e) => model.AddressId = e.EmployeeId); + + generator.Page() + .ConfigureRepository() + .ListingProperty(e => e.Name); + + generator.Page
() + .ConfigureRepository() + .ListingProperty(a => a.City); + } + } + ``` +4. **Optionally** you can also add some of the following attributes to your classes / properties to further configure the admin pages:\ + \ + Attributes for classes: + + ```csharp + [AttributeUsage(AttributeTargets.Class)] + public sealed class AdminButtonConfigAttribute(bool showCreateButton = true, bool showDeleteButton = true, bool showUpdateButton = true) : Attribute { + public bool ShowCreateButton { get; set; } = showCreateButton; + public bool ShowDeleteButton { get; set; } = showDeleteButton; + public bool ShowUpdateButton { get; set; } = showUpdateButton; + } + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Class)] + public sealed class AdminPermissionsAttribute(string view = null, string create = null, string update = null, string delete = null) : Attribute { + public AdminPagePermissions Permissions { get; set; } = new() { + Create = create, + Update = update, + Delete = delete, + View = view + }; + } + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Class)] + public class AdminUrlAttribute(string url) : Attribute { + public string Url { get; set; } = url; + } + ``` + + Attributes for properties: + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public sealed class AdminHideValueAttribute : Attribute; + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public sealed class AdminIgnoreAttribute(bool onlyForListing = false) : Attribute { + public bool OnlyForListing { get; set; } = onlyForListing; + } + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public sealed class AdminPrefixAttribute(string prefix) : Attribute { + public string Prefix { get; set; } = prefix; + } + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public sealed class AdminUneditableAttribute : Attribute; + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public class AdminUniqueAttribute : Attribute; + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public sealed class AdminUnsortableAttribute : Attribute; + ``` + + ```csharp + [AttributeUsage(AttributeTargets.Property)] + public sealed class ListingPropertyAttribute : Attribute; + ``` diff --git a/docs/blazor/auth.md b/docs/blazor/auth.md index 0b15e1c..a759486 100644 --- a/docs/blazor/auth.md +++ b/docs/blazor/auth.md @@ -15,6 +15,6 @@ public interface IAuthService { } ``` ## Automatically refresh user sessions -1. Make sure you have implementented the `AuthMiddleware` how it's described in step 5 of the [installation](./installation.md). +1. Make sure you have implemented the `AuthMiddleware` how it's described in step 5 of the [installation](./installation.md). 2. After that, the access token of the user gets automatically refreshed as long as the refresh token is valid. diff --git a/docs/blazor/pages.md b/docs/blazor/pages.md index e69de29..214b771 100644 --- a/docs/blazor/pages.md +++ b/docs/blazor/pages.md @@ -0,0 +1,14 @@ +# HopFrame Pages +By default, the HopFrame provides some blazor pages for managing user accounts and permissions + +## All currently supported blazor pages + +| Page | Endpoint | Permission | Usage | +|-----------------|------------------------|----------------------------|--------------------------------------------------------------------------------------------------------| +| Admin Dashboard | /administration | hopframe.admin | This page provides an overview to all admin pages built-in and created by [AdminContexts](./admin.md). | +| Admin Login | /administration/login | | This page is a simple login screen so no login screen needs to be created to access the admin pages. | +| User Dashboard | /administration/users | hopframe.admin.users.view | This page serves as a management site for all users and their permissions. | +| Group Dashboard | /administration/groups | hopframe.admin.groups.view | This page serves as a management site for all groups and their permissions. | + +> **Hint:** All pages created by [AdminContexts](./admin.md) are also under the `/administration/` location. This can unfortunately __not__ be changed at the moment. + From fee99c60b6f09e20a2f6d01f1403effcd4ab28d1 Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Fri, 22 Nov 2024 14:18:40 +0100 Subject: [PATCH 11/11] Finished documentation --- docs/README.md | 13 -------- docs/api/endpoints.md | 4 +-- docs/api/models.md | 17 ----------- docs/models.md | 71 +++++++++++++++++++++++++++++++++++++++++++ docs/readme.md | 25 +++++++++++++++ 5 files changed, 98 insertions(+), 32 deletions(-) delete mode 100644 docs/README.md create mode 100644 docs/models.md create mode 100644 docs/readme.md diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index f51bf76..0000000 --- a/docs/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# HopFrame Documentation - -- [x] In code documentation -- [x] Installation -- [x] Database usage -- [x] Authorization usage -- [x] LogicResult usage -- [x] Repositories usage -- [x] AuthService usage -- [x] AuthMiddleware usage -- [x] AdminPages usage -- [x] Endpoints usage -- [x] Blazor pages usage diff --git a/docs/api/endpoints.md b/docs/api/endpoints.md index 8ed7fb0..c02a3bc 100644 --- a/docs/api/endpoints.md +++ b/docs/api/endpoints.md @@ -14,8 +14,8 @@ Base endpoint: `/api/v1/authentication`\ | Method | Endpoint | Payload | Returns | |--------|---------------|--------------------------------------------------------------|-----------------------| -| PUT | /login | [UserLogin](./models.md#UserLogin) | access token (string) | -| POST | /register | [UserRegister](./models#UserRegister) | access token (string) | +| PUT | /login | [UserLogin](../models.md#UserLogin) | access token (string) | +| POST | /register | [UserRegister](../models.md#UserRegister) | access token (string) | | GET | /authenticate | | access token (string) | | DELETE | /logout | | | | DELETE | /delete | [UserPasswordValidation](./models.md#UserPasswordValidation) | | diff --git a/docs/api/models.md b/docs/api/models.md index 049ea1f..c102452 100644 --- a/docs/api/models.md +++ b/docs/api/models.md @@ -8,23 +8,6 @@ public struct SingleValueResult(TValue value) { } ``` -## UserLogin -```csharp -public class UserLogin { - public string Email { get; set; } - public string Password { get; set; } -} -``` - -## UserRegister -```csharp -public class UserRegister { - public string Username { get; set; } - public string Email { get; set; } - public string Password { get; set; } -} -``` - ## UserPasswordValidation ```csharp public sealed class UserPasswordValidation { diff --git a/docs/models.md b/docs/models.md new file mode 100644 index 0000000..39ecc99 --- /dev/null +++ b/docs/models.md @@ -0,0 +1,71 @@ +# HopFrame base models +All models listed below are part of the core HopFrame components and accessible in all installation variations + +> **Note:** All properties of the models that are `virtual` are relational properties and don't directly correspond to columns in the database. + +## User +```csharp +public class User : IPermissionOwner { + public Guid Id { get; init; } + public string Username { get; set; } + public string Email { get; set; } + public string Password { get; set; } + public DateTime CreatedAt { get; set; } + public virtual List Permissions { get; set; } + public virtual List Tokens { get; set; } +} +``` + +## PermissionGroup +```csharp +public class PermissionGroup : IPermissionOwner { + public string Name { get; init; } + public bool IsDefaultGroup { get; set; } + public string Description { get; set; } + public DateTime CreatedAt { get; set; } + public virtual List Permissions { get; set; } +} +``` + +## Permission +```csharp +public class Permission { + public long Id { get; init; } + public string PermissionName { get; set; } + public DateTime GrantedAt { get; set; } + public virtual User User { get; set; } + public virtual PermissionGroup Group { get; set; } +} +``` + +## Token +```csharp +public class Token { + public int Type { get; set; } + public Guid Content { get; set; } + public DateTime CreatedAt { get; set; } + public virtual User Owner { get; set; } +} +``` + +## UserLogin +```csharp +public class UserLogin { + public string Email { get; set; } + public string Password { get; set; } +} +``` + +## UserRegister +```csharp +public class UserRegister { + public string Username { get; set; } + public string Email { get; set; } + public string Password { get; set; } +} +``` + +## IPermissionOwner +```csharp +public interface IPermissionOwner; +``` diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000..289a64c --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,25 @@ +# HopFrame Documentation + +The HopFrame comes in two variations, you can eiter only use the backend with some basic endpoints or with fully fledged blazor pages for managing HopFrame components. + +## Shared HopFrame Modules + +- [Database](./database.md) +- [Repositories](./repositories.md) +- [Base Models](./models.md) + +## HopFrame Web API + +- [Installation](./api/installation.md) +- [Endpoints](./api/endpoints.md) +- [Authorization](./api/authorization.md) +- [Models](./api/models.md) +- [LogicResults](./api/logicresults.md) + +## HopFrame Blazor library + +- [Installation](./blazor/installation.md) +- [Pages](./blazor/pages.md) +- [Authorization](./blazor/authorization.md) +- [Auth Service](./blazor/auth.md) +- [Admin Context](./blazor/admin.md)