From e31dccc2982ea45b4a5a5d1c9826258ae0f0fdbc Mon Sep 17 00:00:00 2001 From: Leon Hoppe Date: Tue, 23 Jul 2024 19:15:01 +0200 Subject: [PATCH] Started creating the docs --- .idea/.idea.HopFrame/.idea/indexLayout.xml | 4 +- FrontendTest/DatabaseContext.cs | 2 +- HopFrame.Api/Models/SingleValueResult.cs | 10 +-- HopFrame.Security/Services/IUserService.cs | 2 + .../Services/Implementation/UserService.cs | 12 +++ .../Components/HopIconDisplay.razor | 76 +++++++++++++++++++ .../Layout/AdminLayout.razor.css | 36 ++++----- .../Administration/Layout/AdminMenu.razor | 17 ++--- .../Administration/Layout/AdminMenu.razor.css | 52 +++++-------- .../Pages/Administration/UserEditPage.razor | 18 +++-- .../Pages/Administration/UsersPage.razor | 70 +++++------------ .../Pages/Administration/UsersPage.razor.css | 12 +++ HopFrame.Web/ServiceCollectionExtensions.cs | 4 + HopFrame.sln | 2 +- {DatabaseTest => RestApiTest}/.gitignore | 0 .../Controllers/TestController.cs | 2 +- .../DatabaseContext.cs | 4 +- {DatabaseTest => RestApiTest}/Program.cs | 2 +- .../Properties/launchSettings.json | 0 .../RestApiTest.csproj | 0 .../appsettings.json | 0 docs/Diagrams/Models/ApiModels.puml | 34 +++++++++ docs/Diagrams/Models/BaseModels.puml | 37 +++++++++ docs/Diagrams/Models/DatabaseModels.puml | 41 ++++++++++ docs/Diagrams/Models/README.md | 21 +++++ docs/Diagrams/Models/img/ApiModels.svg | 1 + docs/Diagrams/Models/img/BaseModels.svg | 1 + docs/Diagrams/Models/img/DatabaseModels.svg | 1 + 28 files changed, 332 insertions(+), 129 deletions(-) create mode 100644 HopFrame.Web/Pages/Administration/Components/HopIconDisplay.razor rename {DatabaseTest => RestApiTest}/.gitignore (100%) rename {DatabaseTest => RestApiTest}/Controllers/TestController.cs (92%) rename {DatabaseTest => RestApiTest}/DatabaseContext.cs (72%) rename {DatabaseTest => RestApiTest}/Program.cs (98%) rename {DatabaseTest => RestApiTest}/Properties/launchSettings.json (100%) rename DatabaseTest/DatabaseTest.csproj => RestApiTest/RestApiTest.csproj (100%) rename {DatabaseTest => RestApiTest}/appsettings.json (100%) create mode 100644 docs/Diagrams/Models/ApiModels.puml create mode 100644 docs/Diagrams/Models/BaseModels.puml create mode 100644 docs/Diagrams/Models/DatabaseModels.puml create mode 100644 docs/Diagrams/Models/README.md create mode 100644 docs/Diagrams/Models/img/ApiModels.svg create mode 100644 docs/Diagrams/Models/img/BaseModels.svg create mode 100644 docs/Diagrams/Models/img/DatabaseModels.svg diff --git a/.idea/.idea.HopFrame/.idea/indexLayout.xml b/.idea/.idea.HopFrame/.idea/indexLayout.xml index 7b08163..db94204 100644 --- a/.idea/.idea.HopFrame/.idea/indexLayout.xml +++ b/.idea/.idea.HopFrame/.idea/indexLayout.xml @@ -1,7 +1,9 @@ - + + docs + diff --git a/FrontendTest/DatabaseContext.cs b/FrontendTest/DatabaseContext.cs index 390d4f2..20945c9 100644 --- a/FrontendTest/DatabaseContext.cs +++ b/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\\DatabaseTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); + optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\RestApiTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); } } \ No newline at end of file diff --git a/HopFrame.Api/Models/SingleValueResult.cs b/HopFrame.Api/Models/SingleValueResult.cs index b1eb551..c09fdb6 100644 --- a/HopFrame.Api/Models/SingleValueResult.cs +++ b/HopFrame.Api/Models/SingleValueResult.cs @@ -1,13 +1,13 @@ namespace HopFrame.Api.Models; -public struct SingleValueResult(T value) { - public T Value { get; set; } = value; +public struct SingleValueResult(TValue value) { + public TValue Value { get; set; } = value; - public static implicit operator T(SingleValueResult v) { + public static implicit operator TValue(SingleValueResult v) { return v.Value; } - public static implicit operator SingleValueResult(T v) { - return new SingleValueResult(v); + public static implicit operator SingleValueResult(TValue v) { + return new SingleValueResult(v); } } \ No newline at end of file diff --git a/HopFrame.Security/Services/IUserService.cs b/HopFrame.Security/Services/IUserService.cs index b9fa6a8..5109dea 100644 --- a/HopFrame.Security/Services/IUserService.cs +++ b/HopFrame.Security/Services/IUserService.cs @@ -24,4 +24,6 @@ public interface IUserService { Task DeleteUser(User user); Task CheckUserPassword(User user, string password); + + Task ChangePassword(User user, string password); } \ No newline at end of file diff --git a/HopFrame.Security/Services/Implementation/UserService.cs b/HopFrame.Security/Services/Implementation/UserService.cs index 8be3df2..0e19b58 100644 --- a/HopFrame.Security/Services/Implementation/UserService.cs +++ b/HopFrame.Security/Services/Implementation/UserService.cs @@ -113,4 +113,16 @@ internal sealed class UserService(TDbContext context) : IUserService return entry.Password == hash; } + + public async Task ChangePassword(User user, string password) { + var entry = await context.Users + .Where(entry => entry.Id == user.Id.ToString()) + .SingleOrDefaultAsync(); + + if (entry is null) return; + + var hash = EncryptionManager.Hash(password, Encoding.Default.GetBytes(user.CreatedAt.ToString(CultureInfo.InvariantCulture))); + entry.Password = hash; + await context.SaveChangesAsync(); + } } \ No newline at end of file diff --git a/HopFrame.Web/Pages/Administration/Components/HopIconDisplay.razor b/HopFrame.Web/Pages/Administration/Components/HopIconDisplay.razor new file mode 100644 index 0000000..48e8c66 --- /dev/null +++ b/HopFrame.Web/Pages/Administration/Components/HopIconDisplay.razor @@ -0,0 +1,76 @@ +@switch (Type) { + case HopIcon.Reload: + + + + + break; + + case HopIcon.ArrowUp: + + + + break; + + case HopIcon.ArrowDown: + + + + break; + + case HopIcon.Cross: + + + + break; + + case HopIcon.User: + + + + break; + + case HopIcon.Group: + + + + break; + + case HopIcon.Logout: + + + + + break; +} + + + +@code { + [Parameter] public HopIcon Type { get; set; } + [Parameter] public bool NavIcon { get; set; } + + public enum HopIcon { + Reload, + ArrowUp, + ArrowDown, + User, + Group, + Logout, + Cross + } + + private string GetClass() { + return NavIcon ? "bi-nav" : "bi"; + } +} \ No newline at end of file diff --git a/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor.css b/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor.css index 038baf1..d49e4b7 100644 --- a/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor.css +++ b/HopFrame.Web/Pages/Administration/Layout/AdminLayout.razor.css @@ -21,20 +21,20 @@ main { align-items: center; } - .top-row ::deep a, .top-row ::deep .btn-link { - white-space: nowrap; - margin-left: 1.5rem; - text-decoration: none; - } +.top-row ::deep a, .top-row ::deep .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + text-decoration: none; +} - .top-row ::deep a:hover, .top-row ::deep .btn-link:hover { - text-decoration: underline; - } +.top-row ::deep a:hover, .top-row ::deep .btn-link:hover { + text-decoration: underline; +} - .top-row ::deep a:first-child { - overflow: hidden; - text-overflow: ellipsis; - } +.top-row ::deep a:first-child { + overflow: hidden; + text-overflow: ellipsis; +} @media (max-width: 640.98px) { .top-row { @@ -88,9 +88,9 @@ main { z-index: 1000; } - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; +} diff --git a/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor b/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor index 0c92c55..68690bd 100644 --- a/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor +++ b/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor @@ -1,7 +1,9 @@ @using Microsoft.AspNetCore.Components.Routing +@using HopFrame.Web.Pages.Administration.Components + @@ -11,26 +13,19 @@ diff --git a/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor.css b/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor.css index 4e15395..7a71600 100644 --- a/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor.css +++ b/HopFrame.Web/Pages/Administration/Layout/AdminMenu.razor.css @@ -17,7 +17,7 @@ .top-row { height: 3.5rem; - background-color: rgba(0,0,0,0.4); + background-color: rgba(0, 0, 0, 0.4); } .navbar-brand { @@ -34,50 +34,38 @@ background-size: cover; } -.bi-house-door-fill-nav-menu { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E"); -} - -.bi-plus-square-fill-nav-menu { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E"); -} - -.bi-list-nested-nav-menu { - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E"); -} - .nav-item { font-size: 0.9rem; padding-bottom: 0.5rem; } - .nav-item:first-of-type { - padding-top: 1rem; - } +.nav-item:first-of-type { + padding-top: 1rem; +} - .nav-item:last-of-type { - padding-bottom: 1rem; - } +.nav-item:last-of-type { + padding-bottom: 1rem; +} - .nav-item ::deep .nav-link { - color: #d7d7d7; - background: none; - border: none; - border-radius: 4px; - height: 3rem; - display: flex; - align-items: center; - line-height: 3rem; - width: 100%; - } +.nav-item ::deep .nav-link { + color: #d7d7d7; + background: none; + border: none; + border-radius: 4px; + height: 3rem; + display: flex; + align-items: center; + line-height: 3rem; + width: 100%; +} .nav-item ::deep a.active { - background-color: rgba(255,255,255,0.37); + background-color: rgba(255, 255, 255, 0.37); color: white; } .nav-item ::deep .nav-link:hover { - background-color: rgba(255,255,255,0.1); + background-color: rgba(255, 255, 255, 0.1); color: white; } diff --git a/HopFrame.Web/Pages/Administration/UserEditPage.razor b/HopFrame.Web/Pages/Administration/UserEditPage.razor index dcf5558..f15eec3 100644 --- a/HopFrame.Web/Pages/Administration/UserEditPage.razor +++ b/HopFrame.Web/Pages/Administration/UserEditPage.razor @@ -8,6 +8,7 @@ @using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Forms @using HopFrame.Web.Components +@using HopFrame.Web.Pages.Administration.Components @layout AdminLayout @rendermode InteractiveServer @@ -34,6 +35,10 @@ +
+ + +
@@ -43,9 +48,7 @@ @foreach (var group in _groups) {
  • @group.Name.Replace("group.", "") @@ -78,9 +81,7 @@ @foreach (var perm in User.Permissions.Where(perm => !perm.PermissionName.StartsWith("group."))) {
  • @perm.PermissionName @@ -119,6 +120,7 @@ private IList _allGroups = new List(); private string _selectedGroup; private string _permissionToAdd; + private string _password; protected override async Task OnInitializedAsync() { if (Guid.TryParse(UserId, out var guid)) { @@ -165,6 +167,10 @@ if (result.IsConfirmed) { await Users.UpdateUser(User); + if (!string.IsNullOrWhiteSpace(_password)) { + await Users.ChangePassword(User, _password); + } + await Alerts.FireAsync(new SweetAlertOptions { Title = "User edited!", Icon = SweetAlertIcon.Success, diff --git a/HopFrame.Web/Pages/Administration/UsersPage.razor b/HopFrame.Web/Pages/Administration/UsersPage.razor index 13e7c20..1d61529 100644 --- a/HopFrame.Web/Pages/Administration/UsersPage.razor +++ b/HopFrame.Web/Pages/Administration/UsersPage.razor @@ -16,13 +16,10 @@
    -

    +

    Users administration - - - - - + +

    @@ -36,75 +33,48 @@ - - + - - - - + + @if (_hasEditPrivileges || _hasDeletePrivileges) { - + } @foreach (var user in _users) { - + - + @if (_hasEditPrivileges || _hasDeletePrivileges) {
    # - E-Mail + # + E-Mail @if (_currentOrder == OrderType.Email) { - @if (_currentOrderDirection == OrderDirection.Asc) { - - - - } - else { - - - - } + } - Username + + Username @if (_currentOrder == OrderType.Username) { - @if (_currentOrderDirection == OrderDirection.Asc) { - - - - } - else { - - - - } + } - Registered + + Registered @if (_currentOrder == OrderType.Registered) { - @if (_currentOrderDirection == OrderDirection.Asc) { - - - - } - else { - - - - } + } Primary GroupPrimary GroupActionsActions
    @user.Id@user.Id @user.Email @user.Username @user.CreatedAt @GetFriendlyGroupName(user)
    @if (_hasEditPrivileges) { } - + @if (_hasDeletePrivileges) { } @@ -210,7 +180,7 @@ Timer = 1500, ShowConfirmButton = false }); - + Reload(); } } diff --git a/HopFrame.Web/Pages/Administration/UsersPage.razor.css b/HopFrame.Web/Pages/Administration/UsersPage.razor.css index 2202636..fa12d28 100644 --- a/HopFrame.Web/Pages/Administration/UsersPage.razor.css +++ b/HopFrame.Web/Pages/Administration/UsersPage.razor.css @@ -3,3 +3,15 @@ flex-direction: row; justify-content: space-between; } + +th, h3 { + user-select: none; +} + +.reload, .sorter { + cursor: pointer; +} + +.bold { + font-weight: bold; +} diff --git a/HopFrame.Web/ServiceCollectionExtensions.cs b/HopFrame.Web/ServiceCollectionExtensions.cs index 744e3f5..d98b951 100644 --- a/HopFrame.Web/ServiceCollectionExtensions.cs +++ b/HopFrame.Web/ServiceCollectionExtensions.cs @@ -13,7 +13,11 @@ public static class ServiceCollectionExtensions { services.AddHttpClient(); services.AddScoped>(); services.AddTransient(); + + // Component library's services.AddSweetAlert2(); + + //TODO: Use https://blazorstrap.io/V5/V5 services.AddHopFrameAuthentication(); diff --git a/HopFrame.sln b/HopFrame.sln index 8ef0dbd..453dbcf 100644 --- a/HopFrame.sln +++ b/HopFrame.sln @@ -4,7 +4,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Database", "HopFra EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{58703056-8DAD-4221-BBE3-42425D2F4929}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseTest", "DatabaseTest\DatabaseTest.csproj", "{921159CE-AF75-44C3-A3F9-6B9B1A4E85CF}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RestApiTest", "RestApiTest\RestApiTest.csproj", "{921159CE-AF75-44C3-A3F9-6B9B1A4E85CF}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HopFrame.Security", "HopFrame.Security\HopFrame.Security.csproj", "{7F82E1C6-4A42-4337-9E03-2EE6429D004F}" EndProject diff --git a/DatabaseTest/.gitignore b/RestApiTest/.gitignore similarity index 100% rename from DatabaseTest/.gitignore rename to RestApiTest/.gitignore diff --git a/DatabaseTest/Controllers/TestController.cs b/RestApiTest/Controllers/TestController.cs similarity index 92% rename from DatabaseTest/Controllers/TestController.cs rename to RestApiTest/Controllers/TestController.cs index 4e74da0..f13bb74 100644 --- a/DatabaseTest/Controllers/TestController.cs +++ b/RestApiTest/Controllers/TestController.cs @@ -3,7 +3,7 @@ using HopFrame.Security.Authorization; using HopFrame.Security.Claims; using Microsoft.AspNetCore.Mvc; -namespace DatabaseTest.Controllers; +namespace RestApiTest.Controllers; [ApiController] [Route("test")] diff --git a/DatabaseTest/DatabaseContext.cs b/RestApiTest/DatabaseContext.cs similarity index 72% rename from DatabaseTest/DatabaseContext.cs rename to RestApiTest/DatabaseContext.cs index c43f7e8..fed4058 100644 --- a/DatabaseTest/DatabaseContext.cs +++ b/RestApiTest/DatabaseContext.cs @@ -1,12 +1,12 @@ using HopFrame.Database; using Microsoft.EntityFrameworkCore; -namespace DatabaseTest; +namespace RestApiTest; public class DatabaseContext : HopDbContextBase { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); - optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\DatabaseTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); + optionsBuilder.UseSqlite("Data Source=C:\\Users\\Remote\\Documents\\Projekte\\HopFrame\\RestApiTest\\bin\\Debug\\net8.0\\test.db;Mode=ReadWrite;"); } } \ No newline at end of file diff --git a/DatabaseTest/Program.cs b/RestApiTest/Program.cs similarity index 98% rename from DatabaseTest/Program.cs rename to RestApiTest/Program.cs index 845e92a..bfcbc38 100644 --- a/DatabaseTest/Program.cs +++ b/RestApiTest/Program.cs @@ -1,4 +1,4 @@ -using DatabaseTest; +using RestApiTest; using HopFrame.Api.Extensions; using Microsoft.OpenApi.Models; diff --git a/DatabaseTest/Properties/launchSettings.json b/RestApiTest/Properties/launchSettings.json similarity index 100% rename from DatabaseTest/Properties/launchSettings.json rename to RestApiTest/Properties/launchSettings.json diff --git a/DatabaseTest/DatabaseTest.csproj b/RestApiTest/RestApiTest.csproj similarity index 100% rename from DatabaseTest/DatabaseTest.csproj rename to RestApiTest/RestApiTest.csproj diff --git a/DatabaseTest/appsettings.json b/RestApiTest/appsettings.json similarity index 100% rename from DatabaseTest/appsettings.json rename to RestApiTest/appsettings.json diff --git a/docs/Diagrams/Models/ApiModels.puml b/docs/Diagrams/Models/ApiModels.puml new file mode 100644 index 0000000..2019855 --- /dev/null +++ b/docs/Diagrams/Models/ApiModels.puml @@ -0,0 +1,34 @@ +@startuml ApiModels + +namespace HopFrame.Security { + class UserLogin { + +Email: string + +Password: string + } + + class UserRegister { + +Username: string + +Email: string + +Password: string + } +} + +namespace HopFrame.Web { + class RegisterData { + +RepeatedPassword: string + } +} + +namespace HopFrame.Api { + class SingleValueResult { + +Value: TValue + } + + class UserPasswordValidation { + +Password: string + } +} + +UserRegister <|-- RegisterData + +@enduml \ No newline at end of file diff --git a/docs/Diagrams/Models/BaseModels.puml b/docs/Diagrams/Models/BaseModels.puml new file mode 100644 index 0000000..62706fc --- /dev/null +++ b/docs/Diagrams/Models/BaseModels.puml @@ -0,0 +1,37 @@ +@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 new file mode 100644 index 0000000..fc3a7b9 --- /dev/null +++ b/docs/Diagrams/Models/DatabaseModels.puml @@ -0,0 +1,41 @@ +@startuml DatabaseModels +set namespaceSeparator none + +namespace HopFrame.Database { + class UserEntry { + +Id: string + +Username: string + +Email: string + +Password: string + +CreatedAt: DateTime + } + + class TokenEntry { + {static} +RefreshTokenType: int = 0 + {static} +AccessTokenType: int = 1 + + +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/README.md b/docs/Diagrams/Models/README.md new file mode 100644 index 0000000..f7f6ab8 --- /dev/null +++ b/docs/Diagrams/Models/README.md @@ -0,0 +1,21 @@ +# Models for HopFrame + +This page shows all models that HopFrame uses. + + +## Base Models +These are the models used by the various database services. + +![](img/BaseModels.svg) + + +## API Models +These are the models used by the REST API and the Blazor API. + +![](img/ApiModels.svg) + + +## Database Models +These are the models that correspond to the scheme in the Database + +![](img/DatabaseModels.svg) diff --git a/docs/Diagrams/Models/img/ApiModels.svg b/docs/Diagrams/Models/img/ApiModels.svg new file mode 100644 index 0000000..82ff3c0 --- /dev/null +++ b/docs/Diagrams/Models/img/ApiModels.svg @@ -0,0 +1 @@ +HopFrameSecurityWebApiUserLoginEmail: stringPassword: stringUserRegisterUsername: stringEmail: stringPassword: stringRegisterDataRepeatedPassword: 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 new file mode 100644 index 0000000..89ed8d2 --- /dev/null +++ b/docs/Diagrams/Models/img/BaseModels.svg @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..06aa882 --- /dev/null +++ b/docs/Diagrams/Models/img/DatabaseModels.svg @@ -0,0 +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