diff --git a/BLAZAM/BLAZAM - Backup.csproj b/BLAZAM/BLAZAM - Backup.csproj new file mode 100644 index 000000000..d3f8fdfae --- /dev/null +++ b/BLAZAM/BLAZAM - Backup.csproj @@ -0,0 +1,142 @@ + + + + net8.0 + enable + enable + false + 1.0.7 + 2024.11.02.0114 + false + BLAZAM + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + True + True + Resources.resx + + + + + + Never + + + PreserveNewest + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + PreserveNewest + + + PreserveNewest + + + + + + + diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 65a731a0b..b335af3c2 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -5,8 +5,8 @@ enable enable false - 1.0.7 - 2024.10.31.0016 + 1.1.0 + 2024.11.13.2234 false BLAZAM False @@ -58,6 +58,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/BLAZAM/Pages/Computers/ViewBitLocker.razor b/BLAZAM/Pages/Computers/ViewBitLocker.razor index b70869a38..6d4f2cb42 100644 --- a/BLAZAM/Pages/Computers/ViewBitLocker.razor +++ b/BLAZAM/Pages/Computers/ViewBitLocker.razor @@ -4,9 +4,7 @@ - - - + diff --git a/BLAZAM/Pages/Computers/ViewComputer.razor b/BLAZAM/Pages/Computers/ViewComputer.razor index c5cdc78e9..a6c329f3a 100644 --- a/BLAZAM/Pages/Computers/ViewComputer.razor +++ b/BLAZAM/Pages/Computers/ViewComputer.razor @@ -24,9 +24,7 @@ OnUnlock="@Unlock" OnShowHistory="@(()=>{ChangeHistoryModal?.ShowAsync();})" OnShowPermissions="@(()=>{EffectivePermissionsModal?.ShowAsync();})" /> - - - + @@ -231,9 +229,7 @@ } } - - - + @@ -292,7 +288,7 @@ Computer.Delete(); SnackBarService.Success(Computer.CanonicalName + " has been deleted."); await AuditLogger.Computer.Deleted(Computer); - _ = OUNotificationService.PostAsync(Computer, NotificationType.Delete); + _ = NotificationGenerationService.PostAsync(Computer, NotificationType.Delete, CurrentUser.State); Nav.NavigateTo("/users/search"); @@ -332,7 +328,7 @@ } if (changes.Any(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName)) { - _ = OUNotificationService.PostAsync(Computer, NotificationType.Modify); + _ = NotificationGenerationService.PostAsync(Computer, NotificationType.Modify, CurrentUser.State); await AuditLogger.User.Changed(Computer, changes.Where(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName).ToList()); } diff --git a/BLAZAM/Pages/Configure/Audit.razor b/BLAZAM/Pages/Configure/Audit.razor index e4a5c8fd9..e62dcb98a 100644 --- a/BLAZAM/Pages/Configure/Audit.razor +++ b/BLAZAM/Pages/Configure/Audit.razor @@ -11,8 +11,8 @@ -Audit -

Audit

