Added inline documentation + fixed small bugs
This commit is contained in:
@@ -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
|
||||
|
||||
121
docs/models.md
121
docs/models.md
@@ -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<Permission>
|
||||
}
|
||||
|
||||
class Permission {
|
||||
+Id: long
|
||||
+PermissionName: string
|
||||
+Owner: Guid
|
||||
+GrantedAt: DateTime
|
||||
}
|
||||
|
||||
class PermissionGroup {
|
||||
+Name: string
|
||||
+IsDefaultGroup: bool
|
||||
+Description: string
|
||||
+CreatedAt: DateTime
|
||||
+Permissions: IList<Permission>
|
||||
}
|
||||
|
||||
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<TValue> {
|
||||
+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
|
||||
```
|
||||
145
docs/services.md
145
docs/services.md
@@ -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<IList<User>> GetUsers();
|
||||
|
||||
Task<User> GetUser(Guid userId);
|
||||
|
||||
Task<User> GetUserByEmail(string email);
|
||||
|
||||
Task<User> GetUserByUsername(string username);
|
||||
|
||||
Task<User> AddUser(UserRegister user);
|
||||
|
||||
Task UpdateUser(User user);
|
||||
|
||||
Task DeleteUser(User user);
|
||||
|
||||
Task<bool> 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<bool> HasPermission(string permission, Guid user);
|
||||
|
||||
Task<IList<PermissionGroup>> GetPermissionGroups();
|
||||
|
||||
Task<PermissionGroup> GetPermissionGroup(string name);
|
||||
|
||||
Task EditPermissionGroup(PermissionGroup group);
|
||||
|
||||
Task<IList<PermissionGroup>> GetUserPermissionGroups(User user);
|
||||
|
||||
Task RemoveGroupFromUser(User user, PermissionGroup group);
|
||||
|
||||
Task<PermissionGroup> CreatePermissionGroup(string name, bool isDefault = false, string description = null);
|
||||
|
||||
Task DeletePermissionGroup(PermissionGroup group);
|
||||
|
||||
Task<Permission> GetPermission(string name, IPermissionOwner owner);
|
||||
|
||||
Task AddPermission(IPermissionOwner owner, string permission);
|
||||
|
||||
Task RemovePermission(Permission permission);
|
||||
|
||||
Task<string[]> 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<T>(ILogicResult<T> result);
|
||||
|
||||
public static implicit operator ActionResult(LogicResult v);
|
||||
}
|
||||
|
||||
public class LogicResult<T> : ILogicResult<T> {
|
||||
public static LogicResult<T> Ok();
|
||||
|
||||
public static LogicResult<T> Ok(T result);
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### IAuthLogic
|
||||
This service handles all logic needed to provide the authentication endpoints by using the LogicResults.
|
||||
|
||||
```csharp
|
||||
public interface IAuthLogic {
|
||||
Task<LogicResult<SingleValueResult<string>>> Login(UserLogin login);
|
||||
|
||||
Task<LogicResult<SingleValueResult<string>>> Register(UserRegister register);
|
||||
|
||||
Task<LogicResult<SingleValueResult<string>>> Authenticate();
|
||||
|
||||
Task<LogicResult> Logout();
|
||||
|
||||
Task<LogicResult> 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<bool> Login(UserLogin login);
|
||||
Task Logout();
|
||||
|
||||
Task<TokenEntry> RefreshLogin();
|
||||
Task<bool> IsLoggedIn();
|
||||
}
|
||||
```
|
||||
@@ -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<DatabaseContext>();
|
||||
builder.Services.AddHopFrame<DatabaseContext>();
|
||||
```
|
||||
|
||||
## 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<DatabaseContext>();
|
||||
builder.Services.AddHopFrame<DatabaseContext>();
|
||||
```
|
||||
|
||||
4. Add the authentication middleware to your app
|
||||
|
||||
```csharp
|
||||
app.UseMiddleware<AuthMiddleware>();
|
||||
```
|
||||
|
||||
5. Add the HopFrame pages to your Razor components
|
||||
|
||||
```csharp
|
||||
app.MapRazorComponents<App>()
|
||||
.AddHopFrameAdminPages()
|
||||
.AddInteractiveServerRenderMode();
|
||||
```
|
||||
@@ -8,9 +8,18 @@ public interface IAuthLogic {
|
||||
|
||||
Task<LogicResult<SingleValueResult<string>>> Register(UserRegister register);
|
||||
|
||||
/// <summary>
|
||||
/// Reassures that the user has a valid refresh token and generates a new access token
|
||||
/// </summary>
|
||||
/// <returns>The newly generated access token</returns>
|
||||
Task<LogicResult<SingleValueResult<string>>> Authenticate();
|
||||
|
||||
Task<LogicResult> Logout();
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the user account that called the endpoint if the provided password is correct
|
||||
/// </summary>
|
||||
/// <param name="validation">The password od the user</param>
|
||||
/// <returns></returns>
|
||||
Task<LogicResult> Delete(UserPasswordValidation validation);
|
||||
}
|
||||
@@ -1,5 +1,10 @@
|
||||
namespace HopFrame.Api.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Useful for endpoints that only return a single int or string
|
||||
/// </summary>
|
||||
/// <param name="value">The value of the result</param>
|
||||
/// <typeparam name="TValue">The type of the result</typeparam>
|
||||
public struct SingleValueResult<TValue>(TValue value) {
|
||||
public TValue Value { get; set; } = value;
|
||||
|
||||
|
||||
@@ -19,5 +19,5 @@ public interface IPermissionRepository {
|
||||
|
||||
Task RemovePermission(IPermissionOwner owner, string permission);
|
||||
|
||||
public Task<IList<string>> GetFullPermissions(IPermissionOwner owner);
|
||||
Task<IList<string>> GetFullPermissions(IPermissionOwner owner);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ using HopFrame.Database.Models;
|
||||
namespace HopFrame.Database.Repositories;
|
||||
|
||||
public interface ITokenRepository {
|
||||
public Task<Token> GetToken(string content);
|
||||
public Task<Token> CreateToken(int type, User owner);
|
||||
public Task DeleteUserTokens(User owner);
|
||||
Task<Token> GetToken(string content);
|
||||
Task<Token> CreateToken(int type, User owner);
|
||||
Task DeleteUserTokens(User owner);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace HopFrame.Web.Admin.Models;
|
||||
|
||||
public sealed class AdminPageProperty {
|
||||
|
||||
@@ -7,6 +7,9 @@ using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace HopFrame.Web;
|
||||
|
||||
/// <summary>
|
||||
/// Assures that the user stays logged in even if the access token is expired
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ using HopFrame.Web.Repositories;
|
||||
|
||||
namespace HopFrame.Web;
|
||||
|
||||
public class HopAdminContext : AdminPagesContext {
|
||||
internal class HopAdminContext : AdminPagesContext {
|
||||
|
||||
public AdminPage<User> Users { get; set; }
|
||||
public AdminPage<PermissionGroup> Groups { get; set; }
|
||||
|
||||
@@ -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
|
||||
|
||||
<AuthorizedView Permission="@AdminPermissions.IsAdmin" RedirectIfUnauthorized="/administration/login" />
|
||||
|
||||
<PageTitle>Admin Dashboard</PageTitle>
|
||||
|
||||
<BSContainer>
|
||||
|
||||
@@ -30,13 +30,12 @@
|
||||
}
|
||||
</BSNav>
|
||||
|
||||
<span style="margin-left: auto; line-height: 100%; color: white">
|
||||
<span style="margin-left: auto; line-height: 100%; color: white; margin-right: 10px">
|
||||
logged in as @Context?.User.Username
|
||||
</span>
|
||||
<BSButton DataId="logout" Size="Size.ExtraSmall" OnClick="Logout" Color="BSColor.Dark">
|
||||
<BSButton DataId="logout" Size="Size.ExtraSmall" OnClick="Logout" Color="BSColor.Dark" style="display: grid; align-items: center">
|
||||
<HopIconDisplay Type="HopIconDisplay.HopIcon.Logout"/>
|
||||
</BSButton>
|
||||
<BSTooltip Placement="Placement.Bottom" Target="logout" ContentAlwaysRendered="false">logout</BSTooltip>
|
||||
</Content>
|
||||
</BSCollapse>
|
||||
</BSContainer>
|
||||
|
||||
Reference in New Issue
Block a user