+@AppLocalization["Audit"] +@AppLocalization["Audit"] diff --git a/BLAZAM/Pages/Configure/Fields.razor b/BLAZAM/Pages/Configure/Fields.razor index 1d1e5ca48..ee92a9053 100644 --- a/BLAZAM/Pages/Configure/Fields.razor +++ b/BLAZAM/Pages/Configure/Fields.razor @@ -3,6 +3,9 @@ @inherits DatabaseComponentBase @attribute [Authorize(Roles = UserRoles.SuperAdmin)] +@AppLocalization["Fields"] + +@AppLocalization["Fields"] - @AppLocalization["Fields"] - - + diff --git a/BLAZAM/Pages/Configure/Permissions.razor b/BLAZAM/Pages/Configure/Permissions.razor index 5a08d27be..bfb88e993 100644 --- a/BLAZAM/Pages/Configure/Permissions.razor +++ b/BLAZAM/Pages/Configure/Permissions.razor @@ -3,8 +3,8 @@ @attribute [Authorize(Roles = UserRoles.SuperAdmin)] @inherits TabbedAppComponentBase +@AppLocalization["Permissions"] -Permissions @@ -48,7 +48,7 @@ @if (Monitor.DirectoryConnectionStatus == ServiceConnectionState.Up) { - + } @@ -76,6 +76,22 @@ + + + + @if (Monitor.DirectoryConnectionStatus == ServiceConnectionState.Up) + { + + + } + + + + + @AppLocalization["Global Settings"] + + + diff --git a/BLAZAM/Pages/Configure/Settings.razor b/BLAZAM/Pages/Configure/Settings.razor index fb19aa314..8d31f69ed 100644 --- a/BLAZAM/Pages/Configure/Settings.razor +++ b/BLAZAM/Pages/Configure/Settings.razor @@ -4,8 +4,8 @@ @attribute [Authorize(Roles = UserRoles.SuperAdmin)] @inherits TabbedAppComponentBase +@AppLocalization["Settings"] -Settings diff --git a/BLAZAM/Pages/Configure/Templates.razor b/BLAZAM/Pages/Configure/Templates.razor index 9113ca5f2..86d0946aa 100644 --- a/BLAZAM/Pages/Configure/Templates.razor +++ b/BLAZAM/Pages/Configure/Templates.razor @@ -127,6 +127,8 @@ + +@AppLocalization["Templates"] @if (Templates.Count() > 0) { diff --git a/BLAZAM/Pages/Error/UnhandledExceptionPage.razor b/BLAZAM/Pages/Error/UnhandledExceptionPage.razor index 02206eff5..3a5c3ecef 100644 --- a/BLAZAM/Pages/Error/UnhandledExceptionPage.razor +++ b/BLAZAM/Pages/Error/UnhandledExceptionPage.razor @@ -40,7 +40,10 @@ } + else + { To see error details, set DebugMode to true in appsettings.json in the Blazam installation directory. + } } catch (Exception ex) diff --git a/BLAZAM/Pages/Groups/ConfirmNewGroup.razor b/BLAZAM/Pages/Groups/ConfirmNewGroup.razor index 018398851..cb1db960f 100644 --- a/BLAZAM/Pages/Groups/ConfirmNewGroup.razor +++ b/BLAZAM/Pages/Groups/ConfirmNewGroup.razor @@ -1,5 +1,5 @@ @inherits AppComponentBase -@inject OUNotificationService OUNotificationService +@inject NotificationGenerationService OUNotificationService Confirm Group Creation @@ -43,7 +43,7 @@ } await AuditLogger.Group.Created(Group); - _ = OUNotificationService.PostAsync(Group, NotificationType.Create); + _ = OUNotificationService.PostAsync(Group, NotificationType.Create,CurrentUser.State); var commitJob = Group.CommitChanges(); await Confirmed.InvokeAsync(Group); diff --git a/BLAZAM/Pages/Groups/ViewGroup.razor b/BLAZAM/Pages/Groups/ViewGroup.razor index 820badf1b..fddddd9e3 100644 --- a/BLAZAM/Pages/Groups/ViewGroup.razor +++ b/BLAZAM/Pages/Groups/ViewGroup.razor @@ -20,7 +20,7 @@ OnShowHistory="@(()=>{ChangeHistoryModal?.ShowAsync();})" OnShowPermissions="@(()=>{EffectivePermissionsModal?.ShowAsync();})" OnToggleEditMode="@ToggleEditMode" /> - + @@ -161,7 +161,7 @@ { await AuditLogger.User.Assigned(assignment.Member, assignment.Group); await AuditLogger.Group.MemberAdded(assignment.Group, assignment.Member); - _ = OUNotificationService.PostAsync(assignment.Member, NotificationType.GroupAssignment, target: Group); + _ = NotificationGenerationService.PostAsync(assignment.Member, NotificationType.GroupAssignment, CurrentUser.State, Group); } @@ -169,12 +169,12 @@ { await AuditLogger.User.Unassigned(assignment.Member, assignment.Group); await AuditLogger.Group.MemberRemoved(assignment.Group, assignment.Member); - _ = OUNotificationService.PostAsync(assignment.Member, NotificationType.GroupAssignment, target: Group); + _ = NotificationGenerationService.PostAsync(assignment.Member, NotificationType.GroupAssignment, CurrentUser.State, Group); } if (changes.Any(c => c.Field != "member")) { - _ = OUNotificationService.PostAsync(Group, NotificationType.Modify); + _ = NotificationGenerationService.PostAsync(Group, NotificationType.Modify, CurrentUser.State); await AuditLogger.Group.Changed(Group, changes.Where(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName).ToList()); } //await AuditLogger.Group.Changed(Group, Group.Changes); @@ -205,7 +205,7 @@ Group.Delete(); SnackBarService.Success(Group.CanonicalName + " has been deleted."); await AuditLogger.Group.Deleted(Group); - _ = OUNotificationService.PostAsync(Group, NotificationType.Delete); + _ = NotificationGenerationService.PostAsync(Group, NotificationType.Delete, CurrentUser.State); //Group = null; Nav.NavigateTo("/groups/search"); diff --git a/BLAZAM/Pages/Login.razor b/BLAZAM/Pages/Login.razor index 0ebc4f7aa..6c38d2271 100644 --- a/BLAZAM/Pages/Login.razor +++ b/BLAZAM/Pages/Login.razor @@ -89,11 +89,7 @@ - - @**@ - + diff --git a/BLAZAM/Pages/OU/ConfirmNewOU.razor b/BLAZAM/Pages/OU/ConfirmNewOU.razor index 59de0d9dc..e004b666f 100644 --- a/BLAZAM/Pages/OU/ConfirmNewOU.razor +++ b/BLAZAM/Pages/OU/ConfirmNewOU.razor @@ -1,5 +1,5 @@ @inherits AppComponentBase -@inject OUNotificationService OUNotificationService +@inject NotificationGenerationService OUNotificationService Confirm OU Creation @@ -30,7 +30,7 @@ await OU.CommitChangesAsync(); SnackBarService.Success("OU created"); await AuditLogger.OU.Created(OU); - _ = OUNotificationService.PostAsync(OU, NotificationType.Create); + _ = OUNotificationService.PostAsync(OU, NotificationType.Create, CurrentUser.State); await Confirmed.InvokeAsync(OU); Nav.NavigateTo("/ou/create",true); } diff --git a/BLAZAM/Pages/OU/CreateOU.razor b/BLAZAM/Pages/OU/CreateOU.razor index a9be162a4..623bacf15 100644 --- a/BLAZAM/Pages/OU/CreateOU.razor +++ b/BLAZAM/Pages/OU/CreateOU.razor @@ -1,49 +1,37 @@ @page "/ou/create" @inherits TabbedAppComponentBase @attribute [Authorize] +@AppLocalization["Create OU"] -Create OU - - - - - + + + + + - - @* - @context.Name - *@ - + - + Next + + + + Create + + + + + + + + + + Confirm + + + - - - - - - - Next - - - - Create - - - - - - - - - - Confirm - - - - @@ -53,11 +41,6 @@ int selectedStep; - - - - - string newOUName; IADOrganizationalUnit? parentOU; IADOrganizationalUnit? newOU; @@ -101,7 +84,7 @@ async void CreateNewOU() { LoadingData = true; - await InvokeAsync(StateHasChanged); + newOU = parentOU?.CreateOU(newOUName); @@ -109,7 +92,7 @@ selectedStep = 1; - LoadingData = true; + LoadingData = false; await InvokeAsync(StateHasChanged); } diff --git a/BLAZAM/Pages/OU/ViewOU.razor b/BLAZAM/Pages/OU/ViewOU.razor index 6f46faa83..732ee10ed 100644 --- a/BLAZAM/Pages/OU/ViewOU.razor +++ b/BLAZAM/Pages/OU/ViewOU.razor @@ -1,5 +1,4 @@ @inherits DirectoryEntryViewBase -@inject OUNotificationService OUNotificationService @OU?.CanonicalName @@ -11,9 +10,7 @@ OnMove="@(()=>{MoveToModal?.ShowAsync();})" OnRename="@(()=>{RenameModal?.ShowAsync();})" OnToggleEditMode="ToggleEditMode" /> - - - + @@ -89,21 +86,27 @@ } async void SaveChanges() { - if (await MessageService.Confirm("Are you sure you want to save the changes?", "Save Changes")) + if (OU != null) { - var changes = OU?.Changes; - await OU.CommitChangesAsync(); - EditMode = false; - //Nav.WarnOnNavigation = false; - await AuditLogger.OU.Changed(OU, changes); - _ = OUNotificationService.PostAsync(OU, NotificationType.Modify); + if (await MessageService.Confirm("Are you sure you want to save the changes?", "Save Changes")) + { + var changes = OU?.Changes; + await OU.CommitChangesAsync(); + EditMode = false; + //Nav.WarnOnNavigation = false; + await AuditLogger.OU.Changed(OU, changes); + _ = NotificationGenerationService.PostAsync(OU, NotificationType.Modify, CurrentUser.State); - SnackBarService.Success("The changes made to this ou have been saved."); - await RefreshEntryComponents(); + SnackBarService.Success(AppLocalization["The changes made to this ou have been saved."]); + await RefreshEntryComponents(); + } + } + else + { + SnackBarService.Error("OU is null"); } - } void ChildClicked(DataGridRowClickEventArgs args) { @@ -118,7 +121,7 @@ OU.Delete(); SnackBarService.Success(OU.CanonicalName + " has been deleted."); await AuditLogger.OU.Deleted(OU); - _ = OUNotificationService.PostAsync(OU, NotificationType.Delete); + _ = NotificationGenerationService.PostAsync(OU, NotificationType.Delete, CurrentUser.State); Nav.NavigateTo("/ou/search"); diff --git a/BLAZAM/Pages/Printers/ViewPrinter.razor b/BLAZAM/Pages/Printers/ViewPrinter.razor index a978c09d2..518bb6994 100644 --- a/BLAZAM/Pages/Printers/ViewPrinter.razor +++ b/BLAZAM/Pages/Printers/ViewPrinter.razor @@ -16,9 +16,7 @@ OnMove="@(()=>{MoveToModal?.ShowAsync();})" OnRename="@(()=>{RenameModal?.ShowAsync();})" OnToggleEditMode="ToggleEditMode" /> - - - + @@ -93,9 +91,7 @@ } } - - - + diff --git a/BLAZAM/Pages/Recycle Bin/RecycleBin.razor b/BLAZAM/Pages/Recycle Bin/RecycleBin.razor index d23ec17d0..5de689e1f 100644 --- a/BLAZAM/Pages/Recycle Bin/RecycleBin.razor +++ b/BLAZAM/Pages/Recycle Bin/RecycleBin.razor @@ -1,8 +1,8 @@ @page "/recyclebin" @inherits AppComponentBase @attribute [Authorize(Roles = UserRoles.SuperAdmin)] +@AppLocalization["Recycle Bin"] -Recycle Bin Confirm User Creation @@ -285,7 +285,7 @@ else confirmed = true; await Confirmed.InvokeAsync(); await AuditLogger.User.Created(User); - _ = OUNotificationService.PostAsync(User, NotificationType.Create); + _ = OUNotificationService.PostAsync(User, NotificationType.Create, CurrentUser.State); try { diff --git a/BLAZAM/Pages/Users/CreateUser.razor b/BLAZAM/Pages/Users/CreateUser.razor index bef809d44..e7e962ec4 100644 --- a/BLAZAM/Pages/Users/CreateUser.razor +++ b/BLAZAM/Pages/Users/CreateUser.razor @@ -6,7 +6,8 @@ { } -Create User +@AppLocalization["Create User"] + - + - } - - - - - - - - @if (MoveToModal?.IsShown == true) - { - - } - - - @if (RenameModal?.IsShown == true) - { - {Renamed(renamedUser);}) User="User" /> - } - - - @if (ChangePasswordModal?.IsShown == true) - { - - } - - - @if (LogOnToModal?.IsShown == true) - { - - } - - - @if (LogonHoursModal?.IsShown == true) - { - - } - + + + + + + + + @if (MoveToModal?.IsShown == true) + { + + } + + + @if (RenameModal?.IsShown == true) + { + {Renamed(renamedUser);}) User="User" /> + } + + + @if (ChangePasswordModal?.IsShown == true) + { + + } + + + @if (LogOnToModal?.IsShown == true) + { + + } + + + @if (LogonHoursModal?.IsShown == true) + { + + } + - - + + -
+
- {showRemoveThumbnail=true;}) - @onmouseleave=@(()=>{showRemoveThumbnail=false;})> + {showRemoveThumbnail=true;}) + @onmouseleave=@(()=>{showRemoveThumbnail=false;})> - @if (User?.ThumbnailPhoto != null) + @if (User?.ThumbnailPhoto != null) + { + + @if (showRemoveThumbnail && CanEditField(ActiveDirectoryFields.Thumbnail)) { - - @if (showRemoveThumbnail && User.CanEditField(ActiveDirectoryFields.Thumbnail)) - { - - - } + } - else - { - - } - @if (showRemoveThumbnail && User?.CanEditField(ActiveDirectoryFields.Thumbnail) == true) - { - {UploadThumbnailModal?.ShowAsync();}) - Style="position:absolute !important;width:40px;height:40px;padding:2px;top:10px;right:10px" - Color=Color.Primary - Icon="@Icons.Material.Filled.Upload" /> - } - + } + else + { + - - @AppLocalization["Created"]: - - + } + @if (showRemoveThumbnail && User?.CanEditField(ActiveDirectoryFields.Thumbnail) == true) + { + {UploadThumbnailModal?.ShowAsync();}) + Style="position:absolute !important;width:40px;height:40px;padding:2px;top:10px;right:10px" + Color=Color.Primary + Icon="@Icons.Material.Filled.Upload" /> + } + - + + @AppLocalization["Created"]: + + - + - @AppLocalization["Last Change"]: - + - + @AppLocalization["Last Change"]: + - + - + - @AppLocalization["Pass Change"]: - - + + @AppLocalization["Pass Change"]: + + - - + - @AppLocalization["Last Logon"]: - - - - @if (User?.LockedOut == true) - { - - @AppLocalization["Lockout Time"]: - - - - } + + + @AppLocalization["Last Logon"]: + + + + @if (User?.LockedOut == true) + { - @AppLocalization["OU"]: + @AppLocalization["Lockout Time"]: - - @User?.OU.ToPrettyOu() + + } + + @AppLocalization["OU"]: + + @User?.OU.ToPrettyOu() + - - @AppLocalization["Groups"]: - {AssignToModal?.ShowAsync();}) Model="User" /> - - - @if (User.Disabled) - { - @AppLocalization["User is disabled"] - } - @if (User.LockedOut) - { - @AppLocalization["User is locked out"] - } - -
- - + @AppLocalization["Groups"]: + {AssignToModal?.ShowAsync();}) Model="User" /> + -
+ @if (User.Disabled) + { + @AppLocalization["User is disabled"] + } + @if (User.LockedOut) + { + @AppLocalization["User is locked out"] + } - +
+
+ + +
- - + - - + + - - @if (EditMode && User?.NewEntry == false) - { - - To modify the user's name click the rename button in the toolbar/gear menu - - } -
+ + -
+ + @if (EditMode && User?.NewEntry == false) + { + + To modify the user's name click the rename button in the toolbar/gear menu + + } +
- +
+ - - - - + + + - @if (User?.NewEntry == true) - { - - - - } + - - - - + @if (User?.NewEntry == true) + { + + + + } + + + - @if (User.CanReadField(ActiveDirectoryFields.AccountExpires)) - { - + - } - + @if (CanReadField(ActiveDirectoryFields.AccountExpires)) + { + + - @if (User.CanReadField(ActiveDirectoryFields.LogOnTo)) - { - - @AppLocalization["Log On To"] - + } - } + - @if (User.CanReadField(ActiveDirectoryFields.LogonHours)) - { - - @AppLocalization["Logon Hours"] - + @if (CanReadField(ActiveDirectoryFields.LogOnTo)) + { + + @AppLocalization["Log On To"] + - } - + } + @if (CanReadField(ActiveDirectoryFields.LogonHours)) + { + + @AppLocalization["Logon Hours"] + + } + @if (User.CanSetPassword) + { + + + } - @if (EditMode && !User.NewEntry) - { - - To modify the account name or email click the rename button in the toolbar/gear menu - + + @if (EditMode && !User.NewEntry) + { - } -
+ + To modify the account name or email click the rename button in the toolbar/gear menu + + } +
- -
-
+ +
+
- @if (User.CanReadField(ActiveDirectoryFields.EmployeeId) || - User.CanReadField(ActiveDirectoryFields.Department) || - User.CanReadField(ActiveDirectoryFields.Company) || - User.CanReadField(ActiveDirectoryFields.Title) || - User.CanReadField(ActiveDirectoryFields.PhysicalDeliveryOffice) - ) - { -
- - @if (User.CanReadField(ActiveDirectoryFields.Description)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.EmployeeId)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.Department)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.Company)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.Title)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.PhysicalDeliveryOffice)) - { - - } - -
- } - @if (User.CanReadField(ActiveDirectoryFields.HomePhone) || - User.CanReadField(ActiveDirectoryFields.StreetAddress) || - User.CanReadField(ActiveDirectoryFields.POBox) || - User.CanReadField(ActiveDirectoryFields.City) || - User.CanReadField(ActiveDirectoryFields.State) || - User.CanReadField(ActiveDirectoryFields.PostalCode) - ) - { -
- + @if (CanReadField(ActiveDirectoryFields.EmployeeId) || + CanReadField(ActiveDirectoryFields.Department) || + CanReadField(ActiveDirectoryFields.Company) || + CanReadField(ActiveDirectoryFields.Title) || + CanReadField(ActiveDirectoryFields.PhysicalDeliveryOffice) + ) + { +
+ - @if (User.CanReadField(ActiveDirectoryFields.HomePhone)) - { - + @if (CanReadField(ActiveDirectoryFields.Description)) + { + + } + @if (CanReadField(ActiveDirectoryFields.EmployeeId)) + { + + } + @if (CanReadField(ActiveDirectoryFields.Department)) + { + + } + @if (CanReadField(ActiveDirectoryFields.Company)) + { + + } + @if (CanReadField(ActiveDirectoryFields.Title)) + { + + } + @if (CanReadField(ActiveDirectoryFields.PhysicalDeliveryOffice)) + { + + } + +
+ } - } - @if (User.CanReadField(ActiveDirectoryFields.StreetAddress)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.POBox)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.City)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.State)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.PostalCode)) - { - - } -
+ @if (CanReadField(ActiveDirectoryFields.HomePhone) || + CanReadField(ActiveDirectoryFields.StreetAddress) || + CanReadField(ActiveDirectoryFields.POBox) || + CanReadField(ActiveDirectoryFields.City) || + CanReadField(ActiveDirectoryFields.State) || + CanReadField(ActiveDirectoryFields.PostalCode) + ) + { +
+ -
- } + @if (CanReadField(ActiveDirectoryFields.HomePhone)) + { + + } + @if (CanReadField(ActiveDirectoryFields.StreetAddress)) + { + + } + @if (CanReadField(ActiveDirectoryFields.POBox)) + { + + } + @if (CanReadField(ActiveDirectoryFields.City)) + { + + } + @if (CanReadField(ActiveDirectoryFields.State)) + { + + } + @if (CanReadField(ActiveDirectoryFields.PostalCode)) + { + + } + - @if (User.CanReadField(ActiveDirectoryFields.HomeDirectory) || - User.CanReadField(ActiveDirectoryFields.HomeDrive) || - User.CanReadField(ActiveDirectoryFields.ScriptPath) || - User.CanReadField(ActiveDirectoryFields.ProfilePath) - ) - { -
- +
+ } - @if (User.CanReadField(ActiveDirectoryFields.HomeDirectory)) - { - - - @if (!User.HomeDirectory.IsNullOrEmpty()) - { + @if (CanReadField(ActiveDirectoryFields.HomeDirectory) || + CanReadField(ActiveDirectoryFields.HomeDrive) || + CanReadField(ActiveDirectoryFields.ScriptPath) || + CanReadField(ActiveDirectoryFields.ProfilePath) + ) + { +
+ - - } - - - } - @if (User.CanReadField(ActiveDirectoryFields.HomeDrive)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.ScriptPath)) - { - - } - @if (User.CanReadField(ActiveDirectoryFields.ProfilePath)) - { - - } - + @if (CanReadField(ActiveDirectoryFields.HomeDirectory)) + { + -
- } + + @if (!User.HomeDirectory.IsNullOrEmpty()) + { - @if (User.CanReadAnyCustomFields && CustomFields != null && CustomFields.Count > 0) - { -
+ + } + + + } + @if (CanReadField(ActiveDirectoryFields.HomeDrive)) + { + + } + @if (CanReadField(ActiveDirectoryFields.ScriptPath)) + { + + } + @if (CanReadField(ActiveDirectoryFields.ProfilePath)) + { + + } + + +
+ } - @foreach (var field in CustomFields) + @if (User.CanReadAnyCustomFields && CustomFields != null && CustomFields.Count > 0) + { +
+ + @foreach (var field in CustomFields) + { + @if (CanReadField(field)) { - @if (User.CanReadField(field)) - { - + - } } + } -
- } +
+ } @@ -465,16 +491,15 @@ } - - - + + } @code { -#nullable disable warnings + #nullable disable warnings string password; [Parameter] @@ -505,10 +530,78 @@ } [Parameter] public EventCallback ConfirmPasswordChanged { get; set; } - + AccessLevel? selfAccessLevel; bool homeDirectoryExists; bool showRemoveThumbnail = false; IADUser User => DirectoryEntry as IADUser; + GlobalPermissionSettings? _globalPermissionSettings; + + private bool isSelf + { + get + { + if (_globalPermissionSettings != null) + { + if (selfAccessLevel != null) + { + return User.SamAccountName.Equals(CurrentUser.Username, StringComparison.InvariantCultureIgnoreCase); + } + } + return false; + } + } + + + private bool CanReadField(IActiveDirectoryField field) + { + if (!isSelf) + { + return User.CanReadField(field); + } + else + { + if (selfAccessLevel.FieldMap.Any(x => x.Field.Id == field.Id && x.FieldAccessLevel.Level > FieldAccessLevels.Deny.Level)) + { + return true; + } + else if (selfAccessLevel.FieldMap.Any(x => x.CustomField.Id == field.Id && x.FieldAccessLevel.Level > FieldAccessLevels.Deny.Level)) + { + return true; + } + else + { + return User.CanReadField(field); + } + } + } + + private bool CanEditField(IActiveDirectoryField field) + { + if (!isSelf) + { + return User.CanEditField(field); + } + else + { + if (selfAccessLevel.FieldMap.Any(x => x.Field.Id == field.Id && x.FieldAccessLevel.Level > FieldAccessLevels.Read.Level)) + { + return true; + } + else if (selfAccessLevel.FieldMap.Any(x => x.CustomField.Id == field.Id && x.FieldAccessLevel.Level > FieldAccessLevels.Read.Level)) + { + return true; + } + else + { + return User.CanEditField(field); + } + } + } + + + + + protected override async Task OnInitializedAsync() { @@ -517,6 +610,16 @@ await InvokeAsync(StateHasChanged); + + + if (Context != null) + { + _globalPermissionSettings = Context.GlobalPermissionSettings.FirstOrDefault(); + + } + selfAccessLevel = Context.AccessLevels.FirstOrDefault(x => x.Name == AccessLevel.SelfAccessLevelName); + + if (User.HomeDirectory != null) { try @@ -545,7 +648,7 @@ async void SaveChanges() { - if (await MessageService.Confirm("Are you sure you want to save the changes?")) + if (await MessageService.Confirm(AppLocalization["Are you sure you want to save the changes?"])) { SavingChanges = true; await RefreshEntryComponents(); @@ -563,7 +666,7 @@ { await AuditLogger.User.Assigned(assignment.Member, assignment.Group); await AuditLogger.Group.MemberAdded(assignment.Group, assignment.Member); - _ = OUNotificationService.PostAsync(User, NotificationType.GroupAssignment,target:assignment.Group); + _ = NotificationGenerationService.PostAsync(User, NotificationType.GroupAssignment, CurrentUser.State, assignment.Group); } @@ -571,12 +674,12 @@ { await AuditLogger.User.Unassigned(assignment.Member, assignment.Group); await AuditLogger.Group.MemberRemoved(assignment.Group, assignment.Member); - _ = OUNotificationService.PostAsync(User, NotificationType.GroupAssignment, target: assignment.Group); + _ = NotificationGenerationService.PostAsync(User, NotificationType.GroupAssignment, CurrentUser.State, assignment.Group); } if (changes.Any(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName)) { - _ = OUNotificationService.PostAsync(User, NotificationType.Modify); + _ = NotificationGenerationService.PostAsync(User, NotificationType.Modify, CurrentUser.State); await AuditLogger.User.Changed(User, changes.Where(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName).ToList()); } @@ -626,7 +729,7 @@ SnackBarService.Success(User.DisplayName + " has been deleted."); await AuditLogger.User.Deleted(User); - _ = OUNotificationService.PostAsync(User, NotificationType.Delete); + _ = NotificationGenerationService.PostAsync(User, NotificationType.Delete, CurrentUser.State); } catch (ApplicationException ex) diff --git a/BLAZAM/Program.cs b/BLAZAM/Program.cs index f3d17541c..3a1b15b8c 100644 --- a/BLAZAM/Program.cs +++ b/BLAZAM/Program.cs @@ -172,7 +172,7 @@ public static void Main(string[] args) AppInstance.Start(); GetRunningWebServerConfiguration(); - ScheduleAutoLoad(); + //ScheduleAutoLoad(); AppInstance.WaitForShutdown(); Log.Information("Application Shutting Down"); diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs index 56b5f2de4..78face01b 100644 --- a/BLAZAM/ProgramHelpers.cs +++ b/BLAZAM/ProgramHelpers.cs @@ -129,7 +129,7 @@ public static WebApplicationBuilder InjectServices(this WebApplicationBuilder bu * Uncomment this to force a language - CultureInfo culture = new CultureInfo("ru"); + CultureInfo culture = new CultureInfo("zh-Hans"); //CultureInfo culture = new CultureInfo("zh-Hans"); CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; @@ -305,7 +305,7 @@ completed so it may not be usable as is builder.Services.AddScoped(); - builder.Services.AddSingleton(); + builder.Services.AddSingleton(); builder.Host.UseWindowsService(); @@ -338,7 +338,7 @@ private static void PreloadServices() { try { - var context = Program.AppInstance.Services.GetRequiredService(); + var context = Program.AppInstance.Services.GetRequiredService(); } catch (Exception ex) { diff --git a/BLAZAM/updater/update.ps1 b/BLAZAM/updater/update.ps1 index 21b141c40..0184c44db 100644 --- a/BLAZAM/updater/update.ps1 +++ b/BLAZAM/updater/update.ps1 @@ -62,6 +62,8 @@ $updateScript= { if(!$global:iis){ Stop-Process -ID $global:processId -Force + + Stop-Service -Name "Blazam" -Force -ErrorAction Continue } Start-Sleep -Seconds 15 @@ -74,56 +76,11 @@ $updateScript= { Remove-Item -Path $global:destination\app_offline.htm -Force if(!$global:iis){ - Write-Host("Process path: " + $global:processFilePath) - - if($global:processArguments -ne $null -and $global:processArguments -ne "") - { - - Write-Host("Starting with arguments: " + $global:processArguments) - $restartedProcess = Start-Process -FilePath $global:processFilePath -ArgumentList $global:processArguments -WorkingDirectory $global:destination -PassThru + Start-Service -Name "Blazam" -ErrorAction Continue - }else{ - $restartedProcess = Start-Process -FilePath $global:processFilePath -WorkingDirectory $global:destination -PassThru - - } Write-Host("Waiting 15 seconds for Application to restart") Start-Sleep -Seconds 15 - <# - Write-Host("Process Stats: "+($restartedProcess| Select-Object *)) - if ($restartedProcess.ExitTime -eq $null -or $global:iis) { - Write-Host("Error: Web Application failed to restart rolling back changes") - #Perform Rollback Section - $restoreSource = $backupDirectory + "*" - Write-Host("Rolling back update") - Write-Host("Source: " + $restoreSource) - Write-Host("Destination: " + $global:destination) - Copy-Item -Path $restoreSource -Destination $backupDirectory -Recurse -Verbose -Force - Write-Host("Restarting ApplicationPool") - - if($global:processArguments -ne $null -and $global:processArguments -ne "") - { - - Write-Host("Starting with arguments: " + $global:processArguments) - $restartedProcess = Start-Process -FilePath $global:processFilePath -ArgumentList $global:processArguments -PassThru - - }else{ - $restartedProcess = Start-Process -FilePath $global:processFilePath -PassThru - - } - #$runningSite | Start-IISSite - Write-Host("Waiting 15 seconds for Application to restart") - - Start-Sleep -Seconds 15 - if ($restartedProcess.ExitTime -eq $null) { - Write-Host("Error: Rollback performed, but application did not start! Oh no...") - } - else { - Write-Host("Rollback completed successfully") - } - Stop-Transcript - exit - } - #> + } diff --git a/BLAZAM/wwwroot/css/site.css b/BLAZAM/wwwroot/css/site.css index 7c6d68a30..48bc83eee 100644 --- a/BLAZAM/wwwroot/css/site.css +++ b/BLAZAM/wwwroot/css/site.css @@ -8,6 +8,13 @@ html, body { h1:focus { outline: none; } + +.badge-repos { + left: 37px !important; + top: 2px !important; +} + + .d-contents{ display:contents !important; } @@ -168,3 +175,5 @@ a, .btn-link { top: 64px !important; } } + + diff --git a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs index 49e0ccc1a..9082141ac 100644 --- a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs +++ b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs @@ -267,7 +267,7 @@ public IADUser CreateUser(string containerName) /// Directory. /// /// The container name of the new group - /// An uncommited group + /// An uncommitted group public IADGroup CreateGroup(string containerName) { EnsureDirectoryEntry(); diff --git a/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs b/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs index 46dce2d27..08e69f031 100644 --- a/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs @@ -35,6 +35,7 @@ public class AccountDirectoryAdapter : GroupableDirectoryAdapter, IAccountDirect public virtual bool CanUnlock { get => HasActionPermission(ObjectActions.Unlock); } + public bool CanSearchDisabled { get diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index fe3706fca..ed8b7a3ad 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -20,6 +20,7 @@ using System.Linq; using System.Reflection; using System.Web; +using static MudBlazor.Colors; namespace BLAZAM.ActiveDirectory.Adapters { @@ -54,6 +55,10 @@ public virtual List Changes get { List changes = new(); + + + + foreach (var prop in NewEntryProperties) { object? currentValue = null; @@ -639,9 +644,13 @@ public virtual IEnumerable Children List directoryEntries = new List(); var children = DirectoryEntry.Children; DirectoryEntryAdapter? thisObject = null; + var list = new List(); foreach (DirectoryEntry child in children) { - + list.Add(child); + } + Parallel.ForEach(list, child => + { if (child.Properties["objectClass"].Contains("top")) { var objectClass = child.Properties["objectClass"]; @@ -673,14 +682,58 @@ public virtual IEnumerable Children if (thisObject != null) { thisObject.Parse(directory: Directory, directoryEntry: child); - directoryEntries.Add(thisObject); + lock (directoryEntries) + { + directoryEntries.Add(thisObject); + } } } thisObject = null; + }); + //foreach (DirectoryEntry child in children) + //{ - } + // if (child.Properties["objectClass"].Contains("top")) + // { + // var objectClass = child.Properties["objectClass"]; + // if (objectClass.Contains("computer")) + // { + // thisObject = new ADComputer(); + // } + // else if (objectClass.Contains("user")) + // { + // thisObject = new ADUser(); + // } + // else if (objectClass.Contains("organizationalUnit")) + // { + // thisObject = new ADOrganizationalUnit(); + // } + // else if (objectClass.Contains("group")) + // { + // thisObject = new ADGroup(); + // } + // else if (objectClass.Contains("printQueue")) + // { + // thisObject = new ADPrinter(); + // } + + // else if (objectClass.Contains("msFVE-RecoveryInformation")) + // { + // thisObject = new ADBitLockerRecovery(); + // } + // if (thisObject != null) + // { + // thisObject.Parse(directory: Directory, directoryEntry: child); + // directoryEntries.Add(thisObject); + + // } + + // } + // thisObject = null; + + //} directoryEntries.OrderBy(x => x.CanonicalName).OrderBy(x => x.ObjectType); CachedChildren = directoryEntries; } @@ -1027,11 +1080,45 @@ private void FetchDirectoryEntry() } } + //protected virtual List GetNonReplicatedProperty(string propertyName) + //{ + // var list = new List(); + // var dcs = new List(Directory.DomainControllers); + // foreach (var dc in dcs) + // { + // try + // { + // if (dc.IsPingable()) + // { + // var searcher = dc.GetDirectorySearcher(); + // searcher.Filter = "(distinguishedName=" + this.DN + ")"; + // searcher.ClientTimeout = TimeSpan.FromMilliseconds(500); + // searcher.ServerTimeLimit = TimeSpan.FromMilliseconds(500); + // var searchResult = searcher.FindOne(); + // if (searchResult != null) + // { + // var value = searchResult.GetDirectoryEntry().Properties[propertyName].Value; + + // list.Add((T)value); + // } + + // } + // } + // catch + // { + // //list.Add(default(T)); + // } + // } + // return list; + //} + + protected virtual List GetNonReplicatedProperty(string propertyName) { var list = new List(); var dcs = new List(Directory.DomainControllers); - foreach (var dc in dcs) + + Parallel.ForEach(dcs, dc => { try { @@ -1045,20 +1132,27 @@ private void FetchDirectoryEntry() if (searchResult != null) { var value = searchResult.GetDirectoryEntry().Properties[propertyName].Value; - - list.Add((T)value); + lock (list) + { + list.Add((T)value); + } } - } } catch { - //list.Add(default(T)); + // Consider logging the exception or handling it appropriately. + lock (list) + { + list.Add(default(T)); + } } - } + }); + return list; } + protected virtual T? GetProperty(string propertyName) { try diff --git a/BLAZAMActiveDirectory/Interfaces/IAccountDirectoryAdapter.cs b/BLAZAMActiveDirectory/Interfaces/IAccountDirectoryAdapter.cs index 5d2260a23..00027fd69 100644 --- a/BLAZAMActiveDirectory/Interfaces/IAccountDirectoryAdapter.cs +++ b/BLAZAMActiveDirectory/Interfaces/IAccountDirectoryAdapter.cs @@ -38,6 +38,11 @@ public interface IAccountDirectoryAdapter : IGroupableDirectoryAdapter /// bool Enabled { get; set; } + /// + /// Indicates whether the current web user can reset the password for this + /// + bool CanSetPassword { get; } + /// /// Indicates whether the current web user can search disabled 's /// diff --git a/BLAZAMCommon/Helpers/CommonHelpers.cs b/BLAZAMCommon/Helpers/CommonHelpers.cs index 540739358..78099eeb7 100644 --- a/BLAZAMCommon/Helpers/CommonHelpers.cs +++ b/BLAZAMCommon/Helpers/CommonHelpers.cs @@ -362,7 +362,18 @@ public static string ToSidString(this byte[] sid) return securityIdentifier.Value; } + public static byte[] ToSidByteArray(this string sidString) + { + if (string.IsNullOrEmpty(sidString)) return Array.Empty(); + + var securityIdentifier = new SecurityIdentifier(sidString); + // Use GetBinaryForm method with appropriate buffer size + byte[] sidBytes = new byte[securityIdentifier.BinaryLength]; + securityIdentifier.GetBinaryForm(sidBytes, 0); + + return sidBytes; + } #endregion } diff --git a/BLAZAMDatabase/Context/AppDatabaseFactory.cs b/BLAZAMDatabase/Context/AppDatabaseFactory.cs index 26ce97c9e..54ef4025e 100644 --- a/BLAZAMDatabase/Context/AppDatabaseFactory.cs +++ b/BLAZAMDatabase/Context/AppDatabaseFactory.cs @@ -60,6 +60,9 @@ private void SeedData() SetupDenyAll(seedContext); + + //EnsureGlobalPermissionSettingsExists(seedContext); + } diff --git a/BLAZAMDatabase/Context/DatabaseContextBase.cs b/BLAZAMDatabase/Context/DatabaseContextBase.cs index cb13536d0..5e0487973 100644 --- a/BLAZAMDatabase/Context/DatabaseContextBase.cs +++ b/BLAZAMDatabase/Context/DatabaseContextBase.cs @@ -139,6 +139,8 @@ public DatabaseContextBase(DbContextOptions options) : base(options) public virtual DbSet PermissionDelegate { get; set; } public virtual DbSet PermissionMap { get; set; } + public virtual DbSet GlobalPermissionSettings { get; set; } + public virtual DbSet GlobalPermissionRequestActions { get; set; } public virtual DbSet ChatRooms { get; set; } public virtual DbSet ChatMessages { get; set; } @@ -527,7 +529,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) new ObjectAction() { Id = 6, Name = "Rename", Action = ActiveDirectoryObjectAction.Rename }, new ObjectAction() { Id = 7, Name = "Move", Action = ActiveDirectoryObjectAction.Move }, new ObjectAction() { Id = 8, Name = "Create", Action = ActiveDirectoryObjectAction.Create }, - new ObjectAction() { Id = 9, Name = "Delete", Action = ActiveDirectoryObjectAction.Delete } + new ObjectAction() { Id = 9, Name = "Delete", Action = ActiveDirectoryObjectAction.Delete }, + new ObjectAction() { Id = 10, Name = "Set Password", Action = ActiveDirectoryObjectAction.SetPassword } ); modelBuilder.Entity(entity => diff --git a/BLAZAMDatabase/Context/IDatabaseContext.cs b/BLAZAMDatabase/Context/IDatabaseContext.cs index b39d6aca1..1ad358357 100644 --- a/BLAZAMDatabase/Context/IDatabaseContext.cs +++ b/BLAZAMDatabase/Context/IDatabaseContext.cs @@ -64,6 +64,8 @@ public interface IDatabaseContext : IEFCoreDbContext DbSet UnreadChatMessages { get; set; } DbSet ActiveDirectoryFieldObjectMappings { get; set; } DbSet NotificationSubscriptions { get; set; } + DbSet GlobalPermissionSettings { get; set; } + DbSet GlobalPermissionRequestActions { get; set; } void Export(string directory); } diff --git a/BLAZAMDatabase/Helpers/DatabaseHelpers.cs b/BLAZAMDatabase/Helpers/DatabaseHelpers.cs index a9adca3da..eea940221 100644 --- a/BLAZAMDatabase/Helpers/DatabaseHelpers.cs +++ b/BLAZAMDatabase/Helpers/DatabaseHelpers.cs @@ -1,4 +1,6 @@ -using BLAZAM.Database.Models.User; +using BLAZAM.Common.Data; +using BLAZAM.Database.Models.Permissions; +using BLAZAM.Database.Models.User; using System; using System.Collections.Generic; using System.Linq; @@ -18,5 +20,132 @@ public static long GetMembersHash(this IEnumerable members) } return hash; } + public static List ToList(this ActiveDirectoryObjectAction _enum) + { + return Enum.GetValues(typeof(ActiveDirectoryObjectAction)).Cast().ToList(); + } + + public static bool IsActionAppropriateForObject(this ActiveDirectoryObjectAction action, ActiveDirectoryObjectType type) + { + + var Name = action.ToString(); + switch (type) + { + case ActiveDirectoryObjectType.User: + case ActiveDirectoryObjectType.Computer: + switch (Name) + { + case "Lock": + case "Unlock": + case "Move": + case "Delete": + case "Create": + case "Enable": + case "Disable": + case "Rename": + case "SetPassword": + return true; + default: + return false; + } + case ActiveDirectoryObjectType.Group: + switch (Name) + { + case "Move": + case "Delete": + case "Create": + case "Unassign": + case "Rename": + case "Assign": + return true; + default: + return false; + } + case ActiveDirectoryObjectType.Printer: + case ActiveDirectoryObjectType.OU: + switch (Name) + { + case "Move": + case "Delete": + case "Rename": + case "Create": + return true; + default: + return false; + } + case ActiveDirectoryObjectType.BitLocker: + switch (Name) + { + case "Delete": + return true; + default: + return false; + } + + default: + return false; + } + } + + public static bool IsActionAppropriateForObject(this ObjectAction action, ActiveDirectoryObjectType type) + { + var Name = action.Name; + switch (type) + { + case ActiveDirectoryObjectType.User: + case ActiveDirectoryObjectType.Computer: + switch (Name) + { + case "Lock": + case "Unlock": + case "Move": + case "Delete": + case "Create": + case "Enable": + case "Disable": + case "Rename": + case "Set Password": + return true; + default: + return false; + } + case ActiveDirectoryObjectType.Group: + switch (Name) + { + case "Move": + case "Delete": + case "Create": + case "UnAssign": + case "Rename": + case "Assign": + return true; + default: + return false; + } + case ActiveDirectoryObjectType.Printer: + case ActiveDirectoryObjectType.OU: + switch (Name) + { + case "Move": + case "Delete": + case "Rename": + case "Create": + return true; + default: + return false; + } + case ActiveDirectoryObjectType.BitLocker: + switch (Name) + { + case "Delete": + return true; + default: + return false; + } + + default: + return false; + } + } } } diff --git a/BLAZAMDatabase/Helpers/WindowsHelpers.cs b/BLAZAMDatabase/Helpers/WindowsHelpers.cs index e312a5822..dc272085c 100644 --- a/BLAZAMDatabase/Helpers/WindowsHelpers.cs +++ b/BLAZAMDatabase/Helpers/WindowsHelpers.cs @@ -6,6 +6,30 @@ namespace BLAZAM.Helpers { public static class WindowsHelpers { + public static WindowsImpersonationUser GetDirectoryImpersonationUser(this ADSettings settings) + { + + return new WindowsImpersonationUser() + { + FQDN = settings.FQDN, + Username = settings.Username, + + Password = settings.Password.Decrypt().ToSecureString(), + }; + + } + public static WindowsImpersonationUser GetUpdateImpersonationUser(this AppSettings settings) + { + + return new WindowsImpersonationUser() + { + FQDN = settings.UpdateDomain, + Username = settings.UpdateUsername, + Password = settings.UpdatePassword.Decrypt().ToSecureString() + }; + + } + /// /// Creates a windows identity from the active directory /// user defined in settings @@ -14,13 +38,7 @@ public static class WindowsHelpers /// public static WindowsImpersonation CreateDirectoryAdminImpersonator(this ADSettings settings) { - return new(new() - { - FQDN = settings.FQDN, - Username = settings.Username, - - Password = settings.Password.Decrypt().ToSecureString(), - }); + return new(settings.GetDirectoryImpersonationUser()); } /// /// Creates a windows identity from the update settins @@ -30,12 +48,7 @@ public static WindowsImpersonation CreateDirectoryAdminImpersonator(this ADSetti public static WindowsImpersonation? CreateUpdateImpersonator(this AppSettings settings) { if (settings != null && settings.UpdateUsername != null && settings.UpdatePassword != null) - return new(new() - { - FQDN = settings.UpdateDomain, - Username = settings.UpdateUsername, - Password = settings.UpdatePassword.Decrypt().ToSecureString() - }); + return new(settings.GetUpdateImpersonationUser()); else return null; } diff --git a/BLAZAMDatabase/Migrations/MySql/20241031220141_Add_Set_Password_Action_MySql.Designer.cs b/BLAZAMDatabase/Migrations/MySql/20241031220141_Add_Set_Password_Action_MySql.Designer.cs new file mode 100644 index 000000000..e8af60f6c --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20241031220141_Add_Set_Password_Action_MySql.Designer.cs @@ -0,0 +1,1978 @@ +// +using System; +using BLAZAM.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BLAZAM.Database.Migrations.MySql +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20241031220141_Add_Set_Password_Action_MySql")] + partial class Add_Set_Password_Action_MySql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("FieldMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "FieldMapId"); + + b.HasIndex("FieldMapId"); + + b.ToTable("AccessLevelFieldAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("ObjectMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "ObjectMapId"); + + b.HasIndex("ObjectMapId"); + + b.ToTable("AccessLevelObjectAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("PermissionMapsId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "PermissionMapsId"); + + b.HasIndex("PermissionMapsId"); + + b.ToTable("AccessLevelPermissionMapping"); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("MembersId") + .HasColumnType("int"); + + b.HasKey("ChatRoomId", "MembersId"); + + b.HasIndex("MembersId"); + + b.ToTable("AppUserChatRoom"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ADSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("ApplicationBaseDN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FQDN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Password") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerPort") + .HasColumnType("int"); + + b.Property("UseTLS") + .HasColumnType("tinyint(1)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectorySettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectoryFields"); + + b.HasData( + new + { + Id = 1, + DisplayName = "Last Name", + FieldName = "sn", + FieldType = 0 + }, + new + { + Id = 2, + DisplayName = "First Name", + FieldName = "givenname", + FieldType = 0 + }, + new + { + Id = 3, + DisplayName = "Office", + FieldName = "physicalDeliveryOfficeName", + FieldType = 0 + }, + new + { + Id = 4, + DisplayName = "Employee ID", + FieldName = "employeeId", + FieldType = 0 + }, + new + { + Id = 5, + DisplayName = "Home Directory", + FieldName = "homeDirectory", + FieldType = 0 + }, + new + { + Id = 6, + DisplayName = "Logon Script Path", + FieldName = "scriptPath", + FieldType = 0 + }, + new + { + Id = 7, + DisplayName = "Profile Path", + FieldName = "profilePath", + FieldType = 0 + }, + new + { + Id = 8, + DisplayName = "Home Phone Number", + FieldName = "homePhone", + FieldType = 0 + }, + new + { + Id = 9, + DisplayName = "Street Address", + FieldName = "streetAddress", + FieldType = 0 + }, + new + { + Id = 10, + DisplayName = "City", + FieldName = "l", + FieldType = 0 + }, + new + { + Id = 11, + DisplayName = "State", + FieldName = "st", + FieldType = 0 + }, + new + { + Id = 12, + DisplayName = "Zip Code", + FieldName = "postalCode", + FieldType = 0 + }, + new + { + Id = 13, + DisplayName = "Site", + FieldName = "site", + FieldType = 0 + }, + new + { + Id = 14, + DisplayName = "Name", + FieldName = "name", + FieldType = 0 + }, + new + { + Id = 15, + DisplayName = "Username", + FieldName = "samaccountname", + FieldType = 0 + }, + new + { + Id = 16, + DisplayName = "SID", + FieldName = "objectSID", + FieldType = 2 + }, + new + { + Id = 17, + DisplayName = "E-Mail Address", + FieldName = "mail", + FieldType = 0 + }, + new + { + Id = 18, + DisplayName = "Description", + FieldName = "description", + FieldType = 0 + }, + new + { + Id = 19, + DisplayName = "Display Name", + FieldName = "displayName", + FieldType = 0 + }, + new + { + Id = 20, + DisplayName = "Distinguished Name", + FieldName = "distinguishedName", + FieldType = 0 + }, + new + { + Id = 21, + DisplayName = "Member Of", + FieldName = "memberOf", + FieldType = 4 + }, + new + { + Id = 22, + DisplayName = "Company", + FieldName = "company", + FieldType = 0 + }, + new + { + Id = 23, + DisplayName = "Title", + FieldName = "title", + FieldType = 0 + }, + new + { + Id = 24, + DisplayName = "User Principal Name", + FieldName = "userPrincipalName", + FieldType = 0 + }, + new + { + Id = 25, + DisplayName = "Telephone Number", + FieldName = "telephoneNumber", + FieldType = 0 + }, + new + { + Id = 26, + DisplayName = "PO Box", + FieldName = "postOfficeBox", + FieldType = 0 + }, + new + { + Id = 27, + DisplayName = "Canonical Name", + FieldName = "cn", + FieldType = 0 + }, + new + { + Id = 28, + DisplayName = "Home Drive", + FieldName = "homeDrive", + FieldType = 3 + }, + new + { + Id = 29, + DisplayName = "Department", + FieldName = "department", + FieldType = 0 + }, + new + { + Id = 30, + DisplayName = "Middle Name", + FieldName = "middleName", + FieldType = 0 + }, + new + { + Id = 31, + DisplayName = "Pager", + FieldName = "pager", + FieldType = 0 + }, + new + { + Id = 32, + DisplayName = "OS", + FieldName = "operatingSystemVersion", + FieldType = 0 + }, + new + { + Id = 33, + DisplayName = "Account Expiration", + FieldName = "accountExpires", + FieldType = 1 + }, + new + { + Id = 34, + DisplayName = "Manager", + FieldName = "manager", + FieldType = 0 + }, + new + { + Id = 35, + DisplayName = "Photo", + FieldName = "thumbnail", + FieldType = 2 + }, + new + { + Id = 36, + DisplayName = "Log On To", + FieldName = "userWorkstations", + FieldType = 0 + }, + new + { + Id = 37, + DisplayName = "Logon Hours", + FieldName = "logonHours", + FieldType = 2 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("CustomActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomActiveDirectoryFieldId"); + + b.ToTable("ActiveDirectoryFieldObjectMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AppSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AnalyticsId") + .HasColumnType("longtext"); + + b.Property("AppFQDN") + .HasColumnType("longtext"); + + b.Property("AppIcon") + .HasColumnType("longblob"); + + b.Property("AppName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AutoUpdate") + .HasColumnType("tinyint(1)"); + + b.Property("AutoUpdateTime") + .HasColumnType("time(6)"); + + b.Property("ForceHTTPS") + .HasColumnType("tinyint(1)"); + + b.Property("InstallationCompleted") + .HasColumnType("tinyint(1)"); + + b.Property("LastUpdateCheck") + .HasColumnType("datetime(6)"); + + b.Property("MOTD") + .HasColumnType("longtext"); + + b.Property("MyrtilleURL") + .HasColumnType("longtext"); + + b.Property("SSLCertificateCipher") + .HasColumnType("longtext"); + + b.Property("SendDeveloperAnalytics") + .HasColumnType("tinyint(1)"); + + b.Property("SendLogsToDeveloper") + .HasColumnType("tinyint(1)"); + + b.Property("UpdateBranch") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdateDomain") + .HasColumnType("longtext"); + + b.Property("UpdatePassword") + .HasColumnType("longtext"); + + b.Property("UpdateUsername") + .HasColumnType("longtext"); + + b.Property("UseUpdateCredentials") + .HasColumnType("tinyint(1)"); + + b.Property("UserHelpdeskURL") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("AppSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1") + .HasName("CK_Table_Column1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.DirectoryEntryAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Sid") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("DirectoryEntryAuditLogs"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.LogonAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("LogonAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.PermissionsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PermissionsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.RequestAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("RequestAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SettingsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SettingsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SystemAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SystemAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AuthenticationSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminPassword") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DuoApiHost") + .HasColumnType("longtext"); + + b.Property("DuoClientId") + .HasColumnType("longtext"); + + b.Property("DuoClientSecret") + .HasColumnType("longtext"); + + b.Property("DuoEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("DuoUnreachableBehavior") + .HasColumnType("int"); + + b.Property("SessionTimeout") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AuthenticationSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1") + .HasName("CK_Table_Column2"); + }); + + b.HasData( + new + { + Id = 1, + AdminPassword = "password", + DuoEnabled = false, + DuoUnreachableBehavior = 0, + SessionTimeout = 15 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsPublic") + .HasColumnType("tinyint(1)"); + + b.Property("MembersHash") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatMessageId") + .HasColumnType("int"); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatMessageId"); + + b.ToTable("UnreadChatMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CustomActiveDirectoryFields"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminBcc") + .HasColumnType("longtext"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("FromAddress") + .HasColumnType("longtext"); + + b.Property("FromName") + .HasColumnType("longtext"); + + b.Property("ReplyToAddress") + .HasColumnType("longtext"); + + b.Property("ReplyToName") + .HasColumnType("longtext"); + + b.Property("SMTPPassword") + .HasColumnType("longtext"); + + b.Property("SMTPPort") + .HasColumnType("int"); + + b.Property("SMTPServer") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SMTPUsername") + .HasColumnType("longtext"); + + b.Property("UseSMTPAuth") + .HasColumnType("tinyint(1)"); + + b.Property("UseTLS") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("EmailSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1") + .HasName("CK_Table_Column3"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Body") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TemplateType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Block") + .HasColumnType("tinyint(1)"); + + b.Property("ByEmail") + .HasColumnType("tinyint(1)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("InApp") + .HasColumnType("tinyint(1)"); + + b.Property("OU") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSubscriptions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("NotificationSubscriptionId") + .HasColumnType("int"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationSubscriptionId"); + + b.ToTable("SubscriptionNotificationType"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("AccessLevels"); + + b.HasData( + new + { + Id = 1, + Name = "Deny All" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AccessLevelId") + .HasColumnType("int"); + + b.Property("AllowOrDeny") + .HasColumnType("tinyint(1)"); + + b.Property("ObjectActionId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccessLevelId"); + + b.HasIndex("ObjectActionId"); + + b.ToTable("ActionAccessMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("FieldAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 100, + Name = "Read" + }, + new + { + Id = 3, + Level = 1000, + Name = "Edit" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("FieldAccessLevelId") + .HasColumnType("int"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("FieldAccessLevelId"); + + b.HasIndex("FieldId"); + + b.ToTable("AccessLevelFieldMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ObjectAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 1000, + Name = "Read" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowDisabled") + .HasColumnType("tinyint(1)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("ObjectAccessLevelId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ObjectAccessLevelId"); + + b.ToTable("AccessLevelObjectMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ObjectActionFlag"); + + b.HasData( + new + { + Id = 1, + Action = 4, + Name = "Assign" + }, + new + { + Id = 2, + Action = 3, + Name = "UnAssign" + }, + new + { + Id = 3, + Action = 8, + Name = "Unlock" + }, + new + { + Id = 4, + Action = 5, + Name = "Enable" + }, + new + { + Id = 5, + Action = 6, + Name = "Disable" + }, + new + { + Id = 6, + Action = 7, + Name = "Rename" + }, + new + { + Id = 7, + Action = 0, + Name = "Move" + }, + new + { + Id = 8, + Action = 2, + Name = "Create" + }, + new + { + Id = 9, + Action = 1, + Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DelegateName") + .HasColumnType("longtext"); + + b.Property("DelegateSid") + .IsRequired() + .HasColumnType("varbinary(3072)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsSuperAdmin") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("DelegateSid") + .IsUnique(); + + b.ToTable("PermissionDelegate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("OU") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PermissionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowCustomGroups") + .HasColumnType("tinyint(1)"); + + b.Property("AllowUsernameOverride") + .HasColumnType("tinyint(1)"); + + b.Property("AskForAlternateEmail") + .HasColumnType("tinyint(1)"); + + b.Property("Category") + .HasColumnType("longtext"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("DisplayNameFormula") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.Property("ParentOU") + .HasColumnType("longtext"); + + b.Property("ParentTemplateId") + .HasColumnType("int"); + + b.Property("PasswordFormula") + .HasColumnType("longtext"); + + b.Property("RequirePasswordChange") + .HasColumnType("tinyint(1)"); + + b.Property("SendWelcomeEmail") + .HasColumnType("tinyint(1)"); + + b.Property("UsernameFormula") + .HasColumnType("longtext"); + + b.Property("Visible") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("ParentTemplateId"); + + b.ToTable("DirectoryTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("Editable") + .HasColumnType("tinyint(1)"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("DirectoryTemplateId"); + + b.HasIndex("FieldId"); + + b.ToTable("DirectoryTemplateFieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("GroupSid") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryTemplateId"); + + b.ToTable("DirectoryTemplateGroups"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("APIToken") + .HasColumnType("longtext"); + + b.Property("DarkMode") + .HasColumnType("tinyint(1)"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("ProfilePicture") + .HasColumnType("longblob"); + + b.Property("SearchDisabledComputers") + .HasColumnType("tinyint(1)"); + + b.Property("SearchDisabledUsers") + .HasColumnType("tinyint(1)"); + + b.Property("Theme") + .HasColumnType("longtext"); + + b.Property("UserGUID") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Username") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserGUID") + .IsUnique(); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("Dismissable") + .HasColumnType("tinyint(1)"); + + b.Property("Expires") + .HasColumnType("datetime(6)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Link") + .HasColumnType("longtext"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("NotificationMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("NewsItemId") + .HasColumnType("double"); + + b.Property("NewsItemUpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ItemsPerPage") + .HasColumnType("int"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Slot") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("WidgetType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserDashboardWidgets"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserFavoriteEntries"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("IsRead") + .HasColumnType("tinyint(1)"); + + b.Property("NotificationId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotifications"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("Message") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.Property("PermissionDelegatesId") + .HasColumnType("int"); + + b.Property("PermissionsMapsId") + .HasColumnType("int"); + + b.HasKey("PermissionDelegatesId", "PermissionsMapsId"); + + b.HasIndex("PermissionsMapsId"); + + b.ToTable("PermissionDelegatePermissionMapping"); + }); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessMapping", null) + .WithMany() + .HasForeignKey("FieldMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", null) + .WithMany() + .HasForeignKey("ObjectMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", null) + .WithMany() + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", null) + .WithMany() + .HasForeignKey("MembersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", null) + .WithMany("ObjectTypes") + .HasForeignKey("CustomActiveDirectoryFieldId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.HasOne("BLAZAM.Server.Data.ChatMessage", "ChatMessage") + .WithMany("NotReadBy") + .HasForeignKey("ChatMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatMessage"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("NotificationSubscriptions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.HasOne("BLAZAM.Database.Models.Notifications.NotificationSubscription", "NotificationSubscription") + .WithMany("NotificationTypes") + .HasForeignKey("NotificationSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationSubscription"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany("ActionMap") + .HasForeignKey("AccessLevelId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAction", "ObjectAction") + .WithMany() + .HasForeignKey("ObjectActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAction"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessLevel", "FieldAccessLevel") + .WithMany() + .HasForeignKey("FieldAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + + b.Navigation("FieldAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", "ObjectAccessLevel") + .WithMany("ObjectAccessMappings") + .HasForeignKey("ObjectAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.Navigation("ParentTemplate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("FieldValues") + .HasForeignKey("DirectoryTemplateId"); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("AssignedGroupSids") + .HasForeignKey("DirectoryTemplateId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("ReadNewsItems") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("DashboardWidgets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("FavoriteEntries") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.HasOne("BLAZAM.Database.Models.User.NotificationMessage", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", "ChatRoom") + .WithMany("Messages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionDelegate", null) + .WithMany() + .HasForeignKey("PermissionDelegatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionsMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Navigation("ObjectTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Navigation("NotificationTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Navigation("ActionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Navigation("ObjectAccessMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Navigation("AssignedGroupSids"); + + b.Navigation("FieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Navigation("DashboardWidgets"); + + b.Navigation("FavoriteEntries"); + + b.Navigation("NotificationSubscriptions"); + + b.Navigation("Notifications"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/20241031220141_Add_Set_Password_Action_MySql.cs b/BLAZAMDatabase/Migrations/MySql/20241031220141_Add_Set_Password_Action_MySql.cs new file mode 100644 index 000000000..48935475d --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20241031220141_Add_Set_Password_Action_MySql.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.MySql +{ + /// + public partial class Add_Set_Password_Action_MySql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + table: "ObjectActionFlag", + columns: new[] { "Id", "Action", "Name" }, + values: new object[] { 10, 9, "Set Password" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "ObjectActionFlag", + keyColumn: "Id", + keyValue: 10); + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/20241108235530_Add_GlobalPerms_Requests_MySql.Designer.cs b/BLAZAMDatabase/Migrations/MySql/20241108235530_Add_GlobalPerms_Requests_MySql.Designer.cs new file mode 100644 index 000000000..95f1c6cae --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20241108235530_Add_GlobalPerms_Requests_MySql.Designer.cs @@ -0,0 +1,2036 @@ +// +using System; +using BLAZAM.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BLAZAM.Database.Migrations.MySql +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20241108235530_Add_GlobalPerms_Requests_MySql")] + partial class Add_GlobalPerms_Requests_MySql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("FieldMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "FieldMapId"); + + b.HasIndex("FieldMapId"); + + b.ToTable("AccessLevelFieldAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("ObjectMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "ObjectMapId"); + + b.HasIndex("ObjectMapId"); + + b.ToTable("AccessLevelObjectAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("PermissionMapsId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "PermissionMapsId"); + + b.HasIndex("PermissionMapsId"); + + b.ToTable("AccessLevelPermissionMapping"); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("MembersId") + .HasColumnType("int"); + + b.HasKey("ChatRoomId", "MembersId"); + + b.HasIndex("MembersId"); + + b.ToTable("AppUserChatRoom"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ADSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("ApplicationBaseDN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FQDN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Password") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServerPort") + .HasColumnType("int"); + + b.Property("UseTLS") + .HasColumnType("tinyint(1)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectorySettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectoryFields"); + + b.HasData( + new + { + Id = 1, + DisplayName = "Last Name", + FieldName = "sn", + FieldType = 0 + }, + new + { + Id = 2, + DisplayName = "First Name", + FieldName = "givenname", + FieldType = 0 + }, + new + { + Id = 3, + DisplayName = "Office", + FieldName = "physicalDeliveryOfficeName", + FieldType = 0 + }, + new + { + Id = 4, + DisplayName = "Employee ID", + FieldName = "employeeId", + FieldType = 0 + }, + new + { + Id = 5, + DisplayName = "Home Directory", + FieldName = "homeDirectory", + FieldType = 0 + }, + new + { + Id = 6, + DisplayName = "Logon Script Path", + FieldName = "scriptPath", + FieldType = 0 + }, + new + { + Id = 7, + DisplayName = "Profile Path", + FieldName = "profilePath", + FieldType = 0 + }, + new + { + Id = 8, + DisplayName = "Home Phone Number", + FieldName = "homePhone", + FieldType = 0 + }, + new + { + Id = 9, + DisplayName = "Street Address", + FieldName = "streetAddress", + FieldType = 0 + }, + new + { + Id = 10, + DisplayName = "City", + FieldName = "l", + FieldType = 0 + }, + new + { + Id = 11, + DisplayName = "State", + FieldName = "st", + FieldType = 0 + }, + new + { + Id = 12, + DisplayName = "Zip Code", + FieldName = "postalCode", + FieldType = 0 + }, + new + { + Id = 13, + DisplayName = "Site", + FieldName = "site", + FieldType = 0 + }, + new + { + Id = 14, + DisplayName = "Name", + FieldName = "name", + FieldType = 0 + }, + new + { + Id = 15, + DisplayName = "Username", + FieldName = "samaccountname", + FieldType = 0 + }, + new + { + Id = 16, + DisplayName = "SID", + FieldName = "objectSID", + FieldType = 2 + }, + new + { + Id = 17, + DisplayName = "E-Mail Address", + FieldName = "mail", + FieldType = 0 + }, + new + { + Id = 18, + DisplayName = "Description", + FieldName = "description", + FieldType = 0 + }, + new + { + Id = 19, + DisplayName = "Display Name", + FieldName = "displayName", + FieldType = 0 + }, + new + { + Id = 20, + DisplayName = "Distinguished Name", + FieldName = "distinguishedName", + FieldType = 0 + }, + new + { + Id = 21, + DisplayName = "Member Of", + FieldName = "memberOf", + FieldType = 4 + }, + new + { + Id = 22, + DisplayName = "Company", + FieldName = "company", + FieldType = 0 + }, + new + { + Id = 23, + DisplayName = "Title", + FieldName = "title", + FieldType = 0 + }, + new + { + Id = 24, + DisplayName = "User Principal Name", + FieldName = "userPrincipalName", + FieldType = 0 + }, + new + { + Id = 25, + DisplayName = "Telephone Number", + FieldName = "telephoneNumber", + FieldType = 0 + }, + new + { + Id = 26, + DisplayName = "PO Box", + FieldName = "postOfficeBox", + FieldType = 0 + }, + new + { + Id = 27, + DisplayName = "Canonical Name", + FieldName = "cn", + FieldType = 0 + }, + new + { + Id = 28, + DisplayName = "Home Drive", + FieldName = "homeDrive", + FieldType = 3 + }, + new + { + Id = 29, + DisplayName = "Department", + FieldName = "department", + FieldType = 0 + }, + new + { + Id = 30, + DisplayName = "Middle Name", + FieldName = "middleName", + FieldType = 0 + }, + new + { + Id = 31, + DisplayName = "Pager", + FieldName = "pager", + FieldType = 0 + }, + new + { + Id = 32, + DisplayName = "OS", + FieldName = "operatingSystemVersion", + FieldType = 0 + }, + new + { + Id = 33, + DisplayName = "Account Expiration", + FieldName = "accountExpires", + FieldType = 1 + }, + new + { + Id = 34, + DisplayName = "Manager", + FieldName = "manager", + FieldType = 0 + }, + new + { + Id = 35, + DisplayName = "Photo", + FieldName = "thumbnail", + FieldType = 2 + }, + new + { + Id = 36, + DisplayName = "Log On To", + FieldName = "userWorkstations", + FieldType = 0 + }, + new + { + Id = 37, + DisplayName = "Logon Hours", + FieldName = "logonHours", + FieldType = 2 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("CustomActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomActiveDirectoryFieldId"); + + b.ToTable("ActiveDirectoryFieldObjectMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AppSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AnalyticsId") + .HasColumnType("longtext"); + + b.Property("AppFQDN") + .HasColumnType("longtext"); + + b.Property("AppIcon") + .HasColumnType("longblob"); + + b.Property("AppName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AutoUpdate") + .HasColumnType("tinyint(1)"); + + b.Property("AutoUpdateTime") + .HasColumnType("time(6)"); + + b.Property("ForceHTTPS") + .HasColumnType("tinyint(1)"); + + b.Property("InstallationCompleted") + .HasColumnType("tinyint(1)"); + + b.Property("LastUpdateCheck") + .HasColumnType("datetime(6)"); + + b.Property("MOTD") + .HasColumnType("longtext"); + + b.Property("MyrtilleURL") + .HasColumnType("longtext"); + + b.Property("SSLCertificateCipher") + .HasColumnType("longtext"); + + b.Property("SendDeveloperAnalytics") + .HasColumnType("tinyint(1)"); + + b.Property("SendLogsToDeveloper") + .HasColumnType("tinyint(1)"); + + b.Property("UpdateBranch") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdateDomain") + .HasColumnType("longtext"); + + b.Property("UpdatePassword") + .HasColumnType("longtext"); + + b.Property("UpdateUsername") + .HasColumnType("longtext"); + + b.Property("UseUpdateCredentials") + .HasColumnType("tinyint(1)"); + + b.Property("UserHelpdeskURL") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("AppSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1") + .HasName("CK_Table_Column1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.DirectoryEntryAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Sid") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("DirectoryEntryAuditLogs"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.LogonAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("LogonAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.PermissionsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PermissionsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.RequestAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("RequestAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SettingsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SettingsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SystemAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("AfterAction") + .HasColumnType("longtext"); + + b.Property("BeforeAction") + .HasColumnType("longtext"); + + b.Property("IpAddress") + .HasColumnType("longtext"); + + b.Property("Target") + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SystemAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AuthenticationSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminPassword") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DuoApiHost") + .HasColumnType("longtext"); + + b.Property("DuoClientId") + .HasColumnType("longtext"); + + b.Property("DuoClientSecret") + .HasColumnType("longtext"); + + b.Property("DuoEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("DuoUnreachableBehavior") + .HasColumnType("int"); + + b.Property("SessionTimeout") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AuthenticationSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1") + .HasName("CK_Table_Column2"); + }); + + b.HasData( + new + { + Id = 1, + AdminPassword = "password", + DuoEnabled = false, + DuoUnreachableBehavior = 0, + SessionTimeout = 15 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsPublic") + .HasColumnType("tinyint(1)"); + + b.Property("MembersHash") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatMessageId") + .HasColumnType("int"); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatMessageId"); + + b.ToTable("UnreadChatMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CustomActiveDirectoryFields"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminBcc") + .HasColumnType("longtext"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("FromAddress") + .HasColumnType("longtext"); + + b.Property("FromName") + .HasColumnType("longtext"); + + b.Property("ReplyToAddress") + .HasColumnType("longtext"); + + b.Property("ReplyToName") + .HasColumnType("longtext"); + + b.Property("SMTPPassword") + .HasColumnType("longtext"); + + b.Property("SMTPPort") + .HasColumnType("int"); + + b.Property("SMTPServer") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SMTPUsername") + .HasColumnType("longtext"); + + b.Property("UseSMTPAuth") + .HasColumnType("tinyint(1)"); + + b.Property("UseTLS") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("EmailSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "Id = 1") + .HasName("CK_Table_Column3"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Body") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TemplateType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Block") + .HasColumnType("tinyint(1)"); + + b.Property("ByEmail") + .HasColumnType("tinyint(1)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("InApp") + .HasColumnType("tinyint(1)"); + + b.Property("OU") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSubscriptions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("NotificationSubscriptionId") + .HasColumnType("int"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationSubscriptionId"); + + b.ToTable("SubscriptionNotificationType"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("AccessLevels"); + + b.HasData( + new + { + Id = 1, + Name = "Deny All" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AccessLevelId") + .HasColumnType("int"); + + b.Property("AllowOrDeny") + .HasColumnType("tinyint(1)"); + + b.Property("ObjectActionId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccessLevelId"); + + b.HasIndex("ObjectActionId"); + + b.ToTable("ActionAccessMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("FieldAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 100, + Name = "Read" + }, + new + { + Id = 3, + Level = 1000, + Name = "Edit" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("FieldAccessLevelId") + .HasColumnType("int"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("FieldAccessLevelId"); + + b.HasIndex("FieldId"); + + b.ToTable("AccessLevelFieldMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionRequestActions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ObjectAction") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionRequestActions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowAccessRequest") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSelfModification") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ObjectAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 1000, + Name = "Read" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowDisabled") + .HasColumnType("tinyint(1)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("ObjectAccessLevelId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ObjectAccessLevelId"); + + b.ToTable("AccessLevelObjectMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ObjectActionFlag"); + + b.HasData( + new + { + Id = 1, + Action = 4, + Name = "Assign" + }, + new + { + Id = 2, + Action = 3, + Name = "UnAssign" + }, + new + { + Id = 3, + Action = 8, + Name = "Unlock" + }, + new + { + Id = 4, + Action = 5, + Name = "Enable" + }, + new + { + Id = 5, + Action = 6, + Name = "Disable" + }, + new + { + Id = 6, + Action = 7, + Name = "Rename" + }, + new + { + Id = 7, + Action = 0, + Name = "Move" + }, + new + { + Id = 8, + Action = 2, + Name = "Create" + }, + new + { + Id = 9, + Action = 1, + Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DelegateName") + .HasColumnType("longtext"); + + b.Property("DelegateSid") + .IsRequired() + .HasColumnType("varbinary(3072)"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("IsSuperAdmin") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("DelegateSid") + .IsUnique(); + + b.ToTable("PermissionDelegate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("OU") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PermissionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowCustomGroups") + .HasColumnType("tinyint(1)"); + + b.Property("AllowUsernameOverride") + .HasColumnType("tinyint(1)"); + + b.Property("AskForAlternateEmail") + .HasColumnType("tinyint(1)"); + + b.Property("Category") + .HasColumnType("longtext"); + + b.Property("DeletedAt") + .HasColumnType("datetime(6)"); + + b.Property("DisplayNameFormula") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.Property("ParentOU") + .HasColumnType("longtext"); + + b.Property("ParentTemplateId") + .HasColumnType("int"); + + b.Property("PasswordFormula") + .HasColumnType("longtext"); + + b.Property("RequirePasswordChange") + .HasColumnType("tinyint(1)"); + + b.Property("SendWelcomeEmail") + .HasColumnType("tinyint(1)"); + + b.Property("UsernameFormula") + .HasColumnType("longtext"); + + b.Property("Visible") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("ParentTemplateId"); + + b.ToTable("DirectoryTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("Editable") + .HasColumnType("tinyint(1)"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("Required") + .HasColumnType("tinyint(1)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("DirectoryTemplateId"); + + b.HasIndex("FieldId"); + + b.ToTable("DirectoryTemplateFieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("GroupSid") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryTemplateId"); + + b.ToTable("DirectoryTemplateGroups"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("APIToken") + .HasColumnType("longtext"); + + b.Property("DarkMode") + .HasColumnType("tinyint(1)"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("ProfilePicture") + .HasColumnType("longblob"); + + b.Property("SearchDisabledComputers") + .HasColumnType("tinyint(1)"); + + b.Property("SearchDisabledUsers") + .HasColumnType("tinyint(1)"); + + b.Property("Theme") + .HasColumnType("longtext"); + + b.Property("UserGUID") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Username") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserGUID") + .IsUnique(); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime(6)"); + + b.Property("CreatorId") + .HasColumnType("int"); + + b.Property("Dismissable") + .HasColumnType("tinyint(1)"); + + b.Property("Expires") + .HasColumnType("datetime(6)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Link") + .HasColumnType("longtext"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("MessageType") + .HasColumnType("int"); + + b.Property("TargetDN") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("NotificationMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("NewsItemId") + .HasColumnType("double"); + + b.Property("NewsItemUpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ItemsPerPage") + .HasColumnType("int"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Slot") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("WidgetType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserDashboardWidgets"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserFavoriteEntries"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("IsRead") + .HasColumnType("tinyint(1)"); + + b.Property("NotificationId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotifications"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("Message") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Timestamp") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.Property("PermissionDelegatesId") + .HasColumnType("int"); + + b.Property("PermissionsMapsId") + .HasColumnType("int"); + + b.HasKey("PermissionDelegatesId", "PermissionsMapsId"); + + b.HasIndex("PermissionsMapsId"); + + b.ToTable("PermissionDelegatePermissionMapping"); + }); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessMapping", null) + .WithMany() + .HasForeignKey("FieldMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", null) + .WithMany() + .HasForeignKey("ObjectMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", null) + .WithMany() + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", null) + .WithMany() + .HasForeignKey("MembersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", null) + .WithMany("ObjectTypes") + .HasForeignKey("CustomActiveDirectoryFieldId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.HasOne("BLAZAM.Server.Data.ChatMessage", "ChatMessage") + .WithMany("NotReadBy") + .HasForeignKey("ChatMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatMessage"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("NotificationSubscriptions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.HasOne("BLAZAM.Database.Models.Notifications.NotificationSubscription", "NotificationSubscription") + .WithMany("NotificationTypes") + .HasForeignKey("NotificationSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationSubscription"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany("ActionMap") + .HasForeignKey("AccessLevelId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAction", "ObjectAction") + .WithMany() + .HasForeignKey("ObjectActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAction"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessLevel", "FieldAccessLevel") + .WithMany() + .HasForeignKey("FieldAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + + b.Navigation("FieldAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", "ObjectAccessLevel") + .WithMany("ObjectAccessMappings") + .HasForeignKey("ObjectAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.Navigation("ParentTemplate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("FieldValues") + .HasForeignKey("DirectoryTemplateId"); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("AssignedGroupSids") + .HasForeignKey("DirectoryTemplateId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("ReadNewsItems") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("DashboardWidgets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("FavoriteEntries") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.HasOne("BLAZAM.Database.Models.User.NotificationMessage", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", "ChatRoom") + .WithMany("Messages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionDelegate", null) + .WithMany() + .HasForeignKey("PermissionDelegatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionsMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Navigation("ObjectTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Navigation("NotificationTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Navigation("ActionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Navigation("ObjectAccessMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Navigation("AssignedGroupSids"); + + b.Navigation("FieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Navigation("DashboardWidgets"); + + b.Navigation("FavoriteEntries"); + + b.Navigation("NotificationSubscriptions"); + + b.Navigation("Notifications"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/20241108235530_Add_GlobalPerms_Requests_MySql.cs b/BLAZAMDatabase/Migrations/MySql/20241108235530_Add_GlobalPerms_Requests_MySql.cs new file mode 100644 index 000000000..f5da96d53 --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20241108235530_Add_GlobalPerms_Requests_MySql.cs @@ -0,0 +1,116 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.MySql +{ + /// + public partial class Add_GlobalPerms_Requests_MySql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Action", + table: "NotificationMessages", + type: "int", + nullable: true); + + migrationBuilder.AddColumn( + name: "CreatorId", + table: "NotificationMessages", + type: "int", + nullable: true); + + migrationBuilder.AddColumn( + name: "MessageType", + table: "NotificationMessages", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "TargetDN", + table: "NotificationMessages", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "GlobalPermissionRequestActions", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ObjectAction = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GlobalPermissionRequestActions", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "GlobalPermissionSettings", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + AllowSelfModification = table.Column(type: "tinyint(1)", nullable: false), + AllowAccessRequest = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GlobalPermissionSettings", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_NotificationMessages_CreatorId", + table: "NotificationMessages", + column: "CreatorId"); + + migrationBuilder.AddForeignKey( + name: "FK_NotificationMessages_UserSettings_CreatorId", + table: "NotificationMessages", + column: "CreatorId", + principalTable: "UserSettings", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_NotificationMessages_UserSettings_CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropTable( + name: "GlobalPermissionRequestActions"); + + migrationBuilder.DropTable( + name: "GlobalPermissionSettings"); + + migrationBuilder.DropIndex( + name: "IX_NotificationMessages_CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "Action", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "MessageType", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "TargetDN", + table: "NotificationMessages"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs index 9d95e57be..fdd7f360d 100644 --- a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("ProductVersion", "8.0.10") .HasAnnotation("Relational:MaxIdentifierLength", 64); MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); @@ -1109,6 +1109,41 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AccessLevelFieldMapping"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionRequestActions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ObjectAction") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionRequestActions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowAccessRequest") + .HasColumnType("tinyint(1)"); + + b.Property("AllowSelfModification") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionSettings"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => { b.Property("Id") @@ -1243,6 +1278,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) Id = 9, Action = 1, Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" }); }); @@ -1470,9 +1511,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Action") + .HasColumnType("int"); + b.Property("Created") .HasColumnType("datetime(6)"); + b.Property("CreatorId") + .HasColumnType("int"); + b.Property("Dismissable") .HasColumnType("tinyint(1)"); @@ -1488,11 +1535,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Message") .HasColumnType("longtext"); + b.Property("MessageType") + .HasColumnType("int"); + + b.Property("TargetDN") + .HasColumnType("longtext"); + b.Property("Title") .HasColumnType("longtext"); b.HasKey("Id"); + b.HasIndex("CreatorId"); + b.ToTable("NotificationMessages"); }); @@ -1828,6 +1883,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasForeignKey("DirectoryTemplateId"); }); + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") diff --git a/BLAZAMDatabase/Migrations/Sql/20241031220115_Add_Set_Password_Action_Sql.Designer.cs b/BLAZAMDatabase/Migrations/Sql/20241031220115_Add_Set_Password_Action_Sql.Designer.cs new file mode 100644 index 000000000..1289cf837 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20241031220115_Add_Set_Password_Action_Sql.Designer.cs @@ -0,0 +1,1978 @@ +// +using System; +using BLAZAM.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sql +{ + [DbContext(typeof(SqlDatabaseContext))] + [Migration("20241031220115_Add_Set_Password_Action_Sql")] + partial class Add_Set_Password_Action_Sql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("FieldMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "FieldMapId"); + + b.HasIndex("FieldMapId"); + + b.ToTable("AccessLevelFieldAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("ObjectMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "ObjectMapId"); + + b.HasIndex("ObjectMapId"); + + b.ToTable("AccessLevelObjectAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("PermissionMapsId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "PermissionMapsId"); + + b.HasIndex("PermissionMapsId"); + + b.ToTable("AccessLevelPermissionMapping"); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("MembersId") + .HasColumnType("int"); + + b.HasKey("ChatRoomId", "MembersId"); + + b.HasIndex("MembersId"); + + b.ToTable("AppUserChatRoom"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ADSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("ApplicationBaseDN") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FQDN") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ServerAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ServerPort") + .HasColumnType("int"); + + b.Property("UseTLS") + .HasColumnType("bit"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectorySettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectoryFields"); + + b.HasData( + new + { + Id = 1, + DisplayName = "Last Name", + FieldName = "sn", + FieldType = 0 + }, + new + { + Id = 2, + DisplayName = "First Name", + FieldName = "givenname", + FieldType = 0 + }, + new + { + Id = 3, + DisplayName = "Office", + FieldName = "physicalDeliveryOfficeName", + FieldType = 0 + }, + new + { + Id = 4, + DisplayName = "Employee ID", + FieldName = "employeeId", + FieldType = 0 + }, + new + { + Id = 5, + DisplayName = "Home Directory", + FieldName = "homeDirectory", + FieldType = 0 + }, + new + { + Id = 6, + DisplayName = "Logon Script Path", + FieldName = "scriptPath", + FieldType = 0 + }, + new + { + Id = 7, + DisplayName = "Profile Path", + FieldName = "profilePath", + FieldType = 0 + }, + new + { + Id = 8, + DisplayName = "Home Phone Number", + FieldName = "homePhone", + FieldType = 0 + }, + new + { + Id = 9, + DisplayName = "Street Address", + FieldName = "streetAddress", + FieldType = 0 + }, + new + { + Id = 10, + DisplayName = "City", + FieldName = "l", + FieldType = 0 + }, + new + { + Id = 11, + DisplayName = "State", + FieldName = "st", + FieldType = 0 + }, + new + { + Id = 12, + DisplayName = "Zip Code", + FieldName = "postalCode", + FieldType = 0 + }, + new + { + Id = 13, + DisplayName = "Site", + FieldName = "site", + FieldType = 0 + }, + new + { + Id = 14, + DisplayName = "Name", + FieldName = "name", + FieldType = 0 + }, + new + { + Id = 15, + DisplayName = "Username", + FieldName = "samaccountname", + FieldType = 0 + }, + new + { + Id = 16, + DisplayName = "SID", + FieldName = "objectSID", + FieldType = 2 + }, + new + { + Id = 17, + DisplayName = "E-Mail Address", + FieldName = "mail", + FieldType = 0 + }, + new + { + Id = 18, + DisplayName = "Description", + FieldName = "description", + FieldType = 0 + }, + new + { + Id = 19, + DisplayName = "Display Name", + FieldName = "displayName", + FieldType = 0 + }, + new + { + Id = 20, + DisplayName = "Distinguished Name", + FieldName = "distinguishedName", + FieldType = 0 + }, + new + { + Id = 21, + DisplayName = "Member Of", + FieldName = "memberOf", + FieldType = 4 + }, + new + { + Id = 22, + DisplayName = "Company", + FieldName = "company", + FieldType = 0 + }, + new + { + Id = 23, + DisplayName = "Title", + FieldName = "title", + FieldType = 0 + }, + new + { + Id = 24, + DisplayName = "User Principal Name", + FieldName = "userPrincipalName", + FieldType = 0 + }, + new + { + Id = 25, + DisplayName = "Telephone Number", + FieldName = "telephoneNumber", + FieldType = 0 + }, + new + { + Id = 26, + DisplayName = "PO Box", + FieldName = "postOfficeBox", + FieldType = 0 + }, + new + { + Id = 27, + DisplayName = "Canonical Name", + FieldName = "cn", + FieldType = 0 + }, + new + { + Id = 28, + DisplayName = "Home Drive", + FieldName = "homeDrive", + FieldType = 3 + }, + new + { + Id = 29, + DisplayName = "Department", + FieldName = "department", + FieldType = 0 + }, + new + { + Id = 30, + DisplayName = "Middle Name", + FieldName = "middleName", + FieldType = 0 + }, + new + { + Id = 31, + DisplayName = "Pager", + FieldName = "pager", + FieldType = 0 + }, + new + { + Id = 32, + DisplayName = "OS", + FieldName = "operatingSystemVersion", + FieldType = 0 + }, + new + { + Id = 33, + DisplayName = "Account Expiration", + FieldName = "accountExpires", + FieldType = 1 + }, + new + { + Id = 34, + DisplayName = "Manager", + FieldName = "manager", + FieldType = 0 + }, + new + { + Id = 35, + DisplayName = "Photo", + FieldName = "thumbnail", + FieldType = 2 + }, + new + { + Id = 36, + DisplayName = "Log On To", + FieldName = "userWorkstations", + FieldType = 0 + }, + new + { + Id = 37, + DisplayName = "Logon Hours", + FieldName = "logonHours", + FieldType = 2 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("CustomActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomActiveDirectoryFieldId"); + + b.ToTable("ActiveDirectoryFieldObjectMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AppSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AnalyticsId") + .HasColumnType("nvarchar(max)"); + + b.Property("AppFQDN") + .HasColumnType("nvarchar(max)"); + + b.Property("AppIcon") + .HasColumnType("varbinary(max)"); + + b.Property("AppName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AutoUpdate") + .HasColumnType("bit"); + + b.Property("AutoUpdateTime") + .HasColumnType("time"); + + b.Property("ForceHTTPS") + .HasColumnType("bit"); + + b.Property("InstallationCompleted") + .HasColumnType("bit"); + + b.Property("LastUpdateCheck") + .HasColumnType("datetime2"); + + b.Property("MOTD") + .HasColumnType("nvarchar(max)"); + + b.Property("MyrtilleURL") + .HasColumnType("nvarchar(max)"); + + b.Property("SSLCertificateCipher") + .HasColumnType("nvarchar(max)"); + + b.Property("SendDeveloperAnalytics") + .HasColumnType("bit"); + + b.Property("SendLogsToDeveloper") + .HasColumnType("bit"); + + b.Property("UpdateBranch") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateDomain") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatePassword") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateUsername") + .HasColumnType("nvarchar(max)"); + + b.Property("UseUpdateCredentials") + .HasColumnType("bit"); + + b.Property("UserHelpdeskURL") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AppSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1") + .HasName("CK_Table_Column1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.DirectoryEntryAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Sid") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DirectoryEntryAuditLogs"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.LogonAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LogonAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.PermissionsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("PermissionsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.RequestAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("RequestAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SettingsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("SettingsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SystemAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("SystemAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AuthenticationSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminPassword") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DuoApiHost") + .HasColumnType("nvarchar(max)"); + + b.Property("DuoClientId") + .HasColumnType("nvarchar(max)"); + + b.Property("DuoClientSecret") + .HasColumnType("nvarchar(max)"); + + b.Property("DuoEnabled") + .HasColumnType("bit"); + + b.Property("DuoUnreachableBehavior") + .HasColumnType("int"); + + b.Property("SessionTimeout") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AuthenticationSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1") + .HasName("CK_Table_Column2"); + }); + + b.HasData( + new + { + Id = 1, + AdminPassword = "password", + DuoEnabled = false, + DuoUnreachableBehavior = 0, + SessionTimeout = 15 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsPublic") + .HasColumnType("bit"); + + b.Property("MembersHash") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatMessageId") + .HasColumnType("int"); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatMessageId"); + + b.ToTable("UnreadChatMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CustomActiveDirectoryFields"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminBcc") + .HasColumnType("nvarchar(max)"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("FromAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("FromName") + .HasColumnType("nvarchar(max)"); + + b.Property("ReplyToAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("ReplyToName") + .HasColumnType("nvarchar(max)"); + + b.Property("SMTPPassword") + .HasColumnType("nvarchar(max)"); + + b.Property("SMTPPort") + .HasColumnType("int"); + + b.Property("SMTPServer") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SMTPUsername") + .HasColumnType("nvarchar(max)"); + + b.Property("UseSMTPAuth") + .HasColumnType("bit"); + + b.Property("UseTLS") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("EmailSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1") + .HasName("CK_Table_Column3"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TemplateType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Block") + .HasColumnType("bit"); + + b.Property("ByEmail") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("InApp") + .HasColumnType("bit"); + + b.Property("OU") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSubscriptions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("NotificationSubscriptionId") + .HasColumnType("int"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationSubscriptionId"); + + b.ToTable("SubscriptionNotificationType"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AccessLevels"); + + b.HasData( + new + { + Id = 1, + Name = "Deny All" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessLevelId") + .HasColumnType("int"); + + b.Property("AllowOrDeny") + .HasColumnType("bit"); + + b.Property("ObjectActionId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccessLevelId"); + + b.HasIndex("ObjectActionId"); + + b.ToTable("ActionAccessMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FieldAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 100, + Name = "Read" + }, + new + { + Id = 3, + Level = 1000, + Name = "Edit" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("FieldAccessLevelId") + .HasColumnType("int"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("FieldAccessLevelId"); + + b.HasIndex("FieldId"); + + b.ToTable("AccessLevelFieldMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ObjectAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 1000, + Name = "Read" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AllowDisabled") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("ObjectAccessLevelId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ObjectAccessLevelId"); + + b.ToTable("AccessLevelObjectMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ObjectActionFlag"); + + b.HasData( + new + { + Id = 1, + Action = 4, + Name = "Assign" + }, + new + { + Id = 2, + Action = 3, + Name = "UnAssign" + }, + new + { + Id = 3, + Action = 8, + Name = "Unlock" + }, + new + { + Id = 4, + Action = 5, + Name = "Enable" + }, + new + { + Id = 5, + Action = 6, + Name = "Disable" + }, + new + { + Id = 6, + Action = 7, + Name = "Rename" + }, + new + { + Id = 7, + Action = 0, + Name = "Move" + }, + new + { + Id = 8, + Action = 2, + Name = "Create" + }, + new + { + Id = 9, + Action = 1, + Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DelegateName") + .HasColumnType("nvarchar(max)"); + + b.Property("DelegateSid") + .IsRequired() + .HasColumnType("varbinary(900)"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsSuperAdmin") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("DelegateSid") + .IsUnique(); + + b.ToTable("PermissionDelegate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("OU") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("PermissionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AllowCustomGroups") + .HasColumnType("bit"); + + b.Property("AllowUsernameOverride") + .HasColumnType("bit"); + + b.Property("AskForAlternateEmail") + .HasColumnType("bit"); + + b.Property("Category") + .HasColumnType("nvarchar(max)"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DisplayNameFormula") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.Property("ParentOU") + .HasColumnType("nvarchar(max)"); + + b.Property("ParentTemplateId") + .HasColumnType("int"); + + b.Property("PasswordFormula") + .HasColumnType("nvarchar(max)"); + + b.Property("RequirePasswordChange") + .HasColumnType("bit"); + + b.Property("SendWelcomeEmail") + .HasColumnType("bit"); + + b.Property("UsernameFormula") + .HasColumnType("nvarchar(max)"); + + b.Property("Visible") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("ParentTemplateId"); + + b.ToTable("DirectoryTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("Editable") + .HasColumnType("bit"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("DirectoryTemplateId"); + + b.HasIndex("FieldId"); + + b.ToTable("DirectoryTemplateFieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("GroupSid") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryTemplateId"); + + b.ToTable("DirectoryTemplateGroups"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("APIToken") + .HasColumnType("nvarchar(max)"); + + b.Property("DarkMode") + .HasColumnType("bit"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("ProfilePicture") + .HasColumnType("varbinary(max)"); + + b.Property("SearchDisabledComputers") + .HasColumnType("bit"); + + b.Property("SearchDisabledUsers") + .HasColumnType("bit"); + + b.Property("Theme") + .HasColumnType("nvarchar(max)"); + + b.Property("UserGUID") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Username") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("UserGUID") + .IsUnique(); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Dismissable") + .HasColumnType("bit"); + + b.Property("Expires") + .HasColumnType("datetime2"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Link") + .HasColumnType("nvarchar(max)"); + + b.Property("Message") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("NotificationMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("NewsItemId") + .HasColumnType("float"); + + b.Property("NewsItemUpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ItemsPerPage") + .HasColumnType("int"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Slot") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("WidgetType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserDashboardWidgets"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DN") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserFavoriteEntries"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsRead") + .HasColumnType("bit"); + + b.Property("NotificationId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotifications"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.Property("PermissionDelegatesId") + .HasColumnType("int"); + + b.Property("PermissionsMapsId") + .HasColumnType("int"); + + b.HasKey("PermissionDelegatesId", "PermissionsMapsId"); + + b.HasIndex("PermissionsMapsId"); + + b.ToTable("PermissionDelegatePermissionMapping"); + }); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessMapping", null) + .WithMany() + .HasForeignKey("FieldMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", null) + .WithMany() + .HasForeignKey("ObjectMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", null) + .WithMany() + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", null) + .WithMany() + .HasForeignKey("MembersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", null) + .WithMany("ObjectTypes") + .HasForeignKey("CustomActiveDirectoryFieldId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.HasOne("BLAZAM.Server.Data.ChatMessage", "ChatMessage") + .WithMany("NotReadBy") + .HasForeignKey("ChatMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatMessage"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("NotificationSubscriptions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.HasOne("BLAZAM.Database.Models.Notifications.NotificationSubscription", "NotificationSubscription") + .WithMany("NotificationTypes") + .HasForeignKey("NotificationSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationSubscription"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany("ActionMap") + .HasForeignKey("AccessLevelId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAction", "ObjectAction") + .WithMany() + .HasForeignKey("ObjectActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAction"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessLevel", "FieldAccessLevel") + .WithMany() + .HasForeignKey("FieldAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + + b.Navigation("FieldAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", "ObjectAccessLevel") + .WithMany("ObjectAccessMappings") + .HasForeignKey("ObjectAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.Navigation("ParentTemplate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("FieldValues") + .HasForeignKey("DirectoryTemplateId"); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("AssignedGroupSids") + .HasForeignKey("DirectoryTemplateId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("ReadNewsItems") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("DashboardWidgets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("FavoriteEntries") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.HasOne("BLAZAM.Database.Models.User.NotificationMessage", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", "ChatRoom") + .WithMany("Messages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionDelegate", null) + .WithMany() + .HasForeignKey("PermissionDelegatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionsMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Navigation("ObjectTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Navigation("NotificationTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Navigation("ActionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Navigation("ObjectAccessMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Navigation("AssignedGroupSids"); + + b.Navigation("FieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Navigation("DashboardWidgets"); + + b.Navigation("FavoriteEntries"); + + b.Navigation("NotificationSubscriptions"); + + b.Navigation("Notifications"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/20241031220115_Add_Set_Password_Action_Sql.cs b/BLAZAMDatabase/Migrations/Sql/20241031220115_Add_Set_Password_Action_Sql.cs new file mode 100644 index 000000000..9723ba63a --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20241031220115_Add_Set_Password_Action_Sql.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sql +{ + /// + public partial class Add_Set_Password_Action_Sql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + table: "ObjectActionFlag", + columns: new[] { "Id", "Action", "Name" }, + values: new object[] { 10, 9, "Set Password" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "ObjectActionFlag", + keyColumn: "Id", + keyValue: 10); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/20241108235510_Add_GlobalPerms_Requests_Sql.Designer.cs b/BLAZAMDatabase/Migrations/Sql/20241108235510_Add_GlobalPerms_Requests_Sql.Designer.cs new file mode 100644 index 000000000..9c1434ba3 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20241108235510_Add_GlobalPerms_Requests_Sql.Designer.cs @@ -0,0 +1,2036 @@ +// +using System; +using BLAZAM.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sql +{ + [DbContext(typeof(SqlDatabaseContext))] + [Migration("20241108235510_Add_GlobalPerms_Requests_Sql")] + partial class Add_GlobalPerms_Requests_Sql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("FieldMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "FieldMapId"); + + b.HasIndex("FieldMapId"); + + b.ToTable("AccessLevelFieldAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("ObjectMapId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "ObjectMapId"); + + b.HasIndex("ObjectMapId"); + + b.ToTable("AccessLevelObjectAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("int"); + + b.Property("PermissionMapsId") + .HasColumnType("int"); + + b.HasKey("AccessLevelsId", "PermissionMapsId"); + + b.HasIndex("PermissionMapsId"); + + b.ToTable("AccessLevelPermissionMapping"); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("MembersId") + .HasColumnType("int"); + + b.HasKey("ChatRoomId", "MembersId"); + + b.HasIndex("MembersId"); + + b.ToTable("AppUserChatRoom"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ADSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("ApplicationBaseDN") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FQDN") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Password") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ServerAddress") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ServerPort") + .HasColumnType("int"); + + b.Property("UseTLS") + .HasColumnType("bit"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectorySettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectoryFields"); + + b.HasData( + new + { + Id = 1, + DisplayName = "Last Name", + FieldName = "sn", + FieldType = 0 + }, + new + { + Id = 2, + DisplayName = "First Name", + FieldName = "givenname", + FieldType = 0 + }, + new + { + Id = 3, + DisplayName = "Office", + FieldName = "physicalDeliveryOfficeName", + FieldType = 0 + }, + new + { + Id = 4, + DisplayName = "Employee ID", + FieldName = "employeeId", + FieldType = 0 + }, + new + { + Id = 5, + DisplayName = "Home Directory", + FieldName = "homeDirectory", + FieldType = 0 + }, + new + { + Id = 6, + DisplayName = "Logon Script Path", + FieldName = "scriptPath", + FieldType = 0 + }, + new + { + Id = 7, + DisplayName = "Profile Path", + FieldName = "profilePath", + FieldType = 0 + }, + new + { + Id = 8, + DisplayName = "Home Phone Number", + FieldName = "homePhone", + FieldType = 0 + }, + new + { + Id = 9, + DisplayName = "Street Address", + FieldName = "streetAddress", + FieldType = 0 + }, + new + { + Id = 10, + DisplayName = "City", + FieldName = "l", + FieldType = 0 + }, + new + { + Id = 11, + DisplayName = "State", + FieldName = "st", + FieldType = 0 + }, + new + { + Id = 12, + DisplayName = "Zip Code", + FieldName = "postalCode", + FieldType = 0 + }, + new + { + Id = 13, + DisplayName = "Site", + FieldName = "site", + FieldType = 0 + }, + new + { + Id = 14, + DisplayName = "Name", + FieldName = "name", + FieldType = 0 + }, + new + { + Id = 15, + DisplayName = "Username", + FieldName = "samaccountname", + FieldType = 0 + }, + new + { + Id = 16, + DisplayName = "SID", + FieldName = "objectSID", + FieldType = 2 + }, + new + { + Id = 17, + DisplayName = "E-Mail Address", + FieldName = "mail", + FieldType = 0 + }, + new + { + Id = 18, + DisplayName = "Description", + FieldName = "description", + FieldType = 0 + }, + new + { + Id = 19, + DisplayName = "Display Name", + FieldName = "displayName", + FieldType = 0 + }, + new + { + Id = 20, + DisplayName = "Distinguished Name", + FieldName = "distinguishedName", + FieldType = 0 + }, + new + { + Id = 21, + DisplayName = "Member Of", + FieldName = "memberOf", + FieldType = 4 + }, + new + { + Id = 22, + DisplayName = "Company", + FieldName = "company", + FieldType = 0 + }, + new + { + Id = 23, + DisplayName = "Title", + FieldName = "title", + FieldType = 0 + }, + new + { + Id = 24, + DisplayName = "User Principal Name", + FieldName = "userPrincipalName", + FieldType = 0 + }, + new + { + Id = 25, + DisplayName = "Telephone Number", + FieldName = "telephoneNumber", + FieldType = 0 + }, + new + { + Id = 26, + DisplayName = "PO Box", + FieldName = "postOfficeBox", + FieldType = 0 + }, + new + { + Id = 27, + DisplayName = "Canonical Name", + FieldName = "cn", + FieldType = 0 + }, + new + { + Id = 28, + DisplayName = "Home Drive", + FieldName = "homeDrive", + FieldType = 3 + }, + new + { + Id = 29, + DisplayName = "Department", + FieldName = "department", + FieldType = 0 + }, + new + { + Id = 30, + DisplayName = "Middle Name", + FieldName = "middleName", + FieldType = 0 + }, + new + { + Id = 31, + DisplayName = "Pager", + FieldName = "pager", + FieldType = 0 + }, + new + { + Id = 32, + DisplayName = "OS", + FieldName = "operatingSystemVersion", + FieldType = 0 + }, + new + { + Id = 33, + DisplayName = "Account Expiration", + FieldName = "accountExpires", + FieldType = 1 + }, + new + { + Id = 34, + DisplayName = "Manager", + FieldName = "manager", + FieldType = 0 + }, + new + { + Id = 35, + DisplayName = "Photo", + FieldName = "thumbnail", + FieldType = 2 + }, + new + { + Id = 36, + DisplayName = "Log On To", + FieldName = "userWorkstations", + FieldType = 0 + }, + new + { + Id = 37, + DisplayName = "Logon Hours", + FieldName = "logonHours", + FieldType = 2 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("CustomActiveDirectoryFieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomActiveDirectoryFieldId"); + + b.ToTable("ActiveDirectoryFieldObjectMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AppSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AnalyticsId") + .HasColumnType("nvarchar(max)"); + + b.Property("AppFQDN") + .HasColumnType("nvarchar(max)"); + + b.Property("AppIcon") + .HasColumnType("varbinary(max)"); + + b.Property("AppName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AutoUpdate") + .HasColumnType("bit"); + + b.Property("AutoUpdateTime") + .HasColumnType("time"); + + b.Property("ForceHTTPS") + .HasColumnType("bit"); + + b.Property("InstallationCompleted") + .HasColumnType("bit"); + + b.Property("LastUpdateCheck") + .HasColumnType("datetime2"); + + b.Property("MOTD") + .HasColumnType("nvarchar(max)"); + + b.Property("MyrtilleURL") + .HasColumnType("nvarchar(max)"); + + b.Property("SSLCertificateCipher") + .HasColumnType("nvarchar(max)"); + + b.Property("SendDeveloperAnalytics") + .HasColumnType("bit"); + + b.Property("SendLogsToDeveloper") + .HasColumnType("bit"); + + b.Property("UpdateBranch") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateDomain") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatePassword") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdateUsername") + .HasColumnType("nvarchar(max)"); + + b.Property("UseUpdateCredentials") + .HasColumnType("bit"); + + b.Property("UserHelpdeskURL") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AppSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1") + .HasName("CK_Table_Column1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.DirectoryEntryAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Sid") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("DirectoryEntryAuditLogs"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.LogonAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("LogonAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.PermissionsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("PermissionsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.RequestAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("RequestAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SettingsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("SettingsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SystemAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AfterAction") + .HasColumnType("nvarchar(max)"); + + b.Property("BeforeAction") + .HasColumnType("nvarchar(max)"); + + b.Property("IpAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("Target") + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("SystemAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AuthenticationSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminPassword") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DuoApiHost") + .HasColumnType("nvarchar(max)"); + + b.Property("DuoClientId") + .HasColumnType("nvarchar(max)"); + + b.Property("DuoClientSecret") + .HasColumnType("nvarchar(max)"); + + b.Property("DuoEnabled") + .HasColumnType("bit"); + + b.Property("DuoUnreachableBehavior") + .HasColumnType("int"); + + b.Property("SessionTimeout") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AuthenticationSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1") + .HasName("CK_Table_Column2"); + }); + + b.HasData( + new + { + Id = 1, + AdminPassword = "password", + DuoEnabled = false, + DuoUnreachableBehavior = 0, + SessionTimeout = 15 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsPublic") + .HasColumnType("bit"); + + b.Property("MembersHash") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatMessageId") + .HasColumnType("int"); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatMessageId"); + + b.ToTable("UnreadChatMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FieldType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CustomActiveDirectoryFields"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailSettings", b => + { + b.Property("Id") + .HasColumnType("int"); + + b.Property("AdminBcc") + .HasColumnType("nvarchar(max)"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("FromAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("FromName") + .HasColumnType("nvarchar(max)"); + + b.Property("ReplyToAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("ReplyToName") + .HasColumnType("nvarchar(max)"); + + b.Property("SMTPPassword") + .HasColumnType("nvarchar(max)"); + + b.Property("SMTPPort") + .HasColumnType("int"); + + b.Property("SMTPServer") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SMTPUsername") + .HasColumnType("nvarchar(max)"); + + b.Property("UseSMTPAuth") + .HasColumnType("bit"); + + b.Property("UseTLS") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("EmailSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1") + .HasName("CK_Table_Column3"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Body") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TemplateType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Block") + .HasColumnType("bit"); + + b.Property("ByEmail") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("InApp") + .HasColumnType("bit"); + + b.Property("OU") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSubscriptions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("NotificationSubscriptionId") + .HasColumnType("int"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationSubscriptionId"); + + b.ToTable("SubscriptionNotificationType"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("AccessLevels"); + + b.HasData( + new + { + Id = 1, + Name = "Deny All" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessLevelId") + .HasColumnType("int"); + + b.Property("AllowOrDeny") + .HasColumnType("bit"); + + b.Property("ObjectActionId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccessLevelId"); + + b.HasIndex("ObjectActionId"); + + b.ToTable("ActionAccessMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("FieldAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 100, + Name = "Read" + }, + new + { + Id = 3, + Level = 1000, + Name = "Edit" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("FieldAccessLevelId") + .HasColumnType("int"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("FieldAccessLevelId"); + + b.HasIndex("FieldId"); + + b.ToTable("AccessLevelFieldMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionRequestActions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ObjectAction") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionRequestActions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AllowAccessRequest") + .HasColumnType("bit"); + + b.Property("AllowSelfModification") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ObjectAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 1000, + Name = "Read" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AllowDisabled") + .HasColumnType("bit"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("ObjectAccessLevelId") + .HasColumnType("int"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ObjectAccessLevelId"); + + b.ToTable("AccessLevelObjectMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("ObjectActionFlag"); + + b.HasData( + new + { + Id = 1, + Action = 4, + Name = "Assign" + }, + new + { + Id = 2, + Action = 3, + Name = "UnAssign" + }, + new + { + Id = 3, + Action = 8, + Name = "Unlock" + }, + new + { + Id = 4, + Action = 5, + Name = "Enable" + }, + new + { + Id = 5, + Action = 6, + Name = "Disable" + }, + new + { + Id = 6, + Action = 7, + Name = "Rename" + }, + new + { + Id = 7, + Action = 0, + Name = "Move" + }, + new + { + Id = 8, + Action = 2, + Name = "Create" + }, + new + { + Id = 9, + Action = 1, + Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DelegateName") + .HasColumnType("nvarchar(max)"); + + b.Property("DelegateSid") + .IsRequired() + .HasColumnType("varbinary(900)"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("IsSuperAdmin") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("DelegateSid") + .IsUnique(); + + b.ToTable("PermissionDelegate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("OU") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("PermissionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AllowCustomGroups") + .HasColumnType("bit"); + + b.Property("AllowUsernameOverride") + .HasColumnType("bit"); + + b.Property("AskForAlternateEmail") + .HasColumnType("bit"); + + b.Property("Category") + .HasColumnType("nvarchar(max)"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DisplayNameFormula") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("ObjectType") + .HasColumnType("int"); + + b.Property("ParentOU") + .HasColumnType("nvarchar(max)"); + + b.Property("ParentTemplateId") + .HasColumnType("int"); + + b.Property("PasswordFormula") + .HasColumnType("nvarchar(max)"); + + b.Property("RequirePasswordChange") + .HasColumnType("bit"); + + b.Property("SendWelcomeEmail") + .HasColumnType("bit"); + + b.Property("UsernameFormula") + .HasColumnType("nvarchar(max)"); + + b.Property("Visible") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("ParentTemplateId"); + + b.ToTable("DirectoryTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CustomFieldId") + .HasColumnType("int"); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("Editable") + .HasColumnType("bit"); + + b.Property("FieldId") + .HasColumnType("int"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("DirectoryTemplateId"); + + b.HasIndex("FieldId"); + + b.ToTable("DirectoryTemplateFieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DirectoryTemplateId") + .HasColumnType("int"); + + b.Property("GroupSid") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryTemplateId"); + + b.ToTable("DirectoryTemplateGroups"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("APIToken") + .HasColumnType("nvarchar(max)"); + + b.Property("DarkMode") + .HasColumnType("bit"); + + b.Property("Email") + .HasColumnType("nvarchar(max)"); + + b.Property("ProfilePicture") + .HasColumnType("varbinary(max)"); + + b.Property("SearchDisabledComputers") + .HasColumnType("bit"); + + b.Property("SearchDisabledUsers") + .HasColumnType("bit"); + + b.Property("Theme") + .HasColumnType("nvarchar(max)"); + + b.Property("UserGUID") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Username") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("UserGUID") + .IsUnique(); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("CreatorId") + .HasColumnType("int"); + + b.Property("Dismissable") + .HasColumnType("bit"); + + b.Property("Expires") + .HasColumnType("datetime2"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Link") + .HasColumnType("nvarchar(max)"); + + b.Property("Message") + .HasColumnType("nvarchar(max)"); + + b.Property("MessageType") + .HasColumnType("int"); + + b.Property("TargetDN") + .HasColumnType("nvarchar(max)"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("NotificationMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("NewsItemId") + .HasColumnType("float"); + + b.Property("NewsItemUpdatedAt") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ItemsPerPage") + .HasColumnType("int"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Slot") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("WidgetType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserDashboardWidgets"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("DN") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserFavoriteEntries"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("IsRead") + .HasColumnType("bit"); + + b.Property("NotificationId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotifications"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ChatRoomId") + .HasColumnType("int"); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Timestamp") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.Property("PermissionDelegatesId") + .HasColumnType("int"); + + b.Property("PermissionsMapsId") + .HasColumnType("int"); + + b.HasKey("PermissionDelegatesId", "PermissionsMapsId"); + + b.HasIndex("PermissionsMapsId"); + + b.ToTable("PermissionDelegatePermissionMapping"); + }); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessMapping", null) + .WithMany() + .HasForeignKey("FieldMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", null) + .WithMany() + .HasForeignKey("ObjectMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", null) + .WithMany() + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", null) + .WithMany() + .HasForeignKey("MembersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", null) + .WithMany("ObjectTypes") + .HasForeignKey("CustomActiveDirectoryFieldId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.HasOne("BLAZAM.Server.Data.ChatMessage", "ChatMessage") + .WithMany("NotReadBy") + .HasForeignKey("ChatMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatMessage"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("NotificationSubscriptions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.HasOne("BLAZAM.Database.Models.Notifications.NotificationSubscription", "NotificationSubscription") + .WithMany("NotificationTypes") + .HasForeignKey("NotificationSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationSubscription"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany("ActionMap") + .HasForeignKey("AccessLevelId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAction", "ObjectAction") + .WithMany() + .HasForeignKey("ObjectActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAction"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessLevel", "FieldAccessLevel") + .WithMany() + .HasForeignKey("FieldAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + + b.Navigation("FieldAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", "ObjectAccessLevel") + .WithMany("ObjectAccessMappings") + .HasForeignKey("ObjectAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.Navigation("ParentTemplate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("FieldValues") + .HasForeignKey("DirectoryTemplateId"); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("AssignedGroupSids") + .HasForeignKey("DirectoryTemplateId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("ReadNewsItems") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("DashboardWidgets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("FavoriteEntries") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.HasOne("BLAZAM.Database.Models.User.NotificationMessage", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", "ChatRoom") + .WithMany("Messages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionDelegate", null) + .WithMany() + .HasForeignKey("PermissionDelegatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionsMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Navigation("ObjectTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Navigation("NotificationTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Navigation("ActionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Navigation("ObjectAccessMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Navigation("AssignedGroupSids"); + + b.Navigation("FieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Navigation("DashboardWidgets"); + + b.Navigation("FavoriteEntries"); + + b.Navigation("NotificationSubscriptions"); + + b.Navigation("Notifications"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/20241108235510_Add_GlobalPerms_Requests_Sql.cs b/BLAZAMDatabase/Migrations/Sql/20241108235510_Add_GlobalPerms_Requests_Sql.cs new file mode 100644 index 000000000..2d1f39a32 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20241108235510_Add_GlobalPerms_Requests_Sql.cs @@ -0,0 +1,112 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sql +{ + /// + public partial class Add_GlobalPerms_Requests_Sql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Action", + table: "NotificationMessages", + type: "int", + nullable: true); + + migrationBuilder.AddColumn( + name: "CreatorId", + table: "NotificationMessages", + type: "int", + nullable: true); + + migrationBuilder.AddColumn( + name: "MessageType", + table: "NotificationMessages", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "TargetDN", + table: "NotificationMessages", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.CreateTable( + name: "GlobalPermissionRequestActions", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + ObjectAction = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GlobalPermissionRequestActions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "GlobalPermissionSettings", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + AllowSelfModification = table.Column(type: "bit", nullable: false), + AllowAccessRequest = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GlobalPermissionSettings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_NotificationMessages_CreatorId", + table: "NotificationMessages", + column: "CreatorId"); + + migrationBuilder.AddForeignKey( + name: "FK_NotificationMessages_UserSettings_CreatorId", + table: "NotificationMessages", + column: "CreatorId", + principalTable: "UserSettings", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_NotificationMessages_UserSettings_CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropTable( + name: "GlobalPermissionRequestActions"); + + migrationBuilder.DropTable( + name: "GlobalPermissionSettings"); + + migrationBuilder.DropIndex( + name: "IX_NotificationMessages_CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "Action", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "MessageType", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "TargetDN", + table: "NotificationMessages"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs index d0d5d4275..2d2275f37 100644 --- a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("ProductVersion", "8.0.10") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -1109,6 +1109,41 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AccessLevelFieldMapping"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionRequestActions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ObjectAction") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionRequestActions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AllowAccessRequest") + .HasColumnType("bit"); + + b.Property("AllowSelfModification") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionSettings"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => { b.Property("Id") @@ -1243,6 +1278,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) Id = 9, Action = 1, Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" }); }); @@ -1470,9 +1511,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("Action") + .HasColumnType("int"); + b.Property("Created") .HasColumnType("datetime2"); + b.Property("CreatorId") + .HasColumnType("int"); + b.Property("Dismissable") .HasColumnType("bit"); @@ -1488,11 +1535,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Message") .HasColumnType("nvarchar(max)"); + b.Property("MessageType") + .HasColumnType("int"); + + b.Property("TargetDN") + .HasColumnType("nvarchar(max)"); + b.Property("Title") .HasColumnType("nvarchar(max)"); b.HasKey("Id"); + b.HasIndex("CreatorId"); + b.ToTable("NotificationMessages"); }); @@ -1828,6 +1883,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasForeignKey("DirectoryTemplateId"); }); + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") diff --git a/BLAZAMDatabase/Migrations/Sqlite/20241031220044_Add_Set_Password_Action_Sqlite.Designer.cs b/BLAZAMDatabase/Migrations/Sqlite/20241031220044_Add_Set_Password_Action_Sqlite.Designer.cs new file mode 100644 index 000000000..cdcc2e037 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20241031220044_Add_Set_Password_Action_Sqlite.Designer.cs @@ -0,0 +1,1904 @@ +// +using System; +using BLAZAM.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sqlite +{ + [DbContext(typeof(SqliteDatabaseContext))] + [Migration("20241031220044_Add_Set_Password_Action_Sqlite")] + partial class Add_Set_Password_Action_Sqlite + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("INTEGER"); + + b.Property("FieldMapId") + .HasColumnType("INTEGER"); + + b.HasKey("AccessLevelsId", "FieldMapId"); + + b.HasIndex("FieldMapId"); + + b.ToTable("AccessLevelFieldAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("INTEGER"); + + b.Property("ObjectMapId") + .HasColumnType("INTEGER"); + + b.HasKey("AccessLevelsId", "ObjectMapId"); + + b.HasIndex("ObjectMapId"); + + b.ToTable("AccessLevelObjectAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("INTEGER"); + + b.Property("PermissionMapsId") + .HasColumnType("INTEGER"); + + b.HasKey("AccessLevelsId", "PermissionMapsId"); + + b.HasIndex("PermissionMapsId"); + + b.ToTable("AccessLevelPermissionMapping"); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.Property("ChatRoomId") + .HasColumnType("INTEGER"); + + b.Property("MembersId") + .HasColumnType("INTEGER"); + + b.HasKey("ChatRoomId", "MembersId"); + + b.HasIndex("MembersId"); + + b.ToTable("AppUserChatRoom"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ADSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("ApplicationBaseDN") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FQDN") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerPort") + .HasColumnType("INTEGER"); + + b.Property("UseTLS") + .HasColumnType("INTEGER"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectorySettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectoryFields"); + + b.HasData( + new + { + Id = 1, + DisplayName = "Last Name", + FieldName = "sn", + FieldType = 0 + }, + new + { + Id = 2, + DisplayName = "First Name", + FieldName = "givenname", + FieldType = 0 + }, + new + { + Id = 3, + DisplayName = "Office", + FieldName = "physicalDeliveryOfficeName", + FieldType = 0 + }, + new + { + Id = 4, + DisplayName = "Employee ID", + FieldName = "employeeId", + FieldType = 0 + }, + new + { + Id = 5, + DisplayName = "Home Directory", + FieldName = "homeDirectory", + FieldType = 0 + }, + new + { + Id = 6, + DisplayName = "Logon Script Path", + FieldName = "scriptPath", + FieldType = 0 + }, + new + { + Id = 7, + DisplayName = "Profile Path", + FieldName = "profilePath", + FieldType = 0 + }, + new + { + Id = 8, + DisplayName = "Home Phone Number", + FieldName = "homePhone", + FieldType = 0 + }, + new + { + Id = 9, + DisplayName = "Street Address", + FieldName = "streetAddress", + FieldType = 0 + }, + new + { + Id = 10, + DisplayName = "City", + FieldName = "l", + FieldType = 0 + }, + new + { + Id = 11, + DisplayName = "State", + FieldName = "st", + FieldType = 0 + }, + new + { + Id = 12, + DisplayName = "Zip Code", + FieldName = "postalCode", + FieldType = 0 + }, + new + { + Id = 13, + DisplayName = "Site", + FieldName = "site", + FieldType = 0 + }, + new + { + Id = 14, + DisplayName = "Name", + FieldName = "name", + FieldType = 0 + }, + new + { + Id = 15, + DisplayName = "Username", + FieldName = "samaccountname", + FieldType = 0 + }, + new + { + Id = 16, + DisplayName = "SID", + FieldName = "objectSID", + FieldType = 2 + }, + new + { + Id = 17, + DisplayName = "E-Mail Address", + FieldName = "mail", + FieldType = 0 + }, + new + { + Id = 18, + DisplayName = "Description", + FieldName = "description", + FieldType = 0 + }, + new + { + Id = 19, + DisplayName = "Display Name", + FieldName = "displayName", + FieldType = 0 + }, + new + { + Id = 20, + DisplayName = "Distinguished Name", + FieldName = "distinguishedName", + FieldType = 0 + }, + new + { + Id = 21, + DisplayName = "Member Of", + FieldName = "memberOf", + FieldType = 4 + }, + new + { + Id = 22, + DisplayName = "Company", + FieldName = "company", + FieldType = 0 + }, + new + { + Id = 23, + DisplayName = "Title", + FieldName = "title", + FieldType = 0 + }, + new + { + Id = 24, + DisplayName = "User Principal Name", + FieldName = "userPrincipalName", + FieldType = 0 + }, + new + { + Id = 25, + DisplayName = "Telephone Number", + FieldName = "telephoneNumber", + FieldType = 0 + }, + new + { + Id = 26, + DisplayName = "PO Box", + FieldName = "postOfficeBox", + FieldType = 0 + }, + new + { + Id = 27, + DisplayName = "Canonical Name", + FieldName = "cn", + FieldType = 0 + }, + new + { + Id = 28, + DisplayName = "Home Drive", + FieldName = "homeDrive", + FieldType = 3 + }, + new + { + Id = 29, + DisplayName = "Department", + FieldName = "department", + FieldType = 0 + }, + new + { + Id = 30, + DisplayName = "Middle Name", + FieldName = "middleName", + FieldType = 0 + }, + new + { + Id = 31, + DisplayName = "Pager", + FieldName = "pager", + FieldType = 0 + }, + new + { + Id = 32, + DisplayName = "OS", + FieldName = "operatingSystemVersion", + FieldType = 0 + }, + new + { + Id = 33, + DisplayName = "Account Expiration", + FieldName = "accountExpires", + FieldType = 1 + }, + new + { + Id = 34, + DisplayName = "Manager", + FieldName = "manager", + FieldType = 0 + }, + new + { + Id = 35, + DisplayName = "Photo", + FieldName = "thumbnail", + FieldType = 2 + }, + new + { + Id = 36, + DisplayName = "Log On To", + FieldName = "userWorkstations", + FieldType = 0 + }, + new + { + Id = 37, + DisplayName = "Logon Hours", + FieldName = "logonHours", + FieldType = 2 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActiveDirectoryFieldId") + .HasColumnType("INTEGER"); + + b.Property("CustomActiveDirectoryFieldId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CustomActiveDirectoryFieldId"); + + b.ToTable("ActiveDirectoryFieldObjectMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AppSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("AnalyticsId") + .HasColumnType("TEXT"); + + b.Property("AppFQDN") + .HasColumnType("TEXT"); + + b.Property("AppIcon") + .HasColumnType("BLOB"); + + b.Property("AppName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AutoUpdate") + .HasColumnType("INTEGER"); + + b.Property("AutoUpdateTime") + .HasColumnType("TEXT"); + + b.Property("ForceHTTPS") + .HasColumnType("INTEGER"); + + b.Property("InstallationCompleted") + .HasColumnType("INTEGER"); + + b.Property("LastUpdateCheck") + .HasColumnType("TEXT"); + + b.Property("MOTD") + .HasColumnType("TEXT"); + + b.Property("MyrtilleURL") + .HasColumnType("TEXT"); + + b.Property("SSLCertificateCipher") + .HasColumnType("TEXT"); + + b.Property("SendDeveloperAnalytics") + .HasColumnType("INTEGER"); + + b.Property("SendLogsToDeveloper") + .HasColumnType("INTEGER"); + + b.Property("UpdateBranch") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateDomain") + .HasColumnType("TEXT"); + + b.Property("UpdatePassword") + .HasColumnType("TEXT"); + + b.Property("UpdateUsername") + .HasColumnType("TEXT"); + + b.Property("UseUpdateCredentials") + .HasColumnType("INTEGER"); + + b.Property("UserHelpdeskURL") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("AppSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.DirectoryEntryAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Sid") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("DirectoryEntryAuditLogs"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.LogonAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LogonAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.PermissionsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PermissionsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.RequestAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RequestAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SettingsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SettingsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SystemAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SystemAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AuthenticationSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("AdminPassword") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DuoApiHost") + .HasColumnType("TEXT"); + + b.Property("DuoClientId") + .HasColumnType("TEXT"); + + b.Property("DuoClientSecret") + .HasColumnType("TEXT"); + + b.Property("DuoEnabled") + .HasColumnType("INTEGER"); + + b.Property("DuoUnreachableBehavior") + .HasColumnType("INTEGER"); + + b.Property("SessionTimeout") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("AuthenticationSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + + b.HasData( + new + { + Id = 1, + AdminPassword = "password", + DuoEnabled = false, + DuoUnreachableBehavior = 0, + SessionTimeout = 15 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("IsPublic") + .HasColumnType("INTEGER"); + + b.Property("MembersHash") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChatMessageId") + .HasColumnType("INTEGER"); + + b.Property("ChatRoomId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChatMessageId"); + + b.ToTable("UnreadChatMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CustomActiveDirectoryFields"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("AdminBcc") + .HasColumnType("TEXT"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("FromAddress") + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasColumnType("TEXT"); + + b.Property("ReplyToAddress") + .HasColumnType("TEXT"); + + b.Property("ReplyToName") + .HasColumnType("TEXT"); + + b.Property("SMTPPassword") + .HasColumnType("TEXT"); + + b.Property("SMTPPort") + .HasColumnType("INTEGER"); + + b.Property("SMTPServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SMTPUsername") + .HasColumnType("TEXT"); + + b.Property("UseSMTPAuth") + .HasColumnType("INTEGER"); + + b.Property("UseTLS") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("EmailSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Body") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TemplateType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Block") + .HasColumnType("INTEGER"); + + b.Property("ByEmail") + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("InApp") + .HasColumnType("INTEGER"); + + b.Property("OU") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSubscriptions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("NotificationSubscriptionId") + .HasColumnType("INTEGER"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NotificationSubscriptionId"); + + b.ToTable("SubscriptionNotificationType"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("AccessLevels"); + + b.HasData( + new + { + Id = 1, + Name = "Deny All" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AccessLevelId") + .HasColumnType("INTEGER"); + + b.Property("AllowOrDeny") + .HasColumnType("INTEGER"); + + b.Property("ObjectActionId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("AccessLevelId"); + + b.HasIndex("ObjectActionId"); + + b.ToTable("ActionAccessMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("FieldAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 100, + Name = "Read" + }, + new + { + Id = 3, + Level = 1000, + Name = "Edit" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CustomFieldId") + .HasColumnType("INTEGER"); + + b.Property("FieldAccessLevelId") + .HasColumnType("INTEGER"); + + b.Property("FieldId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("FieldAccessLevelId"); + + b.HasIndex("FieldId"); + + b.ToTable("AccessLevelFieldMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ObjectAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 1000, + Name = "Read" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowDisabled") + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("ObjectAccessLevelId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ObjectAccessLevelId"); + + b.ToTable("AccessLevelObjectMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ObjectActionFlag"); + + b.HasData( + new + { + Id = 1, + Action = 4, + Name = "Assign" + }, + new + { + Id = 2, + Action = 3, + Name = "UnAssign" + }, + new + { + Id = 3, + Action = 8, + Name = "Unlock" + }, + new + { + Id = 4, + Action = 5, + Name = "Enable" + }, + new + { + Id = 5, + Action = 6, + Name = "Disable" + }, + new + { + Id = 6, + Action = 7, + Name = "Rename" + }, + new + { + Id = 7, + Action = 0, + Name = "Move" + }, + new + { + Id = 8, + Action = 2, + Name = "Create" + }, + new + { + Id = 9, + Action = 1, + Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DelegateName") + .HasColumnType("TEXT"); + + b.Property("DelegateSid") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("IsSuperAdmin") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DelegateSid") + .IsUnique(); + + b.ToTable("PermissionDelegate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("OU") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PermissionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowCustomGroups") + .HasColumnType("INTEGER"); + + b.Property("AllowUsernameOverride") + .HasColumnType("INTEGER"); + + b.Property("AskForAlternateEmail") + .HasColumnType("INTEGER"); + + b.Property("Category") + .HasColumnType("TEXT"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("DisplayNameFormula") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.Property("ParentOU") + .HasColumnType("TEXT"); + + b.Property("ParentTemplateId") + .HasColumnType("INTEGER"); + + b.Property("PasswordFormula") + .HasColumnType("TEXT"); + + b.Property("RequirePasswordChange") + .HasColumnType("INTEGER"); + + b.Property("SendWelcomeEmail") + .HasColumnType("INTEGER"); + + b.Property("UsernameFormula") + .HasColumnType("TEXT"); + + b.Property("Visible") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("ParentTemplateId"); + + b.ToTable("DirectoryTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CustomFieldId") + .HasColumnType("INTEGER"); + + b.Property("DirectoryTemplateId") + .HasColumnType("INTEGER"); + + b.Property("Editable") + .HasColumnType("INTEGER"); + + b.Property("FieldId") + .HasColumnType("INTEGER"); + + b.Property("Required") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("DirectoryTemplateId"); + + b.HasIndex("FieldId"); + + b.ToTable("DirectoryTemplateFieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DirectoryTemplateId") + .HasColumnType("INTEGER"); + + b.Property("GroupSid") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryTemplateId"); + + b.ToTable("DirectoryTemplateGroups"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("APIToken") + .HasColumnType("TEXT"); + + b.Property("DarkMode") + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("ProfilePicture") + .HasColumnType("BLOB"); + + b.Property("SearchDisabledComputers") + .HasColumnType("INTEGER"); + + b.Property("SearchDisabledUsers") + .HasColumnType("INTEGER"); + + b.Property("Theme") + .HasColumnType("TEXT"); + + b.Property("UserGUID") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserGUID") + .IsUnique(); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Dismissable") + .HasColumnType("INTEGER"); + + b.Property("Expires") + .HasColumnType("TEXT"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("NewsItemId") + .HasColumnType("REAL"); + + b.Property("NewsItemUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ItemsPerPage") + .HasColumnType("INTEGER"); + + b.Property("Order") + .HasColumnType("INTEGER"); + + b.Property("Slot") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.Property("WidgetType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserDashboardWidgets"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DN") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserFavoriteEntries"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("NotificationId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotifications"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChatRoomId") + .HasColumnType("INTEGER"); + + b.Property("Message") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.Property("PermissionDelegatesId") + .HasColumnType("INTEGER"); + + b.Property("PermissionsMapsId") + .HasColumnType("INTEGER"); + + b.HasKey("PermissionDelegatesId", "PermissionsMapsId"); + + b.HasIndex("PermissionsMapsId"); + + b.ToTable("PermissionDelegatePermissionMapping"); + }); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessMapping", null) + .WithMany() + .HasForeignKey("FieldMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", null) + .WithMany() + .HasForeignKey("ObjectMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", null) + .WithMany() + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", null) + .WithMany() + .HasForeignKey("MembersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", null) + .WithMany("ObjectTypes") + .HasForeignKey("CustomActiveDirectoryFieldId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.HasOne("BLAZAM.Server.Data.ChatMessage", "ChatMessage") + .WithMany("NotReadBy") + .HasForeignKey("ChatMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatMessage"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("NotificationSubscriptions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.HasOne("BLAZAM.Database.Models.Notifications.NotificationSubscription", "NotificationSubscription") + .WithMany("NotificationTypes") + .HasForeignKey("NotificationSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationSubscription"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany("ActionMap") + .HasForeignKey("AccessLevelId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAction", "ObjectAction") + .WithMany() + .HasForeignKey("ObjectActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAction"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessLevel", "FieldAccessLevel") + .WithMany() + .HasForeignKey("FieldAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + + b.Navigation("FieldAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", "ObjectAccessLevel") + .WithMany("ObjectAccessMappings") + .HasForeignKey("ObjectAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.Navigation("ParentTemplate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("FieldValues") + .HasForeignKey("DirectoryTemplateId"); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("AssignedGroupSids") + .HasForeignKey("DirectoryTemplateId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("ReadNewsItems") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("DashboardWidgets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("FavoriteEntries") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.HasOne("BLAZAM.Database.Models.User.NotificationMessage", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", "ChatRoom") + .WithMany("Messages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionDelegate", null) + .WithMany() + .HasForeignKey("PermissionDelegatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionsMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Navigation("ObjectTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Navigation("NotificationTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Navigation("ActionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Navigation("ObjectAccessMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Navigation("AssignedGroupSids"); + + b.Navigation("FieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Navigation("DashboardWidgets"); + + b.Navigation("FavoriteEntries"); + + b.Navigation("NotificationSubscriptions"); + + b.Navigation("Notifications"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/20241031220044_Add_Set_Password_Action_Sqlite.cs b/BLAZAMDatabase/Migrations/Sqlite/20241031220044_Add_Set_Password_Action_Sqlite.cs new file mode 100644 index 000000000..b4572325e --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20241031220044_Add_Set_Password_Action_Sqlite.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sqlite +{ + /// + public partial class Add_Set_Password_Action_Sqlite : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertData( + table: "ObjectActionFlag", + columns: new[] { "Id", "Action", "Name" }, + values: new object[] { 10, 9, "Set Password" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "ObjectActionFlag", + keyColumn: "Id", + keyValue: 10); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/20241108235451_Add_GlobalPerms_Requests_Sqlite.Designer.cs b/BLAZAMDatabase/Migrations/Sqlite/20241108235451_Add_GlobalPerms_Requests_Sqlite.Designer.cs new file mode 100644 index 000000000..9d697a14f --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20241108235451_Add_GlobalPerms_Requests_Sqlite.Designer.cs @@ -0,0 +1,1958 @@ +// +using System; +using BLAZAM.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sqlite +{ + [DbContext(typeof(SqliteDatabaseContext))] + [Migration("20241108235451_Add_GlobalPerms_Requests_Sqlite")] + partial class Add_GlobalPerms_Requests_Sqlite + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("INTEGER"); + + b.Property("FieldMapId") + .HasColumnType("INTEGER"); + + b.HasKey("AccessLevelsId", "FieldMapId"); + + b.HasIndex("FieldMapId"); + + b.ToTable("AccessLevelFieldAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("INTEGER"); + + b.Property("ObjectMapId") + .HasColumnType("INTEGER"); + + b.HasKey("AccessLevelsId", "ObjectMapId"); + + b.HasIndex("ObjectMapId"); + + b.ToTable("AccessLevelObjectAccessMapping"); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.Property("AccessLevelsId") + .HasColumnType("INTEGER"); + + b.Property("PermissionMapsId") + .HasColumnType("INTEGER"); + + b.HasKey("AccessLevelsId", "PermissionMapsId"); + + b.HasIndex("PermissionMapsId"); + + b.ToTable("AccessLevelPermissionMapping"); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.Property("ChatRoomId") + .HasColumnType("INTEGER"); + + b.Property("MembersId") + .HasColumnType("INTEGER"); + + b.HasKey("ChatRoomId", "MembersId"); + + b.HasIndex("MembersId"); + + b.ToTable("AppUserChatRoom"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ADSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("ApplicationBaseDN") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FQDN") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerPort") + .HasColumnType("INTEGER"); + + b.Property("UseTLS") + .HasColumnType("INTEGER"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectorySettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ActiveDirectoryFields"); + + b.HasData( + new + { + Id = 1, + DisplayName = "Last Name", + FieldName = "sn", + FieldType = 0 + }, + new + { + Id = 2, + DisplayName = "First Name", + FieldName = "givenname", + FieldType = 0 + }, + new + { + Id = 3, + DisplayName = "Office", + FieldName = "physicalDeliveryOfficeName", + FieldType = 0 + }, + new + { + Id = 4, + DisplayName = "Employee ID", + FieldName = "employeeId", + FieldType = 0 + }, + new + { + Id = 5, + DisplayName = "Home Directory", + FieldName = "homeDirectory", + FieldType = 0 + }, + new + { + Id = 6, + DisplayName = "Logon Script Path", + FieldName = "scriptPath", + FieldType = 0 + }, + new + { + Id = 7, + DisplayName = "Profile Path", + FieldName = "profilePath", + FieldType = 0 + }, + new + { + Id = 8, + DisplayName = "Home Phone Number", + FieldName = "homePhone", + FieldType = 0 + }, + new + { + Id = 9, + DisplayName = "Street Address", + FieldName = "streetAddress", + FieldType = 0 + }, + new + { + Id = 10, + DisplayName = "City", + FieldName = "l", + FieldType = 0 + }, + new + { + Id = 11, + DisplayName = "State", + FieldName = "st", + FieldType = 0 + }, + new + { + Id = 12, + DisplayName = "Zip Code", + FieldName = "postalCode", + FieldType = 0 + }, + new + { + Id = 13, + DisplayName = "Site", + FieldName = "site", + FieldType = 0 + }, + new + { + Id = 14, + DisplayName = "Name", + FieldName = "name", + FieldType = 0 + }, + new + { + Id = 15, + DisplayName = "Username", + FieldName = "samaccountname", + FieldType = 0 + }, + new + { + Id = 16, + DisplayName = "SID", + FieldName = "objectSID", + FieldType = 2 + }, + new + { + Id = 17, + DisplayName = "E-Mail Address", + FieldName = "mail", + FieldType = 0 + }, + new + { + Id = 18, + DisplayName = "Description", + FieldName = "description", + FieldType = 0 + }, + new + { + Id = 19, + DisplayName = "Display Name", + FieldName = "displayName", + FieldType = 0 + }, + new + { + Id = 20, + DisplayName = "Distinguished Name", + FieldName = "distinguishedName", + FieldType = 0 + }, + new + { + Id = 21, + DisplayName = "Member Of", + FieldName = "memberOf", + FieldType = 4 + }, + new + { + Id = 22, + DisplayName = "Company", + FieldName = "company", + FieldType = 0 + }, + new + { + Id = 23, + DisplayName = "Title", + FieldName = "title", + FieldType = 0 + }, + new + { + Id = 24, + DisplayName = "User Principal Name", + FieldName = "userPrincipalName", + FieldType = 0 + }, + new + { + Id = 25, + DisplayName = "Telephone Number", + FieldName = "telephoneNumber", + FieldType = 0 + }, + new + { + Id = 26, + DisplayName = "PO Box", + FieldName = "postOfficeBox", + FieldType = 0 + }, + new + { + Id = 27, + DisplayName = "Canonical Name", + FieldName = "cn", + FieldType = 0 + }, + new + { + Id = 28, + DisplayName = "Home Drive", + FieldName = "homeDrive", + FieldType = 3 + }, + new + { + Id = 29, + DisplayName = "Department", + FieldName = "department", + FieldType = 0 + }, + new + { + Id = 30, + DisplayName = "Middle Name", + FieldName = "middleName", + FieldType = 0 + }, + new + { + Id = 31, + DisplayName = "Pager", + FieldName = "pager", + FieldType = 0 + }, + new + { + Id = 32, + DisplayName = "OS", + FieldName = "operatingSystemVersion", + FieldType = 0 + }, + new + { + Id = 33, + DisplayName = "Account Expiration", + FieldName = "accountExpires", + FieldType = 1 + }, + new + { + Id = 34, + DisplayName = "Manager", + FieldName = "manager", + FieldType = 0 + }, + new + { + Id = 35, + DisplayName = "Photo", + FieldName = "thumbnail", + FieldType = 2 + }, + new + { + Id = 36, + DisplayName = "Log On To", + FieldName = "userWorkstations", + FieldType = 0 + }, + new + { + Id = 37, + DisplayName = "Logon Hours", + FieldName = "logonHours", + FieldType = 2 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActiveDirectoryFieldId") + .HasColumnType("INTEGER"); + + b.Property("CustomActiveDirectoryFieldId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CustomActiveDirectoryFieldId"); + + b.ToTable("ActiveDirectoryFieldObjectMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AppSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("AnalyticsId") + .HasColumnType("TEXT"); + + b.Property("AppFQDN") + .HasColumnType("TEXT"); + + b.Property("AppIcon") + .HasColumnType("BLOB"); + + b.Property("AppName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AutoUpdate") + .HasColumnType("INTEGER"); + + b.Property("AutoUpdateTime") + .HasColumnType("TEXT"); + + b.Property("ForceHTTPS") + .HasColumnType("INTEGER"); + + b.Property("InstallationCompleted") + .HasColumnType("INTEGER"); + + b.Property("LastUpdateCheck") + .HasColumnType("TEXT"); + + b.Property("MOTD") + .HasColumnType("TEXT"); + + b.Property("MyrtilleURL") + .HasColumnType("TEXT"); + + b.Property("SSLCertificateCipher") + .HasColumnType("TEXT"); + + b.Property("SendDeveloperAnalytics") + .HasColumnType("INTEGER"); + + b.Property("SendLogsToDeveloper") + .HasColumnType("INTEGER"); + + b.Property("UpdateBranch") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateDomain") + .HasColumnType("TEXT"); + + b.Property("UpdatePassword") + .HasColumnType("TEXT"); + + b.Property("UpdateUsername") + .HasColumnType("TEXT"); + + b.Property("UseUpdateCredentials") + .HasColumnType("INTEGER"); + + b.Property("UserHelpdeskURL") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("AppSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.DirectoryEntryAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Sid") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("DirectoryEntryAuditLogs"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.LogonAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LogonAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.PermissionsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PermissionsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.RequestAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("RequestAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SettingsAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SettingsAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Audit.SystemAuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("AfterAction") + .HasColumnType("TEXT"); + + b.Property("BeforeAction") + .HasColumnType("TEXT"); + + b.Property("IpAddress") + .HasColumnType("TEXT"); + + b.Property("Target") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SystemAuditLog"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.AuthenticationSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("AdminPassword") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DuoApiHost") + .HasColumnType("TEXT"); + + b.Property("DuoClientId") + .HasColumnType("TEXT"); + + b.Property("DuoClientSecret") + .HasColumnType("TEXT"); + + b.Property("DuoEnabled") + .HasColumnType("INTEGER"); + + b.Property("DuoUnreachableBehavior") + .HasColumnType("INTEGER"); + + b.Property("SessionTimeout") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("AuthenticationSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + + b.HasData( + new + { + Id = 1, + AdminPassword = "password", + DuoEnabled = false, + DuoUnreachableBehavior = 0, + SessionTimeout = 15 + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("IsPublic") + .HasColumnType("INTEGER"); + + b.Property("MembersHash") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChatMessageId") + .HasColumnType("INTEGER"); + + b.Property("ChatRoomId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChatMessageId"); + + b.ToTable("UnreadChatMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FieldType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CustomActiveDirectoryFields"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailSettings", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.Property("AdminBcc") + .HasColumnType("TEXT"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("FromAddress") + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasColumnType("TEXT"); + + b.Property("ReplyToAddress") + .HasColumnType("TEXT"); + + b.Property("ReplyToName") + .HasColumnType("TEXT"); + + b.Property("SMTPPassword") + .HasColumnType("TEXT"); + + b.Property("SMTPPort") + .HasColumnType("INTEGER"); + + b.Property("SMTPServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SMTPUsername") + .HasColumnType("TEXT"); + + b.Property("UseSMTPAuth") + .HasColumnType("INTEGER"); + + b.Property("UseTLS") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("EmailSettings", t => + { + t.HasCheckConstraint("CK_Table_Column", "[Id] = 1"); + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.EmailTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Body") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TemplateType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("EmailTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Block") + .HasColumnType("INTEGER"); + + b.Property("ByEmail") + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("InApp") + .HasColumnType("INTEGER"); + + b.Property("OU") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSubscriptions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("NotificationSubscriptionId") + .HasColumnType("INTEGER"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NotificationSubscriptionId"); + + b.ToTable("SubscriptionNotificationType"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("AccessLevels"); + + b.HasData( + new + { + Id = 1, + Name = "Deny All" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AccessLevelId") + .HasColumnType("INTEGER"); + + b.Property("AllowOrDeny") + .HasColumnType("INTEGER"); + + b.Property("ObjectActionId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("AccessLevelId"); + + b.HasIndex("ObjectActionId"); + + b.ToTable("ActionAccessMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("FieldAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 100, + Name = "Read" + }, + new + { + Id = 3, + Level = 1000, + Name = "Edit" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CustomFieldId") + .HasColumnType("INTEGER"); + + b.Property("FieldAccessLevelId") + .HasColumnType("INTEGER"); + + b.Property("FieldId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("FieldAccessLevelId"); + + b.HasIndex("FieldId"); + + b.ToTable("AccessLevelFieldMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionRequestActions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ObjectAction") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionRequestActions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowAccessRequest") + .HasColumnType("INTEGER"); + + b.Property("AllowSelfModification") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ObjectAccessLevel"); + + b.HasData( + new + { + Id = 1, + Level = 10, + Name = "Deny" + }, + new + { + Id = 2, + Level = 1000, + Name = "Read" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowDisabled") + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("ObjectAccessLevelId") + .HasColumnType("INTEGER"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ObjectAccessLevelId"); + + b.ToTable("AccessLevelObjectMapping"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ObjectActionFlag"); + + b.HasData( + new + { + Id = 1, + Action = 4, + Name = "Assign" + }, + new + { + Id = 2, + Action = 3, + Name = "UnAssign" + }, + new + { + Id = 3, + Action = 8, + Name = "Unlock" + }, + new + { + Id = 4, + Action = 5, + Name = "Enable" + }, + new + { + Id = 5, + Action = 6, + Name = "Disable" + }, + new + { + Id = 6, + Action = 7, + Name = "Rename" + }, + new + { + Id = 7, + Action = 0, + Name = "Move" + }, + new + { + Id = 8, + Action = 2, + Name = "Create" + }, + new + { + Id = 9, + Action = 1, + Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DelegateName") + .HasColumnType("TEXT"); + + b.Property("DelegateSid") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("IsSuperAdmin") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DelegateSid") + .IsUnique(); + + b.ToTable("PermissionDelegate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("OU") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PermissionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowCustomGroups") + .HasColumnType("INTEGER"); + + b.Property("AllowUsernameOverride") + .HasColumnType("INTEGER"); + + b.Property("AskForAlternateEmail") + .HasColumnType("INTEGER"); + + b.Property("Category") + .HasColumnType("TEXT"); + + b.Property("DeletedAt") + .HasColumnType("TEXT"); + + b.Property("DisplayNameFormula") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ObjectType") + .HasColumnType("INTEGER"); + + b.Property("ParentOU") + .HasColumnType("TEXT"); + + b.Property("ParentTemplateId") + .HasColumnType("INTEGER"); + + b.Property("PasswordFormula") + .HasColumnType("TEXT"); + + b.Property("RequirePasswordChange") + .HasColumnType("INTEGER"); + + b.Property("SendWelcomeEmail") + .HasColumnType("INTEGER"); + + b.Property("UsernameFormula") + .HasColumnType("TEXT"); + + b.Property("Visible") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("ParentTemplateId"); + + b.ToTable("DirectoryTemplates"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CustomFieldId") + .HasColumnType("INTEGER"); + + b.Property("DirectoryTemplateId") + .HasColumnType("INTEGER"); + + b.Property("Editable") + .HasColumnType("INTEGER"); + + b.Property("FieldId") + .HasColumnType("INTEGER"); + + b.Property("Required") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CustomFieldId"); + + b.HasIndex("DirectoryTemplateId"); + + b.HasIndex("FieldId"); + + b.ToTable("DirectoryTemplateFieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DirectoryTemplateId") + .HasColumnType("INTEGER"); + + b.Property("GroupSid") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryTemplateId"); + + b.ToTable("DirectoryTemplateGroups"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("APIToken") + .HasColumnType("TEXT"); + + b.Property("DarkMode") + .HasColumnType("INTEGER"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("ProfilePicture") + .HasColumnType("BLOB"); + + b.Property("SearchDisabledComputers") + .HasColumnType("INTEGER"); + + b.Property("SearchDisabledUsers") + .HasColumnType("INTEGER"); + + b.Property("Theme") + .HasColumnType("TEXT"); + + b.Property("UserGUID") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserGUID") + .IsUnique(); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Action") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("CreatorId") + .HasColumnType("INTEGER"); + + b.Property("Dismissable") + .HasColumnType("INTEGER"); + + b.Property("Expires") + .HasColumnType("TEXT"); + + b.Property("Level") + .HasColumnType("INTEGER"); + + b.Property("Link") + .HasColumnType("TEXT"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("TargetDN") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.ToTable("NotificationMessages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("NewsItemId") + .HasColumnType("REAL"); + + b.Property("NewsItemUpdatedAt") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ItemsPerPage") + .HasColumnType("INTEGER"); + + b.Property("Order") + .HasColumnType("INTEGER"); + + b.Property("Slot") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.Property("WidgetType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserDashboardWidgets"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DN") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserFavoriteEntries"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("NotificationId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NotificationId"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotifications"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChatRoomId") + .HasColumnType("INTEGER"); + + b.Property("Message") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.Property("PermissionDelegatesId") + .HasColumnType("INTEGER"); + + b.Property("PermissionsMapsId") + .HasColumnType("INTEGER"); + + b.HasKey("PermissionDelegatesId", "PermissionsMapsId"); + + b.HasIndex("PermissionsMapsId"); + + b.ToTable("PermissionDelegatePermissionMapping"); + }); + + modelBuilder.Entity("AccessLevelFieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessMapping", null) + .WithMany() + .HasForeignKey("FieldMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", null) + .WithMany() + .HasForeignKey("ObjectMapId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessLevelPermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany() + .HasForeignKey("AccessLevelsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AppUserChatRoom", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", null) + .WithMany() + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", null) + .WithMany() + .HasForeignKey("MembersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.ActiveDirectoryFieldObjectType", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", null) + .WithMany("ObjectTypes") + .HasForeignKey("CustomActiveDirectoryFieldId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.UnreadChatMessage", b => + { + b.HasOne("BLAZAM.Server.Data.ChatMessage", "ChatMessage") + .WithMany("NotReadBy") + .HasForeignKey("ChatMessageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatMessage"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("NotificationSubscriptions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.HasOne("BLAZAM.Database.Models.Notifications.NotificationSubscription", "NotificationSubscription") + .WithMany("NotificationTypes") + .HasForeignKey("NotificationSubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NotificationSubscription"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) + .WithMany("ActionMap") + .HasForeignKey("AccessLevelId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAction", "ObjectAction") + .WithMany() + .HasForeignKey("ObjectActionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAction"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.FieldAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Permissions.FieldAccessLevel", "FieldAccessLevel") + .WithMany() + .HasForeignKey("FieldAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + + b.Navigation("FieldAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", "ObjectAccessLevel") + .WithMany("ObjectAccessMappings") + .HasForeignKey("ObjectAccessLevelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ObjectAccessLevel"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", "ParentTemplate") + .WithMany() + .HasForeignKey("ParentTemplateId"); + + b.Navigation("ParentTemplate"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateFieldValue", b => + { + b.HasOne("BLAZAM.Database.Models.CustomActiveDirectoryField", "CustomField") + .WithMany() + .HasForeignKey("CustomFieldId"); + + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("FieldValues") + .HasForeignKey("DirectoryTemplateId"); + + b.HasOne("BLAZAM.Database.Models.ActiveDirectoryField", "Field") + .WithMany() + .HasForeignKey("FieldId"); + + b.Navigation("CustomField"); + + b.Navigation("Field"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplateGroup", b => + { + b.HasOne("BLAZAM.Database.Models.Templates.DirectoryTemplate", null) + .WithMany("AssignedGroupSids") + .HasForeignKey("DirectoryTemplateId"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("ReadNewsItems") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserDashboardWidget", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("DashboardWidgets") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserFavoriteEntry", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("FavoriteEntries") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.UserNotification", b => + { + b.HasOne("BLAZAM.Database.Models.User.NotificationMessage", "Notification") + .WithMany() + .HasForeignKey("NotificationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Notification"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.HasOne("BLAZAM.Database.Models.Chat.ChatRoom", "ChatRoom") + .WithMany("Messages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("PermissionDelegatePermissionMapping", b => + { + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionDelegate", null) + .WithMany() + .HasForeignKey("PermissionDelegatesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BLAZAM.Database.Models.Permissions.PermissionMapping", null) + .WithMany() + .HasForeignKey("PermissionsMapsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Chat.ChatRoom", b => + { + b.Navigation("Messages"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.CustomActiveDirectoryField", b => + { + b.Navigation("ObjectTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Navigation("NotificationTypes"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.AccessLevel", b => + { + b.Navigation("ActionMap"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => + { + b.Navigation("ObjectAccessMappings"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Templates.DirectoryTemplate", b => + { + b.Navigation("AssignedGroupSids"); + + b.Navigation("FieldValues"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.User.AppUser", b => + { + b.Navigation("DashboardWidgets"); + + b.Navigation("FavoriteEntries"); + + b.Navigation("NotificationSubscriptions"); + + b.Navigation("Notifications"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/20241108235451_Add_GlobalPerms_Requests_Sqlite.cs b/BLAZAMDatabase/Migrations/Sqlite/20241108235451_Add_GlobalPerms_Requests_Sqlite.cs new file mode 100644 index 000000000..99ffb2767 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20241108235451_Add_GlobalPerms_Requests_Sqlite.cs @@ -0,0 +1,112 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sqlite +{ + /// + public partial class Add_GlobalPerms_Requests_Sqlite : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Action", + table: "NotificationMessages", + type: "INTEGER", + nullable: true); + + migrationBuilder.AddColumn( + name: "CreatorId", + table: "NotificationMessages", + type: "INTEGER", + nullable: true); + + migrationBuilder.AddColumn( + name: "MessageType", + table: "NotificationMessages", + type: "INTEGER", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "TargetDN", + table: "NotificationMessages", + type: "TEXT", + nullable: true); + + migrationBuilder.CreateTable( + name: "GlobalPermissionRequestActions", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ObjectAction = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GlobalPermissionRequestActions", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "GlobalPermissionSettings", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + AllowSelfModification = table.Column(type: "INTEGER", nullable: false), + AllowAccessRequest = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GlobalPermissionSettings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_NotificationMessages_CreatorId", + table: "NotificationMessages", + column: "CreatorId"); + + migrationBuilder.AddForeignKey( + name: "FK_NotificationMessages_UserSettings_CreatorId", + table: "NotificationMessages", + column: "CreatorId", + principalTable: "UserSettings", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_NotificationMessages_UserSettings_CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropTable( + name: "GlobalPermissionRequestActions"); + + migrationBuilder.DropTable( + name: "GlobalPermissionSettings"); + + migrationBuilder.DropIndex( + name: "IX_NotificationMessages_CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "Action", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "CreatorId", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "MessageType", + table: "NotificationMessages"); + + migrationBuilder.DropColumn( + name: "TargetDN", + table: "NotificationMessages"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs index 71ea39ebe..d61591607 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs @@ -15,7 +15,7 @@ partial class SqliteDatabaseContextModelSnapshot : ModelSnapshot protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.8"); + modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); modelBuilder.Entity("AccessLevelFieldAccessMapping", b => { @@ -1065,6 +1065,37 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AccessLevelFieldMapping"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionRequestActions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ObjectAction") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionRequestActions"); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.GlobalPermissionSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowAccessRequest") + .HasColumnType("INTEGER"); + + b.Property("AllowSelfModification") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("GlobalPermissionSettings"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ObjectAccessLevel", b => { b.Property("Id") @@ -1193,6 +1224,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) Id = 9, Action = 1, Name = "Delete" + }, + new + { + Id = 10, + Action = 9, + Name = "Set Password" }); }); @@ -1406,9 +1443,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("Action") + .HasColumnType("INTEGER"); + b.Property("Created") .HasColumnType("TEXT"); + b.Property("CreatorId") + .HasColumnType("INTEGER"); + b.Property("Dismissable") .HasColumnType("INTEGER"); @@ -1424,11 +1467,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Message") .HasColumnType("TEXT"); + b.Property("MessageType") + .HasColumnType("INTEGER"); + + b.Property("TargetDN") + .HasColumnType("TEXT"); + b.Property("Title") .HasColumnType("TEXT"); b.HasKey("Id"); + b.HasIndex("CreatorId"); + b.ToTable("NotificationMessages"); }); @@ -1754,6 +1805,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasForeignKey("DirectoryTemplateId"); }); + modelBuilder.Entity("BLAZAM.Database.Models.User.NotificationMessage", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.Navigation("Creator"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.User.ReadNewsItem", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") diff --git a/BLAZAMDatabase/Models/IActiveDirectoryField.cs b/BLAZAMDatabase/Models/IActiveDirectoryField.cs index 78bf4ad05..2ab1fd8e2 100644 --- a/BLAZAMDatabase/Models/IActiveDirectoryField.cs +++ b/BLAZAMDatabase/Models/IActiveDirectoryField.cs @@ -4,6 +4,7 @@ namespace BLAZAM.Database.Models { public interface IActiveDirectoryField { + public int Id { get; set; } /// /// The display name for this field in the application /// diff --git a/BLAZAMDatabase/Models/Permissions/AccessLevel.cs b/BLAZAMDatabase/Models/Permissions/AccessLevel.cs index 2239e6e3d..c1655c9e5 100644 --- a/BLAZAMDatabase/Models/Permissions/AccessLevel.cs +++ b/BLAZAMDatabase/Models/Permissions/AccessLevel.cs @@ -1,10 +1,14 @@  using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; namespace BLAZAM.Database.Models.Permissions { public class AccessLevel : RecoverableAppDbSetBase, IComparable { + [NotMapped] + public const string SelfAccessLevelName = "BLAZAM_INTERNAL_SelfAccessLevel"; + [Required] public string Name { get; set; } /// diff --git a/BLAZAMDatabase/Models/Permissions/ActionAccessMapping.cs b/BLAZAMDatabase/Models/Permissions/ActionAccessMapping.cs index c488353de..ccf8f433c 100644 --- a/BLAZAMDatabase/Models/Permissions/ActionAccessMapping.cs +++ b/BLAZAMDatabase/Models/Permissions/ActionAccessMapping.cs @@ -18,6 +18,7 @@ public class ActionAccessMapping : AppDbSetBase /// /// public ObjectAction ObjectAction { get; set; } + public int ObjectActionId { get; set; } public override int GetHashCode() { return (ObjectType.ToString() + ObjectAction.Name).GetHashCode(); diff --git a/BLAZAMDatabase/Models/Permissions/GlobalPermissionRequestActions.cs b/BLAZAMDatabase/Models/Permissions/GlobalPermissionRequestActions.cs new file mode 100644 index 000000000..730baf71d --- /dev/null +++ b/BLAZAMDatabase/Models/Permissions/GlobalPermissionRequestActions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Database.Models.Permissions +{ + public class GlobalPermissionRequestActions : AppDbSetBase + { + public ActiveDirectoryObjectAction ObjectAction { get; set; } + + } +} diff --git a/BLAZAMDatabase/Models/Permissions/GlobalPermissionSettings.cs b/BLAZAMDatabase/Models/Permissions/GlobalPermissionSettings.cs new file mode 100644 index 000000000..a0b6b8e60 --- /dev/null +++ b/BLAZAMDatabase/Models/Permissions/GlobalPermissionSettings.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Database.Models.Permissions +{ + public class GlobalPermissionSettings : AppDbSetBase + { + public bool AllowSelfModification { get; set; } + + public bool AllowAccessRequest { get; set; } + + } +} diff --git a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs index 31779f4b7..5e34223b7 100644 --- a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs +++ b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs @@ -5,7 +5,7 @@ namespace BLAZAM.Database.Models.Permissions public enum ActiveDirectoryObjectAction { Move, Delete, Create, Unassign, Assign, Enable, Disable, Rename, - Unlock + Unlock, SetPassword } public class ObjectAction : AppDbSetBase { @@ -21,63 +21,6 @@ public override int GetHashCode() return Name.GetHashCode(); } - public bool IsActionAppropriateForObject(ActiveDirectoryObjectType type) - { - switch (type) - { - case ActiveDirectoryObjectType.User: - case ActiveDirectoryObjectType.Computer: - switch (Name) - { - case "Lock": - case "Unlock": - case "Move": - case "Delete": - case "Create": - case "Enable": - case "Disable": - case "Rename": - return true; - default: - return false; - } - case ActiveDirectoryObjectType.Group: - switch (Name) - { - case "Move": - case "Delete": - case "Create": - case "UnAssign": - case "Rename": - case "Assign": - return true; - default: - return false; - } - case ActiveDirectoryObjectType.Printer: - case ActiveDirectoryObjectType.OU: - switch (Name) - { - case "Move": - case "Delete": - case "Rename": - case "Create": - return true; - default: - return false; - } - case ActiveDirectoryObjectType.BitLocker: - switch (Name) - { - case "Delete": - return true; - default: - return false; - } - default: - return false; - } - } } } \ No newline at end of file diff --git a/BLAZAMDatabase/Models/User/NotificationMessage.cs b/BLAZAMDatabase/Models/User/NotificationMessage.cs index 24fdee539..57272e2bb 100644 --- a/BLAZAMDatabase/Models/User/NotificationMessage.cs +++ b/BLAZAMDatabase/Models/User/NotificationMessage.cs @@ -1,8 +1,11 @@  +using BLAZAM.Database.Models.Permissions; + namespace BLAZAM.Database.Models.User { public enum NotificationLevel { Info, Success, Warning, Error } + public enum MessageType { Notification, AccessRequest } /// /// A notification message for the web user. These are /// placed under the user's notifications panel @@ -14,12 +17,36 @@ public class NotificationMessage : AppDbSetBase /// The severity level of this notification /// public NotificationLevel Level { get; set; } + + /// + /// The message type of this notification + /// + public MessageType MessageType { get; set; } = MessageType.Notification; + /// - /// The title of the notificaiton + /// The DN of the target for this notification + /// + public string? TargetDN { get; set; } + + /// + /// The action being requested access to + /// + public ActiveDirectoryObjectAction? Action { get; set; } + + /// + /// The user who triggered this notification + /// + public AppUser? Creator { get; set; } + public int? CreatorId { get; set; } + + /// + /// The title of the notification /// public string? Title { get; set; } + + /// - /// The message of the notificatioon + /// The message of the notification /// public string? Message { get; set; } @@ -43,10 +70,8 @@ public override bool Equals(object? obj) { return obj is NotificationMessage message && ( - Id != 0 && Id == message.Id || - Level == message.Level && - Title == message.Title && - Message == message.Message); + Id != 0 && Id == message.Id); } + } } diff --git a/BLAZAMDatabase/Models/User/UserDashboardWidget.cs b/BLAZAMDatabase/Models/User/UserDashboardWidget.cs index ddc634218..e22cc8946 100644 --- a/BLAZAMDatabase/Models/User/UserDashboardWidget.cs +++ b/BLAZAMDatabase/Models/User/UserDashboardWidget.cs @@ -17,7 +17,8 @@ public enum DashboardWidgetType FavoriteEntries, DeletedEntries, ChangedEntries, - AppLogons + AppLogons, + StaleUsers } public class UserDashboardWidget : AppDbSetBase { diff --git a/BLAZAMDatabase/Models/User/UserNotification.cs b/BLAZAMDatabase/Models/User/UserNotification.cs index a154c927e..349f3e442 100644 --- a/BLAZAMDatabase/Models/User/UserNotification.cs +++ b/BLAZAMDatabase/Models/User/UserNotification.cs @@ -5,6 +5,7 @@ public class UserNotification : AppDbSetBase { public AppUser User { get; set; } public NotificationMessage Notification { get; set; } + public int NotificationId { get; set; } public bool IsRead { get; set; } } } \ No newline at end of file diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index 67cbab9d3..37d16f22e 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -24,4 +24,10 @@ + + + true + + + diff --git a/BLAZAMEmailMessage/Email/Notifications/AccessRequestEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/AccessRequestEmailMessage.razor new file mode 100644 index 000000000..d70a7cc41 --- /dev/null +++ b/BLAZAMEmailMessage/Email/Notifications/AccessRequestEmailMessage.razor @@ -0,0 +1,40 @@ +@using BLAZAM.Database.Models.User +@using BLAZAM.Helpers +@using System.Security +@inherits NotificationTemplateComponent + + + @Notification.Title + + + + + @(Notification.Creator?.Username) + @AppLocalization["is requesting"] + @AppLocalization[Notification.Action.ToString()].ToString().ToLower() + @AppLocalization["access to"] + @TargetName + +
+ + +
+ + +@code { + [Parameter] + public NotificationMessage Notification { get; set; } + [Parameter] + public string TargetName { get; set; } + + + public override string Render() => new ComponentRenderer() + .UseLayout() + .AddServiceProvider(ApplicationInfo.services) + .Set(c => c.Notification, Notification) + .Set(c => c.TargetName, TargetName) + .Render(); +} + + + diff --git a/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor index fc87a8385..dc7bd1b37 100644 --- a/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor @@ -7,7 +7,7 @@ - @(AppLocalization["he password for "] + EntryName + AppLocalization[" has been changed."]) + @(AppLocalization["The password for "] + EntryName + AppLocalization[" has been changed."])
diff --git a/BLAZAMFileSystem/FileSystemBase.cs b/BLAZAMFileSystem/FileSystemBase.cs index 7e64aeab6..a54745f38 100644 --- a/BLAZAMFileSystem/FileSystemBase.cs +++ b/BLAZAMFileSystem/FileSystemBase.cs @@ -1,5 +1,4 @@ -using Serilog.Configuration; -using System.Security; +using System.Security; using System.Security.AccessControl; using System.Security.Permissions; diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index 549811e3c..d5e2599c7 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -48,16 +48,5 @@ - - - true - - - true - - - true - - diff --git a/BLAZAMGui/Layouts/AppUserButton.razor b/BLAZAMGui/Layouts/AppUserButton.razor index 8b96879cb..d72fa3153 100644 --- a/BLAZAMGui/Layouts/AppUserButton.razor +++ b/BLAZAMGui/Layouts/AppUserButton.razor @@ -1,44 +1,35 @@ @inherits DatabaseComponentBase - +@* *@ - + - @{ - var avatarBgColor = GenerateAvatarColor(UserState?.Username); - } - @if (Notifications.Where(n => !n.IsRead).Count() > 0) - { - - - - } - else - { - - } + - + @CurrentUser.Username - @if (Notifications.Count > 0) - { - Notifications - } - - - + + @AppLocalization["Profile Settings"] - - @AppLocalization["Notification Settings"] - - + + @AppLocalization["Documentation"] @@ -57,40 +48,28 @@ } - + - - - - + + @code { AppModal? profileModal; AppModal? notificationsModal; - /// - /// Indicates whether the notification panel is open - /// - bool NotificationsOpen; - + MudMenu? _userMenu; [CascadingParameter] public MainLayout mainLayout { get; set; } - IList Notifications = new List(); private IApplicationUserState UserState; protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); await InvokeAsync(StateHasChanged); - NotificationPublisher.OnNotificationPublished += (async (notifications) => - { - if (notifications.Select(n => n.User).Contains(UserState.Preferences)) - { - Notifications = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToListAsync(); - } - await InvokeAsync(StateHasChanged); - }); UserState = CurrentUser.State; @@ -98,10 +77,10 @@ if (UserState != null) UserState.OnSettingsChanged += async () => { + InvokeAsync(StateHasChanged); }; - Notifications = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToListAsync(); await InvokeAsync(StateHasChanged); @@ -110,24 +89,5 @@ - /// - /// Generate a repeatable hex color based on the given username - /// - /// - /// A background-color style string - string GenerateAvatarColor(string? username) - { - if (username is null || username.IsNullOrEmpty()) return "background-color:#0c13a7"; - int usernameHash = username.GetAppHashCode(); - byte[] usernameHashBytes = Helpers.ByteHelpers.ToByteArray(usernameHash, (int?)3); - for (int x = 0; x < usernameHashBytes.Length; x++) - { - if (usernameHashBytes[x] > 200) - usernameHashBytes[x] = 200; - } - string hexColor = "background-color:#"; - hexColor += Convert.ToHexString(usernameHashBytes.Take(3).ToArray()); - return hexColor; - } } \ No newline at end of file diff --git a/BLAZAMGui/Layouts/CurrentUserAvatarIcon.razor b/BLAZAMGui/Layouts/CurrentUserAvatarIcon.razor index 3f75161a4..ea7e62774 100644 --- a/BLAZAMGui/Layouts/CurrentUserAvatarIcon.razor +++ b/BLAZAMGui/Layouts/CurrentUserAvatarIcon.razor @@ -1,15 +1,20 @@ +@using System.Security.Claims @inherits AppComponentBase @if (UserState?.Preferences?.ProfilePicture != null) { - + } else { - @GetInitials() + @GetInitials() } @@ -53,15 +58,26 @@ else { if (!UserStateService.CurrentUsername.IsNullOrEmpty()) { - if (UserStateService.CurrentUsername.Split(" ").Length > 1) + var fname = CurrentUser.State.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.GivenName)?.Value; + var lname = CurrentUser.State.User.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Surname)?.Value; + if (!fname.IsNullOrEmpty() && !lname.IsNullOrEmpty()) { - string initials = ""; - UserStateService.CurrentUsername.Split(" ").ForEach(p => initials += p.First()); + string initials = fname.Substring(0, 1) + lname.Substring(0, 1); + initials = initials.ToUpper(); return initials; } else { - return UserStateService.CurrentUsername?.FirstOrDefault().ToString(); + if (UserStateService.CurrentUsername.Split(" ").Length > 1) + { + string initials = ""; + UserStateService.CurrentUsername.Split(" ").ForEach(p => initials += p.First()); + return initials; + } + else + { + return UserStateService.CurrentUsername?.FirstOrDefault().ToString(); + } } } return default; diff --git a/BLAZAMGui/Layouts/MainAppBar.razor b/BLAZAMGui/Layouts/MainAppBar.razor index b6811e6bb..721deba13 100644 --- a/BLAZAMGui/Layouts/MainAppBar.razor +++ b/BLAZAMGui/Layouts/MainAppBar.razor @@ -46,9 +46,10 @@ } - + + diff --git a/BLAZAMGui/Layouts/MainLayout.razor b/BLAZAMGui/Layouts/MainLayout.razor index 9d049cc1a..b30af3245 100644 --- a/BLAZAMGui/Layouts/MainLayout.razor +++ b/BLAZAMGui/Layouts/MainLayout.razor @@ -18,9 +18,7 @@ - - - + @if (ApplicationInfo.inDebugMode) { @@ -30,8 +28,8 @@ @@ -41,6 +39,23 @@ } + + + @if (NotificationsOpen) + { + + } + + + @@ -50,6 +65,7 @@ Variant=@navDrawerVariant Elevation="3" ClipMode="DrawerClipMode.Docked"> +   *@ + @* +   *@ } @@ -113,10 +129,8 @@ - @Body - @@ -150,6 +164,18 @@ AppModal? dataBrowser; bool _drawerOpen = true; bool _devDrawerOpen = false; + bool _notificationsOpen = false; + public bool NotificationsOpen + { + get => _notificationsOpen; set + { + if (_notificationsOpen == value) return; + _notificationsOpen = value; + //TODO Add drawer open preference to user settings + + InvokeAsync(StateHasChanged); + } + } public bool BrowseExpanded = false; public bool DrawerOpen diff --git a/BLAZAMGui/Layouts/NotificationList.razor b/BLAZAMGui/Layouts/NotificationList.razor new file mode 100644 index 000000000..cd42ac607 --- /dev/null +++ b/BLAZAMGui/Layouts/NotificationList.razor @@ -0,0 +1,108 @@ +@inherits DatabaseComponentBase + + + + + + @if (messages.Where(m => !m.IsRead).Count() < 1 || messages.Where(m => !m.IsRead) == null) + { + + + + @AppLocalization["No unread notifications"] + + + } + else + { + foreach (var message in messages.Where(m => !m.IsRead).ToList()) + { + @if (message.Notification.MessageType == MessageType.AccessRequest) + { + + } + else + { + + } + } + } + + @if (messages.Where(m => m.IsRead).Count() > 0) + { + {_showRead=!_showRead; })> + + + @AppLocalization["Read Notifications"] + + + @if (_showRead) + { + + + + + + } + + } + + + + +@code { + + [Parameter] + public IApplicationUserState UserState { get; set; } + + + bool _showRead; + + private IList messages = new List(); + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + RetrieveMessages(); + + UserState.OnSettingsChanged += async () => + { + RetrieveMessages(); + }; + NotificationPublisher.OnNotificationPublished += async (notification) => + { + RetrieveMessages(); + }; + NotificationPublisher.OnNotificationDeleted += async () => + { + RetrieveMessages(); + }; + + } + private void RetrieveMessages() + { + Task.Run(async () => + { + LoadingData = true; + await InvokeAsync(StateHasChanged); + var context = await DbFactory.CreateDbContextAsync(); + + messages = await context.UserNotifications + .Where(un => un.User.Id == UserState.Id) + .OrderByDescending(un => un.Notification.Created) + .ToListAsync(); + LoadingData = false; + + await InvokeAsync(StateHasChanged); + }); + + + } + public override async Task UpdateState() + { + RetrieveMessages(); + + } + +} \ No newline at end of file diff --git a/BLAZAMGui/Layouts/UserNotificationPopover.razor b/BLAZAMGui/Layouts/UserNotificationPopover.razor index 378efd227..5ef090e41 100644 --- a/BLAZAMGui/Layouts/UserNotificationPopover.razor +++ b/BLAZAMGui/Layouts/UserNotificationPopover.razor @@ -1,62 +1,46 @@ @inherits DatabaseComponentBase -@if (messages.Count > 0) -{ - - - Notifications - - - {Open=false;}) /> - - - - @foreach (var notification in messages.Where(m => !m.IsRead)) - { - - { - if(notification.Notification.Link!=null) - Nav.NavigateTo(notification.Notification.Link.ToString()); - }) ShowCloseIcon=notification.Notification.Dismissable - CloseIconClicked="@(async()=>{ - await UserState.MarkRead(notification); - await InvokeAsync(StateHasChanged); - })"> - @if (!notification.Notification.Title.IsNullOrEmpty()) - { - @notification.Notification.Title - } - - @((MarkupString)notification.Notification.Message) - - - } - - - -} + + + + @AppLocalization["Notifications"] + + + + + {mainLayout.NotificationsOpen=false;}) /> + + + + + + + -@code { - private bool _open; - private IList messages = new List(); - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - messages = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToListAsync(); - //messages = UserState.Notifications; - NotificationPublisher.OnNotificationPublished += async (notification) => - { - messages = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToListAsync(); - InvokeAsync(StateHasChanged); - }; - } +@code { + AppModal? notificationsModal; + private bool _open; + private NotificationList? _notificationList; [Parameter] public bool Open { @@ -74,9 +58,14 @@ [Parameter] public IApplicationUserState UserState { get; set; } + [CascadingParameter] + public MainLayout mainLayout { get; set; } + async Task MarkAllRead() { - messages = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToListAsync(); + + var messages = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead && un.Notification.MessageType != MessageType.AccessRequest).ToListAsync(); + foreach (var message in messages) { @@ -84,10 +73,12 @@ await UserState.MarkRead(message); } + UserState.SaveAllUserSettings(); + UserState.GetUserSettingFromDB(); + Open = false; + _notificationList?.UpdateState(); await InvokeAsync(StateHasChanged); } - - } \ No newline at end of file diff --git a/BLAZAMGui/Layouts/UserNotificationsProvider.razor b/BLAZAMGui/Layouts/UserNotificationsProvider.razor new file mode 100644 index 000000000..0a918f174 --- /dev/null +++ b/BLAZAMGui/Layouts/UserNotificationsProvider.razor @@ -0,0 +1,79 @@ +@inherits DatabaseComponentBase +@{ + var notifs = Notifications.Where(n => !n.IsRead); +} + + + + + + + +@code { + + [CascadingParameter] + public MainLayout mainLayout { get; set; } + IList Notifications = new List(); + private IApplicationUserState UserState; + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + await InvokeAsync(StateHasChanged); + NotificationPublisher.OnNotificationPublished += (async (notifications) => + { + + if (notifications != null && notifications.Select(n => n.User).Contains(UserState.Preferences)) + { + await LoadNotifications(); + + } + }); + + NotificationPublisher.OnNotificationDeleted += async () => + { + await LoadNotifications(); + }; + + UserState = CurrentUser.State; + await InvokeAsync(StateHasChanged); + if (UserState != null) + UserState.OnSettingsChanged += async () => + { + await LoadNotifications(); + }; + + Notifications = await Context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToListAsync(); + + await InvokeAsync(StateHasChanged); + + + } + private void ToggleNotifications() + { + mainLayout.NotificationsOpen = !mainLayout.NotificationsOpen; + // _userMenu.Disabled = true; + // Task.Delay(500).ContinueWith((t) => + // { + // InvokeAsync(() => { _userMenu.Disabled = false; _userMenu?.CloseMenuAsync(); }); + + // }); + + } + private async Task LoadNotifications() + { + var context = await DbFactory.CreateDbContextAsync(); + lock (Notifications) + { + Notifications = context.UserNotifications.Where(un => un.User.Id == UserState.Id && !un.IsRead).ToList(); + } + await InvokeAsync(StateHasChanged); + } +} \ No newline at end of file diff --git a/BLAZAMGui/Services/WidgetService.cs b/BLAZAMGui/Services/WidgetService.cs index 2a5eed365..c96cc48b6 100644 --- a/BLAZAMGui/Services/WidgetService.cs +++ b/BLAZAMGui/Services/WidgetService.cs @@ -62,6 +62,7 @@ public List Available() widgets.Add(new ChangedPasswordsWidget() { WidgetType = DashboardWidgetType.PasswordsChanged, Title = AppLocalization["Passwords changed in the last 90 days"] }); widgets.Add(new DeletedEntriesWidget() { WidgetType = DashboardWidgetType.DeletedEntries, Title = AppLocalization["Entries deleted in the last 14 days"] }); widgets.Add(new AppLogonsWidget() { WidgetType = DashboardWidgetType.AppLogons, Title = AppLocalization["Application logons"] }); + widgets.Add(new StaleUsersWidget() { WidgetType = DashboardWidgetType.StaleUsers, Title = AppLocalization["Stale users"] }); } diff --git a/BLAZAMGui/UI/AppComponentBase.cs b/BLAZAMGui/UI/AppComponentBase.cs index 92556e126..0d7573f89 100644 --- a/BLAZAMGui/UI/AppComponentBase.cs +++ b/BLAZAMGui/UI/AppComponentBase.cs @@ -72,8 +72,20 @@ public class AppComponentBase : ComponentBase, IDisposable [Inject] private ScopedActiveDirectoryContext userActiveDirectoryService { get; set; } + private bool _loadingData = true; + /// + /// Indicates whether the current component is loading data. Changing this value causes the component to re-render. + /// + protected bool LoadingData + { + get => _loadingData; set + { + if (_loadingData == value) return; + _loadingData = value; + _ = InvokeAsync(StateHasChanged); - protected bool LoadingData { get; set; } = true; + } + } //protected IDatabaseContext? Context; [Inject] protected IAppDatabaseFactory DbFactory { get; set; } @@ -145,7 +157,11 @@ protected void Refresh(bool forceReload = false) { Nav.NavigateTo(Nav.Uri, forceReload); } + public virtual async Task UpdateState() + { + await InvokeAsync(StateHasChanged); + } public virtual void Dispose() { //This object requires no further disposal diff --git a/BLAZAMGui/UI/AppModal.razor b/BLAZAMGui/UI/AppModal.razor index ca75c42f9..803ba32b8 100644 --- a/BLAZAMGui/UI/AppModal.razor +++ b/BLAZAMGui/UI/AppModal.razor @@ -1,7 +1,7 @@ @inherits MudDialog - + @Title diff --git a/BLAZAMGui/UI/AppModal.razor.cs b/BLAZAMGui/UI/AppModal.razor.cs index 8dd5c6d99..0485eeae2 100644 --- a/BLAZAMGui/UI/AppModal.razor.cs +++ b/BLAZAMGui/UI/AppModal.razor.cs @@ -119,6 +119,8 @@ public bool IsShown [Parameter] public EventCallback IsShownChanged { get; set; } + [Parameter] + public MaxWidth? Width { get; set; } protected override void OnInitialized() @@ -127,6 +129,10 @@ protected override void OnInitialized() YesText = AppLocalization["Ok"]; if (Options == null) Options = new(); + if (Width != null) + { + Options.MaxWidth = Width; + } AllowClose = true; } /// diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor index d742606da..8a2330e6e 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor @@ -58,9 +58,7 @@ - - - + @code { List changdEntries { diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor index 3431e279b..eb0c30f78 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor @@ -49,9 +49,7 @@ - - - + @code { List LockedUsers = new(); diff --git a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor index fcefa84cb..b16a043ca 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor @@ -42,9 +42,7 @@ - - - + @code { List deletedObjects { diff --git a/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor index 034d3550c..c71e18e2d 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor @@ -58,9 +58,7 @@ - - - + @code { List FavoriteEntries { diff --git a/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor new file mode 100644 index 000000000..889c57213 --- /dev/null +++ b/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor @@ -0,0 +1,51 @@ + +@inherits Widget +@attribute [Authorize] + + +@code { + List StaleUsers + { + get => CurrentUser.State.Cache.Get>("StaleUsers"); + set => CurrentUser.State.Cache.Set("StaleUsers", value); + } + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + + CurrentUserDashboardWidgets.OnRefreshWidget += (Widget widget) => + { + if (widget.WidgetType.Equals(WidgetType)) + { + _ = RefreshData(); + + } + + }; + + _ = RefreshData(); + } + async Task RefreshData() + { + LoadingData = true; + await InvokeAsync(StateHasChanged); + var users= Directory.Users.FindUsersByString(null); + ADSearch searcher = new ADSearch(Directory); + + StaleUsers = (await Directory.Users.FindNewUsersAsync(14, false)).Where(u => u.CanRead).OrderByDescending(u => u.Created).ToList(); + LoadingData = false; + await InvokeAsync(StateHasChanged); + + } + void GoTo(DataGridRowClickEventArgs args) + { + Nav.NavigateTo(args.Item.SearchUri); + } +} diff --git a/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs b/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs index eaabaa876..53014256d 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs +++ b/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs @@ -12,7 +12,7 @@ namespace BLAZAM.Gui.UI public class DirectoryEntryViewBase : DatabaseComponentBase { [Inject] - public OUNotificationService OUNotificationService { get; set; } + public NotificationGenerationService NotificationGenerationService { get; set; } [Parameter] public IDirectoryEntryAdapter DirectoryEntry { get; set; } diff --git a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor index 22c0b8c47..8507d61ba 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor +++ b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor @@ -1,6 +1,20 @@ @using BLAZAM.Gui.UI.Chat @inherits DirectoryEntryViewBase -@{ + +@if (LoadingData) +{ + + + + + + + + + +} +else +{ IAccountDirectoryAdapter? accountEntry; accountEntry = DirectoryEntry as IAccountDirectoryAdapter; @@ -9,207 +23,221 @@ IGroupableDirectoryAdapter? groupableEntry; groupableEntry = DirectoryEntry as IGroupableDirectoryAdapter; -} - - - @if (groupableEntry != null && DirectoryEntry is not IADComputer) - { - - @groupableEntry.DisplayName - - } - else + + + + @if (groupableEntry != null && DirectoryEntry is not IADComputer) + { + + @groupableEntry.DisplayName + + } + else + { + + @DirectoryEntry.CanonicalName + + } + @if (!DirectoryEntry.OU.IsNullOrEmpty()) + { + @DirectoryTools.PrettifyOu(DirectoryEntry.OU) + + } + + + + + + @if (accountEntry?.LockedOut == true) { - - @DirectoryEntry.CanonicalName - + } - @if (!DirectoryEntry.OU.IsNullOrEmpty()) - { - @DirectoryTools.PrettifyOu(DirectoryEntry.OU) + + + @if (accountEntry != null) - } + { + + + + + } - + - @if (accountEntry?.LockedOut == true) - { - - } - - - @if (accountEntry != null) + - { - - - - } - + @if (accountEntry != null && accountEntry.LockedOut) + { + - + + + } + @if (groupableEntry != null) + { + - + + - + } + @if (accountEntry != null && accountEntry is not IADComputer) + { + + + + } + - @if (accountEntry != null && accountEntry.LockedOut) - { - + - - } - @if (groupableEntry != null) - { - - + + + + - } - @if (accountEntry != null && accountEntry is not IADComputer) - { - - - } - - - - - - - - - - - - - - - - - - - @if (CurrentUser.State.IsSuperAdmin) - { - - - - } - - - - - - - - - - - @if (accountEntry != null) - { - @if ((accountEntry.Enabled && accountEntry.CanDisable) || (accountEntry.Disabled && accountEntry.CanEnable)) + + @if (CurrentUser.State.IsSuperAdmin) { - - - - - } - } - @if (DirectoryEntry.CanEdit) - { - @(EditMode ? AppLocalization["End Edit"] : AppLocalization["Edit"]) - } - @if (accountEntry != null && accountEntry.LockedOut && accountEntry.CanUnlock) - { - @AppLocalization["Unlock"] - } - @AppLocalization["Assign To"] - @if (accountEntry?.CanDisable == true && accountEntry is not IADComputer) - { - @AppLocalization["Change Password"] - } - @if (DirectoryEntry.CanRename) - { - @AppLocalization["Rename"] - } - @if (DirectoryEntry.CanMove) - { - @AppLocalization["Move"] - } - @if (DirectoryEntry.CanDelete) - { - @AppLocalization["Delete"] - } - @if (DirectoryEntry.CanEdit) - { - @AppLocalization["Change History"] - } - @if (CurrentUser.State.IsSuperAdmin) - { - @AppLocalization["Effective Permissions"] - } - - - + + + + + + + } + @if (_showRequestButton) + { + + + + } + + + + + + + + + + + @if (accountEntry != null) + { + @if ((accountEntry.Enabled && accountEntry.CanDisable) || (accountEntry.Disabled && accountEntry.CanEnable)) + { + + + + + } + } + @if (DirectoryEntry.CanEdit) + { + @(EditMode ? AppLocalization["End Edit"] : AppLocalization["Edit"]) + } + @if (accountEntry != null && accountEntry.LockedOut && accountEntry.CanUnlock) + { + @AppLocalization["Unlock"] + } + @AppLocalization["Assign To"] + @if (accountEntry?.CanSetPassword == true && accountEntry is not IADComputer) + { + @AppLocalization["Change Password"] + } + @if (DirectoryEntry.CanRename) + { + @AppLocalization["Rename"] + } + @if (DirectoryEntry.CanMove) + { + @AppLocalization["Move"] + } + @if (DirectoryEntry.CanDelete) + { + @AppLocalization["Delete"] + } + @if (DirectoryEntry.CanEdit) + { + @AppLocalization["Change History"] + } + @if (CurrentUser.State.IsSuperAdmin) + { + @AppLocalization["Effective Permissions"] + } + + + + @if (_showRequestButton) + { + + + + } +} @code { - - + private AppModal? _requestAccessModal; + private bool _showRequestButton; [Parameter] public EventCallback OnDelete { get; set; } private async Task DeleteUser() @@ -281,8 +309,8 @@ private async Task ShowHistory() { await OnShowHistory.InvokeAsync(); - } - + } + [Parameter] public EventCallback OnShowPermissions { get; set; } private async Task ShowPermissions() @@ -299,6 +327,22 @@ [Parameter] public EventCallback OnToggleEditMode { get; set; } + protected override async Task OnInitializedAsync() + { + + await base.OnInitializedAsync(); + LoadingData = true; + _showRequestButton = Context.GlobalPermissionSettings.FirstOrDefault()?.AllowAccessRequest == true + && Context.GlobalPermissionRequestActions.Count() > 0; + } + protected override void OnAfterRender(bool firstRender) + { + base.OnAfterRender(firstRender); + if (firstRender) + { + LoadingData = false; + } + } private async Task ToggleEditMode(bool editEnabled) { diff --git a/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor b/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor index 4f3a81281..b4f776664 100644 --- a/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor +++ b/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor @@ -86,9 +86,7 @@ } else { - - - + } diff --git a/BLAZAMGui/UI/Groups/GroupMembersPopover.razor b/BLAZAMGui/UI/Groups/GroupMembersPopover.razor index f8eb28b6a..74a445537 100644 --- a/BLAZAMGui/UI/Groups/GroupMembersPopover.razor +++ b/BLAZAMGui/UI/Groups/GroupMembersPopover.razor @@ -91,9 +91,7 @@ } else { - - - + } diff --git a/BLAZAMGui/UI/Inputs/AppCloseButton.razor b/BLAZAMGui/UI/Inputs/AppCloseButton.razor index 3241fdc11..64cdb2a54 100644 --- a/BLAZAMGui/UI/Inputs/AppCloseButton.razor +++ b/BLAZAMGui/UI/Inputs/AppCloseButton.razor @@ -1,13 +1,15 @@ @inherits AppIconButton + + Icon="@(Icon==null?Icons.Material.Filled.Close:Icon)" /> @code { diff --git a/BLAZAMGui/UI/Inputs/AppIconButton.razor b/BLAZAMGui/UI/Inputs/AppIconButton.razor index 3b4c5c950..a568f4cd3 100644 --- a/BLAZAMGui/UI/Inputs/AppIconButton.razor +++ b/BLAZAMGui/UI/Inputs/AppIconButton.razor @@ -1,21 +1,24 @@ - - - + + + @code { [Parameter] public EventCallback OnClick { get; set; } + [Parameter] + public Placement TooltipPlacement { get; set; } = Placement.Bottom; [Parameter] public Color Color { get; set; } [Parameter] diff --git a/BLAZAMGui/UI/Modals/AccessApprovalModalContent.razor b/BLAZAMGui/UI/Modals/AccessApprovalModalContent.razor new file mode 100644 index 000000000..89e53416b --- /dev/null +++ b/BLAZAMGui/UI/Modals/AccessApprovalModalContent.razor @@ -0,0 +1,181 @@ +@using BLAZAM.Common.Exceptions +@using BLAZAM.Server.Data.Services +@inherits AppModalContent + + + + + @AppLocalization["Delegate"] + @AppLocalization["Access Level"] + @AppLocalization["Permission Mapping"] + + + + + + + + + + + + + + + + + @AppLocalization["Name"]: @_delegate?.DelegateName + + + @AppLocalization["Name"]: @_accessLevel?.Name + + + + @AppLocalization["Name"]: @_target?.CanonicalName + + + + + + +@code { + + [Parameter] + public UserNotification Request { get; set; } + [Parameter] + public EventCallback OnApproved { get; set; } + + private IADUser? _creator; + private IDirectoryEntryAdapter? _target; + private PermissionDelegate? _delegate; + private AccessLevel? _accessLevel; + private PermissionMapping? _permissionMapping; + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + Modal.Options.MaxWidth = MaxWidth.Large; + Modal.YesText = AppLocalization["Approve"]; + base.Modal.OnYes += async () => { await Approve(); }; + _ = LoadData(); + Modal.RefreshView(); + + } + + private async Task Approve() + { + LoadingData = true; + if (_delegate.Id == 0) + { + Context.PermissionDelegate.Add(_delegate); + } + if (_permissionMapping.Id == 0) + { + Context.PermissionMap.Add(_permissionMapping); + } + try + { + Context.SaveChangesAsync(); + Modal.Close(); + OnApproved.InvokeAsync(); + + LoadingData = false; + }catch(Exception ex) + { + Loggers.DatabaseLogger.Error("Error adding approved permission mapping {Error}", ex.InnerException); + SnackBarService.Error("Error trying to create permission mapping"); + LoadData(); + } + + } + + private async Task LoadData() + { + //Get matching delegate, access level and mapping from the db, or prepare new ones + await Task.Run(async () => + { + LoadingData = true; + + var _creator = await Context.UserSettings.FirstOrDefaultAsync(x => x.Id == Request.Notification.CreatorId); + var _creatorAD = Directory.GetDirectoryEntryBySid(_creator.UserGUID); + + //Prepare delegate + var _deleg = await Context.PermissionDelegate.FirstOrDefaultAsync(x => x.DelegateSid == _creator.UserGUID.ToSidByteArray()); + if (_deleg == null) + { + _deleg = new PermissionDelegate() + { + DelegateName = _creatorAD != null ? _creatorAD.CanonicalName : _creator.Username, + DelegateSid = _creator.UserGUID.ToSidByteArray() + }; + } + else + { + _deleg.DeletedAt = null; + } + _delegate = _deleg; + + //Prepare target + if (!Request.Notification.TargetDN.IsNullOrEmpty()) + { + var tgtDN = Request.Notification.TargetDN; + _target = Directory.GetDirectoryEntryByDN(tgtDN); + + } + + //Prepare Access Level + var _accessLvl = await Context.AccessLevels.FirstOrDefaultAsync(x => x.ObjectMap.Count == 1 + && x.ObjectMap.Any(x => x.ObjectType == _target.ObjectType) + && x.ActionMap.Count == 1 && x.ActionMap.Any(x => x.AllowOrDeny == true && x.ObjectAction.Action == Request.Notification.Action)); + if (_accessLvl == null) + { + var objActions = await Context.ObjectActionFlag.ToListAsync(); + var objectMap = new ObjectAccessMapping() + { + ObjectAccessLevelId = ObjectAccessLevels.Read.Id, + ObjectType = _target != null ? _target.ObjectType : ActiveDirectoryObjectType.Group + + }; + var actionMap = new ActionAccessMapping() + { + ObjectActionId = objActions.FirstOrDefault(x => x.Action == Request.Notification.Action).Id, + AllowOrDeny = true, + ObjectType = _target != null ? _target.ObjectType : ActiveDirectoryObjectType.Group + }; + _accessLvl = new AccessLevel() + { + ActionMap = new List() { actionMap }, + ObjectMap = new List() { objectMap }, + Name = AppLocalization[Request.Notification.Action.ToString()] + " " + AppLocalization[_target.ObjectType.ToString()] + }; + } + else + { + _accessLvl.DeletedAt = null; + } + _accessLevel = _accessLvl; + + + //Prepare mapping + var _permMap = await Context.PermissionMap.FirstOrDefaultAsync(x => x.OU == _target.DN && x.AccessLevels.Count() == 1 + && x.AccessLevels.Any(x => x.Id == _accessLevel.Id) && x.PermissionDelegates.Count() == 1 + && x.PermissionDelegates.Any(x => x.DelegateSid == _creator.UserGUID.ToSidByteArray())); + if (_permMap == null) + { + _permMap = new PermissionMapping() + { + AccessLevels = new List() { _accessLevel }, + PermissionDelegates = new List() { _delegate }, + OU = _target.DN, + }; + } + _permissionMapping = _permMap; + + LoadingData = false; + + }); + + } +} + + + diff --git a/BLAZAMGui/UI/Modals/RequestAccessModalContent.razor b/BLAZAMGui/UI/Modals/RequestAccessModalContent.razor new file mode 100644 index 000000000..c9eb3c7a1 --- /dev/null +++ b/BLAZAMGui/UI/Modals/RequestAccessModalContent.razor @@ -0,0 +1,171 @@ +@using BLAZAM.Common.Exceptions +@using BLAZAM.EmailMessage.Email.Base +@using BLAZAM.EmailMessage.Email.Notifications +@using BLAZAM.Server.Data.Services +@inherits AppModalContent +@inject NotificationGenerationService notificationGenerationService + +@if (_objectActions != null && _objectActions.Count > 0) +{ + if (globalPermissionRequestActions.Count() > 0) + { + @if (_dbAllowedActions.Any(x => x.IsActionAppropriateForObject(Entry.ObjectType))) + { + + @foreach (var action in _objectActions) + { + if (action.IsActionAppropriateForObject(Entry.ObjectType) && globalPermissionRequestActions.Any(x => x.ObjectAction == action)) + { + + } + } + + + + } + else + { + @AppLocalization["There are no actions available to request for this entry."] + + } + } +} + +@code { + + [Inject] + private AppAuthenticationStateProvider AppAuthenticationStateProvider { get; set; } + + [Parameter] + public IDirectoryEntryAdapter Entry { get; set; } + + IReadOnlyCollection? _selectedActions = new List(); + + List _objectActions; + List _dbAllowedActions; + List globalPermissionRequestActions = new(); + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + _objectActions = ActiveDirectoryObjectAction.Assign.ToList(); + _dbAllowedActions = await Context.GlobalPermissionRequestActions.Select(x => x.ObjectAction).ToListAsync(); + globalPermissionRequestActions = await Context.GlobalPermissionRequestActions.ToListAsync(); + Modal.OnYes += Submit; + } + public async void Submit() + { + if (_selectedActions.Count > 0) + { + LoadingData = true; + await InvokeAsync(StateHasChanged); + var users = await Context.UserSettings.ToListAsync(); + var adminUsers = new List(); + await Parallel.ForEachAsync(users, async (user, cancellationToken) => + { + var adUser = Directory.Users.FindUserBySID(user.UserGUID); + var userState = new ApplicationUserState(DbFactory); + try + { + var appUser = await AppAuthenticationStateProvider.CreateDirectoryPrincipal(userState, adUser); + userState.User = appUser; + if (userState.IsSuperAdmin || user.Username == "admin" || user.Username == "Demo") + { + lock (adminUsers) + { + adminUsers.Add(user); + } + } + } + catch (DeniedLoginException ex) + { + //Ignore users who can't login + } + }); + + foreach (var action in _selectedActions) + { + NotificationMessage notification; + notificationGenerationService.PackageRequest(Entry, action, CurrentUser.State, out notification); + + NotificationPublisher.PublishNotification(adminUsers, notification); + + + var requestEmail = new AccessRequestEmailMessage(); + requestEmail.Notification= notification; + requestEmail.TargetName = Entry.CanonicalName; + foreach (var user in adminUsers) + { + if (EmailService.IsConfigured && !user.Email.IsNullOrEmpty()) + { + string body = CurrentUser.Username + " " + AppLocalization["is requesting"] + + " " + AppLocalization[action.ToString()].ToString().ToLower() + " " + AppLocalization["access to"] + " " + + Entry.CanonicalName; + await EmailService.SendMessage(notification.Title, requestEmail , user.Email); + } + } + } + SnackBarService.Success(AppLocalization["Access request sent"]); + } + Modal.Close(); + LoadingData = false; + await InvokeAsync(StateHasChanged); + } + + private bool IsActionDisabled(ActiveDirectoryObjectAction action) + { + switch (action) + { + case ActiveDirectoryObjectAction.Assign: + if (Entry is IADGroup assign) + return assign.CanAssign; + else + return true; + + case ActiveDirectoryObjectAction.Unassign: + if (Entry is IADGroup unassign) + return unassign.CanUnassign; + else + return true; + case ActiveDirectoryObjectAction.Move: + return Entry.CanMove; + case ActiveDirectoryObjectAction.Delete: + return Entry.CanDelete; + case ActiveDirectoryObjectAction.Disable: + + if (Entry is IAccountDirectoryAdapter disable) + return disable.CanDisable; + else + return true; + case ActiveDirectoryObjectAction.Enable: + if (Entry is IAccountDirectoryAdapter enable) + return enable.CanDisable; + else + return true; + case ActiveDirectoryObjectAction.SetPassword: + if (Entry is IAccountDirectoryAdapter password) + return password.CanSetPassword; + else + return true; + case ActiveDirectoryObjectAction.Rename: + return Entry.CanRename; + case ActiveDirectoryObjectAction.Create: + return Entry.CanCreate; + case ActiveDirectoryObjectAction.Unlock: + if (Entry is IAccountDirectoryAdapter unlock) + return unlock.CanDisable; + else + return true; + default: + return false; + } + } +} \ No newline at end of file diff --git a/BLAZAMGui/UI/OU/MoveToOUModalContent.razor b/BLAZAMGui/UI/OU/MoveToOUModalContent.razor index 72885da62..21aa0ec2b 100644 --- a/BLAZAMGui/UI/OU/MoveToOUModalContent.razor +++ b/BLAZAMGui/UI/OU/MoveToOUModalContent.razor @@ -1,5 +1,5 @@ @inherits AppModalContent -@inject OUNotificationService OUNotificationService +@inject NotificationGenerationService OUNotificationService Choose OU @@ -47,7 +47,7 @@ DirectoryModel.MoveTo(ouToMoveTo); SnackBarService.Warning(DirectoryModel.CanonicalName + " has been moved to " + ouToMoveTo.CanonicalName + ", but changes need to be saved."); - _ = OUNotificationService.PostAsync(DirectoryModel, NotificationType.Modify); + _ = OUNotificationService.PostAsync(DirectoryModel, NotificationType.Modify, CurrentUser.State); _ = AuditLogger.Moved(DirectoryModel,ouMovedFrom, ouToMoveTo); await ModelChanged.InvokeAsync(); Close(); diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsItem.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsItem.razor index e3d0ea862..0a94fefb0 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsItem.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsItem.razor @@ -43,6 +43,7 @@ [Parameter] public EventCallback OnRead { get; set; } + private async void ShowNews() { var result = await Item.ShowNewsItemDialog(MessageService); diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor index 7f24a0811..a3e38a880 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor @@ -10,31 +10,37 @@ TransformOrigin="Origin.TopRight"> @{ - var icon = Icons.Material.Filled.Notifications; var color = Color.Success; } @if (unreadItems.Count > 0) { - icon = Icons.Material.Filled.NotificationImportant; - color = Color.Warning; + color = Color.Info; } - - - - - + + + + + - + Blazam @AppLocalization["News"] @foreach (var item in unreadItems.OrderByDescending(x => x.UpdatedAt)) { - + } @if (showRead) @@ -78,6 +84,17 @@ } +else +{ + + + + + +} @code { private bool showRead; private List unreadItems = new(); diff --git a/BLAZAMGui/UI/Outputs/NotificationMessageListItem.razor b/BLAZAMGui/UI/Outputs/NotificationMessageListItem.razor new file mode 100644 index 000000000..6ae6877e3 --- /dev/null +++ b/BLAZAMGui/UI/Outputs/NotificationMessageListItem.razor @@ -0,0 +1,31 @@ +@inherits AppComponentBase + + + + + @if (!Notification.Notification.Title.IsNullOrEmpty()) + { + @Notification.Notification.Title + } + + @((MarkupString)Notification.Notification.Message) + + + + @if (!Notification.IsRead) + { + + } + + + + +@code { + [Parameter] + public UserNotification Notification { get; set; } +} diff --git a/BLAZAMGui/UI/Outputs/RequestNotificationMessageListItem.razor b/BLAZAMGui/UI/Outputs/RequestNotificationMessageListItem.razor new file mode 100644 index 000000000..1c1e5bc6a --- /dev/null +++ b/BLAZAMGui/UI/Outputs/RequestNotificationMessageListItem.razor @@ -0,0 +1,180 @@ +@inherits DatabaseComponentBase +@if (LoadingData) +{ + + + + + + + + + + + + + + + + + + + + + + + + + +} +else +{ + + + + + + @if (Notification.Notification.Title.IsNullOrEmpty()) + { + + @AppLocalization["Request to"] @AppLocalization[Notification.Notification.Action.ToString()] + + } + else + { + + @AppLocalization["Request to"] @AppLocalization[Notification.Notification.Title] + + } + + @if (Notification.Notification.Message.IsNullOrEmpty()) + { + + + @(_creator != null ? _creator.DisplayName : _creatorAppUser?.Username) + + @AppLocalization["is requesting"] + @AppLocalization[Notification.Notification.Action.ToString()].ToString().ToLower() + @AppLocalization["access to"] + + @(_target != null ? _target.CanonicalName : Notification.Notification.TargetDN) + + + } + else + { + + @((MarkupString)Notification.Notification.Message) + + } + + @AppLocalization["Deny"] + + @AppLocalization["Approve"] + + + + + + + + + + + @if (_approvalModal.IsShown) + { + + } + +} +@code { + AppModal? _approvalModal; + [Parameter] + public UserNotification Notification { get; set; } + private IADUser? _creator; + private IDirectoryEntryAdapter? _target; + private AppUser? _creatorAppUser; + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + LoadData(); + + + } + private void LoadData() + { + Task.Run(async () => + { + LoadingData = true; + //await Task.Delay(10000); + var appUser = await Context.UserSettings.FirstOrDefaultAsync(x => x.Id == Notification.Notification.CreatorId); + if (appUser != null) + { + _creatorAppUser = appUser; + if (!appUser.Username.Equals("admin", StringComparison.InvariantCultureIgnoreCase) + && !appUser.Username.Equals("demo", StringComparison.InvariantCultureIgnoreCase)) + { + var directoryUser = Directory.GetDirectoryEntryBySid(appUser.UserGUID); + if (directoryUser != null && directoryUser is IADUser) + { + _creator = directoryUser as IADUser; + } + } + } + + if (Notification.Notification.TargetDN != null) + { + var dirEntry = Directory.GetDirectoryEntryByDN(Notification.Notification.TargetDN); + if (dirEntry != null) + { + _target = dirEntry; + } + } + LoadingData = false; + }); + } + private async void DenyRequest() + { + if (await MessageService.Confirm(AppLocalization["Are you sure you want to deny this request?"])) + { + try + { + if (await NotificationPublisher.DeleteNotification(Notification.Notification, Notification.User)) + { + SnackBarService.Info(AppLocalization["The request has been denied"]); + + } + + + } + catch (Exception ex) + { + SnackBarService.Warning(AppLocalization["The request could not be deleted"]); + + } + } + } + private async Task OnApproved() + { + + SnackBarService.Success(AppLocalization["The request has been approved"]); + if (!await NotificationPublisher.DeleteNotification(Notification.Notification, Notification.User)) + { + Loggers.SystemLogger.Error("There was an issue deleting a request notification"); + + } + } +} diff --git a/BLAZAMGui/UI/Search/SearchControls.razor b/BLAZAMGui/UI/Search/SearchControls.razor index 7682c8192..756431b49 100644 --- a/BLAZAMGui/UI/Search/SearchControls.razor +++ b/BLAZAMGui/UI/Search/SearchControls.razor @@ -1,76 +1,66 @@ @inherits AppComponentBase - - - - - { SearchService.SeachObjectType=ActiveDirectoryObjectType.All; })> - @AppLocalization["All"] + + + + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.All; })> + @AppLocalization["All"] + + + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.User; })> + @AppLocalization["User"] - + - { SearchService.SeachObjectType=ActiveDirectoryObjectType.User; })> - @AppLocalization["User"] - - - - - { SearchService.SeachObjectType=ActiveDirectoryObjectType.Group; })> - @AppLocalization["Group"] - + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.Group; })> + @AppLocalization["Group"] + - - - { SearchService.SeachObjectType=ActiveDirectoryObjectType.OU; })> - @AppLocalization["OU"] - + + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.OU; })> + @AppLocalization["OU"] + - - - { SearchService.SeachObjectType=ActiveDirectoryObjectType.Computer; })> - @AppLocalization["Computer"] - + + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.Computer; })> + @AppLocalization["Computer"] + - - - { SearchService.SeachObjectType=ActiveDirectoryObjectType.Printer; })> - @AppLocalization["Printer"] - + + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.Printer; })> + @AppLocalization["Printer"] + - - - { SearchService.SeachObjectType=ActiveDirectoryObjectType.BitLocker; })> - @AppLocalization["BitLocker"] - + + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.BitLocker; })> + @AppLocalization["BitLocker"] + - - + + - + @if (IsAdmin == true || CurrentUser.State?.CanSearchDisabled(ActiveDirectoryObjectType.User) == true) { - var buttonColor = Color.Error; - if (!SearchService.IncludeDisabled) - - { - buttonColor = Color.Success; - } - { - SearchService.IncludeDisabled= !SearchService.IncludeDisabled; - await InvokeAsync(StateHasChanged); - }) Color=buttonColor> - Enabled Only - - - - - - + + @AppLocalization["Include Disabled"] + } @{ var adornmentIcon = Icons.Material.Filled.AccountTree; diff --git a/BLAZAMGui/UI/Search/SearchPageHeader.razor b/BLAZAMGui/UI/Search/SearchPageHeader.razor index 5d713391a..0506ed6e0 100644 --- a/BLAZAMGui/UI/Search/SearchPageHeader.razor +++ b/BLAZAMGui/UI/Search/SearchPageHeader.razor @@ -33,7 +33,6 @@ @code { - MudDrawer? _searchDrawer; AppModal? _searchModal; List ObjectTypes = new() { ActiveDirectoryObjectType.All, diff --git a/BLAZAMGui/UI/Settings/ApplicationSettings.razor b/BLAZAMGui/UI/Settings/ApplicationSettings.razor index 4f027e5aa..7c3b352e6 100644 --- a/BLAZAMGui/UI/Settings/ApplicationSettings.razor +++ b/BLAZAMGui/UI/Settings/ApplicationSettings.razor @@ -54,9 +54,9 @@ @* *@ @* *@ - + - + } @@ -121,9 +121,7 @@ - - - + @code { AppSettings settings = new AppSettings(); @@ -159,10 +157,10 @@ } - protected override void Save() + protected override async Task Save() { AuditLogger.System.SettingsChanged("Application", settings.GetChanges(originalSettings)); - base.Save(); + await base.Save(); } } diff --git a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor index a96ea4ac0..41ac613ff 100644 --- a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor +++ b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor @@ -126,7 +126,7 @@ await InvokeAsync(StateHasChanged); } - protected override async void Save() + protected override async Task Save() { var decryptedPass = adminPasswordInDb.Decrypt(); if (!newAdminPassword.Equals(adminPasswordInDb) || decryptedPass.Equals(adminPasswordInDb)) diff --git a/BLAZAMGui/UI/Settings/AvailableUpdate.razor b/BLAZAMGui/UI/Settings/AvailableUpdate.razor index 91407a6a8..5e48345c1 100644 --- a/BLAZAMGui/UI/Settings/AvailableUpdate.razor +++ b/BLAZAMGui/UI/Settings/AvailableUpdate.razor @@ -20,12 +20,22 @@ - @if (Update.Newer && Update.PassesPrerequisiteChecks) + @if ((Update.Newer || ApplicationInfo.InDebugMode) && Update.PassesPrerequisiteChecks) { - Apply Update + + @AppLocalization["Apply Update"] + @if (ApplicationInfo.InDebugMode) { - Test Auto Update + + Test Auto Update + } diff --git a/BLAZAMGui/UI/Settings/DirectorySettings.razor b/BLAZAMGui/UI/Settings/DirectorySettings.razor index b4a187ade..e8926546b 100644 --- a/BLAZAMGui/UI/Settings/DirectorySettings.razor +++ b/BLAZAMGui/UI/Settings/DirectorySettings.razor @@ -192,7 +192,7 @@ await InvokeAsync(StateHasChanged); } - protected override async void Save() + protected override async Task Save() { if (!settings.Password.Equals(passwordInDb)) diff --git a/BLAZAMGui/UI/Settings/EmailSettings.razor b/BLAZAMGui/UI/Settings/EmailSettings.razor index 9378a3763..f98efdc36 100644 --- a/BLAZAMGui/UI/Settings/EmailSettings.razor +++ b/BLAZAMGui/UI/Settings/EmailSettings.razor @@ -111,9 +111,7 @@ - - - + @code { @@ -163,7 +161,7 @@ LoadingData = false; await InvokeAsync(StateHasChanged); } - protected override void Save() + protected override async Task Save() { if (settings.Id == 0 && Context != null) { @@ -171,7 +169,7 @@ Context.EmailSettings.Add(settings); } AuditLogger.System.SettingsChanged("Email", settings.GetChanges(originalSettings)); - base.Save(); + await base.Save(); } } diff --git a/BLAZAMGui/UI/Settings/JobsMonitor.razor b/BLAZAMGui/UI/Settings/JobsMonitor.razor index f43e2eb0a..bcb231a5c 100644 --- a/BLAZAMGui/UI/Settings/JobsMonitor.razor +++ b/BLAZAMGui/UI/Settings/JobsMonitor.razor @@ -1,9 +1,13 @@ +@inherits AppComponentBase @if (JobMonitor.AllJobs.Count > 0) { + Virtualize="true" + Items="JobMonitor.AllJobs.Where(x=>!x.NestedJob)" + RowClick="ShowJobDetails" + RowClass="cursor-pointer"> @@ -17,9 +21,19 @@ } @code { + IJob _selectedJob; protected override void OnInitialized() { base.OnInitialized(); JobMonitor.OnUpdate += async () => { await InvokeAsync(StateHasChanged); }; } + private void ShowJobDetails(DataGridRowClickEventArgs rowClickEventArgs) + { + var job = rowClickEventArgs.Item; + if (job != null) + { + MessageService.ShowMessage(job.ToDialogParameters(), AppLocalization[job.Name]); + + } + } } \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index aa322d7ed..23c59125a 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -63,7 +63,10 @@ default: - + @{ int i = 0; } @@ -76,7 +79,11 @@ - @(ShowAllUpdates == false ? "Show Previous Updates" : "Hide Previous Updates") + + @(ShowAllUpdates == false ? "Show Previous Updates" : "Hide Previous Updates") + @@ -90,7 +97,7 @@ @if (ShowAllUpdates) { - @foreach (var update in UpdateService.AvailableUpdates.Where(x => x.Version<=ApplicationInfo.RunningVersion).OrderBy(x => x.Version)) + @foreach (var update in UpdateService.AvailableUpdates.Where(x => x.Version <= ApplicationInfo.RunningVersion).OrderBy(x => x.Version)) { @@ -100,6 +107,7 @@ } } + @if (UpdateService.NewestAvailableUpdate != null) { if (UpdateService.NewestAvailableUpdate.Version.NewerThan(ApplicationInfo.RunningVersion)) @@ -119,7 +127,7 @@ } } - + @if (UpdateService.IncompatibleUpdates.Count > 0) { var latestIncompatibleUpdate = UpdateService.IncompatibleUpdates.Where(x => x.Newer).OrderByDescending(x => x.Release.ReleaseTime).FirstOrDefault(); diff --git a/BLAZAMGui/UI/Settings/Modals/DeleteAccessLevelModalContent.razor b/BLAZAMGui/UI/Settings/Modals/DeleteAccessLevelModalContent.razor new file mode 100644 index 000000000..778a1660a --- /dev/null +++ b/BLAZAMGui/UI/Settings/Modals/DeleteAccessLevelModalContent.razor @@ -0,0 +1,61 @@ +@using BLAZAM.Database.Models.Audit; +@using BLAZAM.Services.Audit; +@using System.Security.Cryptography.X509Certificates +@inherits AppModalContent + + @if (_usedInMappings.Count > 0) + { + + @_usedInMappings.Count @AppLocalization["mappings use this Access Level and will be deleted"] + + + + + + @foreach (var delag in context.Item.PermissionDelegates) + { + @delag.DelegateName + } + + + + + + @context.Item.OU + + + + + + + } + + +@code { + + [Parameter] + public AccessLevel AccessLevel { get; set; } + [Parameter] + public EventCallback OnConfirm { get; set; } + + List _usedInMappings = new List(); + protected override async Task OnInitializedAsync() + { + Modal.Options.MaxWidth = MaxWidth.Medium; + Modal.YesText = AppLocalization["Delete"]; + Modal.OnYes += ()=>{ OnConfirm.InvokeAsync(); }; + await base.OnInitializedAsync(); + Modal.RefreshView(); + + LoadingData = true; + await InvokeAsync(StateHasChanged); + Task.Run(() => + { + _usedInMappings = Context.PermissionMap.Where(x => x.AccessLevels.Any(al => al.Id == AccessLevel.Id)).Include(x=>x.PermissionDelegates).ToList(); + LoadingData = false; + }); + await InvokeAsync(StateHasChanged); + } + + +} diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor index 68f4f99b2..d84eaefed 100644 --- a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -1,5 +1,6 @@ @inherits DatabaseComponentBase -

@AppLocalization["Manage Notifications"]

+@AppLocalization["Manage Notifications"] + diff --git a/BLAZAMGui/UI/Settings/Permissions/AccessLevelEditor.razor b/BLAZAMGui/UI/Settings/Permissions/AccessLevelEditor.razor index 955ccc148..9514040e3 100644 --- a/BLAZAMGui/UI/Settings/Permissions/AccessLevelEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/AccessLevelEditor.razor @@ -1,5 +1,5 @@ @inherits DatabaseComponentBase - +@AppLocalization["Access Levels"] @AppLocalization["Access Levels"] @@ -34,9 +34,19 @@ LoadingData = true; await InvokeAsync(StateHasChanged); if (Context != null) - CurrentAccessLevels = await Context.AccessLevels.Where(al => al.DeletedAt == null).ToListAsync(); - LoadingData = false; + { + AccessLevel? selfLevel = null; + var selfAccessLevel = await Context.AccessLevels.FirstOrDefaultAsync(x => x.Name == AccessLevel.SelfAccessLevelName); + if (selfAccessLevel != null) + { + selfLevel = selfAccessLevel; + } + + CurrentAccessLevels = await Context.AccessLevels.Where(al => al.DeletedAt == null && al.Name != AccessLevel.SelfAccessLevelName).ToListAsync(); + + LoadingData = false; + } await InvokeAsync(StateHasChanged); } } \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor index 1518aeb13..91eed96e9 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor @@ -2,8 +2,7 @@ @inherits DatabaseComponentBase - -@AppLocalization["Delegates"] +@AppLocalization["Delegates"] Delegates are your approved application users. Only the users your define here, or users in the following Active Directory groups (or nested groups) will be allowed to log in to the application. The access allowed to each delegate is controlled by the mapped access level. diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor index 9ee5786ac..c2db1f8de 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor @@ -110,7 +110,7 @@ SnackBarService.Success("Permission Delegate removed."); await DelegateDeleted.InvokeAsync(); } - protected async override void Save() + protected async override Task Save() { Delegate.DelegateSid = _delegateEntry.SID; await Context.SaveChangesAsync(); diff --git a/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor b/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor index 4c5fd0f8e..cfe36587f 100644 --- a/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor +++ b/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor @@ -1,40 +1,50 @@ +@using BLAZAM.Gui.UI.Settings.Modals @inherits ValidatedForm - + @if (!Self) + { + + } + @if (!Self) + { + + + @AppLocalization["Assign Objects"] + + + @foreach (var adObjectType in Enum.GetValues(typeof(ActiveDirectoryObjectType))) + { - - - @AppLocalization["Assign Objects"] - - - @foreach (var adObjectType in Enum.GetValues(typeof(ActiveDirectoryObjectType))) - { - if ((ActiveDirectoryObjectType)adObjectType != ActiveDirectoryObjectType.All) - { - //Prepare data to show object access addbutons - var existingAccess = WorkingModel.ObjectMap.Where(m => m.ObjectType == (ActiveDirectoryObjectType)adObjectType).FirstOrDefault(); - bool buttonDisabled = true; - if (existingAccess == null) - { - buttonDisabled = false; - } - var name = Enum.GetName(typeof(ActiveDirectoryObjectType), adObjectType); - - @AppLocalization[name] - + if ((ActiveDirectoryObjectType)adObjectType != ActiveDirectoryObjectType.All) + { + //Prepare data to show object access addbutons + var existingAccess = WorkingModel.ObjectMap.Where(m => m.ObjectType == (ActiveDirectoryObjectType)adObjectType).FirstOrDefault(); + bool buttonDisabled = true; + if (existingAccess == null) + { + buttonDisabled = false; + } + var name = Enum.GetName(typeof(ActiveDirectoryObjectType), adObjectType); + + + @AppLocalization[name] + + } } - } - - + + + } @foreach (var objectMap in WorkingModel.ObjectMap) @@ -47,28 +57,34 @@ @name - + @if (!Self) + { + - @foreach (ObjectAccessLevel levelValue in ObjectAccessLevels.Levels) - { - @AppLocalization[levelValue.Name] + @foreach (ObjectAccessLevel levelValue in ObjectAccessLevels.Levels) + { + @AppLocalization[levelValue.Name] + + } + - } - - + + } - @if (objectMap.ObjectType == ActiveDirectoryObjectType.User && objectMap.ObjectAccessLevelId != ObjectAccessLevels.Deny.Id) + @if (objectMap.ObjectType == ActiveDirectoryObjectType.User + && objectMap.ObjectAccessLevelId != ObjectAccessLevels.Deny.Id + && !Self) { + OnClick="()=>RemoveFieldAccess(context.Item)" /> @@ -233,15 +249,33 @@ if (Model.Id > 0) buttonLabel = AppLocalization["Update Access Level"]; } -@buttonLabel -@if (WorkingModel.Id != 0) +@buttonLabel +@if (WorkingModel.Id != 0 && !Self) { - @AppLocalization["Delete Access Level"] + @AppLocalization["Delete Access Level"] + + + } + @code { [Parameter] public EventCallback LevelsChanged { get; set; } + + [Parameter] + public bool Self { get; set; } + + + AppModal? _deleteModal; + bool ShowFields { get @@ -277,7 +311,20 @@ { WorkingModel = Model; } + if (Self && WorkingModel != null) + { + WorkingModel.Name = AccessLevel.SelfAccessLevelName; + if (!WorkingModel.ObjectMap.Any(x => x.ObjectType == ActiveDirectoryObjectType.User)) + { + + WorkingModel.ObjectMap.Add(new ObjectAccessMapping() + { + ObjectType = ActiveDirectoryObjectType.User, + ObjectAccessLevelId = ObjectAccessLevels.Read.Id + }); + } + } } private async void SaveAccessLevel() @@ -299,7 +346,7 @@ SnackBarService.Success(WorkingModel.Name + " has been updated"); - if (addition) + if (addition && !Self) WorkingModel = new(); await LevelsChanged.InvokeAsync(); @@ -394,6 +441,7 @@ WorkingModel.DeletedAt = DateTime.UtcNow; await Context.SaveChangesAsync(); SnackBarService.Success(WorkingModel.Name + " has been deleted"); + await LevelsChanged.InvokeAsync(); await InvokeAsync(StateHasChanged); } /// diff --git a/BLAZAMGui/UI/Settings/Permissions/EffectivePermissionSimulator.razor b/BLAZAMGui/UI/Settings/Permissions/EffectivePermissionSimulator.razor index b669e8eac..e9168d08d 100644 --- a/BLAZAMGui/UI/Settings/Permissions/EffectivePermissionSimulator.razor +++ b/BLAZAMGui/UI/Settings/Permissions/EffectivePermissionSimulator.razor @@ -1,5 +1,8 @@ @using BLAZAM.Server.Data.Services @inherits AppComponentBase + +@AppLocalization["Effective Permissions"] + @AppLocalization["Global Permission Settings"] + + + + + + + + @if (settings.AllowAccessRequest) + { + + + + @AppLocalization["Actions"] + + + @AppLocalization["Assign"] + + + @AppLocalization["Unassign"] + + + + } + + + + + + + @if (settings.AllowSelfModification) + { + + } + + + + + @AppLocalization["Save Changes"] + + + + + + + + +@code { + GlobalPermissionSettings settings = new GlobalPermissionSettings(); + List globalPermissionRequestActions = new List(); + AccessLevel selfAccessLevel = new(); + protected override async Task OnInitializedAsync() + { + originalSettings = await Context.GlobalPermissionSettings + .AsNoTracking() + .FirstOrDefaultAsync(); + + var dbData = await Context.GlobalPermissionSettings + .FirstOrDefaultAsync(); + + if (dbData != null) + { + settings = dbData; + globalPermissionRequestActions = await Context.GlobalPermissionRequestActions.ToListAsync(); + } + else + { + // Context.GlobalPermissionSettings.Add(settings); + + } + var dbSelfAccessLevel = Context.AccessLevels.FirstOrDefault(x => x.Name == AccessLevel.SelfAccessLevelName); + if (dbSelfAccessLevel != null) + { + selfAccessLevel = dbSelfAccessLevel; + } + else + { + selfAccessLevel.Name = AccessLevel.SelfAccessLevelName; + } + LoadingData = false; + await InvokeAsync(StateHasChanged); + + } + + private void AddAction(ActiveDirectoryObjectAction action) + { + + if (settings.AllowAccessRequest) + { + if (!Context.GlobalPermissionRequestActions.Any(x => x.ObjectAction == action)) + { + + var requestAction = new GlobalPermissionRequestActions() { ObjectAction = action }; + if (requestAction != null) + { + var ctx = DbFactory.CreateDbContext(); + // settings.AllowedAccessRequestActions.Add(requestAction); + ctx.GlobalPermissionRequestActions.Add(requestAction); + ctx.SaveChanges(); + } + + } + else + { + var requestAction = Context.GlobalPermissionRequestActions.FirstOrDefault(x => x.ObjectAction == action); + if (requestAction != null) + { + + var ctx = DbFactory.CreateDbContext(); + + ctx.GlobalPermissionRequestActions.Remove(requestAction); + //settings.AllowedAccessRequestActions.Remove(requestAction); + ctx.SaveChanges(); + + } + } + } + + + } + protected override async Task Save() + { + //AccessLevel? accessLevel = null; + + // if (selfAccessLevel != null && selfAccessLevel.Id<1) + // { + // Context.AccessLevels.Add(selfAccessLevel); + // } + if (settings.Id == 0) + { + await Context.GlobalPermissionSettings.AddAsync(settings); + } + + + + + AuditLogger.System.SettingsChanged("Global Permissions", settings.GetChanges(originalSettings)); + if (Context != null) + { + try + { + + await Context.SaveChangesAsync(); + SnackBarService.Success("Settings have been saved"); + } + catch (Exception ex) + { + SnackBarService.Error(ex.Message); + + } + await InvokeAsync(StateHasChanged); + } + else + { + SnackBarService.Success("Database not available"); + + } + //selfAccessLevel = accessLevel; + + } +} diff --git a/BLAZAMGui/UI/Settings/Permissions/ImpersonateUser.razor b/BLAZAMGui/UI/Settings/Permissions/ImpersonateUser.razor index 866e84ec4..203dc5b12 100644 --- a/BLAZAMGui/UI/Settings/Permissions/ImpersonateUser.razor +++ b/BLAZAMGui/UI/Settings/Permissions/ImpersonateUser.razor @@ -2,11 +2,11 @@ @using System.Diagnostics @inherits AppComponentBase @inject IJSRuntime JSRuntime -@if ((CurrentUser.State.IsSuperAdmin && CurrentUser.Username != "Demo") || (CurrentUser.State.IsSuperAdmin|| Debugger.IsAttached)) +@if ((CurrentUser.State.IsSuperAdmin && CurrentUser.Username != "Demo") || (CurrentUser.State.IsSuperAdmin && Debugger.IsAttached)) {
- + - -
} diff --git a/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor b/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor index f6508faee..fe828b471 100644 --- a/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor +++ b/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor @@ -1,5 +1,7 @@  @inherits AppComponentBase + +@AppLocalization["Permission Mappings"]

OU Privilege Mapper

diff --git a/BLAZAMGui/UI/Settings/Permissions/ShowAccessLevel.razor b/BLAZAMGui/UI/Settings/Permissions/ShowAccessLevel.razor index e37ee3bc8..69af8f98d 100644 --- a/BLAZAMGui/UI/Settings/Permissions/ShowAccessLevel.razor +++ b/BLAZAMGui/UI/Settings/Permissions/ShowAccessLevel.razor @@ -14,7 +14,7 @@ else @code { -#nullable disable warnings + #nullable disable warnings [Parameter] public AccessLevel Model { get; set; } diff --git a/BLAZAMGui/UI/Settings/SystemSettings.razor b/BLAZAMGui/UI/Settings/SystemSettings.razor index fc9783d1f..096e1d123 100644 --- a/BLAZAMGui/UI/Settings/SystemSettings.razor +++ b/BLAZAMGui/UI/Settings/SystemSettings.razor @@ -136,10 +136,10 @@ } } - protected override void Save() + protected override async Task Save() { AuditLogger.System.SettingsChanged("Application", settings.GetChanges(originalSettings)); - base.Save(); + await base.Save(); } } diff --git a/BLAZAMGui/UI/Settings/UpdateSettings.razor b/BLAZAMGui/UI/Settings/UpdateSettings.razor index 839e60547..0c49d4bd2 100644 --- a/BLAZAMGui/UI/Settings/UpdateSettings.razor +++ b/BLAZAMGui/UI/Settings/UpdateSettings.razor @@ -174,9 +174,7 @@ - - - + @code { @@ -212,7 +210,7 @@ } - protected override async void Save() + protected override async Task Save() { if ((newUpdatePassword == null && updatePasswordInDb is null) == false) { diff --git a/BLAZAMGui/UI/Settings/ValidatedForm.razor b/BLAZAMGui/UI/Settings/ValidatedForm.razor index 3645fa6d0..af9021f6e 100644 --- a/BLAZAMGui/UI/Settings/ValidatedForm.razor +++ b/BLAZAMGui/UI/Settings/ValidatedForm.razor @@ -14,7 +14,7 @@ [Parameter] public EventCallback OnValidSubmit{ get; set; } - protected virtual async void Save() + protected virtual async Task Save() { if (Context != null) { diff --git a/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor b/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor index 7a7ef3ca4..eb556ee73 100644 --- a/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor +++ b/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor @@ -1,5 +1,5 @@ @inherits AppModalContent -@inject OUNotificationService OUNotificationService +@inject NotificationGenerationService OUNotificationService @@ -63,7 +63,7 @@ } SnackBarService.Success("Changed password for " + User.DisplayName); await AuditLogger.User.PasswordChanged(User, requireChangeSwitch.Value); - _ = OUNotificationService.PostAsync(User, NotificationType.PasswordChange); + _ = OUNotificationService.PostAsync(User, NotificationType.PasswordChange, CurrentUser.State); await InvokeAsync(Close); diff --git a/BLAZAMJobs/JobMonitor.cs b/BLAZAMJobs/JobMonitor.cs index 766debfeb..dd57ae7f1 100644 --- a/BLAZAMJobs/JobMonitor.cs +++ b/BLAZAMJobs/JobMonitor.cs @@ -15,7 +15,7 @@ public static class JobMonitor public static List FailedJobs => Jobs.Where(x => x.Result == JobResult.Failed).ToList(); public static List CompletedJobs => Jobs.Where(x => x.Result == JobResult.Passed).ToList(); public static List PendingJobs => Jobs.Where(x => x.Result == JobResult.NotRun).ToList(); - private static int _maxJobs = 50; + private static int _maxJobs = 200; public static void AddJob(IJob job) diff --git a/BLAZAMNotifications/Services/INotificationPublisher.cs b/BLAZAMNotifications/Services/INotificationPublisher.cs index 3fc3c37e2..286d6a59e 100644 --- a/BLAZAMNotifications/Services/INotificationPublisher.cs +++ b/BLAZAMNotifications/Services/INotificationPublisher.cs @@ -5,6 +5,9 @@ namespace BLAZAM.Notifications.Services public interface INotificationPublisher { AppEvent> OnNotificationPublished { get; set; } + AppEvent OnNotificationDeleted { get; set; } + + Task DeleteNotification(NotificationMessage notificationMessage, AppUser user); /// /// Publishes a notification to a single user diff --git a/BLAZAMNotifications/Services/NotificationPublisher.cs b/BLAZAMNotifications/Services/NotificationPublisher.cs index d1c3ec2bd..ae5a54f51 100644 --- a/BLAZAMNotifications/Services/NotificationPublisher.cs +++ b/BLAZAMNotifications/Services/NotificationPublisher.cs @@ -1,6 +1,9 @@  +using BLAZAM.Common.Data; using BLAZAM.Database.Context; using BLAZAM.Database.Models.User; +using BLAZAM.Logger; +using Microsoft.EntityFrameworkCore; namespace BLAZAM.Notifications.Services { @@ -8,6 +11,7 @@ public class NotificationPublisher : INotificationPublisher { private readonly IAppDatabaseFactory _databaseFactory; public AppEvent> OnNotificationPublished { get; set; } + public AppEvent OnNotificationDeleted { get; set; } public NotificationPublisher(IAppDatabaseFactory databaseFactory) { _databaseFactory = databaseFactory; @@ -23,30 +27,39 @@ public Task PublishNotification(List users, NotificationMessage notific if (notificationMessage.Id == 0) { - notificationMessage = context.NotificationMessages.Add(notificationMessage).Entity; - context.SaveChanges(); + try + { + + notificationMessage = context.NotificationMessages.Add(notificationMessage).Entity; + context.SaveChanges(); + } + catch (Exception ex) + { + Loggers.SystemLogger.Error("Error saving new notification {Error}", ex); + + } } - List sentNotificaitons = new(); + List sentNotifications = new(); foreach (var user in users) { var userNotification = new UserNotification() { User = context.UserSettings.Where(u => u.Equals(user)).FirstOrDefault(), - Notification = notificationMessage + NotificationId = notificationMessage.Id }; context.UserNotifications.Add(userNotification); - sentNotificaitons.Add(userNotification); + sentNotifications.Add(userNotification); } try { context.SaveChanges(); - OnNotificationPublished?.Invoke(sentNotificaitons); + OnNotificationPublished?.Invoke(sentNotifications); } catch (Exception ex) { - + Loggers.SystemLogger.Error("Error saving new usernotification {Error}", ex); } return Task.CompletedTask; @@ -59,5 +72,24 @@ public Task PublishNotification(NotificationMessage notificationMessage) PublishNotification(allUsers, notificationMessage); return Task.CompletedTask; } + + public async Task DeleteNotification(NotificationMessage notificationMessage, AppUser user) + { + try + { + using var context = _databaseFactory.CreateDbContext(); + var dbNotification = await context.NotificationMessages.FirstOrDefaultAsync(x => x.Id == notificationMessage.Id); + + context.NotificationMessages.Remove(dbNotification); + await context.SaveChangesAsync(); + this.OnNotificationDeleted.Invoke(); + return true; + } + catch (Exception ex) + { + Loggers.SystemLogger.Error("Error deleting notification {Error}", ex); + return false; + } + } } } diff --git a/BLAZAMServices/AppAuthenticationStateProvider.cs b/BLAZAMServices/AppAuthenticationStateProvider.cs index 5b152a364..ecad1c3d1 100644 --- a/BLAZAMServices/AppAuthenticationStateProvider.cs +++ b/BLAZAMServices/AppAuthenticationStateProvider.cs @@ -371,7 +371,7 @@ private async Task PerformDuoAuthentication(LoginRequest loginReq) /// The parameters passed from the login attempt /// A fully processed ClaimsPrincipal representing the Web user with data applied depending on /// database permission tables - private async Task CreateDirectoryPrincipal(IApplicationUserState loginUser, IADUser? user, LoginRequest loginReq) + public async Task CreateDirectoryPrincipal(IApplicationUserState loginUser, IADUser? user, LoginRequest? loginReq = null) { ClaimsPrincipal? principal = null; @@ -391,7 +391,7 @@ private async Task PerformDuoAuthentication(LoginRequest loginReq) /// The parameteres passed from the login attempt /// A fully processed ClaimsIdentity representing the user in Active Directory with data applied depending on /// database permission tables - private async Task CreateDirectoryIdentity(IApplicationUserState loginUser, IADUser user, LoginRequest loginReq) + public async Task CreateDirectoryIdentity(IApplicationUserState loginUser, IADUser user, LoginRequest? loginReq = null) { var identity = new ClaimsIdentity(); @@ -429,7 +429,7 @@ private async Task PerformDuoAuthentication(LoginRequest loginReq) if (user.Email != null) claims.Add(new Claim(ClaimTypes.Email, user.Email)); - if (loginReq.Impersonation) + if (loginReq != null && loginReq.Impersonation) { //Handle Impersonated login claims.Add(new Claim(ClaimTypes.UserData, "impersonated")); diff --git a/BLAZAMServices/Background/OUNotificationService.cs b/BLAZAMServices/Background/NotificationGenerationService.cs similarity index 52% rename from BLAZAMServices/Background/OUNotificationService.cs rename to BLAZAMServices/Background/NotificationGenerationService.cs index 39956fc7f..749cd18f1 100644 --- a/BLAZAMServices/Background/OUNotificationService.cs +++ b/BLAZAMServices/Background/NotificationGenerationService.cs @@ -1,6 +1,8 @@ -using BLAZAM.ActiveDirectory.Interfaces; +using AngleSharp.Dom; +using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Database.Context; using BLAZAM.Database.Models.Notifications; +using BLAZAM.Database.Models.Permissions; using BLAZAM.Database.Models.User; using BLAZAM.EmailMessage.Email.Base; using BLAZAM.EmailMessage.Email.Notifications; @@ -10,18 +12,21 @@ using BLAZAM.Notifications.Notifications; using BLAZAM.Notifications.Services; using BLAZAM.Server.Data.Services; +using BLAZAM.Session.Interfaces; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Localization; +using System; namespace BLAZAM.Services.Background { - public class OUNotificationService + public class NotificationGenerationService { private IAppDatabaseFactory _databaseFactory; private readonly INotificationPublisher _notificationPublisher; private readonly IStringLocalizer _appLocalization; private readonly EmailService _emailService; - public OUNotificationService(IAppDatabaseFactory databaseFactory, INotificationPublisher notificationPublisher, IStringLocalizer appLocalization, EmailService emailService) + public NotificationGenerationService(IAppDatabaseFactory databaseFactory, INotificationPublisher notificationPublisher, IStringLocalizer appLocalization, EmailService emailService) { _databaseFactory = databaseFactory; _notificationPublisher = notificationPublisher; @@ -29,74 +34,36 @@ public OUNotificationService(IAppDatabaseFactory databaseFactory, INotificationP _emailService = emailService; } private IDatabaseContext Context => _databaseFactory.CreateDbContext(); - public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType notificationType, ApplicationUserState? actor=null, IDirectoryEntryAdapter? target = null) + + /// + /// Post a notification to OU subscribers + /// + /// + /// + /// + /// + /// + public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType notificationType, IApplicationUserState? actor = null, IDirectoryEntryAdapter? target = null) { await Task.Run(async () => { - var context = Context; + NotificationMessage notification; string notificationTitle; - notificationTitle = _appLocalization[source.ObjectType.ToString()] + " "; - - string notificationBody; - NotificationTemplateComponent? emailMessage = null; - notificationBody = "" + source.CanonicalName + " "; - - switch (notificationType) - { - case NotificationType.Create: - notificationTitle += _appLocalization["Created"]; - notificationBody += _appLocalization["was created at "] + source.Created?.ToLocalTime(); - var createdMessage = NotificationType.Create.ToNotification(); - createdMessage.EntryName = source.CanonicalName; - emailMessage = createdMessage; - break; - case NotificationType.Delete: - notificationTitle += _appLocalization["Deleted"]; - notificationBody += _appLocalization["was deleted at "] + source.LastChanged?.ToLocalTime(); - var deletedMessage = NotificationType.Delete.ToNotification(); - deletedMessage.EntryName = source.CanonicalName; - emailMessage = deletedMessage; - break; - case NotificationType.Modify: - notificationTitle += _appLocalization["Modified"]; - notificationBody += _appLocalization["was modified at "] + source.LastChanged?.ToLocalTime(); - var editedMessage = NotificationType.Modify.ToNotification(); - editedMessage.EntryName = source.CanonicalName; - emailMessage = editedMessage; - break; - case NotificationType.GroupAssignment: - notificationTitle += _appLocalization["Group Membership Changed"]; - notificationBody += _appLocalization["was assigned/removed from "] + "" + target.CanonicalName + " " + _appLocalization[" at "] + source.LastChanged?.ToLocalTime(); - - var groupMembershipMessage = NotificationType.GroupAssignment.ToNotification(); - groupMembershipMessage.EntryName = source.CanonicalName; - emailMessage = groupMembershipMessage; - break; - case NotificationType.PasswordChange: - notificationTitle += _appLocalization["Password Reset"]; - notificationBody += _appLocalization["had a password reset at "] + source.LastChanged?.ToLocalTime(); - var passwordChangeMessage = NotificationType.PasswordChange.ToNotification(); - passwordChangeMessage.EntryName = source.CanonicalName; - emailMessage = passwordChangeMessage; - break; - - } - var notification = new NotificationMessage(); - notification.Title = notificationTitle; - notification.Message = notificationBody; - notification.Dismissable = true; - notification.Created = DateTime.Now; - notification.Level = NotificationLevel.Info; + NotificationTemplateComponent? emailMessage; + PackageNotification(source, notificationType, actor, target, out notification, out notificationTitle, out emailMessage); var _emailConfigured = _emailService.IsConfigured; + var users = Context.UserSettings.Include(us => us.NotificationSubscriptions).ToList(); - foreach (var user in Context.UserSettings.ToList()) + Parallel.ForEach(users, async user => { var effectiveInAppSubscriptions = CalculateEffectiveInAppSubscriptions(user, source); var effectiveEmailSubscriptions = CalculateEffectiveEmailSubscriptions(user, source); + if (effectiveInAppSubscriptions.NotificationTypes.Any(x => x.NotificationType == notificationType)) { await _notificationPublisher.PublishNotification(user, notification); } + if (effectiveEmailSubscriptions.NotificationTypes.Any(x => x.NotificationType == notificationType)) { if (emailMessage != null) @@ -104,7 +71,6 @@ await Task.Run(async () => if (_emailConfigured && !user.Email.IsNullOrEmpty()) { await _emailService.SendMessage(notificationTitle, emailMessage, user.Email); - } } else @@ -113,10 +79,106 @@ await Task.Run(async () => Loggers.SystemLogger.Error("Email message template was not found! {@Error}", error); } } - } + }); + + }); } + /// + /// Package a notification from event parameters + /// + /// + /// + /// + /// + /// + /// + /// + public void PackageNotification(IDirectoryEntryAdapter source, NotificationType notificationType, IApplicationUserState? actor, IDirectoryEntryAdapter? target, out NotificationMessage notification, out string notificationTitle, out NotificationTemplateComponent? emailMessage) + { + notification = new NotificationMessage(); + notificationTitle = _appLocalization[source.ObjectType.ToString()] + " "; + + string notificationBody; + emailMessage = null; + notificationBody = "" + source.CanonicalName + " "; + var time = DateTime.Now.ToString(); + switch (notificationType) + { + case NotificationType.Create: + notification.Action = ActiveDirectoryObjectAction.Create; + + notificationTitle += _appLocalization["Created"]; + notificationBody += _appLocalization["was created at "] + time; + var createdMessage = NotificationType.Create.ToNotification(); + createdMessage.EntryName = source.CanonicalName; + emailMessage = createdMessage; + break; + case NotificationType.Delete: + notification.Action = ActiveDirectoryObjectAction.Delete; + + notificationTitle += _appLocalization["Deleted"]; + notificationBody += _appLocalization["was deleted at "] + time; + var deletedMessage = NotificationType.Delete.ToNotification(); + deletedMessage.EntryName = source.CanonicalName; + emailMessage = deletedMessage; + break; + case NotificationType.Modify: + notificationTitle += _appLocalization["Modified"]; + notificationBody += _appLocalization["was modified at "] + time; + + var editedMessage = NotificationType.Modify.ToNotification(); + editedMessage.EntryName = source.CanonicalName; + emailMessage = editedMessage; + break; + case NotificationType.GroupAssignment: + notification.Action = ActiveDirectoryObjectAction.Assign; + + notificationTitle += _appLocalization["Group Membership Changed"]; + notificationBody += _appLocalization["was assigned/removed from "] + "" + target.CanonicalName + " " + _appLocalization[" at "] + time; + + var groupMembershipMessage = NotificationType.GroupAssignment.ToNotification(); + groupMembershipMessage.EntryName = source.CanonicalName; + emailMessage = groupMembershipMessage; + break; + case NotificationType.PasswordChange: + notification.Action = ActiveDirectoryObjectAction.SetPassword; + + notificationTitle += _appLocalization["Password Reset"]; + notificationBody += _appLocalization["had a password reset at "] + time; + var passwordChangeMessage = NotificationType.PasswordChange.ToNotification(); + passwordChangeMessage.EntryName = source.CanonicalName; + emailMessage = passwordChangeMessage; + break; + + } + if (actor != null) + { + notificationBody += " " + _appLocalization["by"] + " " + actor.AuditUsername; + } + notification.Title = notificationTitle; + notification.Message = notificationBody; + notification.Dismissable = true; + notification.CreatorId = actor?.Preferences.Id; + notification.Level = NotificationLevel.Info; + } + + public void PackageRequest(IDirectoryEntryAdapter target, ActiveDirectoryObjectAction action, IApplicationUserState? actor, out NotificationMessage notification) + { + notification = new NotificationMessage() + { + Action = action, + CreatorId = actor?.Preferences.Id, + Level = NotificationLevel.Info, + TargetDN = target.DN, + MessageType = MessageType.AccessRequest, + Title = _appLocalization["Request to"] + " " + _appLocalization[action.ToString()] + }; + + notification.Level = NotificationLevel.Info; + } + public NotificationSubscription CalculateEffectiveEmailSubscriptions(AppUser user, IDirectoryEntryAdapter ou) { if (ou is not IADOrganizationalUnit) diff --git a/BLAZAMServices/UserSeederService.cs b/BLAZAMServices/UserSeederService.cs index 646f3d1fe..b0513d98d 100644 --- a/BLAZAMServices/UserSeederService.cs +++ b/BLAZAMServices/UserSeederService.cs @@ -37,6 +37,8 @@ private void SeedUsers(object obj = null) try { EnsureAdminExists(); + EnsureSelfExists(); + if (_applicationInfo.InDemoMode) EnsureDemoExists(); using var context = _dbFactory.CreateDbContext(); @@ -117,5 +119,21 @@ private void EnsureDemoExists() } context.SaveChanges(); } + /// + /// Checks the database for the self user, if not found it is added + /// + private void EnsureSelfExists() + { + using var context = _dbFactory.CreateDbContext(); + if (!context.UserSettings.Any(us => us.UserGUID == "3")) + { + context.UserSettings.Add(new() + { + Username = "Self", + UserGUID = "3" + }); + } + context.SaveChanges(); + } } } diff --git a/BLAZAMSession/ApplicationUserState.cs b/BLAZAMSession/ApplicationUserState.cs index 0d501caed..eb3f6c633 100644 --- a/BLAZAMSession/ApplicationUserState.cs +++ b/BLAZAMSession/ApplicationUserState.cs @@ -118,7 +118,7 @@ public async Task MarkRead(UserNotification notification) return false; } - private void GetUserSettingFromDB() + public void GetUserSettingFromDB() { try { diff --git a/BLAZAMSession/Interfaces/IApplicationUserState.cs b/BLAZAMSession/Interfaces/IApplicationUserState.cs index b6adcca3d..7716581f1 100644 --- a/BLAZAMSession/Interfaces/IApplicationUserState.cs +++ b/BLAZAMSession/Interfaces/IApplicationUserState.cs @@ -102,5 +102,6 @@ public interface IApplicationUserState Task SaveDashboardWidgets(); Task SaveReadNewsItems(); Task SaveBasicUserPreferences(); + void GetUserSettingFromDB(); } } \ No newline at end of file diff --git a/BLAZAMThemes/BlueTheme.cs b/BLAZAMThemes/BlueTheme.cs index defdfdd0e..c3b662a56 100644 --- a/BLAZAMThemes/BlueTheme.cs +++ b/BLAZAMThemes/BlueTheme.cs @@ -14,7 +14,7 @@ public BlueTheme() lightPalette.ActionDefault = "#9aafc3"; - lightPalette.AppbarBackground = "#2261d3"; + lightPalette.AppbarBackground = "#2252A8"; lightPalette.DrawerBackground = "#cfd6dc"; lightPalette.DrawerText = "#0f141e"; lightPalette.Dark = "#001529"; diff --git a/BLAZAMThemes/GreenTheme.cs b/BLAZAMThemes/GreenTheme.cs index ef6a3ef1a..6510f8685 100644 --- a/BLAZAMThemes/GreenTheme.cs +++ b/BLAZAMThemes/GreenTheme.cs @@ -15,7 +15,8 @@ public GreenTheme() lightPalette.ActionDefault = "#9AC3A1"; - lightPalette.AppbarBackground = "#1BB836"; + lightPalette.AppbarBackground = "#22A830"; + // lightPalette.AppbarBackground = "#1BB836"; lightPalette.DrawerBackground = "#CFDCD0"; lightPalette.DrawerText = "#0F1E12"; diff --git a/BLAZAMThemes/OrangeTheme.cs b/BLAZAMThemes/OrangeTheme.cs index 8dd21dbb5..45f79c347 100644 --- a/BLAZAMThemes/OrangeTheme.cs +++ b/BLAZAMThemes/OrangeTheme.cs @@ -14,7 +14,6 @@ public OrangeTheme() lightPalette.ActionDefault = "#C3AF9A"; - lightPalette.AppbarBackground = "#D39E22"; lightPalette.DrawerBackground = "#DCD8CF"; lightPalette.DrawerText = "#1E1A0F"; diff --git a/BLAZAMThemes/RedTheme.cs b/BLAZAMThemes/RedTheme.cs index 1b56b9add..d173b4108 100644 --- a/BLAZAMThemes/RedTheme.cs +++ b/BLAZAMThemes/RedTheme.cs @@ -12,7 +12,8 @@ public RedTheme() lightPalette.ActionDefault = "#C39A9A"; - lightPalette.AppbarBackground = "#D32222"; + lightPalette.AppbarBackground = "#A82222"; + //lightPalette.AppbarBackground = "#D32222"; lightPalette.DrawerBackground = "#DCCFCF"; lightPalette.DrawerText = "#1E0F0F"; lightPalette.Dark = "#290500"; diff --git a/BLAZAMUpdate/ApplicationUpdate.cs b/BLAZAMUpdate/ApplicationUpdate.cs index d818e0357..73b1e824d 100644 --- a/BLAZAMUpdate/ApplicationUpdate.cs +++ b/BLAZAMUpdate/ApplicationUpdate.cs @@ -8,11 +8,13 @@ using BLAZAM.Jobs; using BLAZAM.Logger; using BLAZAM.Update.Exceptions; +using BLAZAM.Update.Services; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; using System.Diagnostics; using System.IO.Compression; using System.Security.Principal; +using System.Text; namespace BLAZAM.Update { @@ -41,6 +43,7 @@ public class ApplicationUpdate public string Branch { get => Release.Branch; } private IAppDatabaseFactory _dbFactory; + private UpdateService _updateService; /// /// The application update directory, in temporary files @@ -95,14 +98,15 @@ public string UpdateCommandArguments { get { - return "/c start Powershell -ExecutionPolicy Bypass -command \"" + CommandProcessPath + CommandArguments + "\""; + return "/c start Powershell -ExecutionPolicy Bypass -command \"& '" + CommandProcessPath + + "' " + CommandArguments + "\""; } } private SystemFile CommandProcessPath { get { - var testPath = new SystemFile(_applicationRootDirectory + @"bin\Debug\net6.0\updater\update.ps1"); + var testPath = new SystemFile(_applicationRootDirectory + @"bin\Debug\net8.0\updater\update.ps1"); if (!testPath.Exists) @@ -116,10 +120,23 @@ private string CommandArguments { get { - return " -UpdateSourcePath '" + UpdateStagingDirectory + "' -ProcessId " + _runningProcess.Id + " -ApplicationDirectory '" + _applicationRootDirectory + "'" + - " -Username " + DatabaseCache.ActiveDirectorySettings?.Username + - " -Domain " + DatabaseCache.ActiveDirectorySettings?.FQDN + - " -Password '" + DatabaseCache.ActiveDirectorySettings?.Password.Decrypt() + "'"; + //var creds = _updateService.GetImpersonationUser(); + var args = " -UpdateSourcePath '" + UpdateStagingDirectory + "' -ProcessId " + _runningProcess.Id + " -ApplicationDirectory '" + _applicationRootDirectory; + if (Debugger.IsAttached) + args += "bin\\Debug\\net8.0\\"; + args += "'"; + //if (creds != null) + //{ + // args += " -Username " + creds.Username + + // " -Password '" + creds.Password.ToPlainText() + "'"; + // if (!creds.FQDN.IsNullOrEmpty()) + // { + + // args += " -Domain " + creds.FQDN; + // } + //} + return args; + } } @@ -131,10 +148,10 @@ private string CommandArguments private SystemDirectory _applicationRootDirectory; - public ApplicationUpdate(ApplicationInfo applicationInfo, IAppDatabaseFactory dbFactory) + public ApplicationUpdate(ApplicationInfo applicationInfo, UpdateService updateService, IAppDatabaseFactory dbFactory) { _dbFactory = dbFactory; - + _updateService = updateService; UpdateTempDirectory = new SystemDirectory(applicationInfo.TempDirectory + "update\\"); _runningProcess = applicationInfo.RunningProcess; _runningVersion = applicationInfo.RunningVersion; @@ -219,18 +236,31 @@ private async Task InitiateFileCopy(JobStep? step) //All prerequisites met - //Update the updater first Loggers.UpdateLogger?.Debug("Copying updater script"); Loggers.UpdateLogger?.Debug("Source: " + UpdateStagingDirectory + "\\updater\\*"); Loggers.UpdateLogger?.Debug("Dest: " + _applicationRootDirectory + "updater\\"); using var context = await _dbFactory.CreateDbContextAsync(); + var updateCredentials = _updateService.GetUpdateCredentials(); + if (updateCredentials != null) + { + return updateCredentials.Run(() => + { + try + { + return ApplyFiles(); + } + catch (Exception ex) + { + Loggers.UpdateLogger?.Error("Error applying update: {@Error}", ex); - - if (_applicationRootDirectory.Writable) + } + return false; + }); + } + else { - Loggers.UpdateLogger?.Warning("The application user has write permission to the application directory!"); try { return ApplyFiles(); @@ -238,47 +268,69 @@ private async Task InitiateFileCopy(JobStep? step) catch (Exception ex) { Loggers.UpdateLogger?.Error("Error applying update: {@Error}", ex); - throw new ApplicationUpdateException("Error trying to apply update files", ex); - } - return false; - } - else - { - var settings = context.ActiveDirectorySettings.FirstOrDefault(); - - - if (settings == null) throw new ApplicationUpdateException("No credentials are configured for updates"); - - var impersonation = settings.CreateDirectoryAdminImpersonator(); - try - { - - return impersonation.Run(() => - { - try - { - return ApplyFiles(); - } - catch (Exception ex) - { - Loggers.UpdateLogger?.Error("Error applying update: {@Error}", ex); - - } - return false; - }); - } - catch (ApplicationException ex) - { - Loggers.UpdateLogger?.Error("Unable to apply files {@Error}", ex); - return false; - } - - - } - + return false; + //switch (_updateService.UpdateCredential) + //{ + + // case UpdateCredential.Application: + // Loggers.UpdateLogger?.Warning("The application user has write permission to the application directory!"); + // try + // { + // return ApplyFiles(); + // } + // catch (Exception ex) + // { + // Loggers.UpdateLogger?.Error("Error applying update: {@Error}", ex); + // throw new ApplicationUpdateException("Error trying to apply update files", ex); + // } + // case UpdateCredential.Active_Directory: + // var adCredentials = context.ActiveDirectorySettings.FirstOrDefault()?.CreateDirectoryAdminImpersonator(); + // if (adCredentials != null) + // { + + // return adCredentials.Run(() => + // { + // try + // { + // return ApplyFiles(); + // } + // catch (Exception ex) + // { + // Loggers.UpdateLogger?.Error("Error applying update: {@Error}", ex); + + // } + // return false; + // }); + // } + // break; + // case UpdateCredential.Update: + // var updateCredentials = _updateService.GetUpdateCredentials(); + // if (updateCredentials != null) + // { + + // return updateCredentials.Run(() => + // { + // try + // { + // return ApplyFiles(); + // } + // catch (Exception ex) + // { + // Loggers.UpdateLogger?.Error("Error applying update: {@Error}", ex); + + // } + // return false; + // }); + // } + // break; + // default: + // case UpdateCredential.None: + // return false; + //} + //return false; } @@ -291,9 +343,15 @@ private bool ApplyFiles() SystemDirectory updaterDirFromStagedUpdate = new SystemDirectory(UpdateStagingDirectory.FullPath + "updater\\"); SystemDirectory updaterDir = new SystemDirectory(_applicationRootDirectory.FullPath + "updater\\"); + + + + + + //Update the updater first updaterDirFromStagedUpdate.CopyTo(updaterDir); - //File.Copy(UpdateStagingDirectory + "\\updater\\", _applicationRootDirectory + "updater\\", true); Loggers.UpdateLogger?.Information("Updater updated"); + //If the updater updated we can run the updater var updaterRan = InvokeUpdateExecutable(); @@ -310,8 +368,9 @@ private bool ApplyFiles() } } - private bool InvokeUpdateExecutable() + private bool InvokeUpdateExecutable_old() { + var startTime = DateTime.Now; var process = new Process { StartInfo = new ProcessStartInfo @@ -326,16 +385,69 @@ private bool InvokeUpdateExecutable() } }; + Loggers.UpdateLogger?.Information("Starting update process"); process.Start(); + Loggers.UpdateLogger?.Information("Update process id: " + process.Id); process.WaitForExit(); + Loggers.UpdateLogger?.Information("Update process exited: " + process.ExitCode); + Loggers.UpdateLogger?.Information("Update process execution time: " + (DateTime.Now - startTime).TotalMilliseconds + "ms"); return true; } + private bool InvokeUpdateExecutable() + { + var startTime = DateTime.Now; + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = UpdateCommandProcess, + Arguments = UpdateCommandArguments, + RedirectStandardOutput = true, // Enable output redirection + RedirectStandardError = true, + UseShellExecute = false, // Required for redirection + CreateNoWindow = true, + } + }; + Loggers.UpdateLogger?.Information("Starting update process"); + process.Start(); + Loggers.UpdateLogger?.Information("Update process id: " + process.Id); + + // Read and log the output asynchronously + var output = new StringBuilder(); + process.OutputDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + output.AppendLine(e.Data); + Loggers.UpdateLogger?.Information("Update process output: " + e.Data); + } + }; + process.ErrorDataReceived += (sender, e) => + { + if (!string.IsNullOrEmpty(e.Data)) + { + output.AppendLine(e.Data); + Loggers.UpdateLogger?.Error("Update process error: " + e.Data); // Log as error + } + }; + process.BeginOutputReadLine(); // Start asynchronous reading + + process.WaitForExit(); + + Loggers.UpdateLogger?.Information("Update process exited: " + process.ExitCode); + Loggers.UpdateLogger?.Information("Update process execution time: " + (DateTime.Now - startTime).TotalMilliseconds + "ms"); + + // Log the complete output (if needed) + Loggers.UpdateLogger?.Information("Complete update process output:\n" + output.ToString()); + + return true; + } public async Task Backup(JobStep? step) { Loggers.UpdateLogger?.Information("Attempting backup of current version to: " + BackupPath); diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index 9099de5db..e13b5d4ef 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Localization; using Octokit; using System.Diagnostics; +using System.Runtime.ExceptionServices; using System.Security.Principal; namespace BLAZAM.Update.Services @@ -231,7 +232,7 @@ private async Task SetBranch() Version = releaseVersion, }; - var update = new ApplicationUpdate(_applicationInfo, _dbFactory) { Release = release }; + var update = new ApplicationUpdate(_applicationInfo, this, _dbFactory) { Release = release }; if (releaseVersion.NewerThan(new ApplicationVersion("0.9.99"))) { update.PreRequisiteChecks.Add(new(() => @@ -287,7 +288,7 @@ public UpdateCredential UpdateCredential { Loggers.UpdateLogger.Information("Checking update credentials"); - if (!Debugger.IsAttached && ApplicationInfo.applicationRoot.Writable) + if (ApplicationInfo.applicationRoot.Writable) return UpdateCredential.Application; //Test Directory Credentials @@ -306,6 +307,24 @@ public UpdateCredential UpdateCredential } } + public WindowsImpersonation? GetUpdateCredentials() + { + using var context = _dbFactory.CreateDbContext(); + switch (UpdateCredential) + { + case UpdateCredential.Application: + return null; + case UpdateCredential.Active_Directory: + //Pull ad settings to test if app ad account can write to the application directory + var adSettings = context.ActiveDirectorySettings.FirstOrDefault(); + return adSettings?.CreateDirectoryAdminImpersonator(); + case UpdateCredential.Update: + var appSettings = context.AppSettings.FirstOrDefault(); + return appSettings?.CreateUpdateImpersonator(); + default: + return null; + } + } private bool TestCustomCredentials() { using var context = _dbFactory.CreateDbContext(); @@ -349,10 +368,18 @@ private bool TestDirectoryCredentials() if (impersonation != null) { + var applicationIdentity = WindowsIdentity.GetCurrent(); return impersonation.Run(() => { Loggers.UpdateLogger.Information("Checking AD update credential permissions: " + WindowsIdentity.GetCurrent().Name); - + var impersonatedIdentity = WindowsIdentity.GetCurrent(); + if (adSettings.Username != applicationIdentity.Name && impersonatedIdentity.Name.Equals(applicationIdentity.Name)) + { + var exception = new ApplicationException("Impersonation running as application identity"); + ExceptionDispatchInfo.SetCurrentStackTrace(exception); + Loggers.ActiveDirectoryLogger.Error("Impersonation running as application identity {@Error}", exception); + return false; + } if (ApplicationInfo.applicationRoot.Writable) return true; return false; diff --git a/PlaywrightTests/UnitTest1.cs b/PlaywrightTests/UnitTest1.cs index d3f9d5c68..15c7d4a60 100644 --- a/PlaywrightTests/UnitTest1.cs +++ b/PlaywrightTests/UnitTest1.cs @@ -1,3 +1,5 @@ +using Microsoft.Playwright; + namespace PlaywrightTests { [Parallelizable(ParallelScope.Self)] @@ -13,8 +15,349 @@ public async Task LandingPageHasDemoLoginButtonAndLogsIntoHome() await Expect(Page).ToHaveURLAsync(new Regex(".*home")); } + [Test] + public async Task UserMenuTest() + { + await LogIn(); + + await OpenUserMenu(); + await OpenProfileSettings(); + await CloseDialog(); + + + // Expects the URL to contain intro. + //await Expect(Page).ToHaveURLAsync(new Regex(".*home")); + } + [Test] + public async Task MainMenuTest() + { + await LogIn(); + + + await OpenRecycleBin(); + + await OpenConfigureSubMenu(); + + await OpenSettingsPages(); + + await OpenManageNotifications(); + + await OpenPermissions(); + + await OpenFields(); + + await OpenTemplates(); + + + // Expects the URL to contain intro. + //await Expect(Page).ToHaveURLAsync(new Regex(".*home")); + } + + private async Task CloseDialog() + { + var closeButton = Page.GetByRole(AriaRole.Button, new() { Name = "Close dialog" }); + + await Expect(closeButton).ToBeVisibleAsync(); + await Expect(closeButton).ToBeEnabledAsync(); + await closeButton.ClickAsync(); + await Expect(closeButton).ToBeHiddenAsync(); + } + private async Task OpenRecycleBin() + { + var recycleButton = Page.Locator("text=Recycle Bin"); + + await Expect(recycleButton).ToBeVisibleAsync(); + await Expect(recycleButton).ToBeEnabledAsync(); + await recycleButton.ClickAsync(); + + var recycleHeader = Page.Locator("text=RESTORE SELECTED"); + + await Expect(recycleHeader).ToBeVisibleAsync(); + } + private async Task OpenConfigureSubMenu() + { + var recycleButton = Page.Locator("text=Configure"); + + await Expect(recycleButton).ToBeVisibleAsync(); + await Expect(recycleButton).ToBeEnabledAsync(); + await recycleButton.ClickAsync(); + + var recycleHeader = Page.Locator("text=Settings"); + + await Expect(recycleHeader).ToBeVisibleAsync(); + } + + private async Task OpenManageNotifications() + { + var recycleButton = Page.Locator("text=Notifications"); + + await Expect(recycleButton).ToBeVisibleAsync(); + await Expect(recycleButton).ToBeEnabledAsync(); + await recycleButton.ClickAsync(); + + await Expect(Page).ToHaveURLAsync(new Regex(".*notifications")); + + + var recycleHeader = Page.Locator("text=Manage Notifications"); + + await Expect(recycleHeader).ToBeVisibleAsync(); + } + private async Task OpenFields() + { + var button = Page.Locator("text=Fields"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + await Expect(Page).ToHaveURLAsync(new Regex(".*fields")); + + var header = Page.Locator("text=Field Type"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + } + private async Task OpenTemplates() + { + var button = Page.Locator("text=Templates"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + await Expect(Page).ToHaveURLAsync(new Regex(".*templates")); + + var header = Page.Locator("text=Inheritance Tree"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + //button = Page.Locator("text=ACCESS LEVELS"); + + //await Expect(button).ToBeVisibleAsync(); + //await Expect(button).ToBeEnabledAsync(); + //await button.ClickAsync(); + + //header = Page.Locator("text=Access levels are a template"); + + //await Expect(header).ToBeVisibleAsync(); + + + } + private async Task OpenPermissions() + { + var button = Page.Locator("text=Permissions"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + await Expect(Page).ToHaveURLAsync(new Regex(".*permissions")); + + var header = Page.Locator("text=Delegates are your approved application users"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + button = Page.Locator("text=ACCESS LEVELS"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=Access levels are a template"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + + button = Page.Locator("text=MAPPINGS"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=OU Privilege Mapper"); + + await Expect(header).ToBeVisibleAsync(); + await Task.Delay(500); + + + + + + } + private async Task OpenSettingsPages() + { + var button = Page.Locator("text=Settings"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + await Expect(Page).ToHaveURLAsync(new Regex(".*settings")); + var header = Page.Locator("text=Application Settings"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=AUTHENTICATION"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=Authentication Settings"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=ACTIVE DIRECTORY"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=Active Directory Settings"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=DATABASE"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=Database Status"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=EMAIL"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=Email Settings"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=UPDATE"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=Update Settings"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=USER ACTIVITY"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=User Activity"); + + await Expect(header).ToBeVisibleAsync(); + + + await Task.Delay(500); + + + button = Page.Locator("text=SYSTEM"); + + await Expect(button).ToBeVisibleAsync(); + await Expect(button).ToBeEnabledAsync(); + await button.ClickAsync(); + + header = Page.Locator("text=System Settings"); + + await Expect(header).ToBeVisibleAsync(); + + + + } + + + + private async Task OpenNotificationSettings() + { + var notificationSettingsButton = Page.Locator("text=Notification Settings"); + + await notificationSettingsButton.ClickAsync(); + + var notificationHeader = Page.Locator("text=Effective Notification Settings for"); + + await Expect(notificationHeader).ToBeInViewportAsync(); + await Expect(notificationHeader).ToBeVisibleAsync(); + await Expect(notificationHeader).ToBeEnabledAsync(); + } + private async Task OpenProfileSettings() + { + var profileSettingsButton = Page.Locator("text=Profile Settings"); + + await profileSettingsButton.ClickAsync(); + + var uploadProfileIconButton = Page.Locator("text=Upload Profile Icon"); + + await Expect(uploadProfileIconButton).ToBeInViewportAsync(); + await Expect(uploadProfileIconButton).ToBeVisibleAsync(); + await Expect(uploadProfileIconButton).ToBeEnabledAsync(); + } + + private async Task OpenUserMenu() + { + var userButton = Page.GetByRole(AriaRole.Img).Locator("text=D"); + + // Expect an attribute "to be strictly equal" to the value. + //await Expect(getStarted).ToHaveAttributeAsync("href", "/docs/intro"); + + // Click the get started link. + await userButton.ClickAsync(); + + var profileSettingsButton = Page.Locator("text=Profile Settings"); + + await Expect(profileSettingsButton).ToBeInViewportAsync(); + await Expect(profileSettingsButton).ToBeVisibleAsync(); + await Expect(profileSettingsButton).ToBeEnabledAsync(); + } + private async Task LogIn() { await Page.GotoAsync("https://blazam.azurewebsites.net/");