From 1db55d6085a61bd37f8a3b7f26bd9d5fcbd61ff0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:26:36 +0000 Subject: [PATCH 001/116] Bump Microsoft.AspNetCore.Identity.EntityFrameworkCore Bumps [Microsoft.AspNetCore.Identity.EntityFrameworkCore](https://github.com/dotnet/aspnetcore) from 6.0.30 to 6.0.31. - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](https://github.com/dotnet/aspnetcore/compare/v6.0.30...v6.0.31) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Identity.EntityFrameworkCore dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 199f3c06..8a7dc6b0 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -60,7 +60,7 @@ - + From d8a17666aae117075bb86f8c90d4dacb4da8a2e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:33:03 +0000 Subject: [PATCH 002/116] Bump Microsoft.EntityFrameworkCore, Microsoft.EntityFrameworkCore.Abstractions and Microsoft.EntityFrameworkCore.Analyzers Bumps [Microsoft.EntityFrameworkCore](https://github.com/dotnet/efcore), [Microsoft.EntityFrameworkCore.Abstractions](https://github.com/dotnet/efcore) and [Microsoft.EntityFrameworkCore.Analyzers](https://github.com/dotnet/efcore). These dependencies needed to be updated together. Updates `Microsoft.EntityFrameworkCore` from 7.0.19 to 7.0.20 - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.19...v7.0.20) Updates `Microsoft.EntityFrameworkCore.Abstractions` from 7.0.19 to 7.0.20 - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.19...v7.0.20) Updates `Microsoft.EntityFrameworkCore.Analyzers` from 7.0.19 to 7.0.20 - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.19...v7.0.20) --- updated-dependencies: - dependency-name: Microsoft.EntityFrameworkCore dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.EntityFrameworkCore.Abstractions dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.EntityFrameworkCore.Analyzers dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 4 ++-- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 4 ++-- BLAZAMCommon/BLAZAMCommon.csproj | 4 ++-- BLAZAMDatabase/BLAZAMDatabase.csproj | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 199f3c06..428f71b3 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -63,8 +63,8 @@ - - + + diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 821c8aa7..74144510 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 3a215e67..e51b500a 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -21,8 +21,8 @@ - - + + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index e8c174ae..973613b6 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -8,9 +8,9 @@ - - - + + + From a8536186121c7e67b2591a71b9c03f8239e4cfa0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 10:48:32 +0000 Subject: [PATCH 003/116] Bump Microsoft.EntityFrameworkCore.Abstractions from 7.0.19 to 7.0.20 Bumps [Microsoft.EntityFrameworkCore.Abstractions](https://github.com/dotnet/efcore) from 7.0.19 to 7.0.20. - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.19...v7.0.20) --- updated-dependencies: - dependency-name: Microsoft.EntityFrameworkCore.Abstractions dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 2 +- BLAZAMCommon/BLAZAMCommon.csproj | 2 +- BLAZAMDatabase/BLAZAMDatabase.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 199f3c06..b9c965ad 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -64,7 +64,7 @@ - + diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 821c8aa7..83111507 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 3a215e67..d4a5a2a6 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -22,7 +22,7 @@ - + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index e8c174ae..1259ebf6 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -9,7 +9,7 @@ - + diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index a15f1148..91b7fbbb 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -25,7 +25,7 @@ - + From 5f6b2728149c22331542667d7b2b6cf2c3881ba0 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 9 Jun 2024 22:46:04 -0400 Subject: [PATCH 004/116] Handle missing groups --- BLAZAM/BLAZAM.csproj | 2 +- .../Permissions/PermissionMapEditor.razor | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 2402f8b7..32e51024 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.09.1748 + 2024.06.10.0243 false BLAZAM False diff --git a/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor b/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor index c7d11eee..aab96b96 100644 --- a/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor @@ -93,9 +93,7 @@ await base.OnInitializedAsync(); await RefreshData(); - LoadingData = false; - await InvokeAsync(StateHasChanged); } async Task RefreshData() @@ -130,13 +128,19 @@ selectedAccessLevelNames = concatenatd; concatenatd = ""; - Map.PermissionDelegates.Select( - a => Directory.FindEntryBySID(a.DelegateSid).CanonicalName) - .ToList().ForEach(s => - { - concatenatd += s + ", "; - - }); + var sids = Map.PermissionDelegates.Select(a => a.DelegateSid).ToList(); + foreach(var sid in sids) + { + try + { + concatenatd += Directory.FindEntryBySID(sid) + ", "; + } + catch (Exception ex) + { + concatenatd += sid.ToSidString()+", "; + } + } + if (concatenatd != "") concatenatd = concatenatd.Substring(0, concatenatd.Length - 2); @@ -146,6 +150,7 @@ } LoadingData = false; + await InvokeAsync(StateHasChanged); } async Task DeleteMapping() From b6260dc1f03bd4b2d94acf0a224a6ece1d3ad043 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 10 Jun 2024 19:14:50 -0400 Subject: [PATCH 005/116] Sort Children #386 --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs | 1 + BLAZAMGui/Navs/Buttons/NavBrowseButton.razor | 5 +++-- BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 32e51024..3fdf9d69 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.10.0243 + 2024.06.10.2307 false BLAZAM False diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index b25e61fe..96b89aa4 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -608,6 +608,7 @@ public virtual IEnumerable Children thisObject = null; } + directoryEntries.OrderBy(x=>x.CanonicalName).OrderBy(x=>x.ObjectType); CachedChildren = directoryEntries; } return CachedChildren; diff --git a/BLAZAMGui/Navs/Buttons/NavBrowseButton.razor b/BLAZAMGui/Navs/Buttons/NavBrowseButton.razor index b390a7ca..a6ce0e4a 100644 --- a/BLAZAMGui/Navs/Buttons/NavBrowseButton.razor +++ b/BLAZAMGui/Navs/Buttons/NavBrowseButton.razor @@ -8,13 +8,14 @@ Disabled=@(Monitor.DirectoryConnectionStatus != ServiceConnectionState.Up) Title="@AppLocalization["Browse"]" Icon="@Icons.Material.Filled.ViewList"> - {if(entry is IADOrganizationalUnit ou) return (ou.CanReadUsersInSubOus || ou.CanReadNonOUs); return false;}) SelectedEntryChanged="@((entry)=>{SelectedEntryChanged.InvokeAsync(entry);})" /> + {if(entry is IADOrganizationalUnit ou) return (ou.CanReadUsersInSubOus || ou.CanReadNonOUs); return false;}) + SelectedEntryChanged="@((entry)=>{SelectedEntryChanged.InvokeAsync(entry);})" /> @code { [Parameter] public EventCallback BrowseExpandedChanged { get; set; } [Parameter] - public EventCallback SelectedEntryChanged{ get; set; } + public EventCallback SelectedEntryChanged { get; set; } } diff --git a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs index 8a655fed..680421c6 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs @@ -38,8 +38,8 @@ public partial class ADTreeView : OUTreeViewBase { items = items.Where(i => i.ObjectType == ActiveDirectoryObjectType.OU); } - var hashst = items.ToHashSet(); - return hashst; + var hashset = items.ToHashSet(); + return hashset; } return null; } From c74f017ca8540f4a708632c3c45c5a41b499bbf7 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 14 Jun 2024 17:48:11 -0400 Subject: [PATCH 006/116] Use BetaDev tag --- .github/workflows/build-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index b5a7f727..d731cc85 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -74,8 +74,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} with: - tag_name: Dev - name: 'Dev' + tag_name: BetaDev + name: 'BetaDev' prerelease: true body: This release is highly unstable. Expect bugs and crashes on this branch. Developers Only! files: | From ed27f66229fce9d8ccba15fea6d9599764ae2c7e Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 14 Jun 2024 17:56:57 -0400 Subject: [PATCH 007/116] Back to dev --- .github/workflows/build-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index d731cc85..b5a7f727 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -74,8 +74,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} with: - tag_name: BetaDev - name: 'BetaDev' + tag_name: Dev + name: 'Dev' prerelease: true body: This release is highly unstable. Expect bugs and crashes on this branch. Developers Only! files: | From e3b58c490712af86f7e616d5aae889bc7104dc1b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 20 Jun 2024 19:38:26 -0400 Subject: [PATCH 008/116] Fix for Up To Date message not showing --- BLAZAM/BLAZAM.csproj | 2 +- .../Settings/ManualApplicationUpdater.razor | 2 +- BLAZAMUpdate/Services/UpdateService.cs | 44 +++++++++---------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 3fdf9d69..3ce8aea3 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.10.2307 + 2024.06.20.2322 false BLAZAM False diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index b602ce3a..78adbebc 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -106,7 +106,7 @@ } - @if (LatestAvailableVersion != null && !LatestAvailableVersion.Version.OlderThan(ApplicationInfo.RunningVersion)) + @if (LatestAvailableVersion != null && !LatestAvailableVersion.Version.NewerThan(ApplicationInfo.RunningVersion)) { diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index eb426c1b..8de9d3c0 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -128,28 +128,28 @@ private async Task GetReleases() LatestUpdate = latestBranchUpdate; } - if (Debugger.IsAttached) - { - ApplicationUpdate? testUpdate = EncapsulateUpdate(latestRelease, SelectedBranch); - - testUpdate.PreRequisiteChecks.Add(new(() => { - if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) - { - testUpdate.PrequisiteMessage = "ASP NET Core 8 Runtime is missing."; - return false; - - } - if (ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCoreHosting()) - { - testUpdate.PrequisiteMessage = "ASP NET Core 8 Web Hosting Bundle is missing."; - return false; - - } - return true; - })); - testUpdate.Version = new ApplicationVersion("1.0.0.2024.07.01.0000"); - LatestUpdate = testUpdate; - } + //if (Debugger.IsAttached) + //{ + // ApplicationUpdate? testUpdate = EncapsulateUpdate(latestRelease, SelectedBranch); + + // testUpdate.PreRequisiteChecks.Add(new(() => { + // if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) + // { + // testUpdate.PrequisiteMessage = "ASP NET Core 8 Runtime is missing."; + // return false; + + // } + // if (ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCoreHosting()) + // { + // testUpdate.PrequisiteMessage = "ASP NET Core 8 Web Hosting Bundle is missing."; + // return false; + + // } + // return true; + // })); + // testUpdate.Version = new ApplicationVersion("1.0.0.2024.07.01.0000"); + // LatestUpdate = testUpdate; + //} } /// From 5fa200d8ad242bbfefd5d236444896fc0df21733 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 20 Jun 2024 21:48:25 -0400 Subject: [PATCH 009/116] Get BitLocker Recoveries by computer --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Computers/ViewComputer.razor | 14 +++++ .../ActiveDirectoryContext.cs | 18 ++---- .../Adapters/ADBitLockerRecovery.cs | 35 +++++++++++ BLAZAMActiveDirectory/Adapters/ADComputer.cs | 5 ++ .../Adapters/DirectoryEntryAdapter.cs | 21 +++++-- .../Helpers/ActiveDirectoryHelpers.cs | 8 +++ .../Interfaces/IADBitLockerRecovery.cs | 9 +++ .../Interfaces/IADBitLockerSearcher.cs | 16 +++++ .../Interfaces/IADComputer.cs | 2 + .../Interfaces/IActiveDirectory.cs | 4 ++ .../Searchers/ADBitLockerSearcher.cs | 61 +++++++++++++++++++ BLAZAMActiveDirectory/Searchers/ADSearch.cs | 6 +- .../Searchers/ADSearchFields.cs | 1 + .../Data/ActiveDirectoryObjectType.cs | 4 +- 15 files changed, 185 insertions(+), 21 deletions(-) create mode 100644 BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs create mode 100644 BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs create mode 100644 BLAZAMActiveDirectory/Interfaces/IADBitLockerSearcher.cs create mode 100644 BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 3fdf9d69..7729bdb3 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.10.2307 + 2024.06.21.0147 false BLAZAM False diff --git a/BLAZAM/Pages/Computers/ViewComputer.razor b/BLAZAM/Pages/Computers/ViewComputer.razor index f79c1ac0..ec5f17b2 100644 --- a/BLAZAM/Pages/Computers/ViewComputer.razor +++ b/BLAZAM/Pages/Computers/ViewComputer.razor @@ -114,6 +114,18 @@ +
+ + + + + + + + + + +
@@ -231,6 +243,7 @@ @code { IADComputer? Computer => DirectoryEntry as IADComputer; + List _recoveries = new(); protected override async Task OnInitializedAsync() { Computer?.MonitorOnlineStatus(); @@ -243,6 +256,7 @@ RefreshEntryComponents(); }); } + _recoveries = await Computer.GetBitLockerRecoveryAsync(); await AuditLogger.Searched(Computer); LoadingData = false; diff --git a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs index 421dd220..d1a22f51 100644 --- a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs +++ b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs @@ -138,28 +138,19 @@ public List GetDeletedObjects() } - /// - /// public IADUserSearcher Users { get; } - /// - - /// public IADGroupSearcher Groups { get; } - /// - - /// public IADOUSearcher OUs { get; } - ///
- public IADPrinterSearcher Printers { get; } - /// + public IADPrinterSearcher Printers { get; } - /// public IADComputerSearcher Computers { get; } + public IADBitLockerSearcher BitLocker { get; } + public IDatabaseContext? Context { get; private set; } /// @@ -238,6 +229,7 @@ INotificationPublisher notificationPublisher Groups = new ADGroupSearcher(this); OUs = new ADOUSearcher(this); Printers = new ADPrinterSearcher(this); + BitLocker = new ADBitLockerSearcher(this); Computers = new ADComputerSearcher(this, _wmiFactory); } /// @@ -265,7 +257,7 @@ public ActiveDirectoryContext(ActiveDirectoryContext activeDirectoryContextSeed) Groups = new ADGroupSearcher(this); OUs = new ADOUSearcher(this); Printers = new ADPrinterSearcher(this); - + BitLocker = new ADBitLockerSearcher(this); Computers = new ADComputerSearcher(this, activeDirectoryContextSeed._wmiFactory); } private DirectoryContext DirectoryContext => new DirectoryContext( diff --git a/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs b/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs new file mode 100644 index 00000000..7ff74219 --- /dev/null +++ b/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs @@ -0,0 +1,35 @@ + +using System.Net.NetworkInformation; +using System.Net; +using BLAZAM.Logger; +using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.Database.Models; +using System.Net.Sockets; + +namespace BLAZAM.ActiveDirectory.Adapters +{ + public class ADBitLockerRecovery : DirectoryEntryAdapter, IADBitLockerRecovery + { + + + public Guid? RecoveryId + { + get + { + var rawData = GetProperty("msFVE-RecoveryGuid"); + var id = new Guid(rawData); + return id; + } + + + } + + public string? RecoveryPassword + { + get + { + return GetStringProperty("msFVE-RecoveryPassword"); + } + } + } +} diff --git a/BLAZAMActiveDirectory/Adapters/ADComputer.cs b/BLAZAMActiveDirectory/Adapters/ADComputer.cs index a02ede4e..2d30e41e 100644 --- a/BLAZAMActiveDirectory/Adapters/ADComputer.cs +++ b/BLAZAMActiveDirectory/Adapters/ADComputer.cs @@ -27,6 +27,11 @@ public ADComputer() } + public async Task?> GetBitLockerRecoveryAsync() { + var recovery= await Directory.BitLocker.FindByComputerAsync(this); + return recovery; + } + public string? OperatingSystem { get diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index 96b89aa4..929cca48 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -192,6 +192,11 @@ public ActiveDirectoryObjectType ObjectType { return ActiveDirectoryObjectType.Printer; } + if (Classes.Contains("ms-FVE-RecoveryInformation")) + { + return ActiveDirectoryObjectType.Printer; + + } } return ActiveDirectoryObjectType.OU; @@ -577,26 +582,32 @@ public virtual IEnumerable Children if (child.Properties["objectClass"].Contains("top")) { - if (child.Properties["objectClass"].Contains("computer")) + var objectClass = child.Properties["objectClass"]; + if (objectClass.Contains("computer")) { thisObject = new ADComputer(); } - else if (child.Properties["objectClass"].Contains("user")) + else if (objectClass.Contains("user")) { thisObject = new ADUser(); } - else if (child.Properties["objectClass"].Contains("organizationalUnit")) + else if (objectClass.Contains("organizationalUnit")) { thisObject = new ADOrganizationalUnit(); } - else if (child.Properties["objectClass"].Contains("group")) + else if (objectClass.Contains("group")) { thisObject = new ADGroup(); } - else if (child.Properties["objectClass"].Contains("printQueue")) + 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); diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index f5ce5226..59036e56 100644 --- a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs +++ b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs @@ -164,6 +164,10 @@ public static List Encapsulate(this SearchResultCollecti { thisObject = new ADPrinter(); } + else if (sr.Properties["objectClass"].Contains("msFVE-RecoveryInformation")) + { + thisObject = new ADBitLockerRecovery(); + } if (thisObject != null) { thisObject.Parse(directory: ActiveDirectoryContext.Instance, searchResult: sr); @@ -220,6 +224,10 @@ public static List Encapsulate(this DirectoryEntries r) { thisObject = new ADPrinter(); } + else if (sr.Properties["objectClass"].Contains("msFVE-RecoveryInformation")) + { + thisObject = new ADBitLockerRecovery(); + } if (thisObject != null) { thisObject.Parse(directory: ActiveDirectoryContext.Instance, directoryEntry: sr); diff --git a/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs b/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs new file mode 100644 index 00000000..00704890 --- /dev/null +++ b/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs @@ -0,0 +1,9 @@ + +namespace BLAZAM.ActiveDirectory.Interfaces +{ + public interface IADBitLockerRecovery + { + Guid? RecoveryId { get; } + string? RecoveryPassword { get; } + } +} \ No newline at end of file diff --git a/BLAZAMActiveDirectory/Interfaces/IADBitLockerSearcher.cs b/BLAZAMActiveDirectory/Interfaces/IADBitLockerSearcher.cs new file mode 100644 index 00000000..dc9b1688 --- /dev/null +++ b/BLAZAMActiveDirectory/Interfaces/IADBitLockerSearcher.cs @@ -0,0 +1,16 @@ +using BLAZAM.Common.Data.Services; + +namespace BLAZAM.ActiveDirectory.Interfaces +{ + /// + /// A searcher class for BitLocker objects in an + /// + public interface IADBitLockerSearcher + { + + List FindByRecoveryId(string searchTerm); + Task> FindByRecoveryIdAsync(string searchTerm); + List FindByComputer(IADComputer computer); + Task> FindByComputerAsync(IADComputer computer); + } +} \ No newline at end of file diff --git a/BLAZAMActiveDirectory/Interfaces/IADComputer.cs b/BLAZAMActiveDirectory/Interfaces/IADComputer.cs index 50845d97..6797ae73 100644 --- a/BLAZAMActiveDirectory/Interfaces/IADComputer.cs +++ b/BLAZAMActiveDirectory/Interfaces/IADComputer.cs @@ -49,6 +49,8 @@ public interface IADComputer : IAccountDirectoryAdapter /// List SharedPrinters { get; } + Task?> GetBitLockerRecoveryAsync(); + /// /// Gets the drive details from this computer /// diff --git a/BLAZAMActiveDirectory/Interfaces/IActiveDirectory.cs b/BLAZAMActiveDirectory/Interfaces/IActiveDirectory.cs index ce151b15..0cebb76e 100644 --- a/BLAZAMActiveDirectory/Interfaces/IActiveDirectory.cs +++ b/BLAZAMActiveDirectory/Interfaces/IActiveDirectory.cs @@ -62,6 +62,10 @@ public interface IActiveDirectoryContext:IDisposable /// Provides Computer search functions /// IADComputerSearcher Computers { get; } + /// + /// Provides Computer search functions + /// + IADBitLockerSearcher BitLocker { get; } /// /// Called when the connection state of the Active Directory server has diff --git a/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs new file mode 100644 index 00000000..90f3a72d --- /dev/null +++ b/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs @@ -0,0 +1,61 @@ +using BLAZAM.ActiveDirectory; +using BLAZAM.ActiveDirectory.Adapters; +using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.Common.Data; +using BLAZAM.Common.Data.Services; + +namespace BLAZAM.ActiveDirectory.Searchers +{ + public class ADBitLockerSearcher : ADSearcher, IADBitLockerSearcher + { + + public ADBitLockerSearcher(IActiveDirectoryContext directory) : base(directory) + { + } + + + public List FindByRecoveryId(string searchTerm) + { + var searchFields = new ADSearchFields(); + searchFields.BitLockerRecoveryId = searchTerm; + return new ADSearch() + { + ObjectTypeFilter = ActiveDirectoryObjectType.BitLocker, + EnabledOnly = false, + Fields = searchFields + + }.Search(); + } + + public async Task> FindByRecoveryIdAsync(string searchTerm) + { + return await Task.Run(() => + { + return FindByRecoveryId(searchTerm); + }); + } + + public List FindByComputer(IADComputer computer) + { + var children = computer.Children; + return children.Where(c => c is IADBitLockerRecovery).Cast().ToList(); + var searchFields = new ADSearchFields(); + searchFields.CN = "*"+computer.DN; + return new ADSearch() + { + ObjectTypeFilter = ActiveDirectoryObjectType.BitLocker, + EnabledOnly = false, + Fields = searchFields + + }.Search(); + } + + public async Task> FindByComputerAsync(IADComputer computer) + { + return await Task.Run(() => + { + return FindByComputer(computer); + }); + } + } +} diff --git a/BLAZAMActiveDirectory/Searchers/ADSearch.cs b/BLAZAMActiveDirectory/Searchers/ADSearch.cs index 469136d1..1f502ffb 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearch.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearch.cs @@ -178,6 +178,9 @@ public async Task> SearchAsync() if (GeneralSearchTerm != null) FilterQuery = "(|(samaccountname=*" + GeneralSearchTerm + "*)(anr=*" + GeneralSearchTerm + "*)(distinguishedName=*" + GeneralSearchTerm + "*))"; + break; + case ActiveDirectoryObjectType.BitLocker: + searcher.Filter = "(&(objectCategory=*ms-FVE-RecoveryInformation*))"; break; case ActiveDirectoryObjectType.OU: searcher.VirtualListView = null; @@ -214,7 +217,8 @@ public async Task> SearchAsync() FilterQuery += $"(objectSid={Fields.SID})"; if (Fields.NestedMemberOf != null) FilterQuery += $"(memberOf:1.2.840.113556.1.4.1941:={Fields.NestedMemberOf.DN})"; - + if (Fields.BitLockerRecoveryId != null) + FilterQuery += $"(name=*{Fields.BitLockerRecoveryId}*)"; diff --git a/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs b/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs index dd6274e4..0183e10d 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs @@ -28,5 +28,6 @@ public class ADSearchFields public string? MemberOf { get; set; } public ADGroup? NestedMemberOf { get; internal set; } + public string BitLockerRecoveryId { get; internal set; } } } \ No newline at end of file diff --git a/BLAZAMCommon/Data/ActiveDirectoryObjectType.cs b/BLAZAMCommon/Data/ActiveDirectoryObjectType.cs index 38b8c1e9..86e1869d 100644 --- a/BLAZAMCommon/Data/ActiveDirectoryObjectType.cs +++ b/BLAZAMCommon/Data/ActiveDirectoryObjectType.cs @@ -1,7 +1,9 @@ namespace BLAZAM.Common.Data { - public enum ActiveDirectoryObjectType { All, User, Group, Computer, OU, Printer } + public enum ActiveDirectoryObjectType { All, User, Group, Computer, OU, Printer, + BitLocker + } } From 8681697584db2195757863b91729ad2b83654ea5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 21 Jun 2024 20:39:07 -0400 Subject: [PATCH 010/116] Search for bitlocker recovery almost complete --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Browse/ViewDirectoryEntry.razor | 3 ++ BLAZAM/Pages/Computers/ViewBitLocker.razor | 39 +++++++++++++++++++ BLAZAM/Pages/Computers/ViewComputer.razor | 39 +++++++++++-------- .../Adapters/ADBitLockerRecovery.cs | 3 ++ .../Adapters/DirectoryEntryAdapter.cs | 6 +-- .../Interfaces/IADBitLockerRecovery.cs | 2 +- BLAZAMActiveDirectory/Searchers/ADSearch.cs | 6 ++- BLAZAMGui/UI/Search/SearchControls.razor | 7 ++++ 9 files changed, 84 insertions(+), 23 deletions(-) create mode 100644 BLAZAM/Pages/Computers/ViewBitLocker.razor diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 7729bdb3..827990c4 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.21.0147 + 2024.06.21.2335 false BLAZAM False diff --git a/BLAZAM/Pages/Browse/ViewDirectoryEntry.razor b/BLAZAM/Pages/Browse/ViewDirectoryEntry.razor index 34919d0c..b88f4f0a 100644 --- a/BLAZAM/Pages/Browse/ViewDirectoryEntry.razor +++ b/BLAZAM/Pages/Browse/ViewDirectoryEntry.razor @@ -17,6 +17,9 @@ case ActiveDirectoryObjectType.Printer: break; + case ActiveDirectoryObjectType.BitLocker: + + break; } diff --git a/BLAZAM/Pages/Computers/ViewBitLocker.razor b/BLAZAM/Pages/Computers/ViewBitLocker.razor new file mode 100644 index 00000000..0be380f2 --- /dev/null +++ b/BLAZAM/Pages/Computers/ViewBitLocker.razor @@ -0,0 +1,39 @@ +@using BLAZAM.Gui.UI.Computers +@inherits DirectoryEntryViewBase +@{ + string _fieldMudStackClasses = "flex-wrap gap-10"; +} + + + + + + + + + + + + + + + +@code { + IADBitLockerRecovery? BitLocker=> DirectoryEntry as IADBitLockerRecovery; + List _recoveries = new(); + protected override async Task OnInitializedAsync() + { + + await base.OnInitializedAsync(); + await InvokeAsync(StateHasChanged); + + + var computer = BitLocker.GetParent(); + + LoadingData = false; + await RefreshEntryComponents(); + } + + + +} diff --git a/BLAZAM/Pages/Computers/ViewComputer.razor b/BLAZAM/Pages/Computers/ViewComputer.razor index ec5f17b2..39d33e8c 100644 --- a/BLAZAM/Pages/Computers/ViewComputer.razor +++ b/BLAZAM/Pages/Computers/ViewComputer.razor @@ -4,7 +4,7 @@ string _fieldMudStackClasses = "flex-wrap gap-10"; } @Computer?.CanonicalName - @if (Computer != null) +@if (Computer != null) { @@ -22,7 +22,7 @@ OnResetPassword="@(()=>{ChangePasswordModal?.Show();})" OnToggleEditMode="ToggleEditMode" OnUnlock="@Unlock" - OnShowHistory="@(()=>{ChangeHistoryModal?.Show();})"/> + OnShowHistory="@(()=>{ChangeHistoryModal?.Show();})" /> @@ -113,19 +113,21 @@ - -
- - - - - - - - - - -
+ @if (CurrentUser.State.IsSuperAdmin) + { +
+ + + + + + + + + + +
+ } @@ -167,7 +169,10 @@ @if (Computer.IsOnline == true) { - + if (CurrentUser.State.IsSuperAdmin) + { + + } } else { @@ -266,7 +271,7 @@ async Task Unlock() { - if (Computer!=null && await MessageService.Confirm("Are you sure you want to unlock " + Computer?.CanonicalName + "?", "Unlock Computer")) + if (Computer != null && await MessageService.Confirm("Are you sure you want to unlock " + Computer?.CanonicalName + "?", "Unlock Computer")) { Computer.LockedOut = false; } diff --git a/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs b/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs index 7ff74219..23fa4927 100644 --- a/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs +++ b/BLAZAMActiveDirectory/Adapters/ADBitLockerRecovery.cs @@ -5,6 +5,7 @@ using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Database.Models; using System.Net.Sockets; +using BLAZAM.Common.Data; namespace BLAZAM.ActiveDirectory.Adapters { @@ -31,5 +32,7 @@ public string? RecoveryPassword return GetStringProperty("msFVE-RecoveryPassword"); } } + + // public override ActiveDirectoryObjectType ObjectType => ActiveDirectoryObjectType.BitLocker; } } diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index 929cca48..9e58da8e 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -166,7 +166,7 @@ public void EnsureDirectoryEntry() } } - public ActiveDirectoryObjectType ObjectType + public virtual ActiveDirectoryObjectType ObjectType { get { @@ -192,9 +192,9 @@ public ActiveDirectoryObjectType ObjectType { return ActiveDirectoryObjectType.Printer; } - if (Classes.Contains("ms-FVE-RecoveryInformation")) + if (Classes.Contains("msFVE-RecoveryInformation")) { - return ActiveDirectoryObjectType.Printer; + return ActiveDirectoryObjectType.BitLocker; } diff --git a/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs b/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs index 00704890..092dc043 100644 --- a/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs +++ b/BLAZAMActiveDirectory/Interfaces/IADBitLockerRecovery.cs @@ -1,7 +1,7 @@  namespace BLAZAM.ActiveDirectory.Interfaces { - public interface IADBitLockerRecovery + public interface IADBitLockerRecovery:IDirectoryEntryAdapter { Guid? RecoveryId { get; } string? RecoveryPassword { get; } diff --git a/BLAZAMActiveDirectory/Searchers/ADSearch.cs b/BLAZAMActiveDirectory/Searchers/ADSearch.cs index 1f502ffb..4d444165 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearch.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearch.cs @@ -180,7 +180,11 @@ public async Task> SearchAsync() break; case ActiveDirectoryObjectType.BitLocker: - searcher.Filter = "(&(objectCategory=*ms-FVE-RecoveryInformation*))"; + searcher.Filter = "(&(objectCategory=*msFVE-RecoveryInformation*))"; + if (GeneralSearchTerm != null) + + searcher.Filter = $"(name=*{GeneralSearchTerm}*)"; + break; case ActiveDirectoryObjectType.OU: searcher.VirtualListView = null; diff --git a/BLAZAMGui/UI/Search/SearchControls.razor b/BLAZAMGui/UI/Search/SearchControls.razor index 1dd07bfb..ca18bd0c 100644 --- a/BLAZAMGui/UI/Search/SearchControls.razor +++ b/BLAZAMGui/UI/Search/SearchControls.razor @@ -29,6 +29,10 @@ { SearchService.SeachObjectType=ActiveDirectoryObjectType.Printer; })>@AppLocalization["Printer"] + + { SearchService.SeachObjectType=ActiveDirectoryObjectType.BitLocker; })>@AppLocalization["BitLocker"] + + @@ -73,6 +77,9 @@ case ActiveDirectoryObjectType.Printer: adornmentIcon = Icons.Material.Filled.Print; break; + case ActiveDirectoryObjectType.BitLocker: + adornmentIcon = Icons.Material.Filled.EnhancedEncryption; + break; } } From 029b86520c67acbc625342665f3e098de737faf4 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 25 Jun 2024 08:20:05 -0400 Subject: [PATCH 011/116] Fix for IsMemberOf nested search --- BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs | 11 ++++++++++- BLAZAMActiveDirectory/Searchers/ADSearchFields.cs | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs index 53efd152..d102d24d 100644 --- a/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs @@ -193,9 +193,18 @@ public List GetGroupMembers(IADGroup group) } - public bool IsAMemberOf(IADGroup? group, IGroupableDirectoryAdapter? userOrGroup, bool v, bool ignoreDisabledUsers = true) + public bool IsAMemberOf(IADGroup group, IGroupableDirectoryAdapter? userOrGroup, bool v, bool ignoreDisabledUsers = true) { + return new ADSearch() + { + Fields = new() + { + DN = userOrGroup.DN, + NestedMemberOf = group + }, + ExactMatch = false + }.Search().Count>0; string UserSearchFieldsQuery = "(&(memberOf:1.2.840.113556.1.4.1941:=" + group.DN + ")(distinguishedName=" + userOrGroup.DN + "))"; return SearchObjects(UserSearchFieldsQuery, userOrGroup.ObjectType, 50, ignoreDisabledUsers)?.Count > 0; diff --git a/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs b/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs index 0183e10d..98b47430 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearchFields.cs @@ -1,4 +1,4 @@ -using BLAZAM.ActiveDirectory.Adapters; +using BLAZAM.ActiveDirectory.Interfaces; namespace BLAZAM.ActiveDirectory.Searchers { @@ -27,7 +27,7 @@ public class ADSearchFields public string? CN { get; set; } public string? MemberOf { get; set; } - public ADGroup? NestedMemberOf { get; internal set; } + public IADGroup? NestedMemberOf { get; internal set; } public string BitLockerRecoveryId { get; internal set; } } } \ No newline at end of file From 64d4cf2cc64488f9991662861806502ff3c14188 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 25 Jun 2024 08:21:06 -0400 Subject: [PATCH 012/116] Changes for getting parent of BitLocker objects --- BLAZAM/Pages/Computers/BitLockerViewer.razor | 40 +++++++ BLAZAM/Pages/Computers/ViewBitLocker.razor | 5 +- BLAZAM/Pages/Computers/ViewComputer.razor | 17 +-- BLAZAM/Pages/OU/ViewOU.razor | 2 +- BLAZAMActiveDirectory/Adapters/ADComputer.cs | 46 ++++++-- .../Adapters/DirectoryEntryAdapter.cs | 5 +- BLAZAMActiveDirectory/GlobalSuppressions.cs | 1 + .../Helpers/ActiveDirectoryHelpers.cs | 103 +++++++++++------- .../Interfaces/IADComputer.cs | 1 + .../Interfaces/IDirectoryEntryAdapter.cs | 2 +- BLAZAMGui/UI/OU/MoveToOUModalContent.razor | 2 +- 11 files changed, 148 insertions(+), 76 deletions(-) create mode 100644 BLAZAM/Pages/Computers/BitLockerViewer.razor diff --git a/BLAZAM/Pages/Computers/BitLockerViewer.razor b/BLAZAM/Pages/Computers/BitLockerViewer.razor new file mode 100644 index 00000000..337e45cd --- /dev/null +++ b/BLAZAM/Pages/Computers/BitLockerViewer.razor @@ -0,0 +1,40 @@ +@inherits AppComponentBase +
+ + + + + + + + + + +
+ +@code{ + [Parameter] + public string Class{ get; set; } + + private IADComputer _computer; + [Parameter] + public IADComputer Computer{ get=>_computer; set + { + if (_computer == value) return; + _computer = value; + GetRecoveries(); + + } } + + List _recoveries = new(); + + protected override async Task OnInitializedAsync(){ + await base.OnInitializedAsync(); + + + } + private async void GetRecoveries(){ + _recoveries = await Computer.GetBitLockerRecoveryAsync(); + await InvokeAsync(StateHasChanged); + } +} \ No newline at end of file diff --git a/BLAZAM/Pages/Computers/ViewBitLocker.razor b/BLAZAM/Pages/Computers/ViewBitLocker.razor index 0be380f2..7017a736 100644 --- a/BLAZAM/Pages/Computers/ViewBitLocker.razor +++ b/BLAZAM/Pages/Computers/ViewBitLocker.razor @@ -5,7 +5,7 @@ } - + @@ -21,6 +21,7 @@ @code { IADBitLockerRecovery? BitLocker=> DirectoryEntry as IADBitLockerRecovery; List _recoveries = new(); + IADComputer _computer; protected override async Task OnInitializedAsync() { @@ -28,7 +29,7 @@ await InvokeAsync(StateHasChanged); - var computer = BitLocker.GetParent(); + _computer = (IADComputer)BitLocker.GetParent(); LoadingData = false; await RefreshEntryComponents(); diff --git a/BLAZAM/Pages/Computers/ViewComputer.razor b/BLAZAM/Pages/Computers/ViewComputer.razor index 39d33e8c..66edb550 100644 --- a/BLAZAM/Pages/Computers/ViewComputer.razor +++ b/BLAZAM/Pages/Computers/ViewComputer.razor @@ -113,20 +113,9 @@
- @if (CurrentUser.State.IsSuperAdmin) + @if (Computer.CanReadBitLocker) { -
- - - - - - - - - - -
+ } @@ -248,7 +237,6 @@ @code { IADComputer? Computer => DirectoryEntry as IADComputer; - List _recoveries = new(); protected override async Task OnInitializedAsync() { Computer?.MonitorOnlineStatus(); @@ -261,7 +249,6 @@ RefreshEntryComponents(); }); } - _recoveries = await Computer.GetBitLockerRecoveryAsync(); await AuditLogger.Searched(Computer); LoadingData = false; diff --git a/BLAZAM/Pages/OU/ViewOU.razor b/BLAZAM/Pages/OU/ViewOU.razor index 7cad7cfa..523bc970 100644 --- a/BLAZAM/Pages/OU/ViewOU.razor +++ b/BLAZAM/Pages/OU/ViewOU.razor @@ -78,7 +78,7 @@ await AuditLogger.Searched(OU); if (OU != null) { - parentOU = OU.GetParent(); + parentOU = (IADOrganizationalUnit)OU.GetParent(); } LoadingData = false; await RefreshEntryComponents(); diff --git a/BLAZAMActiveDirectory/Adapters/ADComputer.cs b/BLAZAMActiveDirectory/Adapters/ADComputer.cs index 2d30e41e..075b6134 100644 --- a/BLAZAMActiveDirectory/Adapters/ADComputer.cs +++ b/BLAZAMActiveDirectory/Adapters/ADComputer.cs @@ -5,6 +5,8 @@ using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Database.Models; using System.Net.Sockets; +using BLAZAM.Database.Models.Permissions; +using BLAZAM.Common.Data; namespace BLAZAM.ActiveDirectory.Adapters { @@ -17,7 +19,7 @@ private WmiConnection? wmiConnection get { if (CanonicalName == null) return null; - return new WmiConnection(Directory.Computers.WmiFactory.CreateWmiConnection(CanonicalName),this); + return new WmiConnection(Directory.Computers.WmiFactory.CreateWmiConnection(CanonicalName), this); } } private CancellationTokenSource cts; @@ -27,8 +29,9 @@ public ADComputer() } - public async Task?> GetBitLockerRecoveryAsync() { - var recovery= await Directory.BitLocker.FindByComputerAsync(this); + public async Task?> GetBitLockerRecoveryAsync() + { + var recovery = await Directory.BitLocker.FindByComputerAsync(this); return recovery; } @@ -61,10 +64,10 @@ public virtual bool? IsOnline OnOnlineChanged?.Invoke((bool)value); } } - public List Services => wmiConnection?.Services?? new (); + public List Services => wmiConnection?.Services ?? new(); public ComputerMemory Memory => wmiConnection?.Memory ?? new(); public int Processor => wmiConnection?.Processor ?? 0; - public double MemoryUsedPercent => wmiConnection?.Memory.PercentUsed ?? 0 ; + public double MemoryUsedPercent => wmiConnection?.Memory.PercentUsed ?? 0; public List GetDrives() { if (wmiConnection == null) return new(); @@ -97,11 +100,32 @@ public List SharedPrinters { get { - return wmiConnection?.SharePrinters ?? new (); + return wmiConnection?.SharePrinters ?? new(); } } + public bool CanReadBitLocker + { + get + { + return HasPermission(p => p.Where(pm => + pm.AccessLevels.Any(al => + al.ObjectMap.Any(om => + om.ObjectType == ActiveDirectoryObjectType.BitLocker && + om.ObjectAccessLevel.Level > ObjectAccessLevels.Deny.Level + ))), + p => p.Where(pm => + pm.AccessLevels.Any(al => + al.ObjectMap.Any(om => + om.ObjectType == ActiveDirectoryObjectType.BitLocker && + om.ObjectAccessLevel.Level == ObjectAccessLevels.Deny.Level + ))) + ); + } + + } + /// /// Rename this computer @@ -118,7 +142,7 @@ public List SharedPrinters } catch (Exception ex) { - Loggers.ActiveDirectryLogger.Error(ex.Message + " {@Error}",ex); + Loggers.ActiveDirectryLogger.Error(ex.Message + " {@Error}", ex); } return false; @@ -160,7 +184,7 @@ private void Ping(int timeout = 5000) { try { - if (IPHostEntry == null && !cts.IsCancellationRequested && CanonicalName!=null) + if (IPHostEntry == null && !cts.IsCancellationRequested && CanonicalName != null) { IPHostEntry = Dns.GetHostEntry(CanonicalName); Task.Delay(60000).ContinueWith((s) => @@ -175,7 +199,7 @@ private void Ping(int timeout = 5000) { try { - if (cts.IsCancellationRequested || CanonicalName ==null) return; + if (cts.IsCancellationRequested || CanonicalName == null) return; PingReply response = ping.Send(CanonicalName, timeout); if (response != null) @@ -207,11 +231,11 @@ private void Ping(int timeout = 5000) } catch (Exception ex) { - Loggers.ActiveDirectryLogger.Error(ex.Message + " {@Error}", ex ); + Loggers.ActiveDirectryLogger.Error(ex.Message + " {@Error}", ex); } } - + public override void Dispose() { base.Dispose(); diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index 9e58da8e..b56c396c 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -439,13 +439,12 @@ public virtual void MoveTo(IADOrganizationalUnit parentOUToMoveTo) public virtual string? OU { get => DirectoryTools.DnToOu(DN) ?? DirectoryTools.DnToOu(ADSPath); } - public IADOrganizationalUnit? GetParent() + public IDirectoryEntryAdapter? GetParent() { if (DirectoryEntry == null || DirectoryEntry.Parent == null) return null; - var parent = new ADOrganizationalUnit(); + var parent = DirectoryEntry.Parent.Encapsulate(); - parent.Parse(Directory, DirectoryEntry.Parent); return parent; diff --git a/BLAZAMActiveDirectory/GlobalSuppressions.cs b/BLAZAMActiveDirectory/GlobalSuppressions.cs index 86e0de26..8f6f8842 100644 --- a/BLAZAMActiveDirectory/GlobalSuppressions.cs +++ b/BLAZAMActiveDirectory/GlobalSuppressions.cs @@ -62,3 +62,4 @@ [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.SearchResultCollection)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntries)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.KeepAlive(System.Object)")] +[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntry)~BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter")] diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index 59036e56..cd7dd547 100644 --- a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs +++ b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs @@ -2,6 +2,7 @@ using BLAZAM.ActiveDirectory.Adapters; using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Common.Data; +using BLAZAM.Logger; using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; @@ -184,14 +185,65 @@ public static List Encapsulate(this SearchResultCollecti return objects; } /// - /// Encapsulates a raw DirectoryEntry search's within a of the appropriate entry type + /// Encapsulates a raw DirectoryEntry within a of the appropriate entry type /// - /// - /// This is used when getting child ojects from a OU - /// /// - /// A list of whose types correspond the directory object type they encapsulate - public static List Encapsulate(this DirectoryEntries r) + /// A whose types correspond the directory object type they encapsulate + + public static IDirectoryEntryAdapter? Encapsulate(this DirectoryEntry sr) + { + IDirectoryEntryAdapter? thisObject = null; + + if (sr.Properties["objectClass"].Contains("top")) + { + if (sr.Properties["objectClass"].Contains("computer")) + { + thisObject = new ADComputer(); + } + else if (sr.Properties["objectClass"].Contains("user")) + { + thisObject = new ADUser(); + } + else if (sr.Properties["objectClass"].Contains("organizationalUnit")) + { + thisObject = new ADOrganizationalUnit(); + } + else if (sr.Properties["objectClass"].Contains("group")) + { + thisObject = new ADGroup(); + } + else if (sr.Properties["objectClass"].Contains("printQueue")) + { + thisObject = new ADPrinter(); + } + else if (sr.Properties["objectClass"].Contains("msFVE-RecoveryInformation")) + { + thisObject = new ADBitLockerRecovery(); + } + if (thisObject != null) + { + thisObject.Parse(directory: ActiveDirectoryContext.Instance, directoryEntry: sr); + + return thisObject; + + } + else + { + Loggers.ActiveDirectryLogger.Warning("Unable to match ad object type. {Object}", sr); + + } + } + return null; + } + /// + /// Encapsulates a raw DirectoryEntry search's within a of the appropriate entry type + /// + /// + /// This is used when getting child ojects from a OU + /// + /// + /// A list of whose types correspond the directory object type they encapsulate + public static List Encapsulate(this DirectoryEntries r) { List objects = new(); @@ -199,44 +251,11 @@ public static List Encapsulate(this DirectoryEntries r) if (r != null) { - IDirectoryEntryAdapter? thisObject = null; foreach (DirectoryEntry sr in r) { - if (sr.Properties["objectClass"].Contains("top")) - { - if (sr.Properties["objectClass"].Contains("computer")) - { - thisObject = new ADComputer(); - } - else if (sr.Properties["objectClass"].Contains("user")) - { - thisObject = new ADUser(); - } - else if (sr.Properties["objectClass"].Contains("organizationalUnit")) - { - thisObject = new ADOrganizationalUnit(); - } - else if (sr.Properties["objectClass"].Contains("group")) - { - thisObject = new ADGroup(); - } - else if (sr.Properties["objectClass"].Contains("printQueue")) - { - thisObject = new ADPrinter(); - } - else if (sr.Properties["objectClass"].Contains("msFVE-RecoveryInformation")) - { - thisObject = new ADBitLockerRecovery(); - } - if (thisObject != null) - { - thisObject.Parse(directory: ActiveDirectoryContext.Instance, directoryEntry: sr); - - objects.Add(thisObject); - - } - } - thisObject = null; + var encapsulated = Encapsulate(sr); + if(encapsulated != null) + objects.Add(encapsulated); } } diff --git a/BLAZAMActiveDirectory/Interfaces/IADComputer.cs b/BLAZAMActiveDirectory/Interfaces/IADComputer.cs index 6797ae73..a7ad1d06 100644 --- a/BLAZAMActiveDirectory/Interfaces/IADComputer.cs +++ b/BLAZAMActiveDirectory/Interfaces/IADComputer.cs @@ -20,6 +20,7 @@ public interface IADComputer : IAccountDirectoryAdapter /// Null indicates that the check has not yet completed. /// bool? IsOnline { get; } + bool CanReadBitLocker { get; } /// /// If this computer is online, this is the resolved IP address from the server. /// Otherwise, this is null diff --git a/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs index 7e80980a..5de65d5d 100644 --- a/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs @@ -309,7 +309,7 @@ public interface IDirectoryEntryAdapter : IDisposable /// Get's the parent of this entry /// /// - IADOrganizationalUnit? GetParent(); + IDirectoryEntryAdapter? GetParent(); /// /// Wrapper method for the base diff --git a/BLAZAMGui/UI/OU/MoveToOUModalContent.razor b/BLAZAMGui/UI/OU/MoveToOUModalContent.razor index f6acbac3..179ae134 100644 --- a/BLAZAMGui/UI/OU/MoveToOUModalContent.razor +++ b/BLAZAMGui/UI/OU/MoveToOUModalContent.razor @@ -22,7 +22,7 @@ protected override void OnInitialized() { base.OnInitialized(); - StartingOU = DirectoryModel.GetParent(); + StartingOU = (IADOrganizationalUnit)DirectoryModel.GetParent(); Modal.OnYes = MoveTo; Modal.YesText = AppLocalization["Move"]; Modal.Title = "Move To"; From c9b1c08a9884c1158e5c401ddb0e295a14523ed5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 25 Jun 2024 08:21:30 -0400 Subject: [PATCH 013/116] Fix for crash on startup if database is unreachable --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMDatabase/Context/AppDatabaseFactory.cs | 67 ++++++++++++-------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 827990c4..b84c3ec8 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.21.2335 + 2024.06.25.1215 false BLAZAM False diff --git a/BLAZAMDatabase/Context/AppDatabaseFactory.cs b/BLAZAMDatabase/Context/AppDatabaseFactory.cs index 9505af48..4ae78ef5 100644 --- a/BLAZAMDatabase/Context/AppDatabaseFactory.cs +++ b/BLAZAMDatabase/Context/AppDatabaseFactory.cs @@ -3,6 +3,7 @@ using BLAZAM.Database.Exceptions; using BLAZAM.Database.Models.Permissions; using BLAZAM.Logger; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System.Net.WebSockets; @@ -65,41 +66,57 @@ private void SeedData() private void SetupDenyAll(IDatabaseContext seedContext) { - bool saveRequired = false; - var denyAll = seedContext.AccessLevels.First(x => x.Id == 1); - if (denyAll != null) - { - foreach (var adObjectType in Enum.GetValues(typeof(ActiveDirectoryObjectType))) + Task.Run(() => { + bool saveRequired = false; + try { - if ((ActiveDirectoryObjectType)adObjectType != ActiveDirectoryObjectType.All) + var denyAll = seedContext.AccessLevels.First(x => x.Id == 1); + if (denyAll != null) { - if (denyAll.ObjectMap.Any(x => x.ObjectType == (ActiveDirectoryObjectType)adObjectType)) + foreach (var adObjectType in Enum.GetValues(typeof(ActiveDirectoryObjectType))) { - var eexisingObjectMap = denyAll.ObjectMap.First(x => x.ObjectType == (ActiveDirectoryObjectType)adObjectType); - if (eexisingObjectMap.ObjectAccessLevelId != ObjectAccessLevels.Deny.Id) + if ((ActiveDirectoryObjectType)adObjectType != ActiveDirectoryObjectType.All) { - denyAll.ObjectMap.Remove(eexisingObjectMap); - saveRequired = true; + if (denyAll.ObjectMap.Any(x => x.ObjectType == (ActiveDirectoryObjectType)adObjectType)) + { + var eexisingObjectMap = denyAll.ObjectMap.First(x => x.ObjectType == (ActiveDirectoryObjectType)adObjectType); + if (eexisingObjectMap.ObjectAccessLevelId != ObjectAccessLevels.Deny.Id) + { + denyAll.ObjectMap.Remove(eexisingObjectMap); + saveRequired = true; + } + } + if (!denyAll.ObjectMap.Any(x => x.ObjectType == (ActiveDirectoryObjectType)adObjectType && x.ObjectAccessLevel.Id == ObjectAccessLevels.Deny.Id)) + { + denyAll.ObjectMap.Add(new() + { + ObjectType = (ActiveDirectoryObjectType)adObjectType, + ObjectAccessLevelId = ObjectAccessLevels.Deny.Id, + }); + saveRequired = true; + + } } } - if (!denyAll.ObjectMap.Any(x => x.ObjectType == (ActiveDirectoryObjectType)adObjectType && x.ObjectAccessLevel.Id == ObjectAccessLevels.Deny.Id)) - { - denyAll.ObjectMap.Add(new() - { - ObjectType = (ActiveDirectoryObjectType)adObjectType, - ObjectAccessLevelId = ObjectAccessLevels.Deny.Id, - }); - saveRequired = true; - } } + + } + catch (SqlException ex) + { + Loggers.DatabaseLogger.Warning("Error attempting to seed denyAll {@Error}", ex); } + catch (Exception ex) + { + Loggers.DatabaseLogger.Error("Unexpected error attempting to seed denyAll {@Error}", ex); - } - if (saveRequired) - { - seedContext.SaveChanges(); - } + } + if (saveRequired) + { + seedContext.SaveChanges(); + } + }); + } private void StartDatabaseCache() From bfa69bff40949ca64bbe242f7094b6e571c9b698 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 28 Jun 2024 20:47:55 -0400 Subject: [PATCH 014/116] Fix for error when modifying custom field #406 --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Configure/Fields.razor | 10 +++++++--- BLAZAMActiveDirectory/Searchers/ADSearch.cs | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index b84c3ec8..19a2e585 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.06.25.1215 + 2024.06.29.0045 false BLAZAM False diff --git a/BLAZAM/Pages/Configure/Fields.razor b/BLAZAM/Pages/Configure/Fields.razor index 331d0073..e7f4d1e5 100644 --- a/BLAZAM/Pages/Configure/Fields.razor +++ b/BLAZAM/Pages/Configure/Fields.razor @@ -127,10 +127,14 @@ { foreach (var field in ADFields) { - for (int x=0; x < field.ObjectTypes.Count;x++) + + for (int x = 0; x < field.ObjectTypes.Count; x++) { - var trackedObjType = Context.ActiveDirectoryFieldObjectMappings.First(x => x.Id == field.Id); - field.ObjectTypes[x] = trackedObjType; + var trackedObjType = Context.ActiveDirectoryFieldObjectMappings.FirstOrDefault(oType => oType.ObjectType == field.ObjectTypes[x].ObjectType); + if (trackedObjType != null) + { + field.ObjectTypes[x] = trackedObjType; + } } } if (await Context.SaveChangesAsync() > 0) diff --git a/BLAZAMActiveDirectory/Searchers/ADSearch.cs b/BLAZAMActiveDirectory/Searchers/ADSearch.cs index 4d444165..19477354 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearch.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearch.cs @@ -97,7 +97,7 @@ public List Search() { return Search(); } - + public async Task> SearchAsync() { return await SearchAsync(); From 0c572fc9575456ca3cfa2476ae6676167fdeaa48 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 28 Jun 2024 20:58:20 -0400 Subject: [PATCH 015/116] Inccrement version --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 19a2e585..fd4a7842 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -5,7 +5,7 @@ enable enable false - 0.9.3 + 0.9.4 2024.06.29.0045 false BLAZAM From 5c1941dc5a96a8964c94d4a20277f28cba32d2a4 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 28 Jun 2024 20:59:09 -0400 Subject: [PATCH 016/116] Increment build --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index fd4a7842..2051cae2 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.06.29.0045 + 2024.06.29.0058 false BLAZAM False From c7d977ef910b15e42f372550fbc78c493da637a3 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 28 Jun 2024 21:06:19 -0400 Subject: [PATCH 017/116] Update Serilog --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMFileSystem/BLAZAMFileSystem.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 2051cae2..b096d0f3 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.06.29.0058 + 2024.06.29.0104 false BLAZAM False diff --git a/BLAZAMFileSystem/BLAZAMFileSystem.csproj b/BLAZAMFileSystem/BLAZAMFileSystem.csproj index ca603285..f88022e7 100644 --- a/BLAZAMFileSystem/BLAZAMFileSystem.csproj +++ b/BLAZAMFileSystem/BLAZAMFileSystem.csproj @@ -8,7 +8,7 @@ - + From 2d3c1c3b302ea7d8b26d903a93f49be54db506eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 01:09:57 +0000 Subject: [PATCH 018/116] Bump Microsoft.EntityFrameworkCore and Microsoft.EntityFrameworkCore.Analyzers Bumps [Microsoft.EntityFrameworkCore](https://github.com/dotnet/efcore) and [Microsoft.EntityFrameworkCore.Analyzers](https://github.com/dotnet/efcore). These dependencies needed to be updated together. Updates `Microsoft.EntityFrameworkCore` from 7.0.19 to 7.0.20 - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.19...v7.0.20) Updates `Microsoft.EntityFrameworkCore.Analyzers` from 7.0.19 to 7.0.20 - [Release notes](https://github.com/dotnet/efcore/releases) - [Commits](https://github.com/dotnet/efcore/compare/v7.0.19...v7.0.20) --- updated-dependencies: - dependency-name: Microsoft.EntityFrameworkCore dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: Microsoft.EntityFrameworkCore.Analyzers dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 2 +- BLAZAMCommon/BLAZAMCommon.csproj | 2 +- BLAZAMDatabase/BLAZAMDatabase.csproj | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 4be116f6..c77904e3 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -63,7 +63,7 @@ - + diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 83111507..74144510 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index d4a5a2a6..e51b500a 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -21,7 +21,7 @@ - + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index 1259ebf6..973613b6 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -8,9 +8,9 @@ - + - + From d6e33f087521e9929f486c09044af564da27a0c8 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 28 Jun 2024 21:11:48 -0400 Subject: [PATCH 019/116] Update dependencies --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 17d183c5..55311fce 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.06.29.0104 + 2024.06.29.0111 false BLAZAM False From 46d4a58b40768be943cc4b85914a82e6abcf0c2f Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 29 Jun 2024 17:53:20 -0400 Subject: [PATCH 020/116] Allow update to .NET 8 version --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 55311fce..1a740e06 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.06.29.0111 + 2024.06.29.2134 false BLAZAM False From a5e70c8f56e6b0fceea6aac77cbe5adcab6659a1 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 29 Jun 2024 22:06:40 -0400 Subject: [PATCH 021/116] Fixes to updating --- BLAZAM/BLAZAM.csproj | 2 +- .../Settings/ManualApplicationUpdater.razor | 2 +- BLAZAMGui/UI/Settings/UpdateSettings.razor | 8 +++++-- BLAZAMUpdate/ApplicationReleaseBranches.cs | 2 +- BLAZAMUpdate/Services/AutoUpdateService.cs | 18 +++++++++----- BLAZAMUpdate/Services/UpdateService.cs | 24 +++++++++++++++---- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 1a740e06..2c6bf1a0 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.06.29.2134 + 2024.06.30.0205 false BLAZAM False diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index 78adbebc..b0e876ef 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -90,7 +90,7 @@ @if (ShowAllUpdates) { - @foreach (var update in UpdateService.StableUpdates.OrderBy(x => x.Version)) + @foreach (var update in UpdateService.StableUpdates.Where(x=>x.Version.OlderThan(LatestAvailableVersion.Version)).OrderBy(x => x.Version)) { diff --git a/BLAZAMGui/UI/Settings/UpdateSettings.razor b/BLAZAMGui/UI/Settings/UpdateSettings.razor index b729c08e..0099c320 100644 --- a/BLAZAMGui/UI/Settings/UpdateSettings.razor +++ b/BLAZAMGui/UI/Settings/UpdateSettings.razor @@ -86,7 +86,9 @@ - + } @@ -95,7 +97,9 @@ - + @foreach (var val in updateBranches) { @val diff --git a/BLAZAMUpdate/ApplicationReleaseBranches.cs b/BLAZAMUpdate/ApplicationReleaseBranches.cs index dc6e0dce..99b35d9b 100644 --- a/BLAZAMUpdate/ApplicationReleaseBranches.cs +++ b/BLAZAMUpdate/ApplicationReleaseBranches.cs @@ -2,7 +2,7 @@ { public class ApplicationReleaseBranches { - public const string Stable = "Stable"; + public const string Stable = "Release"; public const string Nightly = "Nightly"; public const string Dev = "Dev"; } diff --git a/BLAZAMUpdate/Services/AutoUpdateService.cs b/BLAZAMUpdate/Services/AutoUpdateService.cs index 952a5c9a..fc8073fc 100644 --- a/BLAZAMUpdate/Services/AutoUpdateService.cs +++ b/BLAZAMUpdate/Services/AutoUpdateService.cs @@ -63,7 +63,7 @@ private void CleanDirectories(object? state) Loggers.UpdateLogger.Warning("Attempting Update credentials to delete old update file: " + file); var impersonation = factory.CreateDbContext().AppSettings.FirstOrDefault()?.CreateUpdateImpersonator(); - if (impersonation!=null && !impersonation.Run(() => + if (impersonation != null && !impersonation.Run(() => { if (file.Writable) { @@ -74,7 +74,7 @@ private void CleanDirectories(object? state) })) { impersonation = factory.CreateDbContext().ActiveDirectorySettings.FirstOrDefault()?.CreateDirectoryAdminImpersonator(); - if (impersonation !=null && !impersonation.Run(() => + if (impersonation != null && !impersonation.Run(() => { if (file.Writable) { @@ -167,7 +167,7 @@ private void CleanDirectories(object? state) } catch (IndexOutOfRangeException ex) { - Loggers.UpdateLogger.Error("Deleting unknown directory: " + dir+ "{@Error}",ex); + Loggers.UpdateLogger.Error("Deleting unknown directory: " + dir + "{@Error}", ex); //dir.Delete(true); } catch (Exception ex) @@ -188,12 +188,18 @@ private async void CheckForUpdate(object? state) Loggers.UpdateLogger.Information("Checking for automatic update"); var latestUpdate = await updateService.GetUpdates(); - if (latestUpdate != null && latestUpdate.Version.NewerThan(_applicationInfo.RunningVersion)){ + if (latestUpdate != null && latestUpdate.Version.NewerThan(_applicationInfo.RunningVersion)) + { IsUpdateAvailable = true; - if(appSettings.AutoUpdate && appSettings.AutoUpdateTime != null) + if (appSettings.AutoUpdate && appSettings.AutoUpdateTime != null) { - ScheduleUpdate(appSettings.AutoUpdateTime.Value, latestUpdate); + if (latestUpdate.PassesPrerequisiteChecks) + ScheduleUpdate(appSettings.AutoUpdateTime.Value, latestUpdate); + else + { + Loggers.UpdateLogger.Warning("Update failed prerequisite check, cancelling scheduling {@Error}", latestUpdate.PrequisiteMessage); + } } } diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index 8de9d3c0..c81572a6 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -48,12 +48,13 @@ public class UpdateService : UpdateServiceBase protected readonly IHttpClientFactory httpClientFactory; private readonly ApplicationInfo _applicationInfo; - public UpdateService(IHttpClientFactory _clientFactory, ApplicationInfo applicationInfo, IAppDatabaseFactory? dbFactory = null) + public UpdateService(IHttpClientFactory _clientFactory, ApplicationInfo applicationInfo, IAppDatabaseFactory? dbFactory = null, IStringLocalizer appLocalization=null) { _dbFactory = dbFactory; httpClientFactory = _clientFactory; _updateCheckTimer = new Timer(CheckForUpdate, null, TimeSpan.FromSeconds(20), TimeSpan.FromHours(1)); _applicationInfo = applicationInfo; + AppLocalization = appLocalization; } /// /// Polls Github for the latest release in the selected branch @@ -166,6 +167,12 @@ private async Task SetBranch() { using var context = await _dbFactory.CreateDbContextAsync(); SelectedBranch = context.AppSettings.FirstOrDefault()?.UpdateBranch; + if(SelectedBranch == "Stable") + { + context.AppSettings.FirstOrDefault().UpdateBranch= ApplicationReleaseBranches.Stable; + SelectedBranch = ApplicationReleaseBranches.Stable; + context.SaveChanges(); + } } catch (Exception ex) { @@ -204,15 +211,24 @@ private async Task SetBranch() if(releaseVersion.NewerThan(new ApplicationVersion("0.9.99"))) { update.PreRequisiteChecks.Add(new(() => { - if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) + if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) { + if(AppLocalization!=null) update.PrequisiteMessage = AppLocalization["ASP NET Core 8 Runtime is missing."]; - return false; + else + update.PrequisiteMessage = "ASP NET Core 8 Runtime is missing."; + + return false; } if (ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCoreHosting()) { - update.PrequisiteMessage = AppLocalization["ASP NET Core 8 Web Hosting Bundle is missing."]; + if (AppLocalization != null) + + update.PrequisiteMessage = AppLocalization["ASP NET Core 8 Web Hosting Bundle is missing."]; + else + update.PrequisiteMessage = "ASP NET Core 8 Web Hosting Bundle is missing."; + return false; } From 84788821b4d9d6f341d30de50ca3c76caa31ecc0 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 17:16:48 -0400 Subject: [PATCH 022/116] Pull beta stable releases as well --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMUpdate/Services/UpdateService.cs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 2c6bf1a0..6b5e5f98 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.06.30.0205 + 2024.07.01.2113 false BLAZAM False diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index c81572a6..e827d0aa 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -108,6 +108,24 @@ private async Task GetReleases() latestStableRelease = stableReleases.FirstOrDefault(); //Store all other releases for use later StableUpdates.Clear(); + try { + var betaStableReleases = releases.Where(r => r.TagName.Contains("Stable", StringComparison.OrdinalIgnoreCase)); + + foreach (var release in betaStableReleases) + { + //Get the release filename to prepare a version object + var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); + //Create that version object + if (fn == null) continue; + StableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); + + } + } + catch (Exception ex) + { + Loggers.UpdateLogger.Error("Error trying to get beta releases {@Error}", ex); + } + foreach (var release in stableReleases) { //Get the release filename to prepare a version object From b1d438367bd9ee2ca055d945ba6877368b1bb0f4 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 18:05:50 -0400 Subject: [PATCH 023/116] Remove CI Pipeline caching --- .github/workflows/build-dev.yml | 7 ------- .github/workflows/build-nightly.yml | 7 ------- 2 files changed, 14 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index b5a7f727..2a687643 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -15,13 +15,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - name: Cache Nuget Packages - uses: actions/cache@v1 - with: - path: ~/.nuget/packages - key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} - restore-keys: | - ${{ runner.os }}-nuget- - name: Setup .NET Core SDK 6 uses: actions/setup-dotnet@v1 with: diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 0d28ef34..779cd58e 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -15,13 +15,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - name: Cache Nuget Packages - uses: actions/cache@v1 - with: - path: ~/.nuget/packages - key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} - restore-keys: | - ${{ runner.os }}-nuget- - name: Setup .NET Core SDK 6 uses: actions/setup-dotnet@v1 with: From 816ba4ccac27dd9312bd064a459100ded0548f6f Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 18:17:27 -0400 Subject: [PATCH 024/116] Try different token --- .github/workflows/build-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 2a687643..08484b5b 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -65,7 +65,7 @@ jobs: - name: Update dev release uses: andelf/nightly-release@main env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: Dev name: 'Dev' From c8bbfabfa3a42864e4c72232e5d9925551d0591b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 18:25:56 -0400 Subject: [PATCH 025/116] Add permissions --- .github/workflows/build-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 08484b5b..088faf8e 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -10,7 +10,7 @@ on: jobs: build: runs-on: windows-latest - + permissions: write-all steps: - name: Checkout code From d2c8f3c0181416f38cd98443d67c28b1115537e2 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 18:33:08 -0400 Subject: [PATCH 026/116] Switch to AutoGen GitHub Token --- .github/workflows/build-nightly.yml | 3 ++- .github/workflows/deploy-demo.yml | 1 + .github/workflows/release-stable.yml | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 779cd58e..37f782ba 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -10,6 +10,7 @@ on: jobs: build: runs-on: windows-latest + permissions: write-all steps: @@ -63,7 +64,7 @@ jobs: - name: Update nightly release uses: andelf/nightly-release@main env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: Nightly name: 'Nightly' diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index 25907e11..ed442e95 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -13,6 +13,7 @@ on: jobs: build: runs-on: windows-latest + permissions: write-all steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index 43a617ae..8d8bf973 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -10,6 +10,7 @@ on: jobs: build: runs-on: windows-latest + permissions: write-all steps: @@ -52,7 +53,7 @@ jobs: id: create_release uses: actions/create-release@v1 env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: Stable-v${{ env.ASSEMBLY_VERSION }} @@ -64,7 +65,7 @@ jobs: id: upload-release-asset uses: actions/upload-release-asset@v1 env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: blazam-stable-v${{ env.ASSEMBLY_VERSION }}.zip From 7f351fb969bf8dde35e4805724a414e495fea59d Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 18:34:58 -0400 Subject: [PATCH 027/116] Switch to AutoGen GitHub Token --- .github/workflows/build-dev.yml | 3 ++- .github/workflows/build-nightly.yml | 3 ++- .github/workflows/release-stable.yml | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 3e7220b0..447d811b 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -10,6 +10,7 @@ on: jobs: build: runs-on: windows-latest + permissions: write-all steps: @@ -68,7 +69,7 @@ jobs: - name: Update dev release uses: andelf/nightly-release@main env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: 'Dev1' name: 'Dev1' diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 3801f83b..a489959b 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -10,6 +10,7 @@ on: jobs: build: runs-on: windows-latest + permissions: write-all steps: @@ -70,7 +71,7 @@ jobs: - name: Update nightly release uses: andelf/nightly-release@main env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: 'Nightly1' name: 'Nightly1' diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index cfdda188..ab415200 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -10,6 +10,7 @@ on: jobs: build: runs-on: windows-latest + permissions: write-all steps: @@ -48,7 +49,7 @@ jobs: id: create_release uses: actions/create-release@v1 env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: Release-v${{ env.ASSEMBLY_VERSION }} @@ -60,7 +61,7 @@ jobs: id: upload-release-asset uses: actions/upload-release-asset@v1 env: - GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: blazam-stable-v${{ env.ASSEMBLY_VERSION }}.zip From 547e8eb36e08800cf5fab6dd200fad1028988a20 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 1 Jul 2024 20:40:40 -0400 Subject: [PATCH 028/116] Include Beta Update in history and allow further beta updates before 1.0 update --- BLAZAM/BLAZAM.csproj | 2 +- .../Settings/ManualApplicationUpdater.razor | 20 +++++++++++++------ BLAZAMGui/UI/Settings/UpdateSettings.razor | 14 ++++++++----- BLAZAMUpdate/Services/UpdateService.cs | 10 +++++++--- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 6b5e5f98..91115286 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.01.2113 + 2024.07.02.0039 false BLAZAM False diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index b0e876ef..70d5c677 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -80,17 +80,17 @@ - + - - + + - @if (ShowAllUpdates) + @if (ShowAllUpdates) { - @foreach (var update in UpdateService.StableUpdates.Where(x=>x.Version.OlderThan(LatestAvailableVersion.Version)).OrderBy(x => x.Version)) + @foreach (var update in UpdateService.StableUpdates.Where(x => x.Version.OlderThan(LatestAvailableVersion.Version)).OrderBy(x => x.Version)) { @@ -102,7 +102,7 @@ } @if (UpdateService.LatestUpdate.Version.NewerThan(ApplicationInfo.RunningVersion)) { - + } @@ -117,7 +117,15 @@ } + @if (UpdateService.IncompatibleUpdates.Count > 0) + { + var latestIncompatibleUpdate = UpdateService.IncompatibleUpdates.Where(x => x.Newer).OrderByDescending(x => x.Release.ReleaseTime).FirstOrDefault(); + if (latestIncompatibleUpdate != null) + { + + } + } @if (AutoUpdateService.IsUpdatedScheduled) diff --git a/BLAZAMGui/UI/Settings/UpdateSettings.razor b/BLAZAMGui/UI/Settings/UpdateSettings.razor index 0099c320..931e3bd7 100644 --- a/BLAZAMGui/UI/Settings/UpdateSettings.razor +++ b/BLAZAMGui/UI/Settings/UpdateSettings.razor @@ -45,13 +45,17 @@ } } - if (!UpdateService.LatestUpdate.PassesPrerequisiteChecks) + if (UpdateService.IncompatibleUpdates.Count > 0) { - - @AppLocalization["Unable to update!"] - @(UpdateService.LatestUpdate.PrequisiteMessage) + var latestIncompatibleUpdate = UpdateService.IncompatibleUpdates.Where(x => x.Newer).OrderByDescending(x => x.Release.ReleaseTime).FirstOrDefault(); + if (latestIncompatibleUpdate != null) + { + + @AppLocalization["Unable to update!"] + @(latestIncompatibleUpdate.PrequisiteMessage) - + + } } diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index e827d0aa..79b6d2f8 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -12,6 +12,7 @@ using BLAZAM.Localization; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; +using System.Net.WebSockets; namespace BLAZAM.Update.Services { @@ -105,7 +106,6 @@ private async Task GetReleases() var stableReleases = releases.Where(r => r.TagName.Contains(ApplicationReleaseBranches.Stable, StringComparison.OrdinalIgnoreCase)); //Get the first release,which should be the most recent latestRelease = branchReleases.FirstOrDefault(); - latestStableRelease = stableReleases.FirstOrDefault(); //Store all other releases for use later StableUpdates.Clear(); try { @@ -135,12 +135,15 @@ private async Task GetReleases() StableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); } - var latestStableUpdate = EncapsulateUpdate(latestStableRelease, ApplicationReleaseBranches.Stable); + + var latestStableUpdate = StableUpdates.Where(x=>x.PassesPrerequisiteChecks).OrderByDescending(x=>x.Release.ReleaseTime).FirstOrDefault(); + IncompatibleUpdates = StableUpdates.Where(x => !x.PassesPrerequisiteChecks).ToList(); var latestBranchUpdate = EncapsulateUpdate(latestRelease, SelectedBranch); //Override branch if stable has more recent release - if (latestStableUpdate!=null && latestStableUpdate.Version.NewerThan(latestBranchUpdate.Version)) + if (latestStableUpdate!=null) { LatestUpdate = latestStableUpdate; + } else if(latestBranchUpdate!=null) { @@ -361,5 +364,6 @@ private bool TestDirectoryCredentials() /// public bool HasWritePermission => UpdateCredential != UpdateCredential.None; + public List IncompatibleUpdates { get; private set; } = new(); } } From 31a8aec59daf1daa6eb5dfdebd5711e8279e8b76 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 4 Jul 2024 13:52:51 -0400 Subject: [PATCH 029/116] Add stale issue workflow --- .github/workflows/mark-stale.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/mark-stale.yml diff --git a/.github/workflows/mark-stale.yml b/.github/workflows/mark-stale.yml new file mode 100644 index 00000000..86900852 --- /dev/null +++ b/.github/workflows/mark-stale.yml @@ -0,0 +1,23 @@ +name: Close inactive issues +on: + workflow_dispatch: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v5 + with: + days-before-issue-stale: 14 + days-before-issue-close: 14 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 14 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale." + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From db945c705e341f0e79b24da5079b258e04e6ba75 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 5 Jul 2024 17:12:01 -0400 Subject: [PATCH 030/116] Create completly custom MudSelectList --- BLAZAM/BLAZAM.csproj | 10 +- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 6 +- BLAZAMCommon/BLAZAMCommon.csproj | 8 +- BLAZAMDatabase/Add-AppMigration.ps1 | 6 +- BLAZAMDatabase/BLAZAMDatabase.csproj | 8 +- ...And_EmailTemplateChanges_MySql.Designer.cs | 1817 ++++++++++++++++ ...gateName_And_EmailTemplateChanges_MySql.cs | 73 + .../MySqlDatabaseContextModelSnapshot.cs | 18 +- ...e_And_EmailTemplateChanges_Sql.Designer.cs | 1882 +++++++++++++++++ ...legateName_And_EmailTemplateChanges_Sql.cs | 72 + .../Sql/SqlDatabaseContextModelSnapshot.cs | 18 +- ...nd_EmailTemplateChanges_Sqlite.Designer.cs | 1812 ++++++++++++++++ ...ateName_And_EmailTemplateChanges_Sqlite.cs | 72 + .../SqliteDatabaseContextModelSnapshot.cs | 18 +- .../Models/Permissions/PermissionDelegate.cs | 4 +- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 2 +- BLAZAMGui/UI/Inputs/MudSelectList.razor | 149 +- BLAZAMGui/UI/Inputs/MudSelectList_old.razor | 81 + .../Settings/Permissions/DelegateEditor.razor | 4 +- .../Permissions/DelegateListItem.razor | 37 +- .../Permissions/PermissionMapEditor.razor | 13 +- .../BLAZAMNotifications.csproj | 2 +- BLAZAMThemes/BLAZAMThemes.csproj | 2 +- 24 files changed, 5982 insertions(+), 134 deletions(-) create mode 100644 BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.Designer.cs create mode 100644 BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.cs create mode 100644 BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.Designer.cs create mode 100644 BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.cs create mode 100644 BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.Designer.cs create mode 100644 BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.cs create mode 100644 BLAZAMGui/UI/Inputs/MudSelectList_old.razor diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 91115286..bd4856d0 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.02.0039 + 2024.07.05.2110 false BLAZAM False @@ -65,10 +65,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 74144510..ae76699a 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index e51b500a..4727b02a 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -23,10 +23,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BLAZAMDatabase/Add-AppMigration.ps1 b/BLAZAMDatabase/Add-AppMigration.ps1 index 2b7b6456..c61b68ef 100644 --- a/BLAZAMDatabase/Add-AppMigration.ps1 +++ b/BLAZAMDatabase/Add-AppMigration.ps1 @@ -6,20 +6,20 @@ $sqlName = $Name + "Sql"; $mysqlName = $Name + "MySql"; $sqliteName = $Name + "Sqlite"; try { - Add-Migration $sqliteName -OutputDir Migrations/Sqlite -Context SqliteDatabaseContext + Add-Migration -Name $sqliteName -OutputDir Migrations/Sqlite -Context SqliteDatabaseContext } catch { exit } try { - Add-Migration $sqlName -OutputDir Migrations/Sql -Context SqlDatabaseContext + Add-Migration -Name $sqlName -OutputDir Migrations/Sql -Context SqlDatabaseContext } catch { Remove-Migration -Context SqliteDatabaseContext exit } try { - Add-Migration $mysqlName -OutputDir Migrations/MySql -Context MySqlDatabaseContext + Add-Migration -Name $mysqlName -OutputDir Migrations/MySql -Context MySqlDatabaseContext } catch { Remove-Migration -Context SqliteDatabaseContext diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index 973613b6..a96cf4c0 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -11,10 +11,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.Designer.cs b/BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.Designer.cs new file mode 100644 index 00000000..aa2dc06a --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.Designer.cs @@ -0,0 +1,1817 @@ +// +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.MySql +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql")] + partial class Add_DelegateName_And_EmailTemplateChanges_MySql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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"); + + 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"); + + b.Property("AllowCustomGroups") + .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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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.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("Messages") + .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.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("Messages"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.cs b/BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.cs new file mode 100644 index 00000000..62be5ac0 --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20240704204619_Add_DelegateName_And_EmailTemplateChanges_MySql.cs @@ -0,0 +1,73 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.MySql +{ + /// + public partial class Add_DelegateName_And_EmailTemplateChanges_MySql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BCC", + table: "EmailTemplates"); + + migrationBuilder.DropColumn( + name: "CC", + table: "EmailTemplates"); + + migrationBuilder.DropColumn( + name: "TemplateName", + table: "EmailTemplates"); + + migrationBuilder.AddColumn( + name: "DelegateName", + table: "PermissionDelegate", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "TemplateType", + table: "EmailTemplates", + type: "int", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DelegateName", + table: "PermissionDelegate"); + + migrationBuilder.DropColumn( + name: "TemplateType", + table: "EmailTemplates"); + + migrationBuilder.AddColumn( + name: "BCC", + table: "EmailTemplates", + type: "longtext", + nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "CC", + table: "EmailTemplates", + type: "longtext", + nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "TemplateName", + table: "EmailTemplates", + type: "longtext", + nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs index 36895730..cdfba259 100644 --- a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs @@ -16,7 +16,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.19") + .HasAnnotation("ProductVersion", "7.0.20") .HasAnnotation("Relational:MaxIdentifierLength", 64); modelBuilder.Entity("AccessLevelFieldAccessMapping", b => @@ -884,25 +884,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("BCC") - .IsRequired() - .HasColumnType("longtext"); - b.Property("Body") .IsRequired() .HasColumnType("longtext"); - b.Property("CC") - .IsRequired() - .HasColumnType("longtext"); - b.Property("Subject") .IsRequired() .HasColumnType("longtext"); - b.Property("TemplateName") - .IsRequired() - .HasColumnType("longtext"); + b.Property("TemplateType") + .HasColumnType("int"); b.HasKey("Id"); @@ -1165,6 +1156,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + b.Property("DelegateName") + .HasColumnType("longtext"); + b.Property("DelegateSid") .IsRequired() .HasColumnType("varbinary(3072)"); diff --git a/BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.Designer.cs b/BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.Designer.cs new file mode 100644 index 00000000..e5891d48 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.Designer.cs @@ -0,0 +1,1882 @@ +// +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("20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql")] + partial class Add_DelegateName_And_EmailTemplateChanges_Sql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .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.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" + }); + }); + + 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("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("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.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("Messages") + .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.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("Messages"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.cs b/BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.cs new file mode 100644 index 00000000..af4ba660 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20240704204540_Add_DelegateName_And_EmailTemplateChanges_Sql.cs @@ -0,0 +1,72 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sql +{ + /// + public partial class Add_DelegateName_And_EmailTemplateChanges_Sql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BCC", + table: "EmailTemplates"); + + migrationBuilder.DropColumn( + name: "CC", + table: "EmailTemplates"); + + migrationBuilder.DropColumn( + name: "TemplateName", + table: "EmailTemplates"); + + migrationBuilder.AddColumn( + name: "DelegateName", + table: "PermissionDelegate", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "TemplateType", + table: "EmailTemplates", + type: "int", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DelegateName", + table: "PermissionDelegate"); + + migrationBuilder.DropColumn( + name: "TemplateType", + table: "EmailTemplates"); + + migrationBuilder.AddColumn( + name: "BCC", + table: "EmailTemplates", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "CC", + table: "EmailTemplates", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "TemplateName", + table: "EmailTemplates", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs index b79214a6..8f8572ee 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", "7.0.19") + .HasAnnotation("ProductVersion", "7.0.20") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -911,25 +911,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - b.Property("BCC") - .IsRequired() - .HasColumnType("nvarchar(max)"); - b.Property("Body") .IsRequired() .HasColumnType("nvarchar(max)"); - b.Property("CC") - .IsRequired() - .HasColumnType("nvarchar(max)"); - b.Property("Subject") .IsRequired() .HasColumnType("nvarchar(max)"); - b.Property("TemplateName") - .IsRequired() - .HasColumnType("nvarchar(max)"); + b.Property("TemplateType") + .HasColumnType("int"); b.HasKey("Id"); @@ -1208,6 +1199,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + b.Property("DelegateName") + .HasColumnType("nvarchar(max)"); + b.Property("DelegateSid") .IsRequired() .HasColumnType("varbinary(900)"); diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.Designer.cs b/BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.Designer.cs new file mode 100644 index 00000000..9857fed3 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.Designer.cs @@ -0,0 +1,1812 @@ +// +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("20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite")] + partial class Add_DelegateName_And_EmailTemplateChanges_Sqlite + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.20"); + + 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.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" + }); + }); + + 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("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("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.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("Messages") + .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.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("Messages"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.cs b/BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.cs new file mode 100644 index 00000000..5c202cb3 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20240704204410_Add_DelegateName_And_EmailTemplateChanges_Sqlite.cs @@ -0,0 +1,72 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sqlite +{ + /// + public partial class Add_DelegateName_And_EmailTemplateChanges_Sqlite : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "BCC", + table: "EmailTemplates"); + + migrationBuilder.DropColumn( + name: "CC", + table: "EmailTemplates"); + + migrationBuilder.DropColumn( + name: "TemplateName", + table: "EmailTemplates"); + + migrationBuilder.AddColumn( + name: "DelegateName", + table: "PermissionDelegate", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "TemplateType", + table: "EmailTemplates", + type: "INTEGER", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DelegateName", + table: "PermissionDelegate"); + + migrationBuilder.DropColumn( + name: "TemplateType", + table: "EmailTemplates"); + + migrationBuilder.AddColumn( + name: "BCC", + table: "EmailTemplates", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "CC", + table: "EmailTemplates", + type: "TEXT", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "TemplateName", + table: "EmailTemplates", + type: "TEXT", + nullable: false, + defaultValue: ""); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs index 12258bb6..9e2b2af5 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", "7.0.19"); + modelBuilder.HasAnnotation("ProductVersion", "7.0.20"); modelBuilder.Entity("AccessLevelFieldAccessMapping", b => { @@ -879,25 +879,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("BCC") - .IsRequired() - .HasColumnType("TEXT"); - b.Property("Body") .IsRequired() .HasColumnType("TEXT"); - b.Property("CC") - .IsRequired() - .HasColumnType("TEXT"); - b.Property("Subject") .IsRequired() .HasColumnType("TEXT"); - b.Property("TemplateName") - .IsRequired() - .HasColumnType("TEXT"); + b.Property("TemplateType") + .HasColumnType("INTEGER"); b.HasKey("Id"); @@ -1160,6 +1151,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("DelegateName") + .HasColumnType("TEXT"); + b.Property("DelegateSid") .IsRequired() .HasColumnType("BLOB"); diff --git a/BLAZAMDatabase/Models/Permissions/PermissionDelegate.cs b/BLAZAMDatabase/Models/Permissions/PermissionDelegate.cs index cd2e6224..fd34e889 100644 --- a/BLAZAMDatabase/Models/Permissions/PermissionDelegate.cs +++ b/BLAZAMDatabase/Models/Permissions/PermissionDelegate.cs @@ -9,11 +9,9 @@ public class PermissionDelegate : RecoverableAppDbSetBase, IComparable public byte[] DelegateSid { get; set; } public bool IsSuperAdmin { get; set; } public List PermissionsMaps { get; set; } - - - [NotMapped] public string? DelegateName { get; set; } + public int CompareTo(object? obj) { if (obj != null && obj is PermissionDelegate pl) diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index 97b89b17..300bdb11 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -14,7 +14,7 @@ - + diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index 91b7fbbb..29d6dbaf 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -27,7 +27,7 @@ - + diff --git a/BLAZAMGui/UI/Inputs/MudSelectList.razor b/BLAZAMGui/UI/Inputs/MudSelectList.razor index babc7790..d9bf5daa 100644 --- a/BLAZAMGui/UI/Inputs/MudSelectList.razor +++ b/BLAZAMGui/UI/Inputs/MudSelectList.razor @@ -1,58 +1,72 @@ @inherits MudSelect @typeparam T - - - @if (Values != null && Values.Count() > 0) - { - @foreach (var val in Values) + + + + + @if (SelectedValues.Count() > 0) + { + + @Text + + } + else + { + + @Placeholder + + } + + + + + + + @if (Values != null && Values.Count() > 0) { - - - @if (ToStringFunc != null) - { - - @ToStringFunc.Invoke(val) - - } - else - { - - @val?.ToString() - - } - - + @foreach (var val in Values) + { + + + @if (MultiSelection) + { + + } + @if (ToStringFunc != null) + { + + @ToStringFunc.Invoke(val) + + } + else + { + + @val?.ToString() + + } + + + } + } - } - + + @code { + private MudMenu? _selectMenu; [Parameter] public Color Color { get; set; } private IEnumerable _values; @@ -63,9 +77,9 @@ { _values = value; Text = ""; - if(_values!=null && _values.Count() > 0) + if (_values != null && _values.Count() > 0) { - foreach(var item in _values) + foreach (var item in _values) { if (item != null) { @@ -76,6 +90,41 @@ } } + } + + private void ToggleSelected(T item) + { + if (SelectedValues.Contains(item)) + { + @if (MultiSelection) + { + SelectedValues = SelectedValues.Where(x => !x.Equals(item)); + SelectedValuesChanged.InvokeAsync(SelectedValues); + + } + + } + else + { + @if (MultiSelection) + { + SelectedValues = SelectedValues.Append(item); + SelectedValuesChanged.InvokeAsync(SelectedValues); + + } + else + { + SelectedValues = new List() { item }; + Value = item; + ValueChanged.InvokeAsync(item); + + } + } + + + + + } } diff --git a/BLAZAMGui/UI/Inputs/MudSelectList_old.razor b/BLAZAMGui/UI/Inputs/MudSelectList_old.razor new file mode 100644 index 00000000..babc7790 --- /dev/null +++ b/BLAZAMGui/UI/Inputs/MudSelectList_old.razor @@ -0,0 +1,81 @@ +@inherits MudSelect +@typeparam T + + + @if (Values != null && Values.Count() > 0) + { + @foreach (var val in Values) + { + + + @if (ToStringFunc != null) + { + + @ToStringFunc.Invoke(val) + + } + else + { + + @val?.ToString() + + } + + + } + } + + + +@code { + [Parameter] + public Color Color { get; set; } + private IEnumerable _values; + [Parameter] + public IEnumerable Values + { + get => _values; set + { + _values = value; + Text = ""; + if(_values!=null && _values.Count() > 0) + { + foreach(var item in _values) + { + if (item != null) + { + Text += ToStringFunc.Invoke(item) + ", "; + } + } + Text = Text.Substring(0, Text.Length - 2); + } + + } + } +} + diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor index 31d3f6db..f05155a4 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor @@ -24,7 +24,7 @@ .Contains(DelegateFilter, StringComparison.OrdinalIgnoreCase))*@; @foreach (var pl in delegates) { - + } } @@ -35,7 +35,7 @@ @foreach (var deleg in AllDelegates.Where(l => l.DeletedAt != null)) { - var model = @Directory.FindEntryBySID(deleg.DelegateSid); + var model = Directory.FindEntryBySID(deleg.DelegateSid); @model?.ObjectType
@model?.CanonicalName diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor index 997feb7b..c51dec9f 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor @@ -3,15 +3,11 @@ - @if(Group!=null){ - @Group?.CanonicalName - }else { - @("Group not found") - - } + @Delegate.DelegateName + - + @@ -23,7 +19,7 @@ @**@ @@ -31,7 +27,7 @@ - + @@ -49,9 +45,9 @@ @code { #nullable disable warnings - IDirectoryEntryAdapter? Group; + IDirectoryEntryAdapter? _delegateEntry; [Parameter] - public PermissionDelegate Level { get; set; } + public PermissionDelegate Delegate { get; set; } [Parameter] public new IDatabaseContext Context { get; set; } @@ -61,20 +57,33 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - Group = Directory.FindEntryBySID(Level.DelegateSid); + _delegateEntry = Directory.FindEntryBySID(Delegate.DelegateSid); + if(_delegateEntry != null) + { + if(Delegate.DelegateName!= _delegateEntry.CanonicalName) + { + Delegate.DelegateName = _delegateEntry.CanonicalName; + var result = await Context.SaveChangesAsync(); + } + } + else + { + Delegate.DelegateName = ("(" +Delegate.DelegateSid.ToSidString()+")").Trim(); + var result = await Context.SaveChangesAsync(); + } } async Task DeleteDelegate() { - Level.DeletedAt = DateTime.UtcNow; + Delegate.DeletedAt = DateTime.UtcNow; await Context.SaveChangesAsync(); SnackBarService.Success("Permission Delegate removed."); await DelegateDeleted.InvokeAsync(); } protected async override void Save() { - Level.DelegateSid = Group.SID; + Delegate.DelegateSid = _delegateEntry.SID; await Context.SaveChangesAsync(); await InvokeAsync(StateHasChanged); } diff --git a/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor b/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor index aab96b96..a05dd4b0 100644 --- a/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor @@ -7,16 +7,16 @@ @if (!ReadOnly && _permissionDelegates != null) { - + MultiSelection=true + @bind-Text=@selectedPermissionDelegateNames + @bind-SelectedValues=@Map.PermissionDelegates /> + - + diff --git a/BLAZAMThemes/BLAZAMThemes.csproj b/BLAZAMThemes/BLAZAMThemes.csproj index 703ff05b..2ede2c12 100644 --- a/BLAZAMThemes/BLAZAMThemes.csproj +++ b/BLAZAMThemes/BLAZAMThemes.csproj @@ -8,7 +8,7 @@ - + From 015b34e9e7a93a2ab60a9a959173e5496db806b1 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 5 Jul 2024 17:35:58 -0400 Subject: [PATCH 031/116] Revert beta workflows to beta --- .github/workflows/build-dev.yml | 10 +++++++--- .github/workflows/build-nightly.yml | 6 +++--- .github/workflows/release-stable.yml | 10 +++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 933cc0ed..3f4f0771 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - v1-Dev + - Beta-Dev jobs: @@ -15,6 +15,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 + - name: Setup .NET Core SDK 6 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.x - name: Setup .NET Core SDK 8 uses: actions/setup-dotnet@v1 with: @@ -63,8 +67,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: 'Dev1' - name: 'Dev1' + tag_name: 'Dev' + name: 'Dev' prerelease: true body: This release is highly unstable. Expect bugs and crashes on this branch. Developers Only! files: | diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index b69c514b..65c7e9fb 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - v1-Nightly + - Beta-Nightly jobs: @@ -66,8 +66,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: 'Nightly1' - name: 'Nightly1' + tag_name: 'Nightly' + name: 'Nightly' prerelease: true body: This release is always the latest nightly release. These versions are unstable and may break your application. You've been warned. files: | diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index ab415200..fbe8fc76 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - v1-Stable + - Beta-Stable jobs: @@ -16,6 +16,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 + - name: Setup .NET Core SDK 6 + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.x - name: Setup .NET Core SDK 8 uses: actions/setup-dotnet@v1 with: @@ -52,8 +56,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: Release-v${{ env.ASSEMBLY_VERSION }} - release_name: Release - v${{ env.ASSEMBLY_VERSION }} + tag_name: Stable-v${{ env.ASSEMBLY_VERSION }} + release_name: Stable - v${{ env.ASSEMBLY_VERSION }} body: "" draft: true prerelease: true From fe380ff5041ed08229fc61043c7e341bee66269d Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 5 Jul 2024 17:38:35 -0400 Subject: [PATCH 032/116] Rename workflows --- .github/workflows/build-dev.yml | 2 +- .github/workflows/build-nightly.yml | 2 +- .github/workflows/release-stable.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 3f4f0771..8e6bfb8f 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -1,4 +1,4 @@ -name: Build v1 Dev +name: Build Dev on: workflow_dispatch: diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 65c7e9fb..91f03565 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -1,4 +1,4 @@ -name: Build v1 Nightly +name: Build Nightly on: workflow_dispatch: diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index fbe8fc76..8d8bf973 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -1,4 +1,4 @@ -name: Publish and Release v1 Stable +name: Publish and Release Stable on: workflow_dispatch: From 88fa9b18675057ac0d8e65c9d047b5f8de254ff0 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 6 Jul 2024 09:08:35 -0400 Subject: [PATCH 033/116] Fix assembly version for beta --- BLAZAM/BLAZAM.csproj | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 60f24d56..8f652e73 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -6,9 +6,7 @@ enable false 0.9.4 - 2024.07.05.2110 - 1.0.0 - 2024.07.05.2110 + 2024.07.06.1307 false BLAZAM False From 17a3202a6a5a11ba3035f312b9342ce1f4cf0b9b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 6 Jul 2024 10:58:27 -0400 Subject: [PATCH 034/116] Lot of update fixes and accidental v1 inclusions --- BLAZAM.Tests/BLAZAM.Tests.csproj | 2 +- BLAZAM/BLAZAM.csproj | 40 +++---- .../BLAZAMActiveDirectory.csproj | 2 +- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 2 +- BLAZAMCommon/BLAZAMCommon.csproj | 42 +++---- BLAZAMDatabase/BLAZAMDatabase.csproj | 28 ++--- BLAZAMEmail/BLAZAMEmail.csproj | 2 +- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 4 +- BLAZAMFileSystem/BLAZAMFileSystem.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 108 +++++++++--------- .../Settings/ManualApplicationUpdater.razor | 33 +++--- BLAZAMJobs/BLAZAMJobs.csproj | 2 +- BLAZAMLocalization/BLAZAMLocalization.csproj | 2 +- BLAZAMLoggers/BLAZAMLogger.csproj | 2 +- BLAZAMNav/BLAZAMNav.csproj | 2 +- .../BLAZAMNotifications.csproj | 2 +- BLAZAMServices/BLAZAMServices.csproj | 2 +- BLAZAMSession/BLAZAMSession.csproj | 2 +- BLAZAMStatic/BLAZAMStatic.csproj | 2 +- BLAZAMThemes/BLAZAMThemes.csproj | 2 +- BLAZAMUpdate/BLAZAMUpdate.csproj | 2 +- BLAZAMUpdate/Services/UpdateService.cs | 59 +++++++--- 22 files changed, 186 insertions(+), 158 deletions(-) diff --git a/BLAZAM.Tests/BLAZAM.Tests.csproj b/BLAZAM.Tests/BLAZAM.Tests.csproj index 3826f8d4..08426028 100644 --- a/BLAZAM.Tests/BLAZAM.Tests.csproj +++ b/BLAZAM.Tests/BLAZAM.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 8f652e73..cbb833ee 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,12 +1,12 @@ - + - net8.0 + net6.0 enable enable false - 0.9.4 - 2024.07.06.1307 + 0.9.2 + 2024.07.06.1446 false BLAZAM False @@ -29,7 +29,7 @@ - + @@ -59,25 +59,25 @@ - - - - - - - - - - + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + @@ -110,9 +110,9 @@
- - PreserveNewest - + + PreserveNewest + diff --git a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj index 76658c34..5d630802 100644 --- a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj +++ b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.ActiveDirectory diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index f7000a8e..4e1b5ff2 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 8a0d962f..8c1d33f6 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Common @@ -18,26 +18,26 @@ - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index d9f02a13..5663a9ab 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -1,26 +1,26 @@  - net8.0 + net6.0 enable enable BLAZAM.Database - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/BLAZAMEmail/BLAZAMEmail.csproj b/BLAZAMEmail/BLAZAMEmail.csproj index ab7e9981..2197dd71 100644 --- a/BLAZAMEmail/BLAZAMEmail.csproj +++ b/BLAZAMEmail/BLAZAMEmail.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable BLAZAM.Email diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index 0abd8650..ec669fd0 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable BLAZAM.EmailMessage @@ -13,7 +13,7 @@ - + diff --git a/BLAZAMFileSystem/BLAZAMFileSystem.csproj b/BLAZAMFileSystem/BLAZAMFileSystem.csproj index 057484f2..f88022e7 100644 --- a/BLAZAMFileSystem/BLAZAMFileSystem.csproj +++ b/BLAZAMFileSystem/BLAZAMFileSystem.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable BLAZAM.FileSystem diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index 16617983..e135ad9a 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -1,65 +1,65 @@  - - net8.0 - enable - enable - BLAZAM.Gui - + + net6.0 + enable + enable + BLAZAM.Gui + - - - - - - - - - - + + + + + + + + + + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - ..\BLAZAMSession\ApplicationNews.dll - - + + + ..\BLAZAMSession\ApplicationNews.dll + + - - - true - - - true - - - true - - + + + true + + + true + + + true + + diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index 70d5c677..68ba1148 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -90,7 +90,7 @@ @if (ShowAllUpdates) { - @foreach (var update in UpdateService.StableUpdates.Where(x => x.Version.OlderThan(LatestAvailableVersion.Version)).OrderBy(x => x.Version)) + @foreach (var update in UpdateService.AvailableUpdates.Where(x => x.Version.OlderThan(LatestAvailableVersion.Version)).OrderBy(x => x.Version)) { @@ -100,23 +100,26 @@ } } - @if (UpdateService.LatestUpdate.Version.NewerThan(ApplicationInfo.RunningVersion)) + @if (UpdateService.NewestAvailableUpdate != null) { - - - } + if (UpdateService.NewestAvailableUpdate.Version.NewerThan(ApplicationInfo.RunningVersion)) + { + - @if (LatestAvailableVersion != null && !LatestAvailableVersion.Version.NewerThan(ApplicationInfo.RunningVersion)) - { - - - @AppLocalization["Up to date"] - - - - - + } + else + { + + + @AppLocalization["Up to date"] + + + + + + } } + @if (UpdateService.IncompatibleUpdates.Count > 0) { var latestIncompatibleUpdate = UpdateService.IncompatibleUpdates.Where(x => x.Newer).OrderByDescending(x => x.Release.ReleaseTime).FirstOrDefault(); diff --git a/BLAZAMJobs/BLAZAMJobs.csproj b/BLAZAMJobs/BLAZAMJobs.csproj index 17a354ae..0fc399c5 100644 --- a/BLAZAMJobs/BLAZAMJobs.csproj +++ b/BLAZAMJobs/BLAZAMJobs.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable diff --git a/BLAZAMLocalization/BLAZAMLocalization.csproj b/BLAZAMLocalization/BLAZAMLocalization.csproj index db9fe4a4..5c37bba1 100644 --- a/BLAZAMLocalization/BLAZAMLocalization.csproj +++ b/BLAZAMLocalization/BLAZAMLocalization.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Localization diff --git a/BLAZAMLoggers/BLAZAMLogger.csproj b/BLAZAMLoggers/BLAZAMLogger.csproj index f2f2a7f2..b7fa8f9c 100644 --- a/BLAZAMLoggers/BLAZAMLogger.csproj +++ b/BLAZAMLoggers/BLAZAMLogger.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Logger diff --git a/BLAZAMNav/BLAZAMNav.csproj b/BLAZAMNav/BLAZAMNav.csproj index b934e5db..66b3ad4a 100644 --- a/BLAZAMNav/BLAZAMNav.csproj +++ b/BLAZAMNav/BLAZAMNav.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Nav diff --git a/BLAZAMNotifications/BLAZAMNotifications.csproj b/BLAZAMNotifications/BLAZAMNotifications.csproj index 1eaca79a..ad494c08 100644 --- a/BLAZAMNotifications/BLAZAMNotifications.csproj +++ b/BLAZAMNotifications/BLAZAMNotifications.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable BLAZAM.Notifications diff --git a/BLAZAMServices/BLAZAMServices.csproj b/BLAZAMServices/BLAZAMServices.csproj index f12bfa19..65b5705d 100644 --- a/BLAZAMServices/BLAZAMServices.csproj +++ b/BLAZAMServices/BLAZAMServices.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Services diff --git a/BLAZAMSession/BLAZAMSession.csproj b/BLAZAMSession/BLAZAMSession.csproj index 549819a4..c1cb444d 100644 --- a/BLAZAMSession/BLAZAMSession.csproj +++ b/BLAZAMSession/BLAZAMSession.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Session diff --git a/BLAZAMStatic/BLAZAMStatic.csproj b/BLAZAMStatic/BLAZAMStatic.csproj index 17911521..a771c162 100644 --- a/BLAZAMStatic/BLAZAMStatic.csproj +++ b/BLAZAMStatic/BLAZAMStatic.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable BLAZAM.Static diff --git a/BLAZAMThemes/BLAZAMThemes.csproj b/BLAZAMThemes/BLAZAMThemes.csproj index 4ba9d299..2ede2c12 100644 --- a/BLAZAMThemes/BLAZAMThemes.csproj +++ b/BLAZAMThemes/BLAZAMThemes.csproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 enable enable BLAZAM.Themes diff --git a/BLAZAMUpdate/BLAZAMUpdate.csproj b/BLAZAMUpdate/BLAZAMUpdate.csproj index 585662f8..069c8553 100644 --- a/BLAZAMUpdate/BLAZAMUpdate.csproj +++ b/BLAZAMUpdate/BLAZAMUpdate.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Update diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index 79b6d2f8..f4572c78 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -36,7 +36,7 @@ public class UpdateService : UpdateServiceBase /// /// All updates released under the stable branch /// - public List StableUpdates { get; set; } = new(); + public List AvailableUpdates { get; set; } = new(); /// /// The branch configured in the database @@ -72,7 +72,7 @@ public UpdateService(IHttpClientFactory _clientFactory, ApplicationInfo applicat await SetBranch(); await GetReleases(); - return LatestUpdate; + return NewestAvailableUpdate; } catch (Octokit.RateLimitExceededException ex) @@ -91,7 +91,7 @@ private async Task GetReleases() { //Create a github client to get api data from repo - Release? latestRelease = null; + Release? latestBranchRelease = null; Release? latestStableRelease = null; var client = new GitHubClient(new ProductHeaderValue(Publisher_Name)); @@ -105,9 +105,9 @@ private async Task GetReleases() var branchReleases = releases.Where(r => r.TagName.Contains(SelectedBranch, StringComparison.OrdinalIgnoreCase)); var stableReleases = releases.Where(r => r.TagName.Contains(ApplicationReleaseBranches.Stable, StringComparison.OrdinalIgnoreCase)); //Get the first release,which should be the most recent - latestRelease = branchReleases.FirstOrDefault(); + latestBranchRelease = branchReleases.FirstOrDefault(); //Store all other releases for use later - StableUpdates.Clear(); + AvailableUpdates.Clear(); try { var betaStableReleases = releases.Where(r => r.TagName.Contains("Stable", StringComparison.OrdinalIgnoreCase)); @@ -117,7 +117,7 @@ private async Task GetReleases() var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); //Create that version object if (fn == null) continue; - StableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); + AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); } } @@ -132,24 +132,48 @@ private async Task GetReleases() var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); //Create that version object if (fn == null) continue; - StableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); + AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); } - var latestStableUpdate = StableUpdates.Where(x=>x.PassesPrerequisiteChecks).OrderByDescending(x=>x.Release.ReleaseTime).FirstOrDefault(); - IncompatibleUpdates = StableUpdates.Where(x => !x.PassesPrerequisiteChecks).ToList(); - var latestBranchUpdate = EncapsulateUpdate(latestRelease, SelectedBranch); - //Override branch if stable has more recent release - if (latestStableUpdate!=null) + var latestBranchUpdate = EncapsulateUpdate(latestBranchRelease, SelectedBranch); + if (latestBranchUpdate.Branch != ApplicationReleaseBranches.Stable && latestBranchUpdate.Branch != "Stable") { - LatestUpdate = latestStableUpdate; - + if (!AvailableUpdates.Contains(latestBranchUpdate)) + { + AvailableUpdates.Add(latestBranchUpdate); + } + } - else if(latestBranchUpdate!=null) + IncompatibleUpdates = AvailableUpdates.Where(x => !x.PassesPrerequisiteChecks).ToList(); + foreach (var release in IncompatibleUpdates) { - LatestUpdate = latestBranchUpdate; - + AvailableUpdates.Remove(release); } + ////Override branch if stable has more recent release + //if (latestStableUpdate!=null) + //{ + // if(latestBranchUpdate!=null) + // { + // if (latestStableUpdate.Version.NewerThan(latestBranchUpdate.Version)) + // { + // LatestUpdate = latestStableUpdate; + + // } + // else + // { + // LatestUpdate = latestBranchUpdate; + + // } + + // } + // else + // { + // LatestUpdate = latestStableUpdate; + + // } + + //} //if (Debugger.IsAttached) //{ // ApplicationUpdate? testUpdate = EncapsulateUpdate(latestRelease, SelectedBranch); @@ -365,5 +389,6 @@ private bool TestDirectoryCredentials() public bool HasWritePermission => UpdateCredential != UpdateCredential.None; public List IncompatibleUpdates { get; private set; } = new(); + public ApplicationUpdate? NewestAvailableUpdate => AvailableUpdates.OrderByDescending(x => x.Version).FirstOrDefault(); } } From ffaa4ef6f74a7c2235f7b4d5ed353471ec7886e9 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 6 Jul 2024 10:58:53 -0400 Subject: [PATCH 035/116] Back to current 0.9.3 --- BLAZAM/BLAZAM.csproj | 4 ++-- BlazamUpdate/BLAZAMUpdate.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index cbb833ee..48597878 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,11 +1,11 @@ - + net6.0 enable enable false - 0.9.2 + 0.9.3 2024.07.06.1446 false BLAZAM diff --git a/BlazamUpdate/BLAZAMUpdate.csproj b/BlazamUpdate/BLAZAMUpdate.csproj index 585662f8..069c8553 100644 --- a/BlazamUpdate/BLAZAMUpdate.csproj +++ b/BlazamUpdate/BLAZAMUpdate.csproj @@ -1,7 +1,7 @@  - net8.0 + net6.0 enable enable BLAZAM.Update From f5f3b394f59603270aaa61d8f71fc13466ff6a7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 15:02:25 +0000 Subject: [PATCH 036/116] Bump DuoUniversal from 1.2.4 to 1.2.5 Bumps [DuoUniversal](https://github.com/duosecurity/duo_universal_csharp) from 1.2.4 to 1.2.5. - [Release notes](https://github.com/duosecurity/duo_universal_csharp/releases) - [Commits](https://github.com/duosecurity/duo_universal_csharp/compare/1.2.4...1.2.5) --- updated-dependencies: - dependency-name: DuoUniversal dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMServices/BLAZAMServices.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 48597878..70e8794d 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -56,7 +56,7 @@ - + diff --git a/BLAZAMServices/BLAZAMServices.csproj b/BLAZAMServices/BLAZAMServices.csproj index 65b5705d..19291ced 100644 --- a/BLAZAMServices/BLAZAMServices.csproj +++ b/BLAZAMServices/BLAZAMServices.csproj @@ -8,7 +8,7 @@ - + From da25307dd4a1c52cc4c0d53f6f564b50fa4767b5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 6 Jul 2024 16:10:48 -0400 Subject: [PATCH 037/116] Fix for links applying search object type filters #405 --- BLAZAM/BLAZAM.csproj | 4 +- BLAZAM/Pages/Configure/Audit.razor | 2 +- BLAZAM/Pages/View.razor | 218 ++++++++++++++++++ .../Adapters/ADOrganizationalUnit.cs | 2 +- .../Adapters/DirectoryEntryAdapter.cs | 2 +- 5 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 BLAZAM/Pages/View.razor diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 48597878..52729f05 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.07.06.1446 + 2024.07.06.2008 false BLAZAM False diff --git a/BLAZAM/Pages/Configure/Audit.razor b/BLAZAM/Pages/Configure/Audit.razor index 0be093b3..6100aa18 100644 --- a/BLAZAM/Pages/Configure/Audit.razor +++ b/BLAZAM/Pages/Configure/Audit.razor @@ -35,7 +35,7 @@ - @context.Item.Target + @context.Item.Target diff --git a/BLAZAM/Pages/View.razor b/BLAZAM/Pages/View.razor new file mode 100644 index 00000000..8b255b32 --- /dev/null +++ b/BLAZAM/Pages/View.razor @@ -0,0 +1,218 @@ +@page "/view" +@page "/view/{SearchTermParameter}" +@using System.Web + +@inherits AppComponentBase +@attribute [Authorize(Roles = (UserRoles.SearchOUs + "," + UserRoles.SearchComputers + "," + UserRoles.SearchGroups + "," + UserRoles.SearchUsers + "," + UserRoles.SuperAdmin))] + + + + @if (ApplicationInfo.InDemoMode) + { + + Try searching Moore, Howard, Evans, Manny... + + } + + + + @if (Searcher.Results.Count > 1) + { + + Results found: @Searcher.Results.Count + Time elapsed: @Searcher.SearchTime + + + + + @if (u.CanRead) + { + { + Searcher.Results.Clear();Searcher.Results.Add(u); + }) /> + + + } + + + Loading... + + + + + } + else if (Searcher.Results.Count == 1) + { + + var result = Searcher.Results[0]; + if (result.CanRead) + { + result.OnModelDeleted = (() => { InvokeAsync(StateHasChanged); }); + + @if (result.IsDeleted) + { + Deleted + } + else + { + + } + } + @* else + { + + + } + *@ + } + + else if (LoadingData) + { + + } + else if (Searcher.Results.Count == 0) + { + + No results were found. + + } + + +@code { + + [CascadingParameter] + public SearchService SearchParameters { get; set; } + + string ModelsTypeName = "Search"; + protected string SearchIcon { get; set; } = ""; + string? _searchTermParameter; + /// + /// The search term that comes from the URI + /// + [Parameter] + public virtual string? SearchTermParameter + { + get => _searchTermParameter; set + { + if (_searchTermParameter == HttpUtility.UrlDecode(value)) return; + LoadingData = true; + Searcher?.Cancel(); + _searchTermParameter = HttpUtility.UrlDecode(value); + Task.Run(async () => + { + await PerformSearch(); + if (_searchTermParameter.IsNullOrEmpty()) + LoadingData = false; + }); + + + } + } + + + public ADSearch Searcher { get; set; } = new ADSearch(); + + + [CascadingParameter] + public MainLayout? MainLayout { get; set; } + + /// + /// The search term that comes from the search text box + /// + [CascadingParameter] + public string? SearchTerm { get; set; } + + /// + /// Standard search page initializer that copies the url search term to the + /// text search term if it is set. + /// + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + Searcher = new ADSearch(); + SearchService.SearchTerm = SearchTermParameter; + Searcher.GeneralSearchTerm = SearchTermParameter; + + await base.OnInitializedAsync(); + + + + Searcher.OnSearchStarted += (() => + { + InvokeAsync(StateHasChanged); + }); + Searcher.OnSearchCompleted += (() => + { + InvokeAsync(StateHasChanged); + }); + Searcher.ResultsCollected += ((batch) => + { + results.AddRange(batch.Where(r=>r.CanRead)); + }); + } + /// + /// Filter for searching objects of only this type + /// + [CascadingParameter] + public ActiveDirectoryObjectType? SearchObjectType { get; set; } + + protected virtual List results { get; set; } = new List(); + + + /// + /// Called internally to start a search + /// + /// + /// This method in turn calls + /// if the is not + /// null or empty. + /// + /// + protected async Task PerformSearch() + { + results.Clear(); + + LoadingData = true; + await InvokeAsync(StateHasChanged); + if (!SearchTermParameter.IsNullOrEmpty() && SearchTermParameter?.Length > 0) + await InvokeSearch(); + else + Searcher.Results.Clear(); + LoadingData = false; + + await InvokeAsync(StateHasChanged); + + + + } + + /// + /// Invokes the actual search function + /// that processes the current + /// settings. + /// + /// + protected async Task InvokeSearch() + { + if (Searcher == null) + Searcher = new ADSearch(); + else + Searcher.Cancel(); + SearchService.SearchTerm = SearchTermParameter; + //Searcher.EnabledOnly = !SearchService.IncludeDisabled; + Searcher.GeneralSearchTerm = SearchService.SearchTerm; + //Searcher.ObjectTypeFilter = SearchService.SeachObjectType; + Searcher.ExactMatch = true; + + //Try exact match search first + await Searcher.SearchAsync(); + if (Searcher.Results.Count < 1) + { + Searcher.ExactMatch = false; + results = await Searcher.SearchAsync(); + + } + } + +} diff --git a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs index d6440eb1..62b8f171 100644 --- a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs +++ b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs @@ -58,7 +58,7 @@ public IEnumerable SubOUs - public override string SearchUri => "/search/" + HttpUtility.UrlEncode(DN); + public override string SearchUri => "/view/" + HttpUtility.UrlEncode(DN); public override string? CanonicalName { diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index b56c396c..66d48649 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -32,7 +32,7 @@ public virtual string SearchUri { get { - return "/search/" + CanonicalName; + return "/view/" + CanonicalName; } } From 032f2f6d4e3e6fa3e98b1902fe65a9d4a686cba6 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 6 Jul 2024 16:30:12 -0400 Subject: [PATCH 038/116] Fix for common test packages targeting net8 --- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 54 ++++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 4e1b5ff2..6bbe6bfe 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -1,34 +1,34 @@  - - net6.0 - enable - enable + + net6.0 + enable + enable - false - + false + - - - - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - - - + + + From 8604b5918eeea58496f42db2800a35603fec3b31 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 7 Jul 2024 13:44:10 -0400 Subject: [PATCH 039/116] Prepare for Email Notification Subscriptions --- BLAZAMEmail/Services/EmailService.cs | 4 +-- ...nt.cs => NotificationTemplateComponent.cs} | 16 ++++++---- .../Email/GenericEmailMessage.razor | 6 ++-- .../NewUserWelcomeEmailMessage.razor | 2 +- .../PasswordChangedEmailMessage.razor | 29 +++++++++++++++++++ .../Email/TestEmailMessage.razor | 2 +- .../Email/UpdateEmailMessage.razor | 2 +- .../BLAZAMNotifications.csproj | 1 + .../Notifications/NotificationTypes.cs | 16 ++++++++++ 9 files changed, 64 insertions(+), 14 deletions(-) rename BLAZAMEmailMessage/Email/Base/{EmailTemplateComponent.cs => NotificationTemplateComponent.cs} (55%) rename BLAZAMEmailMessage/Email/{ => Notifications}/NewUserWelcomeEmailMessage.razor (97%) create mode 100644 BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor create mode 100644 BLAZAMNotifications/Notifications/NotificationTypes.cs diff --git a/BLAZAMEmail/Services/EmailService.cs b/BLAZAMEmail/Services/EmailService.cs index 5d2ecbe4..80a6409f 100644 --- a/BLAZAMEmail/Services/EmailService.cs +++ b/BLAZAMEmail/Services/EmailService.cs @@ -55,8 +55,8 @@ public EmailService(IAppDatabaseFactory factory) protected string WrapMessage() where TComponent : IComponent => GetRenderer().Render(); protected string WrapGenericMessage(MarkupString header, MarkupString body) => GetRenderer() - .Set(c => c.Header, header) - .Set(c => c.Body, body).Render(); + .Set(c => c.EmailMessageHeader, header) + .Set(c => c.EmailMessageBody, body).Render(); /// diff --git a/BLAZAMEmailMessage/Email/Base/EmailTemplateComponent.cs b/BLAZAMEmailMessage/Email/Base/NotificationTemplateComponent.cs similarity index 55% rename from BLAZAMEmailMessage/Email/Base/EmailTemplateComponent.cs rename to BLAZAMEmailMessage/Email/Base/NotificationTemplateComponent.cs index 6616673e..42679979 100644 --- a/BLAZAMEmailMessage/Email/Base/EmailTemplateComponent.cs +++ b/BLAZAMEmailMessage/Email/Base/NotificationTemplateComponent.cs @@ -7,26 +7,30 @@ namespace BLAZAM.EmailMessage.Email.Base { - public class EmailTemplateComponent : ComponentBase + public class NotificationTemplateComponent : ComponentBase { [Inject] protected IStringLocalizer AppLocalization { get; set; } [Inject] protected ApplicationInfo ApplicationInfo { get; set; } [Parameter] - public MarkupString Header { get; set; } + public MarkupString EmailMessageHeader { get; set; } [Parameter] - public MarkupString Body { get; set; } + public MarkupString EmailMessageBody { get; set; } + + [Parameter] + public string NotificationHeader { get; set; } + public string NotificationBody { get; set; } - public virtual string Render() => new ComponentRenderer() + public virtual string Render() => new ComponentRenderer() .UseLayout() .AddServiceProvider(ApplicationInfo.services) - .Set(c => c.Header, Header) - .Set(c => c.Body, Body).Render(); + .Set(c => c.EmailMessageHeader, EmailMessageHeader) + .Set(c => c.EmailMessageBody, EmailMessageBody).Render(); diff --git a/BLAZAMEmailMessage/Email/GenericEmailMessage.razor b/BLAZAMEmailMessage/Email/GenericEmailMessage.razor index fc68f989..21596028 100644 --- a/BLAZAMEmailMessage/Email/GenericEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/GenericEmailMessage.razor @@ -1,11 +1,11 @@ -@inherits EmailTemplateComponent +@inherits NotificationTemplateComponent - @Header + @EmailMessageHeader - @Body + @EmailMessageBody diff --git a/BLAZAMEmailMessage/Email/NewUserWelcomeEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor similarity index 97% rename from BLAZAMEmailMessage/Email/NewUserWelcomeEmailMessage.razor rename to BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor index 96cad1a7..76df34cd 100644 --- a/BLAZAMEmailMessage/Email/NewUserWelcomeEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor @@ -1,7 +1,7 @@ @using BLAZAM.ActiveDirectory.Interfaces @using BLAZAM.Helpers @using System.Security -@inherits EmailTemplateComponent +@inherits NotificationTemplateComponent @AppLocalization["Welcome"] diff --git a/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor new file mode 100644 index 00000000..be2445bb --- /dev/null +++ b/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor @@ -0,0 +1,29 @@ +@using BLAZAM.ActiveDirectory.Interfaces +@using BLAZAM.Helpers +@using System.Security +@inherits NotificationTemplateComponent + + + @AppLocalization["Password changed"] + + + + @(AppLocalization["he password for "]+Entry.CanonicalName+AppLocalization[" has been changed."]) +
+ + +
+ + +@code{ + [Parameter] + public IAccountDirectoryAdapter Entry { get; set; } + + public override string Render() => new ComponentRenderer() + .UseLayout() + .AddServiceProvider(ApplicationInfo.services) + .Set(c=>c.Entry,Entry).Render(); +} + + + diff --git a/BLAZAMEmailMessage/Email/TestEmailMessage.razor b/BLAZAMEmailMessage/Email/TestEmailMessage.razor index b176977b..87e417b8 100644 --- a/BLAZAMEmailMessage/Email/TestEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/TestEmailMessage.razor @@ -1,5 +1,5 @@  -@inherits EmailTemplateComponent +@inherits NotificationTemplateComponent @AppLocalization["Success"] diff --git a/BLAZAMEmailMessage/Email/UpdateEmailMessage.razor b/BLAZAMEmailMessage/Email/UpdateEmailMessage.razor index e6b5be27..416df300 100644 --- a/BLAZAMEmailMessage/Email/UpdateEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/UpdateEmailMessage.razor @@ -1,4 +1,4 @@ -@inherits EmailTemplateComponent +@inherits NotificationTemplateComponent Update Scheduled diff --git a/BLAZAMNotifications/BLAZAMNotifications.csproj b/BLAZAMNotifications/BLAZAMNotifications.csproj index b9906cb2..92722a65 100644 --- a/BLAZAMNotifications/BLAZAMNotifications.csproj +++ b/BLAZAMNotifications/BLAZAMNotifications.csproj @@ -13,6 +13,7 @@ + diff --git a/BLAZAMNotifications/Notifications/NotificationTypes.cs b/BLAZAMNotifications/Notifications/NotificationTypes.cs new file mode 100644 index 00000000..04856261 --- /dev/null +++ b/BLAZAMNotifications/Notifications/NotificationTypes.cs @@ -0,0 +1,16 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Notifications +{ + public class NotificationTypes + { + public NotificationTemplateComponent + + public PasswordChangedEmailMessage PasswordChange => new PasswordChangedEmailMessage(); + } +} From 4e45a6fc772623185b8afc972982d3372de58f7b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 7 Jul 2024 18:44:16 -0400 Subject: [PATCH 040/116] Migration created, boilerplate started --- BLAZAM/BLAZAM.csproj | 2 +- ...lateSettings.razor => Notifications.razor} | 3 +- BLAZAM/Pages/Users/ConfirmNewUser.razor | 3 +- BLAZAM/Program.cs | 16 +- BLAZAM/ProgramHelpers.cs | 30 + .../BLAZAMActiveDirectory.csproj | 1 - BLAZAMDatabase/Context/DatabaseContextBase.cs | 5 + BLAZAMDatabase/Context/IDatabaseContext.cs | 2 + ...tification_Subscriptions_MySql.Designer.cs | 1854 ++++++++++++++++ ...16_Add_Notification_Subscriptions_MySql.cs | 51 + .../MySqlDatabaseContextModelSnapshot.cs | 37 + ...Notification_Subscriptions_Sql.Designer.cs | 1921 +++++++++++++++++ ...4854_Add_Notification_Subscriptions_Sql.cs | 48 + .../Sql/SqlDatabaseContextModelSnapshot.cs | 39 + ...ification_Subscriptions_Sqlite.Designer.cs | 1849 ++++++++++++++++ ...0_Add_Notification_Subscriptions_Sqlite.cs | 48 + .../SqliteDatabaseContextModelSnapshot.cs | 37 + .../Notifications/NotificationSubscription.cs | 17 + .../Models/Notifications/NotificationType.cs | 11 + BLAZAMDatabase/Models/User/AppUser.cs | 8 + BLAZAMEmail/Services/EmailService.cs | 2 +- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 1 - .../NewUserWelcomeEmailMessage.razor | 3 +- .../PasswordChangedEmailMessage.razor | 9 +- BLAZAMGui/GlobalUsing.cs | 2 + .../UI/Settings/NotificationSettings.razor | 5 - .../Notifications/NotificationSettings.razor | 66 + .../BLAZAMNotifications.csproj | 2 +- BLAZAMNotifications/GlobalUsings.cs | 3 + .../NotificationTypeExtentions.cs | 28 + .../Notifications/NotificationTypes.cs | 16 - BLAZAMServices/UserSeederService.cs | 11 +- BLAZAMSession/ApplicationUserState.cs | 2 + .../Interfaces/IApplicationUserState.cs | 2 + 34 files changed, 6081 insertions(+), 53 deletions(-) rename BLAZAM/Pages/Configure/{EmailTemplateSettings.razor => Notifications.razor} (93%) create mode 100644 BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs create mode 100644 BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs create mode 100644 BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs create mode 100644 BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs create mode 100644 BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs create mode 100644 BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs create mode 100644 BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs create mode 100644 BLAZAMDatabase/Models/Notifications/NotificationType.cs delete mode 100644 BLAZAMGui/UI/Settings/NotificationSettings.razor create mode 100644 BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor create mode 100644 BLAZAMNotifications/GlobalUsings.cs create mode 100644 BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs delete mode 100644 BLAZAMNotifications/Notifications/NotificationTypes.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 11c5811c..9299863b 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.07.06.2008 + 2024.07.07.2231 false BLAZAM False diff --git a/BLAZAM/Pages/Configure/EmailTemplateSettings.razor b/BLAZAM/Pages/Configure/Notifications.razor similarity index 93% rename from BLAZAM/Pages/Configure/EmailTemplateSettings.razor rename to BLAZAM/Pages/Configure/Notifications.razor index 538cdae3..87b1a86a 100644 --- a/BLAZAM/Pages/Configure/EmailTemplateSettings.razor +++ b/BLAZAM/Pages/Configure/Notifications.razor @@ -1,4 +1,5 @@ @page "/notifications" +@using BLAZAM.Gui.UI.Settings.Notifications @attribute [Authorize(Roles = UserRoles.SuperAdmin)] @inherits TabbedAppComponentBase @@ -17,7 +18,7 @@ - + diff --git a/BLAZAM/Pages/Users/ConfirmNewUser.razor b/BLAZAM/Pages/Users/ConfirmNewUser.razor index a5ff9bfc..518a6e4c 100644 --- a/BLAZAM/Pages/Users/ConfirmNewUser.razor +++ b/BLAZAM/Pages/Users/ConfirmNewUser.razor @@ -1,5 +1,6 @@ @using BLAZAM.EmailMessage.Email @using System.Security +@using BLAZAM.EmailMessage.Email.Notifications @inherits DirectoryModelComponent @inject IJSRuntime JSRuntime Confirm User Creation @@ -266,7 +267,7 @@ else message.Username = _username; message.Password = _userPassword; var html = message.Render(); - EmailService.SendMessage(AppLocalization["New Account Details"], message,to); + await EmailService.SendMessage(AppLocalization["New Account Details"], message,to); SnackBarService.Info(AppLocalization["Welcome Email Sent to "] + to); SendWelcomeModal.Close(); }catch (Exception ex) diff --git a/BLAZAM/Program.cs b/BLAZAM/Program.cs index 310eb11d..3f1cbc12 100644 --- a/BLAZAM/Program.cs +++ b/BLAZAM/Program.cs @@ -120,20 +120,8 @@ public static void Main(string[] args) ApplicationInfo.services = AppInstance.Services; - - try - { - var context = AppInstance.Services.GetRequiredService().CreateDbContext(); - if(context!=null && context.AppSettings.FirstOrDefault()?.SendLogsToDeveloper != null) - { - Loggers.SendToSeqServer = context.AppSettings.FirstOrDefault().SendLogsToDeveloper; - - } - - }catch (Exception ex) - { - Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); - } + AppInstance.PreRun(); + Loggers.SetupLoggers(WritablePath + @"logs\", ApplicationInfo.runningVersion.ToString()); diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs index 107065b2..155598cd 100644 --- a/BLAZAM/ProgramHelpers.cs +++ b/BLAZAM/ProgramHelpers.cs @@ -320,5 +320,35 @@ completed so it may not be usable as is return builder; } + public static void PreRun(this WebApplication application) + { + //Setup Seq logging if allowed by admin + try + { + var context = Program.AppInstance.Services.GetRequiredService().CreateDbContext(); + if (context != null && context.AppSettings.FirstOrDefault()?.SendLogsToDeveloper != null) + { + Loggers.SendToSeqServer = context.AppSettings.FirstOrDefault().SendLogsToDeveloper; + + } + + } + catch (Exception ex) + { + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + try + { + var context = Program.AppInstance.Services.GetRequiredService(); + + + } + catch (Exception ex) + { + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + + } + } } diff --git a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj index 5d630802..30c6322c 100644 --- a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj +++ b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj @@ -15,7 +15,6 @@ - diff --git a/BLAZAMDatabase/Context/DatabaseContextBase.cs b/BLAZAMDatabase/Context/DatabaseContextBase.cs index ce62b3ee..fd92bff2 100644 --- a/BLAZAMDatabase/Context/DatabaseContextBase.cs +++ b/BLAZAMDatabase/Context/DatabaseContextBase.cs @@ -20,6 +20,7 @@ using System.Data; using BLAZAM.FileSystem; using Microsoft.EntityFrameworkCore.ChangeTracking; +using BLAZAM.Database.Models.Notifications; namespace BLAZAM.Database.Context { @@ -112,6 +113,7 @@ public DatabaseContextBase(DbContextOptions options) : base(options) public virtual DbSet UserFavoriteEntries { get; set; } public virtual DbSet UserDashboardWidgets { get; set; } public virtual DbSet NotificationMessages { get; set; } + public virtual DbSet NotificationSubscriptions { get; set; } //Audit Logs @@ -519,6 +521,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Navigation(e => e.Field).AutoInclude(); entity.Navigation(e => e.CustomField).AutoInclude(); }); + modelBuilder.Entity().HasData( new ObjectAction() { Id = 1, Name = "Assign", Action = ActiveDirectoryObjectAction.Assign }, new ObjectAction() { Id = 2, Name = "UnAssign", Action = ActiveDirectoryObjectAction.Unassign }, @@ -609,6 +612,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Navigation(e => e.ReadNewsItems).AutoInclude(); entity.Navigation(e => e.FavoriteEntries).AutoInclude(); entity.Navigation(e => e.DashboardWidgets).AutoInclude(); + entity.Navigation(e => e.NotificationSubscriptions).AutoInclude(); + //entity.Navigation(e => e.UnreadChatMessages).AutoInclude(); }); diff --git a/BLAZAMDatabase/Context/IDatabaseContext.cs b/BLAZAMDatabase/Context/IDatabaseContext.cs index 6f25f783..b39d6aca 100644 --- a/BLAZAMDatabase/Context/IDatabaseContext.cs +++ b/BLAZAMDatabase/Context/IDatabaseContext.cs @@ -3,6 +3,7 @@ using BLAZAM.Database.Models; using BLAZAM.Database.Models.Audit; using BLAZAM.Database.Models.Chat; +using BLAZAM.Database.Models.Notifications; using BLAZAM.Database.Models.Permissions; using BLAZAM.Database.Models.Templates; using BLAZAM.Database.Models.User; @@ -62,6 +63,7 @@ public interface IDatabaseContext : IEFCoreDbContext DbSet ChatMessages { get; set; } DbSet UnreadChatMessages { get; set; } DbSet ActiveDirectoryFieldObjectMappings { get; set; } + DbSet NotificationSubscriptions { get; set; } void Export(string directory); } diff --git a/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs b/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs new file mode 100644 index 00000000..6834a2da --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs @@ -0,0 +1,1854 @@ +// +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.MySql +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20240707194916_Add_Notification_Subscriptions_MySql")] + partial class Add_Notification_Subscriptions_MySql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + b.Property("Block") + .HasColumnType("tinyint(1)"); + + b.Property("NotificationType") + .HasColumnType("int"); + + 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.Permissions.AccessLevel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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" + }); + }); + + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.PermissionDelegate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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"); + + 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"); + + b.Property("AllowCustomGroups") + .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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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"); + + 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() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + 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("Messages") + .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.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("Messages"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs b/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs new file mode 100644 index 00000000..44e3667c --- /dev/null +++ b/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs @@ -0,0 +1,51 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.MySql +{ + /// + public partial class Add_Notification_Subscriptions_MySql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "NotificationSubscriptions", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "int", nullable: false), + NotificationType = table.Column(type: "int", nullable: false), + OU = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Block = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_NotificationSubscriptions", x => x.Id); + table.ForeignKey( + name: "FK_NotificationSubscriptions_UserSettings_UserId", + column: x => x.UserId, + principalTable: "UserSettings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_NotificationSubscriptions_UserId", + table: "NotificationSubscriptions", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "NotificationSubscriptions"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs index cdfba259..7191045a 100644 --- a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs @@ -900,6 +900,32 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("EmailTemplates"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Block") + .HasColumnType("tinyint(1)"); + + b.Property("NotificationType") + .HasColumnType("int"); + + 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.Permissions.AccessLevel", b => { b.Property("Id") @@ -1596,6 +1622,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("ChatMessage"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => { b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) diff --git a/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs b/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs new file mode 100644 index 00000000..1dea2966 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs @@ -0,0 +1,1921 @@ +// +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("20240707194854_Add_Notification_Subscriptions_Sql")] + partial class Add_Notification_Subscriptions_Sql + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.20") + .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("NotificationType") + .HasColumnType("int"); + + 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.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" + }); + }); + + 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("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("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() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + 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("Messages") + .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.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("Messages"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs b/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs new file mode 100644 index 00000000..201a67f0 --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sql +{ + /// + public partial class Add_Notification_Subscriptions_Sql : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "NotificationSubscriptions", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "int", nullable: false), + NotificationType = table.Column(type: "int", nullable: false), + OU = table.Column(type: "nvarchar(max)", nullable: false), + Block = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_NotificationSubscriptions", x => x.Id); + table.ForeignKey( + name: "FK_NotificationSubscriptions_UserSettings_UserId", + column: x => x.UserId, + principalTable: "UserSettings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_NotificationSubscriptions_UserId", + table: "NotificationSubscriptions", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "NotificationSubscriptions"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs index 8f8572ee..139f295c 100644 --- a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs @@ -927,6 +927,34 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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("NotificationType") + .HasColumnType("int"); + + 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.Permissions.AccessLevel", b => { b.Property("Id") @@ -1661,6 +1689,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("ChatMessage"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => { b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs b/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs new file mode 100644 index 00000000..627aee7c --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs @@ -0,0 +1,1849 @@ +// +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("20240707194830_Add_Notification_Subscriptions_Sqlite")] + partial class Add_Notification_Subscriptions_Sqlite + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.20"); + + 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("NotificationType") + .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.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" + }); + }); + + 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("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("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() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + 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("Messages") + .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.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("Messages"); + + b.Navigation("ReadNewsItems"); + }); + + modelBuilder.Entity("BLAZAM.Server.Data.ChatMessage", b => + { + b.Navigation("NotReadBy"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs b/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs new file mode 100644 index 00000000..5fefd60c --- /dev/null +++ b/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace BLAZAM.Database.Migrations.Sqlite +{ + /// + public partial class Add_Notification_Subscriptions_Sqlite : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "NotificationSubscriptions", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "INTEGER", nullable: false), + NotificationType = table.Column(type: "INTEGER", nullable: false), + OU = table.Column(type: "TEXT", nullable: false), + Block = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_NotificationSubscriptions", x => x.Id); + table.ForeignKey( + name: "FK_NotificationSubscriptions_UserSettings_UserId", + column: x => x.UserId, + principalTable: "UserSettings", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_NotificationSubscriptions_UserId", + table: "NotificationSubscriptions", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "NotificationSubscriptions"); + } + } +} diff --git a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs index 9e2b2af5..f5cdbd32 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs @@ -895,6 +895,32 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("EmailTemplates"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Block") + .HasColumnType("INTEGER"); + + b.Property("NotificationType") + .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.Permissions.AccessLevel", b => { b.Property("Id") @@ -1591,6 +1617,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("ChatMessage"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => + { + b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + modelBuilder.Entity("BLAZAM.Database.Models.Permissions.ActionAccessMapping", b => { b.HasOne("BLAZAM.Database.Models.Permissions.AccessLevel", null) diff --git a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs new file mode 100644 index 00000000..1c4c7ad3 --- /dev/null +++ b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs @@ -0,0 +1,17 @@ +using BLAZAM.Database.Models.User; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Database.Models.Notifications +{ + public class NotificationSubscription:AppDbSetBase + { + public AppUser User { get; set; } + public NotificationType NotificationType { get; set; } + public string OU { get; set; } + public bool Block { get; set; } = false; + } +} diff --git a/BLAZAMDatabase/Models/Notifications/NotificationType.cs b/BLAZAMDatabase/Models/Notifications/NotificationType.cs new file mode 100644 index 00000000..e1266ac6 --- /dev/null +++ b/BLAZAMDatabase/Models/Notifications/NotificationType.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Database.Models.Notifications +{ + public enum NotificationType { PasswordChange } + +} diff --git a/BLAZAMDatabase/Models/User/AppUser.cs b/BLAZAMDatabase/Models/User/AppUser.cs index 44155bb4..90dd8091 100644 --- a/BLAZAMDatabase/Models/User/AppUser.cs +++ b/BLAZAMDatabase/Models/User/AppUser.cs @@ -1,6 +1,7 @@  using BLAZAM.Database.Models.Chat; +using BLAZAM.Database.Models.Notifications; using BLAZAM.Server.Data; namespace BLAZAM.Database.Models.User @@ -22,8 +23,15 @@ public class AppUser : AppDbSetBase //public List ChatRooms{ get; set; } = new(); public List DashboardWidgets { get; set; }= new(); + public List NotificationSubscriptions { get; set; }= new(); public byte[]? ProfilePicture { get; set; } public string? Email { get; set; } + + public override string? ToString() + { + return Username + ; + } } } diff --git a/BLAZAMEmail/Services/EmailService.cs b/BLAZAMEmail/Services/EmailService.cs index 80a6409f..164ff8f4 100644 --- a/BLAZAMEmail/Services/EmailService.cs +++ b/BLAZAMEmail/Services/EmailService.cs @@ -213,7 +213,7 @@ public async Task SendMessage(string subject, string to, string? cc = n } } - public async Task SendMessage(string subject, EmailTemplateComponent body, string to, string? cc = null, string? bcc = null) + public async Task SendMessage(string subject, NotificationTemplateComponent body, string to, string? cc = null, string? bcc = null) { try { diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index ec669fd0..bafe9f20 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -18,7 +18,6 @@ - diff --git a/BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor index 76df34cd..7c249fc2 100644 --- a/BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/Notifications/NewUserWelcomeEmailMessage.razor @@ -1,5 +1,4 @@ -@using BLAZAM.ActiveDirectory.Interfaces -@using BLAZAM.Helpers +@using BLAZAM.Helpers @using System.Security @inherits NotificationTemplateComponent diff --git a/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor index be2445bb..fc87a838 100644 --- a/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor +++ b/BLAZAMEmailMessage/Email/Notifications/PasswordChangedEmailMessage.razor @@ -1,5 +1,4 @@ -@using BLAZAM.ActiveDirectory.Interfaces -@using BLAZAM.Helpers +@using BLAZAM.Helpers @using System.Security @inherits NotificationTemplateComponent @@ -8,7 +7,7 @@ - @(AppLocalization["he password for "]+Entry.CanonicalName+AppLocalization[" has been changed."]) + @(AppLocalization["he password for "] + EntryName + AppLocalization[" has been changed."])
@@ -17,12 +16,12 @@ @code{ [Parameter] - public IAccountDirectoryAdapter Entry { get; set; } + public string EntryName { get; set; } public override string Render() => new ComponentRenderer() .UseLayout() .AddServiceProvider(ApplicationInfo.services) - .Set(c=>c.Entry,Entry).Render(); + .Set(c => c.EntryName, EntryName).Render(); } diff --git a/BLAZAMGui/GlobalUsing.cs b/BLAZAMGui/GlobalUsing.cs index 66f35ff2..e385e548 100644 --- a/BLAZAMGui/GlobalUsing.cs +++ b/BLAZAMGui/GlobalUsing.cs @@ -15,3 +15,5 @@ global using Microsoft.AspNetCore.Components; global using Microsoft.Extensions.Localization; global using Microsoft.JSInterop; +global using BLAZAM.Database.Models.Notifications; + diff --git a/BLAZAMGui/UI/Settings/NotificationSettings.razor b/BLAZAMGui/UI/Settings/NotificationSettings.razor deleted file mode 100644 index 913edacd..00000000 --- a/BLAZAMGui/UI/Settings/NotificationSettings.razor +++ /dev/null @@ -1,5 +0,0 @@ -

NotificationSettings

- -@code { - -} diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor new file mode 100644 index 00000000..9d068dd4 --- /dev/null +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -0,0 +1,66 @@ +@inherits AppComponentBase +

NotificationSettings

+ +@if (_selectedUser != null) +{ + + + + + @if (_selectedOU != null) + { + var subscription = _selectedUser.NotificationSubscriptions.Where(x => x.OU.Equals(_selectedOU.DN, StringComparison.InvariantCultureIgnoreCase)); + + + + + + + + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @originalEnum.ToString() + + } + + + @foreach (var sub in subscription) + { + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + + + + + + } + + } + + + } + + + +} +@code { + IDirectoryEntryAdapter? _selectedOU = null; + IList Users = new List(); + AppUser? _selectedUser = null; + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + Users = await Context.UserSettings.ToListAsync(); + } + private async Task> SearchUsers(string value) + { + if (value == null) value = String.Empty; + return Users.Where(x => x.Username.Contains(value)); + } +} diff --git a/BLAZAMNotifications/BLAZAMNotifications.csproj b/BLAZAMNotifications/BLAZAMNotifications.csproj index 65b3e1f5..44298634 100644 --- a/BLAZAMNotifications/BLAZAMNotifications.csproj +++ b/BLAZAMNotifications/BLAZAMNotifications.csproj @@ -1,4 +1,4 @@ - + net6.0 diff --git a/BLAZAMNotifications/GlobalUsings.cs b/BLAZAMNotifications/GlobalUsings.cs new file mode 100644 index 00000000..4b7aaa2d --- /dev/null +++ b/BLAZAMNotifications/GlobalUsings.cs @@ -0,0 +1,3 @@ +global using BLAZAM.EmailMessage.Email.Base; +global using BLAZAM.EmailMessage.Email.Notifications; + diff --git a/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs b/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs new file mode 100644 index 00000000..975e4efb --- /dev/null +++ b/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs @@ -0,0 +1,28 @@ +using BLAZAM.Database.Models.Notifications; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Notifications.Notifications +{ + public static class NotificationTypeExtentions + { + public static T? ToNotification(this NotificationType type) where T:NotificationTemplateComponent + { + NotificationTemplateComponent? notificationTemplate=null; + switch (type) + { + case NotificationType.PasswordChange: + notificationTemplate = new PasswordChangedEmailMessage(); + break; + } + if(notificationTemplate != null) + { + return (T?)notificationTemplate; + } + return default(T); + } + } +} diff --git a/BLAZAMNotifications/Notifications/NotificationTypes.cs b/BLAZAMNotifications/Notifications/NotificationTypes.cs deleted file mode 100644 index 04856261..00000000 --- a/BLAZAMNotifications/Notifications/NotificationTypes.cs +++ /dev/null @@ -1,16 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BLAZAM.Notifications -{ - public class NotificationTypes - { - public NotificationTemplateComponent - - public PasswordChangedEmailMessage PasswordChange => new PasswordChangedEmailMessage(); - } -} diff --git a/BLAZAMServices/UserSeederService.cs b/BLAZAMServices/UserSeederService.cs index f06a342a..efb7f199 100644 --- a/BLAZAMServices/UserSeederService.cs +++ b/BLAZAMServices/UserSeederService.cs @@ -22,13 +22,16 @@ public UserSeederService(IAppDatabaseFactory dbFactory, _applicationInfo = applicationInfo; _activeDirectoryContext = adFactory.CreateActiveDirectoryContext(); _dbFactory = dbFactory; - + //TODO Move ProgramEvents to Common //ProgramEvents.PermissionsChanged += SeedUsers; - SeedUsers(); + Task.Delay(30000).ContinueWith(task => { + SeedUsers(); + }); + //SeedUsers(); } - private void SeedUsers() + private void SeedUsers(object obj=null) { try { @@ -37,7 +40,7 @@ private void SeedUsers() EnsureDemoExists(); using var context = _dbFactory.CreateDbContext(); if (context.Status != ServiceConnectionState.Up) return; - foreach (var deleg in context.PermissionDelegate.ToList()) + foreach (var deleg in context.PermissionDelegate.Where(x=>x.DeletedAt==null).ToList()) { var entry = _activeDirectoryContext.FindEntryBySID(deleg.DelegateSid); if (entry != null) diff --git a/BLAZAMSession/ApplicationUserState.cs b/BLAZAMSession/ApplicationUserState.cs index 133a2c55..bc7eb9c8 100644 --- a/BLAZAMSession/ApplicationUserState.cs +++ b/BLAZAMSession/ApplicationUserState.cs @@ -2,6 +2,7 @@ using BLAZAM.Common.Data.Services; using BLAZAM.Database.Context; using BLAZAM.Database.Models.Chat; +using BLAZAM.Database.Models.Notifications; using BLAZAM.Database.Models.Permissions; using BLAZAM.Database.Models.User; using BLAZAM.Helpers; @@ -337,6 +338,7 @@ public bool HasRole(string userRole) public bool CanUnlockUsers => HasObjectActionPermission(ActiveDirectoryObjectType.User,ObjectActions.Unlock); public string DuoAuthState { get; set; } = ""; + public List NotificationSubscriptions { get => userSettings?.NotificationSubscriptions; set { userSettings.NotificationSubscriptions=value; } } private bool HasObjectActionPermission(ActiveDirectoryObjectType objectType, ObjectAction actionType) { diff --git a/BLAZAMSession/Interfaces/IApplicationUserState.cs b/BLAZAMSession/Interfaces/IApplicationUserState.cs index 01290ccb..37c78007 100644 --- a/BLAZAMSession/Interfaces/IApplicationUserState.cs +++ b/BLAZAMSession/Interfaces/IApplicationUserState.cs @@ -1,6 +1,7 @@  using BLAZAM.Common.Data; using BLAZAM.Database.Models.Chat; +using BLAZAM.Database.Models.Notifications; using BLAZAM.Database.Models.Permissions; using BLAZAM.Database.Models.User; using BLAZAM.Server.Data; @@ -69,6 +70,7 @@ public interface IApplicationUserState bool IsAuthenticated { get; } List PermissionDelegates { get; set; } List PermissionMappings { get; set; } + List NotificationSubscriptions { get; set; } bool HasUserPrivilege { get; } bool HasCreateUserPrivilege { get; } bool HasGroupPrivilege { get; } From 00a518f0f2b18cedb2e1732d39e112f8a196019e Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 8 Jul 2024 14:08:49 -0400 Subject: [PATCH 041/116] Improved subscription foundation --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMDatabase/Context/DatabaseContextBase.cs | 7 ++- ...ification_Subscriptions_MySql.Designer.cs} | 44 ++++++++++++++++-- ...4_Add_Notification_Subscriptions_MySql.cs} | 30 +++++++++++- .../MySqlDatabaseContextModelSnapshot.cs | 42 +++++++++++++++-- ...otification_Subscriptions_Sql.Designer.cs} | 46 +++++++++++++++++-- ...212_Add_Notification_Subscriptions_Sql.cs} | 29 +++++++++++- .../Sql/SqlDatabaseContextModelSnapshot.cs | 44 ++++++++++++++++-- ...fication_Subscriptions_Sqlite.Designer.cs} | 44 ++++++++++++++++-- ..._Add_Notification_Subscriptions_Sqlite.cs} | 29 +++++++++++- .../SqliteDatabaseContextModelSnapshot.cs | 42 +++++++++++++++-- .../Notifications/NotificationSubscription.cs | 3 +- .../Models/Notifications/NotificationType.cs | 2 +- .../SubscriptionNotificationType.cs | 15 ++++++ .../Notifications/NotificationSettings.razor | 25 +++++++--- BLAZAMSession/ApplicationUserState.cs | 2 +- 16 files changed, 364 insertions(+), 42 deletions(-) rename BLAZAMDatabase/Migrations/MySql/{20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs => 20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs} (97%) rename BLAZAMDatabase/Migrations/MySql/{20240707194916_Add_Notification_Subscriptions_MySql.cs => 20240708180234_Add_Notification_Subscriptions_MySql.cs} (59%) rename BLAZAMDatabase/Migrations/Sql/{20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs => 20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs} (97%) rename BLAZAMDatabase/Migrations/Sql/{20240707194854_Add_Notification_Subscriptions_Sql.cs => 20240708180212_Add_Notification_Subscriptions_Sql.cs} (58%) rename BLAZAMDatabase/Migrations/Sqlite/{20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs => 20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs} (97%) rename BLAZAMDatabase/Migrations/Sqlite/{20240707194830_Add_Notification_Subscriptions_Sqlite.cs => 20240708180150_Add_Notification_Subscriptions_Sqlite.cs} (58%) create mode 100644 BLAZAMDatabase/Models/Notifications/SubscriptionNotificationType.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 9299863b..80fff49a 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.07.07.2231 + 2024.07.08.1806 false BLAZAM False diff --git a/BLAZAMDatabase/Context/DatabaseContextBase.cs b/BLAZAMDatabase/Context/DatabaseContextBase.cs index fd92bff2..d4323bb1 100644 --- a/BLAZAMDatabase/Context/DatabaseContextBase.cs +++ b/BLAZAMDatabase/Context/DatabaseContextBase.cs @@ -612,7 +612,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Navigation(e => e.ReadNewsItems).AutoInclude(); entity.Navigation(e => e.FavoriteEntries).AutoInclude(); entity.Navigation(e => e.DashboardWidgets).AutoInclude(); - entity.Navigation(e => e.NotificationSubscriptions).AutoInclude(); + // entity.Navigation(e => e.NotificationSubscriptions).AutoInclude(); //entity.Navigation(e => e.UnreadChatMessages).AutoInclude(); @@ -641,7 +641,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Navigation(e => e.User).AutoInclude(); }); + modelBuilder.Entity(entity => + { + + entity.Navigation(e => e.NotificationTypes).AutoInclude(); + }); modelBuilder.Entity(entity => { entity.Navigation(e => e.ChatMessage).AutoInclude(); diff --git a/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs b/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs similarity index 97% rename from BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs rename to BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs index 6834a2da..45be6132 100644 --- a/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.Designer.cs +++ b/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs @@ -11,7 +11,7 @@ namespace BLAZAM.Database.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] - [Migration("20240707194916_Add_Notification_Subscriptions_MySql")] + [Migration("20240708180234_Add_Notification_Subscriptions_MySql")] partial class Add_Notification_Subscriptions_MySql { /// @@ -912,9 +912,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Block") .HasColumnType("tinyint(1)"); - b.Property("NotificationType") - .HasColumnType("int"); - b.Property("OU") .IsRequired() .HasColumnType("longtext"); @@ -929,6 +926,25 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("NotificationSubscriptions"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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") @@ -1628,7 +1644,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") - .WithMany() + .WithMany("NotificationSubscriptions") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1636,6 +1652,17 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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) @@ -1816,6 +1843,11 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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"); @@ -1841,6 +1873,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("Messages"); + b.Navigation("NotificationSubscriptions"); + b.Navigation("ReadNewsItems"); }); diff --git a/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs b/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.cs similarity index 59% rename from BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs rename to BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.cs index 44e3667c..5af12213 100644 --- a/BLAZAMDatabase/Migrations/MySql/20240707194916_Add_Notification_Subscriptions_MySql.cs +++ b/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.cs @@ -18,7 +18,6 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(type: "int", nullable: false) .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), UserId = table.Column(type: "int", nullable: false), - NotificationType = table.Column(type: "int", nullable: false), OU = table.Column(type: "longtext", nullable: false) .Annotation("MySql:CharSet", "utf8mb4"), Block = table.Column(type: "tinyint(1)", nullable: false) @@ -35,15 +34,44 @@ protected override void Up(MigrationBuilder migrationBuilder) }) .Annotation("MySql:CharSet", "utf8mb4"); + migrationBuilder.CreateTable( + name: "SubscriptionNotificationType", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + NotificationSubscriptionId = table.Column(type: "int", nullable: false), + NotificationType = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SubscriptionNotificationType", x => x.Id); + table.ForeignKey( + name: "FK_SubscriptionNotificationType_NotificationSubscriptions_Notif~", + column: x => x.NotificationSubscriptionId, + principalTable: "NotificationSubscriptions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + migrationBuilder.CreateIndex( name: "IX_NotificationSubscriptions_UserId", table: "NotificationSubscriptions", column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_SubscriptionNotificationType_NotificationSubscriptionId", + table: "SubscriptionNotificationType", + column: "NotificationSubscriptionId"); } /// protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "SubscriptionNotificationType"); + migrationBuilder.DropTable( name: "NotificationSubscriptions"); } diff --git a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs index 7191045a..aadad661 100644 --- a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs @@ -909,9 +909,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Block") .HasColumnType("tinyint(1)"); - b.Property("NotificationType") - .HasColumnType("int"); - b.Property("OU") .IsRequired() .HasColumnType("longtext"); @@ -926,6 +923,25 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("NotificationSubscriptions"); }); + modelBuilder.Entity("BLAZAM.Database.Models.Notifications.SubscriptionNotificationType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + 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") @@ -1625,7 +1641,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") - .WithMany() + .WithMany("NotificationSubscriptions") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1633,6 +1649,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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) @@ -1813,6 +1840,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); @@ -1838,6 +1870,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Messages"); + b.Navigation("NotificationSubscriptions"); + b.Navigation("ReadNewsItems"); }); diff --git a/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs b/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs similarity index 97% rename from BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs rename to BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs index 1dea2966..67f3445e 100644 --- a/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.Designer.cs +++ b/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs @@ -12,7 +12,7 @@ namespace BLAZAM.Database.Migrations.Sql { [DbContext(typeof(SqlDatabaseContext))] - [Migration("20240707194854_Add_Notification_Subscriptions_Sql")] + [Migration("20240708180212_Add_Notification_Subscriptions_Sql")] partial class Add_Notification_Subscriptions_Sql { /// @@ -941,9 +941,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Block") .HasColumnType("bit"); - b.Property("NotificationType") - .HasColumnType("int"); - b.Property("OU") .IsRequired() .HasColumnType("nvarchar(max)"); @@ -958,6 +955,27 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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") @@ -1695,7 +1713,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") - .WithMany() + .WithMany("NotificationSubscriptions") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1703,6 +1721,17 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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) @@ -1883,6 +1912,11 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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"); @@ -1908,6 +1942,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("Messages"); + b.Navigation("NotificationSubscriptions"); + b.Navigation("ReadNewsItems"); }); diff --git a/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs b/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.cs similarity index 58% rename from BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs rename to BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.cs index 201a67f0..32638faf 100644 --- a/BLAZAMDatabase/Migrations/Sql/20240707194854_Add_Notification_Subscriptions_Sql.cs +++ b/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.cs @@ -17,7 +17,6 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), UserId = table.Column(type: "int", nullable: false), - NotificationType = table.Column(type: "int", nullable: false), OU = table.Column(type: "nvarchar(max)", nullable: false), Block = table.Column(type: "bit", nullable: false) }, @@ -32,15 +31,43 @@ protected override void Up(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "SubscriptionNotificationType", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + NotificationSubscriptionId = table.Column(type: "int", nullable: false), + NotificationType = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SubscriptionNotificationType", x => x.Id); + table.ForeignKey( + name: "FK_SubscriptionNotificationType_NotificationSubscriptions_NotificationSubscriptionId", + column: x => x.NotificationSubscriptionId, + principalTable: "NotificationSubscriptions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateIndex( name: "IX_NotificationSubscriptions_UserId", table: "NotificationSubscriptions", column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_SubscriptionNotificationType_NotificationSubscriptionId", + table: "SubscriptionNotificationType", + column: "NotificationSubscriptionId"); } /// protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "SubscriptionNotificationType"); + migrationBuilder.DropTable( name: "NotificationSubscriptions"); } diff --git a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs index 139f295c..70a13313 100644 --- a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs @@ -938,9 +938,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Block") .HasColumnType("bit"); - b.Property("NotificationType") - .HasColumnType("int"); - b.Property("OU") .IsRequired() .HasColumnType("nvarchar(max)"); @@ -955,6 +952,27 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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") @@ -1692,7 +1710,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") - .WithMany() + .WithMany("NotificationSubscriptions") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1700,6 +1718,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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) @@ -1880,6 +1909,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); @@ -1905,6 +1939,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Messages"); + b.Navigation("NotificationSubscriptions"); + b.Navigation("ReadNewsItems"); }); diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs b/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs similarity index 97% rename from BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs rename to BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs index 627aee7c..886ff784 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.Designer.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs @@ -11,7 +11,7 @@ namespace BLAZAM.Database.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] - [Migration("20240707194830_Add_Notification_Subscriptions_Sqlite")] + [Migration("20240708180150_Add_Notification_Subscriptions_Sqlite")] partial class Add_Notification_Subscriptions_Sqlite { /// @@ -907,9 +907,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Block") .HasColumnType("INTEGER"); - b.Property("NotificationType") - .HasColumnType("INTEGER"); - b.Property("OU") .IsRequired() .HasColumnType("TEXT"); @@ -924,6 +921,25 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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") @@ -1623,7 +1639,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") - .WithMany() + .WithMany("NotificationSubscriptions") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1631,6 +1647,17 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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) @@ -1811,6 +1838,11 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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"); @@ -1836,6 +1868,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("Messages"); + b.Navigation("NotificationSubscriptions"); + b.Navigation("ReadNewsItems"); }); diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs b/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.cs similarity index 58% rename from BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs rename to BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.cs index 5fefd60c..183e5939 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/20240707194830_Add_Notification_Subscriptions_Sqlite.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.cs @@ -17,7 +17,6 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(type: "INTEGER", nullable: false) .Annotation("Sqlite:Autoincrement", true), UserId = table.Column(type: "INTEGER", nullable: false), - NotificationType = table.Column(type: "INTEGER", nullable: false), OU = table.Column(type: "TEXT", nullable: false), Block = table.Column(type: "INTEGER", nullable: false) }, @@ -32,15 +31,43 @@ protected override void Up(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "SubscriptionNotificationType", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + NotificationSubscriptionId = table.Column(type: "INTEGER", nullable: false), + NotificationType = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SubscriptionNotificationType", x => x.Id); + table.ForeignKey( + name: "FK_SubscriptionNotificationType_NotificationSubscriptions_NotificationSubscriptionId", + column: x => x.NotificationSubscriptionId, + principalTable: "NotificationSubscriptions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateIndex( name: "IX_NotificationSubscriptions_UserId", table: "NotificationSubscriptions", column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_SubscriptionNotificationType_NotificationSubscriptionId", + table: "SubscriptionNotificationType", + column: "NotificationSubscriptionId"); } /// protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "SubscriptionNotificationType"); + migrationBuilder.DropTable( name: "NotificationSubscriptions"); } diff --git a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs index f5cdbd32..5dc93961 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs @@ -904,9 +904,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Block") .HasColumnType("INTEGER"); - b.Property("NotificationType") - .HasColumnType("INTEGER"); - b.Property("OU") .IsRequired() .HasColumnType("TEXT"); @@ -921,6 +918,25 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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") @@ -1620,7 +1636,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("BLAZAM.Database.Models.Notifications.NotificationSubscription", b => { b.HasOne("BLAZAM.Database.Models.User.AppUser", "User") - .WithMany() + .WithMany("NotificationSubscriptions") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -1628,6 +1644,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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) @@ -1808,6 +1835,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); @@ -1833,6 +1865,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Messages"); + b.Navigation("NotificationSubscriptions"); + b.Navigation("ReadNewsItems"); }); diff --git a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs index 1c4c7ad3..c6ebee7d 100644 --- a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs +++ b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs @@ -9,8 +9,9 @@ namespace BLAZAM.Database.Models.Notifications { public class NotificationSubscription:AppDbSetBase { + public int UserId { get; set; } public AppUser User { get; set; } - public NotificationType NotificationType { get; set; } + public List NotificationTypes { get; set; } = new(); public string OU { get; set; } public bool Block { get; set; } = false; } diff --git a/BLAZAMDatabase/Models/Notifications/NotificationType.cs b/BLAZAMDatabase/Models/Notifications/NotificationType.cs index e1266ac6..5c58a608 100644 --- a/BLAZAMDatabase/Models/Notifications/NotificationType.cs +++ b/BLAZAMDatabase/Models/Notifications/NotificationType.cs @@ -6,6 +6,6 @@ namespace BLAZAM.Database.Models.Notifications { - public enum NotificationType { PasswordChange } + public enum NotificationType { Create,Delete,Modify,GroupAssignment,PasswordChange } } diff --git a/BLAZAMDatabase/Models/Notifications/SubscriptionNotificationType.cs b/BLAZAMDatabase/Models/Notifications/SubscriptionNotificationType.cs new file mode 100644 index 00000000..134706ca --- /dev/null +++ b/BLAZAMDatabase/Models/Notifications/SubscriptionNotificationType.cs @@ -0,0 +1,15 @@ +using BLAZAM.Database.Models.User; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Database.Models.Notifications +{ + public class SubscriptionNotificationType : AppDbSetBase + { + public NotificationSubscription NotificationSubscription { get; set; } + public NotificationType NotificationType { get; set; } + } +} diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor index 9d068dd4..5b8ddca5 100644 --- a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -9,8 +9,12 @@ @if (_selectedOU != null) { - var subscription = _selectedUser.NotificationSubscriptions.Where(x => x.OU.Equals(_selectedOU.DN, StringComparison.InvariantCultureIgnoreCase)); - + var subscription = _selectedUser.NotificationSubscriptions.Where(x => x.OU.Equals(_selectedOU.DN, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); + if (subscription == null) + { + subscription = new(); + subscription.UserId = _selectedUser.Id; + } @@ -25,23 +29,30 @@ @originalEnum.ToString() } + + @AppLocalization["Block"] + - @foreach (var sub in subscription) - { @foreach (var type in Enum.GetValues(typeof(NotificationType))) { var originalEnum = (NotificationType)type; - - + @{ + + } + } + + + + - } + } diff --git a/BLAZAMSession/ApplicationUserState.cs b/BLAZAMSession/ApplicationUserState.cs index bc7eb9c8..1cb17ea5 100644 --- a/BLAZAMSession/ApplicationUserState.cs +++ b/BLAZAMSession/ApplicationUserState.cs @@ -147,7 +147,7 @@ private void GetUserSettingFromDB() if (User == null) return; using var context = _dbFactory.CreateDbContext(); - userSettings = context.UserSettings.Where(us => us.UserGUID == User.FindFirstValue(ClaimTypes.Sid)).FirstOrDefault(); + userSettings = context.UserSettings.Include(x=>x.NotificationSubscriptions).Where(us => us.UserGUID == User.FindFirstValue(ClaimTypes.Sid)).FirstOrDefault(); if (userSettings == null) { userSettings = new AppUser(); From 57adb0bc141860f5b29dbc8cf1d5c7dc213bdeab Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 9 Jul 2024 19:51:49 -0400 Subject: [PATCH 042/116] Need to add noification types --- BLAZAM/BLAZAM.csproj | 2 +- .../Notifications/NotificationSettings.razor | 99 +++++++++++++++---- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 80fff49a..838825bf 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.07.08.1806 + 2024.07.09.2316 false BLAZAM False diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor index 5b8ddca5..92953c12 100644 --- a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -5,16 +5,14 @@ { - + @if (_selectedOU != null) { - var subscription = _selectedUser.NotificationSubscriptions.Where(x => x.OU.Equals(_selectedOU.DN, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); - if (subscription == null) - { - subscription = new(); - subscription.UserId = _selectedUser.Id; - } + var subscriptions = Context.NotificationSubscriptions.Include(x=>x.NotificationTypes).Where(x =>x.UserId==_selectedUser.Id && x.OU.Equals(_selectedOU.DN)).ToList(); + + newSubscription.UserId = _selectedUser.Id; + newSubscription.OU = _selectedOU.DN; @@ -32,27 +30,63 @@ @AppLocalization["Block"] + + @AppLocalization["Save"] + + @if (subscriptions != null && subscriptions.Count > 0) + { + foreach (var sub in subscriptions) + { + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @{ + + } + - - @foreach (var type in Enum.GetValues(typeof(NotificationType))) - { - var originalEnum = (NotificationType)type; - - @{ - - } - + + } + + - } + + + + + } + } + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; - + @{ + + } + + - - + } + + + + + + + + + + } @@ -64,6 +98,7 @@ IDirectoryEntryAdapter? _selectedOU = null; IList Users = new List(); AppUser? _selectedUser = null; + NotificationSubscription newSubscription = new(); protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -74,4 +109,28 @@ if (value == null) value = String.Empty; return Users.Where(x => x.Username.Contains(value)); } + private async void ouChanged(IDirectoryEntryAdapter entry) + { + var ou = (IADOrganizationalUnit)entry; + if(ou!=null) + { + _selectedOU = ou; + InvokeAsync(StateHasChanged); + } + } + private async void AddSubscription() + { + await Context.NotificationSubscriptions.AddAsync(newSubscription); + var changes = await Context.SaveChangesAsync(); + if (changes > 0) + { + newSubscription = new(); + SnackBarService.Success(AppLocalization["Saved notification subscription"]); + } + else + { + SnackBarService.Warning(AppLocalization["Unable to save notification subscription"]); + + } + } } From f42456e9636b1909f3f880b0124d662e676216de Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 16 Jul 2024 21:14:33 -0400 Subject: [PATCH 043/116] Notification subscription walls built --- BLAZAM/BLAZAM.csproj | 7 +- BLAZAM/Pages/Configure/Notifications.razor | 42 --- ...ification_Subscriptions_MySql.Designer.cs} | 11 +- ...9_Add_Notification_Subscriptions_MySql.cs} | 8 +- .../MySqlDatabaseContextModelSnapshot.cs | 9 + ...otification_Subscriptions_Sql.Designer.cs} | 11 +- ...436_Add_Notification_Subscriptions_Sql.cs} | 8 +- .../Sql/SqlDatabaseContextModelSnapshot.cs | 9 + ...fication_Subscriptions_Sqlite.Designer.cs} | 11 +- ..._Add_Notification_Subscriptions_Sqlite.cs} | 8 +- .../SqliteDatabaseContextModelSnapshot.cs | 9 + .../Notifications/NotificationSubscription.cs | 4 +- .../UI/Outputs/ApplicationNewsProvider.razor | 50 ++- .../EditNotificationSubscriptionRow.razor | 95 +++++ .../Notifications/NotificationSettings.razor | 114 +----- .../OUNotificationSubscriptions.razor | 328 ++++++++++++++++++ .../Notifications/NotificationService.cs | 27 ++ 17 files changed, 592 insertions(+), 159 deletions(-) rename BLAZAMDatabase/Migrations/MySql/{20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs => 20240716000529_Add_Notification_Subscriptions_MySql.Designer.cs} (99%) rename BLAZAMDatabase/Migrations/MySql/{20240708180234_Add_Notification_Subscriptions_MySql.cs => 20240716000529_Add_Notification_Subscriptions_MySql.cs} (90%) rename BLAZAMDatabase/Migrations/Sql/{20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs => 20240716000436_Add_Notification_Subscriptions_Sql.Designer.cs} (99%) rename BLAZAMDatabase/Migrations/Sql/{20240708180212_Add_Notification_Subscriptions_Sql.cs => 20240716000436_Add_Notification_Subscriptions_Sql.cs} (90%) rename BLAZAMDatabase/Migrations/Sqlite/{20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs => 20240716000342_Add_Notification_Subscriptions_Sqlite.Designer.cs} (99%) rename BLAZAMDatabase/Migrations/Sqlite/{20240708180150_Add_Notification_Subscriptions_Sqlite.cs => 20240716000342_Add_Notification_Subscriptions_Sqlite.cs} (90%) create mode 100644 BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor create mode 100644 BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor create mode 100644 BLAZAMServices/Notifications/NotificationService.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 838825bf..a5ee70d0 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.3 - 2024.07.09.2316 + 2024.07.17.0112 false BLAZAM False @@ -115,6 +115,11 @@ + + + + + True diff --git a/BLAZAM/Pages/Configure/Notifications.razor b/BLAZAM/Pages/Configure/Notifications.razor index 87b1a86a..817c99fc 100644 --- a/BLAZAM/Pages/Configure/Notifications.razor +++ b/BLAZAM/Pages/Configure/Notifications.razor @@ -13,52 +13,10 @@ - - - - - - - @AppLocalization["Templates"] - - - - - - - - - - - - @AppLocalization["Access Levels"] - - - - - - - @if (Monitor.DirectoryConnectionStatus == ServiceConnectionState.Up) - { - - - - } - - - - - @AppLocalization["Mappings"] - - - - - - diff --git a/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs b/BLAZAMDatabase/Migrations/MySql/20240716000529_Add_Notification_Subscriptions_MySql.Designer.cs similarity index 99% rename from BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs rename to BLAZAMDatabase/Migrations/MySql/20240716000529_Add_Notification_Subscriptions_MySql.Designer.cs index 45be6132..257fecfe 100644 --- a/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.Designer.cs +++ b/BLAZAMDatabase/Migrations/MySql/20240716000529_Add_Notification_Subscriptions_MySql.Designer.cs @@ -11,7 +11,7 @@ namespace BLAZAM.Database.Migrations.MySql { [DbContext(typeof(MySqlDatabaseContext))] - [Migration("20240708180234_Add_Notification_Subscriptions_MySql")] + [Migration("20240716000529_Add_Notification_Subscriptions_MySql")] partial class Add_Notification_Subscriptions_MySql { /// @@ -912,6 +912,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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"); diff --git a/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.cs b/BLAZAMDatabase/Migrations/MySql/20240716000529_Add_Notification_Subscriptions_MySql.cs similarity index 90% rename from BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.cs rename to BLAZAMDatabase/Migrations/MySql/20240716000529_Add_Notification_Subscriptions_MySql.cs index 5af12213..cf14c6f1 100644 --- a/BLAZAMDatabase/Migrations/MySql/20240708180234_Add_Notification_Subscriptions_MySql.cs +++ b/BLAZAMDatabase/Migrations/MySql/20240716000529_Add_Notification_Subscriptions_MySql.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore.Metadata; +using System; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -20,7 +21,10 @@ protected override void Up(MigrationBuilder migrationBuilder) UserId = table.Column(type: "int", nullable: false), OU = table.Column(type: "longtext", nullable: false) .Annotation("MySql:CharSet", "utf8mb4"), - Block = table.Column(type: "tinyint(1)", nullable: false) + InApp = table.Column(type: "tinyint(1)", nullable: false), + ByEmail = table.Column(type: "tinyint(1)", nullable: false), + Block = table.Column(type: "tinyint(1)", nullable: false), + DeletedAt = table.Column(type: "datetime(6)", nullable: true) }, constraints: table => { diff --git a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs index aadad661..4233ea5f 100644 --- a/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/MySql/MySqlDatabaseContextModelSnapshot.cs @@ -909,6 +909,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); diff --git a/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs b/BLAZAMDatabase/Migrations/Sql/20240716000436_Add_Notification_Subscriptions_Sql.Designer.cs similarity index 99% rename from BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs rename to BLAZAMDatabase/Migrations/Sql/20240716000436_Add_Notification_Subscriptions_Sql.Designer.cs index 67f3445e..d4d77318 100644 --- a/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.Designer.cs +++ b/BLAZAMDatabase/Migrations/Sql/20240716000436_Add_Notification_Subscriptions_Sql.Designer.cs @@ -12,7 +12,7 @@ namespace BLAZAM.Database.Migrations.Sql { [DbContext(typeof(SqlDatabaseContext))] - [Migration("20240708180212_Add_Notification_Subscriptions_Sql")] + [Migration("20240716000436_Add_Notification_Subscriptions_Sql")] partial class Add_Notification_Subscriptions_Sql { /// @@ -941,6 +941,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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)"); diff --git a/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.cs b/BLAZAMDatabase/Migrations/Sql/20240716000436_Add_Notification_Subscriptions_Sql.cs similarity index 90% rename from BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.cs rename to BLAZAMDatabase/Migrations/Sql/20240716000436_Add_Notification_Subscriptions_Sql.cs index 32638faf..c3dd30e5 100644 --- a/BLAZAMDatabase/Migrations/Sql/20240708180212_Add_Notification_Subscriptions_Sql.cs +++ b/BLAZAMDatabase/Migrations/Sql/20240716000436_Add_Notification_Subscriptions_Sql.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using System; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -18,7 +19,10 @@ protected override void Up(MigrationBuilder migrationBuilder) .Annotation("SqlServer:Identity", "1, 1"), UserId = table.Column(type: "int", nullable: false), OU = table.Column(type: "nvarchar(max)", nullable: false), - Block = table.Column(type: "bit", nullable: false) + InApp = table.Column(type: "bit", nullable: false), + ByEmail = table.Column(type: "bit", nullable: false), + Block = table.Column(type: "bit", nullable: false), + DeletedAt = table.Column(type: "datetime2", nullable: true) }, constraints: table => { diff --git a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs index 70a13313..bad44e4d 100644 --- a/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sql/SqlDatabaseContextModelSnapshot.cs @@ -938,6 +938,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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)"); diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs b/BLAZAMDatabase/Migrations/Sqlite/20240716000342_Add_Notification_Subscriptions_Sqlite.Designer.cs similarity index 99% rename from BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs rename to BLAZAMDatabase/Migrations/Sqlite/20240716000342_Add_Notification_Subscriptions_Sqlite.Designer.cs index 886ff784..0c8bd6ee 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.Designer.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/20240716000342_Add_Notification_Subscriptions_Sqlite.Designer.cs @@ -11,7 +11,7 @@ namespace BLAZAM.Database.Migrations.Sqlite { [DbContext(typeof(SqliteDatabaseContext))] - [Migration("20240708180150_Add_Notification_Subscriptions_Sqlite")] + [Migration("20240716000342_Add_Notification_Subscriptions_Sqlite")] partial class Add_Notification_Subscriptions_Sqlite { /// @@ -907,6 +907,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) 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"); diff --git a/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.cs b/BLAZAMDatabase/Migrations/Sqlite/20240716000342_Add_Notification_Subscriptions_Sqlite.cs similarity index 90% rename from BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.cs rename to BLAZAMDatabase/Migrations/Sqlite/20240716000342_Add_Notification_Subscriptions_Sqlite.cs index 183e5939..02847741 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/20240708180150_Add_Notification_Subscriptions_Sqlite.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/20240716000342_Add_Notification_Subscriptions_Sqlite.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore.Migrations; +using System; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -18,7 +19,10 @@ protected override void Up(MigrationBuilder migrationBuilder) .Annotation("Sqlite:Autoincrement", true), UserId = table.Column(type: "INTEGER", nullable: false), OU = table.Column(type: "TEXT", nullable: false), - Block = table.Column(type: "INTEGER", nullable: false) + InApp = table.Column(type: "INTEGER", nullable: false), + ByEmail = table.Column(type: "INTEGER", nullable: false), + Block = table.Column(type: "INTEGER", nullable: false), + DeletedAt = table.Column(type: "TEXT", nullable: true) }, constraints: table => { diff --git a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs index 5dc93961..393f84de 100644 --- a/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs +++ b/BLAZAMDatabase/Migrations/Sqlite/SqliteDatabaseContextModelSnapshot.cs @@ -904,6 +904,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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"); diff --git a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs index c6ebee7d..4def18ee 100644 --- a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs +++ b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs @@ -7,12 +7,14 @@ namespace BLAZAM.Database.Models.Notifications { - public class NotificationSubscription:AppDbSetBase + public class NotificationSubscription:RecoverableAppDbSetBase { public int UserId { get; set; } public AppUser User { get; set; } public List NotificationTypes { get; set; } = new(); public string OU { get; set; } + public bool InApp { get; set; } + public bool ByEmail { get; set; } public bool Block { get; set; } = false; } } diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor index 7ac33716..216fa95c 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor @@ -3,7 +3,7 @@ @inherits AppComponentBase @if (readItems.Count > 0 || unreadItems.Count > 0) { - + @{ var icon = Icons.Material.Filled.Notifications; @@ -23,10 +23,7 @@ - @if (readItems.Count > 0) - { - - } + @foreach (var item in unreadItems.OrderByDescending(x => x.UpdatedAt)) { @@ -67,6 +64,14 @@ @AppLocalization["There is nothing new to see here"] } } + @if (readItems.Count > 0) + { + + + @AppLocalization["Mark all read"] + + + } @@ -75,6 +80,7 @@ private bool showRead; private List unreadItems = new(); private List readItems = new(); + private MudMenu? newsMenu; private ApplicationUpdate? latestUpdate; private NewsItem? appUpdateNewsItem { @@ -93,11 +99,41 @@ }; } } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { - base.OnInitialized(); + await base.OnInitializedAsync(); ApplicationNewsService.OnNewItemsAvailable += RefreshItems; RefreshItems(); + await InvokeAsync(StateHasChanged); + + + } + + protected override void OnAfterRender(bool firstRender) + { + base.OnAfterRender(firstRender); + + if (firstRender && unreadItems.Count > 0) + { + newsMenu?.OpenMenu(new()); + } + } + private async void MarkAllRead() + { + foreach(var newsItem in unreadItems) + { + try{ + CurrentUser.State.ReadNewsItems.Add(new ReadNewsItem { NewsItemId = newsItem.Id, NewsItemUpdatedAt = newsItem.UpdatedAt, User = CurrentUser.State.Preferences }); + } + catch + { + + } + } + await CurrentUser.State.SaveUserSettings(); + RefreshItems(); + await InvokeAsync(StateHasChanged); + } private void RefreshItems() { diff --git a/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor b/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor new file mode 100644 index 00000000..4c12b319 --- /dev/null +++ b/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor @@ -0,0 +1,95 @@ + + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @{ + + } + {ToggleType(originalEnum,val);}) + Value="@(Subscription.NotificationTypes.FirstOrDefault(x=>x.NotificationType==originalEnum)!=null)" /> + + + + } + + + + + + + + + + + + + @if (Subscription.Id == 0) + { + + + + } + else + { + + + + + + + + } + + +@code { + [Parameter] + public IDatabaseContext Context { get; set; } + + [Parameter] + public NotificationSubscription Subscription { get; set; } + + [Parameter] + public EventCallback SubscriptionChanged { get; set; } + + [Parameter] + public EventCallback OnSaved { get; set; } + + [Parameter] + public EventCallback OnDeleted { get; set; } + + [Parameter] + public EventCallback OnAdded { get; set; } + + private async void ToggleType(NotificationType type, bool value) + { + if (!value) + { + Subscription.NotificationTypes.RemoveAll(x => x.NotificationType == type); + } + else + { + if (!Subscription.NotificationTypes.Any(x => x.NotificationType == type)) + { + SubscriptionNotificationType notificationType = new(); + notificationType.NotificationType = type; + Subscription.NotificationTypes.Add(notificationType); + } + } + } + private async void AddSubscription() + { + await Context.NotificationSubscriptions.AddAsync(Subscription); + OnAdded.InvokeAsync(); + + } + +} \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor index 92953c12..9e4b1a39 100644 --- a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -1,94 +1,23 @@ @inherits AppComponentBase -

NotificationSettings

- +

@AppLocalization["Managee Notifications"]

+ @if (_selectedUser != null) { - + @if (_selectedOU != null) { - var subscriptions = Context.NotificationSubscriptions.Include(x=>x.NotificationTypes).Where(x =>x.UserId==_selectedUser.Id && x.OU.Equals(_selectedOU.DN)).ToList(); + - newSubscription.UserId = _selectedUser.Id; - newSubscription.OU = _selectedOU.DN; - - - - - - - @foreach (var type in Enum.GetValues(typeof(NotificationType))) - { - var originalEnum = (NotificationType)type; - - @originalEnum.ToString() - - } - - @AppLocalization["Block"] - - - @AppLocalization["Save"] - - - @if (subscriptions != null && subscriptions.Count > 0) - { - foreach (var sub in subscriptions) - { - - @foreach (var type in Enum.GetValues(typeof(NotificationType))) - { - var originalEnum = (NotificationType)type; - - @{ - - } - - - - - } - - - - - - - - - } - } - - @foreach (var type in Enum.GetValues(typeof(NotificationType))) - { - var originalEnum = (NotificationType)type; - - @{ - - } - - - - - } - - - - - - - - - - - - } @@ -98,7 +27,6 @@ IDirectoryEntryAdapter? _selectedOU = null; IList Users = new List(); AppUser? _selectedUser = null; - NotificationSubscription newSubscription = new(); protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -111,26 +39,14 @@ } private async void ouChanged(IDirectoryEntryAdapter entry) { - var ou = (IADOrganizationalUnit)entry; - if(ou!=null) + var ou = (IADOrganizationalUnit)entry; + if (ou != null) { _selectedOU = ou; - InvokeAsync(StateHasChanged); + await InvokeAsync(StateHasChanged); } } - private async void AddSubscription() - { - await Context.NotificationSubscriptions.AddAsync(newSubscription); - var changes = await Context.SaveChangesAsync(); - if (changes > 0) - { - newSubscription = new(); - SnackBarService.Success(AppLocalization["Saved notification subscription"]); - } - else - { - SnackBarService.Warning(AppLocalization["Unable to save notification subscription"]); - } - } + + } diff --git a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor new file mode 100644 index 00000000..8cfe740f --- /dev/null +++ b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor @@ -0,0 +1,328 @@ +@inherits AppComponentBase + + + + + + + + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @originalEnum.ToString() + + } + + @AppLocalization["In App"] + + + @AppLocalization["To Email"] + + + @AppLocalization["Block"] + + + @AppLocalization["Save"] + + + @AppLocalization["Delete"] + + + @if (subscriptions != null && subscriptions.Count > 0) + { + foreach (var sub in subscriptions) + { + + + } + } + + + + + + + + + + + @AppLocalization["Effective Notification Settings"] + + + + + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @originalEnum.ToString() + + } + + @AppLocalization["In App"] + + + @AppLocalization["To Email"] + +   +   +   + + + + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @{ + + } + + + + + } + + + @{ + + } + + + + + + @{ + + } + + + + + + + + + + @foreach (var type in Enum.GetValues(typeof(NotificationType))) + { + var originalEnum = (NotificationType)type; + + @{ + + } + + + + + } + + + @{ + + } + + + + + + @{ + + } + + + + + + + + +@code +{ + private IDirectoryEntryAdapter? _ou = null; + [Parameter] + public IDirectoryEntryAdapter? OU + { + get => _ou; set + { + if (_ou?.Equals(value) == true) return; + _ou = value; + ouChanged(_ou); + } + } + + [Parameter] + public AppUser User { get; set; } + + + NotificationSubscription newSubscription = new(); + NotificationSubscription effectiveInAppSubscription = new(); + NotificationSubscription effectiveByEmailSubscription = new(); + List subscriptions = new(); + + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + UpdateSubscriptions(); + } + + private async void ouChanged(IDirectoryEntryAdapter entry) + { + var ou = (IADOrganizationalUnit)entry; + if (ou != null) + { + if (User != null) + { + newSubscription.UserId = User.Id; + newSubscription.OU = ou.DN; + if (Context != null) + UpdateSubscriptions(); + } + + } + } + + private void CalculateEffectiveSubscriptions() + { + effectiveInAppSubscription = new(); + effectiveInAppSubscription.OU = OU.DN; + effectiveInAppSubscription.User = User; + effectiveInAppSubscription.InApp = true; + effectiveByEmailSubscription = new(); + effectiveByEmailSubscription.OU = OU.DN; + effectiveByEmailSubscription.User = User; + effectiveByEmailSubscription.ByEmail = true; + var userSubscriptions = Context.NotificationSubscriptions.Where(x => x.DeletedAt == null && x.UserId == User.Id).ToList(); + userSubscriptions = userSubscriptions.OrderBy(x => x.OU).ToList(); + foreach (var sub in userSubscriptions) + { + if (OU.DN.Contains(sub.OU)) + { + if (sub.Block) + { + if (sub.InApp) + { + foreach (var type in sub.NotificationTypes) + { + effectiveInAppSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); + } + } + if (sub.ByEmail) + { + foreach (var type in sub.NotificationTypes) + { + effectiveByEmailSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); + } + } + } + else + { + if (sub.InApp) + { + foreach (var type in sub.NotificationTypes) + { + if (!effectiveInAppSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) + { + effectiveInAppSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); + } + } + } + if (sub.ByEmail) + { + + foreach (var type in sub.NotificationTypes) + { + if (!effectiveByEmailSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) + { + effectiveByEmailSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); + } + } + } + + + } + } + } + } + private async void AddSubscription() + { + + var changes = await Context.SaveChangesAsync(); + if (changes > 0) + { + newSubscription = new(); + SnackBarService.Success(AppLocalization["Saved notification subscription"]); + UpdateSubscriptions(); + + + } + else + { + SnackBarService.Warning(AppLocalization["Unable to save notification subscription"]); + + } + + } + + private async void SaveExisting() + { + var result = await Context.SaveChangesAsync(); + if (result > 0) + { + SnackBarService.Success("Subscription saved."); + UpdateSubscriptions(); + } + else + { + SnackBarService.Warning("Subscription could not be saved."); + + } + } + private async void DeleteExisting(NotificationSubscription subscription) + { + subscription.DeletedAt = DateTime.UtcNow; + var result = await Context.SaveChangesAsync(); + if (result > 0) + { + SnackBarService.Success("Subscription deleted."); + } + else + { + SnackBarService.Warning("Subscription could not be deleted."); + + } + UpdateSubscriptions(); + + + } + private async void UpdateSubscriptions() + { + subscriptions = Context.NotificationSubscriptions.Include(x => x.NotificationTypes).Where(x => x.DeletedAt == null && x.UserId == User.Id && x.OU.Equals(OU.DN)).ToList(); + + + CalculateEffectiveSubscriptions(); + await InvokeAsync(StateHasChanged); + } + +} \ No newline at end of file diff --git a/BLAZAMServices/Notifications/NotificationService.cs b/BLAZAMServices/Notifications/NotificationService.cs new file mode 100644 index 00000000..fa601df5 --- /dev/null +++ b/BLAZAMServices/Notifications/NotificationService.cs @@ -0,0 +1,27 @@ +using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.Database.Context; +using BLAZAM.Database.Models.Notifications; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Services.Notifications +{ + public class NotificationService + { + private AppDatabaseFactory _databaseFactory; + + public NotificationService(AppDatabaseFactory databaseFactory) + { + _databaseFactory = databaseFactory; + } + + public void Post(IDirectoryEntryAdapter source, NotificationType notificationType) + { + + } + + } +} From c5853c1f5159e40f202e8098c1dba1babeb21be6 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 21 Jul 2024 14:23:33 -0400 Subject: [PATCH 044/116] Functional In-App notifications --- BLAZAM/BLAZAM.csproj | 5 +- BLAZAM/Pages/Users/ViewUser.razor | 3 +- BLAZAM/ProgramHelpers.cs | 20 +- BLAZAM/_Imports.razor | 2 + .../Layouts/UserNotificationPopover.razor | 2 +- BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs | 2 + .../OUNotificationSubscriptions.razor | 65 +----- .../Background/OUNotificationService.cs | 190 ++++++++++++++++++ .../Notifications/NotificationService.cs | 27 --- 9 files changed, 222 insertions(+), 94 deletions(-) create mode 100644 BLAZAMServices/Background/OUNotificationService.cs delete mode 100644 BLAZAMServices/Notifications/NotificationService.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index a5ee70d0..c76dbdc9 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -5,8 +5,8 @@ enable enable false - 0.9.3 - 2024.07.17.0112 + 0.9.4 + 2024.07.21.1741 false BLAZAM False @@ -117,7 +117,6 @@ - diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index 4e178249..53acb824 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -469,7 +469,7 @@ @code { -#nullable disable warnings + #nullable disable warnings string password; [Parameter] @@ -553,6 +553,7 @@ await AuditLogger.User.Changed(User, changes); + _ = OUNotificationService.PostAsync(User, NotificationType.Modify); EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this user have been saved."); diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs index 155598cd..384bdc39 100644 --- a/BLAZAM/ProgramHelpers.cs +++ b/BLAZAM/ProgramHelpers.cs @@ -313,6 +313,7 @@ completed so it may not be usable as is builder.Services.AddScoped(); + builder.Services.AddSingleton(); builder.Host.UseWindowsService(); @@ -332,6 +333,22 @@ public static void PreRun(this WebApplication application) } + } + catch (Exception ex) + { + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + PreloadServices(); + + } + + private static void PreloadServices() + { + try + { + var context = Program.AppInstance.Services.GetRequiredService(); + + } catch (Exception ex) { @@ -340,7 +357,7 @@ public static void PreRun(this WebApplication application) try { var context = Program.AppInstance.Services.GetRequiredService(); - + } catch (Exception ex) @@ -349,6 +366,5 @@ public static void PreRun(this WebApplication application) } } - } } diff --git a/BLAZAM/_Imports.razor b/BLAZAM/_Imports.razor index 17a2a059..b367d5f8 100644 --- a/BLAZAM/_Imports.razor +++ b/BLAZAM/_Imports.razor @@ -101,6 +101,8 @@ @using BLAZAM.Database; @using BLAZAM.Database.Context; +@using BLAZAM.Database.Models.Notifications + @using BLAZAM.Database.Models; @using BLAZAM.Database.Models.Audit; @using BLAZAM.Database.Models.Permissions; diff --git a/BLAZAMGui/Layouts/UserNotificationPopover.razor b/BLAZAMGui/Layouts/UserNotificationPopover.razor index e48c0a01..9031b118 100644 --- a/BLAZAMGui/Layouts/UserNotificationPopover.razor +++ b/BLAZAMGui/Layouts/UserNotificationPopover.razor @@ -37,7 +37,7 @@ @notification.Notification.Title } - @notification.Notification.Message + @((MarkupString)notification.Notification.Message) } diff --git a/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs b/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs index ac881f2f..006c8c82 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs +++ b/BLAZAMGui/UI/DirectoryEntryViewBase.razor.cs @@ -11,6 +11,8 @@ namespace BLAZAM.Gui.UI ///
public class DirectoryEntryViewBase : AppComponentBase { + [Inject] + public OUNotificationService OUNotificationService { get; set; } [Parameter] public IDirectoryEntryAdapter DirectoryEntry { get; set; } diff --git a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor index 8cfe740f..1351b69f 100644 --- a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor +++ b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor @@ -1,5 +1,5 @@ @inherits AppComponentBase - +@inject OUNotificationService ouNotificationService @@ -205,65 +205,10 @@ private void CalculateEffectiveSubscriptions() { - effectiveInAppSubscription = new(); - effectiveInAppSubscription.OU = OU.DN; - effectiveInAppSubscription.User = User; - effectiveInAppSubscription.InApp = true; - effectiveByEmailSubscription = new(); - effectiveByEmailSubscription.OU = OU.DN; - effectiveByEmailSubscription.User = User; - effectiveByEmailSubscription.ByEmail = true; - var userSubscriptions = Context.NotificationSubscriptions.Where(x => x.DeletedAt == null && x.UserId == User.Id).ToList(); - userSubscriptions = userSubscriptions.OrderBy(x => x.OU).ToList(); - foreach (var sub in userSubscriptions) - { - if (OU.DN.Contains(sub.OU)) - { - if (sub.Block) - { - if (sub.InApp) - { - foreach (var type in sub.NotificationTypes) - { - effectiveInAppSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); - } - } - if (sub.ByEmail) - { - foreach (var type in sub.NotificationTypes) - { - effectiveByEmailSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); - } - } - } - else - { - if (sub.InApp) - { - foreach (var type in sub.NotificationTypes) - { - if (!effectiveInAppSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) - { - effectiveInAppSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); - } - } - } - if (sub.ByEmail) - { - - foreach (var type in sub.NotificationTypes) - { - if (!effectiveByEmailSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) - { - effectiveByEmailSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); - } - } - } - - - } - } - } + effectiveInAppSubscription = ouNotificationService.CalculateEffectiveInAppSubscriptions(User, OU); + effectiveByEmailSubscription = ouNotificationService.CalculateEffectiveEmailSubscriptions(User, OU); + return; + } private async void AddSubscription() { diff --git a/BLAZAMServices/Background/OUNotificationService.cs b/BLAZAMServices/Background/OUNotificationService.cs new file mode 100644 index 00000000..b00d6818 --- /dev/null +++ b/BLAZAMServices/Background/OUNotificationService.cs @@ -0,0 +1,190 @@ +using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.Database.Context; +using BLAZAM.Database.Models.Notifications; +using BLAZAM.Database.Models.User; +using BLAZAM.Localization; +using BLAZAM.Notifications.Services; +using BLAZAM.Session.Interfaces; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.Extensions.Localization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Services.Background +{ + public class OUNotificationService + { + private IAppDatabaseFactory _databaseFactory; + private readonly INotificationPublisher _notificationPublisher; + private readonly IStringLocalizer _appLocalization; + + public OUNotificationService(IAppDatabaseFactory databaseFactory,INotificationPublisher notificationPublisher, IStringLocalizerappLocalization) + { + _databaseFactory = databaseFactory; + _notificationPublisher = notificationPublisher; + _appLocalization = appLocalization; + } + private IDatabaseContext Context => _databaseFactory.CreateDbContext(); + public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType notificationType) + { + await Task.Delay(150); + var context = Context; + string notificationTitle; + notificationTitle = _appLocalization[source.ObjectType.ToString()] + " "; + + string notificationBody; + notificationBody = "" + source.CanonicalName + " "; + + switch (notificationType) + { + case NotificationType.Create: + notificationTitle += _appLocalization["Created"]; + notificationBody += _appLocalization["was created at"] + source.Created.Value.ToLocalTime(); + + break; + case NotificationType.Delete: + notificationTitle += _appLocalization["Deleted"]; + notificationBody += _appLocalization["was deleted at"] + source.LastChanged.Value.ToLocalTime(); + + break; + case NotificationType.Modify: + notificationTitle += _appLocalization["Modified"]; + notificationBody += _appLocalization["was modified at"] + source.LastChanged.Value.ToLocalTime(); + + break; + case NotificationType.GroupAssignment: + notificationTitle += _appLocalization["Group Membership Changed"]; + notificationBody += _appLocalization["was modified at"] + source.LastChanged.Value.ToLocalTime(); + + break; + case NotificationType.PasswordChange: + notificationTitle += _appLocalization["Password Reset"]; + notificationBody += _appLocalization["had a password reset at"] + source.LastChanged.Value.ToLocalTime(); + + break; + + } + var notification = new NotificationMessage(); + notification.Title = notificationTitle; + notification.Message = notificationBody; + notification.Dismissable = true; + notification.Created = DateTime.Now; + notification.Level = NotificationLevel.Info; + + foreach (var user in Context.UserSettings.ToList()) + { + var effectiveInAppSubscriptions = CalculateEffectiveInAppSubscriptions(user, source); + var effectiveEmailSubscriptions = CalculateEffectiveEmailSubscriptions(user, source); + if (effectiveInAppSubscriptions.NotificationTypes.Any(x => x.NotificationType == notificationType)) + { + _notificationPublisher.PublishNotification(user, notification); + } + } + } + public NotificationSubscription CalculateEffectiveEmailSubscriptions(AppUser user, IDirectoryEntryAdapter ou) + { + if (ou is not IADOrganizationalUnit) + ou = ou.GetParent(); + if (ou is not IADOrganizationalUnit) + return default; + var context = Context; + NotificationSubscription effectiveByEmailSubscription = new(); + + effectiveByEmailSubscription = new(); + effectiveByEmailSubscription.OU = ou.DN; + effectiveByEmailSubscription.User = user; + effectiveByEmailSubscription.ByEmail = true; + var userSubscriptions = context.NotificationSubscriptions.Where(x => x.DeletedAt == null && x.UserId == user.Id).ToList(); + userSubscriptions = userSubscriptions.OrderBy(x => x.OU).ToList(); + foreach (var sub in userSubscriptions) + { + if (ou.DN.Contains(sub.OU)) + { + if (sub.Block) + { + + if (sub.ByEmail) + { + foreach (var type in sub.NotificationTypes) + { + effectiveByEmailSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); + } + } + } + else + { + + if (sub.ByEmail) + { + + foreach (var type in sub.NotificationTypes) + { + if (!effectiveByEmailSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) + { + effectiveByEmailSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); + } + } + } + + + } + } + } + return effectiveByEmailSubscription; + } + + public NotificationSubscription CalculateEffectiveInAppSubscriptions(AppUser user, IDirectoryEntryAdapter ou) + { + if (ou is not IADOrganizationalUnit) + ou = ou.GetParent(); + if (ou is not IADOrganizationalUnit) + return default; + var context = Context; + NotificationSubscription effectiveInAppSubscription = new(); + effectiveInAppSubscription = new(); + effectiveInAppSubscription.OU = ou.DN; + effectiveInAppSubscription.User = user; + effectiveInAppSubscription.InApp = true; + + var userSubscriptions = context.NotificationSubscriptions.Where(x => x.DeletedAt == null && x.UserId == user.Id).ToList(); + userSubscriptions = userSubscriptions.OrderBy(x => x.OU).ToList(); + foreach (var sub in userSubscriptions) + { + if (ou.DN.Contains(sub.OU)) + { + if (sub.Block) + { + if (sub.InApp) + { + foreach (var type in sub.NotificationTypes) + { + effectiveInAppSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); + } + } + + } + else + { + if (sub.InApp) + { + foreach (var type in sub.NotificationTypes) + { + if (!effectiveInAppSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) + { + effectiveInAppSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); + } + } + } + + + + } + } + } + return effectiveInAppSubscription; + } + } +} diff --git a/BLAZAMServices/Notifications/NotificationService.cs b/BLAZAMServices/Notifications/NotificationService.cs deleted file mode 100644 index fa601df5..00000000 --- a/BLAZAMServices/Notifications/NotificationService.cs +++ /dev/null @@ -1,27 +0,0 @@ -using BLAZAM.ActiveDirectory.Interfaces; -using BLAZAM.Database.Context; -using BLAZAM.Database.Models.Notifications; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BLAZAM.Services.Notifications -{ - public class NotificationService - { - private AppDatabaseFactory _databaseFactory; - - public NotificationService(AppDatabaseFactory databaseFactory) - { - _databaseFactory = databaseFactory; - } - - public void Post(IDirectoryEntryAdapter source, NotificationType notificationType) - { - - } - - } -} From 8004e516583e03d4329d7a7d48c87a3f18cae338 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 21 Jul 2024 16:28:03 -0400 Subject: [PATCH 045/116] Fill out notification triggers --- BLAZAM/Pages/Computers/ViewComputer.razor | 4 ++ BLAZAM/Pages/Groups/CreateGroup.razor | 3 ++ BLAZAM/Pages/Groups/ViewGroup.razor | 4 ++ BLAZAM/Pages/OU/CreateOU.razor | 4 ++ BLAZAM/Pages/OU/ViewOU.razor | 8 ++++ BLAZAM/Pages/Users/ConfirmNewUser.razor | 4 ++ BLAZAM/Pages/Users/ViewUser.razor | 6 ++- .../ChangeUserPasswordModalContent.razor | 3 ++ .../Background/OUNotificationService.cs | 37 +++++++++++-------- 9 files changed, 57 insertions(+), 16 deletions(-) diff --git a/BLAZAM/Pages/Computers/ViewComputer.razor b/BLAZAM/Pages/Computers/ViewComputer.razor index 66edb550..57493522 100644 --- a/BLAZAM/Pages/Computers/ViewComputer.razor +++ b/BLAZAM/Pages/Computers/ViewComputer.razor @@ -283,6 +283,8 @@ { Computer.Delete(); SnackBarService.Success(Computer.CanonicalName + " has been deleted."); + await AuditLogger.Computer.Deleted(Computer); + _ = OUNotificationService.PostAsync(Computer, NotificationType.Delete); Nav.NavigateTo("/users/search"); @@ -304,6 +306,8 @@ await AuditLogger.Computer.Changed(Computer, Computer.Changes); + _ = OUNotificationService.PostAsync(Computer, NotificationType.Modify); + EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this computer have been saved."); diff --git a/BLAZAM/Pages/Groups/CreateGroup.razor b/BLAZAM/Pages/Groups/CreateGroup.razor index d8f07fb8..245f7242 100644 --- a/BLAZAM/Pages/Groups/CreateGroup.razor +++ b/BLAZAM/Pages/Groups/CreateGroup.razor @@ -1,6 +1,7 @@ @page "/groups/create" @inherits TabbedAppComponentBase @attribute [Authorize] +@inject OUNotificationService OUNotificationService Create Group @@ -123,5 +124,7 @@ async Task GroupCreated(IADGroup ou) { await AuditLogger.Group.Created(ou); + _ = OUNotificationService.PostAsync(ou, NotificationType.Create); + } } diff --git a/BLAZAM/Pages/Groups/ViewGroup.razor b/BLAZAM/Pages/Groups/ViewGroup.razor index b4e09a18..882a4695 100644 --- a/BLAZAM/Pages/Groups/ViewGroup.razor +++ b/BLAZAM/Pages/Groups/ViewGroup.razor @@ -150,6 +150,8 @@ { await AuditLogger.Group.Changed(Group, Group.Changes); + _ = OUNotificationService.PostAsync(Group, NotificationType.Modify); + EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this group have been saved."); @@ -173,6 +175,8 @@ { Group.Delete(); SnackBarService.Success(Group.CanonicalName + " has been deleted."); + await AuditLogger.Group.Deleted(Group); + _ = OUNotificationService.PostAsync(Group, NotificationType.Delete); //Group = null; Nav.NavigateTo("/groups/search"); diff --git a/BLAZAM/Pages/OU/CreateOU.razor b/BLAZAM/Pages/OU/CreateOU.razor index 4c003f85..f560aac8 100644 --- a/BLAZAM/Pages/OU/CreateOU.razor +++ b/BLAZAM/Pages/OU/CreateOU.razor @@ -1,6 +1,8 @@ @page "/ou/create" @inherits TabbedAppComponentBase @attribute [Authorize] +@inject OUNotificationService OUNotificationService + Create OU @@ -119,5 +121,7 @@ async Task OUCreated(IADOrganizationalUnit ou) { await AuditLogger.OU.Created(ou); + _ = OUNotificationService.PostAsync(ou, NotificationType.Create); + } } diff --git a/BLAZAM/Pages/OU/ViewOU.razor b/BLAZAM/Pages/OU/ViewOU.razor index 523bc970..8c9c3587 100644 --- a/BLAZAM/Pages/OU/ViewOU.razor +++ b/BLAZAM/Pages/OU/ViewOU.razor @@ -1,4 +1,6 @@ @inherits DirectoryEntryViewBase +@inject OUNotificationService OUNotificationService + @OU?.CanonicalName @@ -87,9 +89,13 @@ { 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); + _ = OUNotificationService.PostAsync(OU, NotificationType.Modify); + SnackBarService.Success("The changes made to this ou have been saved."); await RefreshEntryComponents(); @@ -109,6 +115,8 @@ { OU.Delete(); SnackBarService.Success(OU.CanonicalName + " has been deleted."); + await AuditLogger.OU.Deleted(OU); + _ = OUNotificationService.PostAsync(OU, NotificationType.Delete); Nav.NavigateTo("/ou/search"); diff --git a/BLAZAM/Pages/Users/ConfirmNewUser.razor b/BLAZAM/Pages/Users/ConfirmNewUser.razor index 518a6e4c..bd179e9c 100644 --- a/BLAZAM/Pages/Users/ConfirmNewUser.razor +++ b/BLAZAM/Pages/Users/ConfirmNewUser.razor @@ -3,6 +3,9 @@ @using BLAZAM.EmailMessage.Email.Notifications @inherits DirectoryModelComponent @inject IJSRuntime JSRuntime +@inject OUNotificationService OUNotificationService + + Confirm User Creation @@ -229,6 +232,7 @@ else } await AuditLogger.User.Created(User); + _ = OUNotificationService.PostAsync(User, NotificationType.Create); try { diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index 53acb824..21741fc5 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -553,7 +553,8 @@ await AuditLogger.User.Changed(User, changes); - _ = OUNotificationService.PostAsync(User, NotificationType.Modify); + if((changes.Count==1 && changes.First().Field==ActiveDirectoryFields.MemberOf.FieldName)==false) + _ = OUNotificationService.PostAsync(User, NotificationType.Modify); EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this user have been saved."); @@ -597,8 +598,11 @@ try { User.Delete(); + SnackBarService.Success(User.DisplayName + " has been deleted."); await AuditLogger.User.Deleted(User); + _ = OUNotificationService.PostAsync(User, NotificationType.Delete); + } catch (ApplicationException ex) { diff --git a/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor b/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor index 9ec1b0ae..19cbfb68 100644 --- a/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor +++ b/BLAZAMGui/UI/Users/ChangeUserPasswordModalContent.razor @@ -1,4 +1,5 @@ @inherits AppModalContent +@inject OUNotificationService OUNotificationService @@ -59,6 +60,8 @@ } SnackBarService.Success("Changed password for " + User.DisplayName); await AuditLogger.User.PasswordChanged(User, requireChangeSwitch.Value); + _ = OUNotificationService.PostAsync(User, NotificationType.PasswordChange); + await InvokeAsync(Close); diff --git a/BLAZAMServices/Background/OUNotificationService.cs b/BLAZAMServices/Background/OUNotificationService.cs index b00d6818..ddedaf88 100644 --- a/BLAZAMServices/Background/OUNotificationService.cs +++ b/BLAZAMServices/Background/OUNotificationService.cs @@ -3,6 +3,7 @@ using BLAZAM.Database.Models.Notifications; using BLAZAM.Database.Models.User; using BLAZAM.Localization; +using BLAZAM.Logger; using BLAZAM.Notifications.Services; using BLAZAM.Session.Interfaces; using Microsoft.AspNetCore.Mvc.ModelBinding; @@ -101,36 +102,42 @@ public NotificationSubscription CalculateEffectiveEmailSubscriptions(AppUser use userSubscriptions = userSubscriptions.OrderBy(x => x.OU).ToList(); foreach (var sub in userSubscriptions) { - if (ou.DN.Contains(sub.OU)) + try { - if (sub.Block) + if (ou.DN.Contains(sub.OU)) { - - if (sub.ByEmail) + if (sub.Block) { - foreach (var type in sub.NotificationTypes) + + if (sub.ByEmail) { - effectiveByEmailSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); + foreach (var type in sub.NotificationTypes) + { + effectiveByEmailSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); + } } } - } - else - { - - if (sub.ByEmail) + else { - foreach (var type in sub.NotificationTypes) + if (sub.ByEmail) { - if (!effectiveByEmailSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) + + foreach (var type in sub.NotificationTypes) { - effectiveByEmailSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); + if (!effectiveByEmailSubscription.NotificationTypes.Any(x => x.NotificationType == type.NotificationType)) + { + effectiveByEmailSubscription.NotificationTypes.Add(new() { NotificationType = type.NotificationType }); + } } } - } + } } + }catch (Exception ex) + { + Loggers.SystemLogger.Error("Error while parsing users for notification broadcast {@Error}", ex); } } return effectiveByEmailSubscription; From e4b1ca94e95c2c10938279eaf5da2ad5088d6b47 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 21 Jul 2024 17:47:56 -0400 Subject: [PATCH 046/116] Job Monitor Addeed --- BLAZAM/BLAZAM.csproj | 3 +- BLAZAM/Pages/Home.razor | 16 ++++---- .../Adapters/DirectoryEntryAdapter.cs | 18 +++++---- .../UI/Outputs/ApplicationNewsProvider.razor | 24 ++++++++---- BLAZAMGui/UI/Settings/DatabaseStatus.razor | 38 +++++++++---------- BLAZAMGui/UI/Settings/JobsMonitor.razor | 25 ++++++++++++ BLAZAMGui/UI/Settings/SystemSettings.razor | 9 +++-- BLAZAMJobs/BLAZAMJobs.csproj | 1 + BLAZAMJobs/IJob.cs | 8 ++-- BLAZAMJobs/Job.cs | 28 ++++++++++++-- BLAZAMJobs/JobMonitor.cs | 31 +++++++++++++++ BLAZAMUpdate/ApplicationUpdate.cs | 14 +++---- 12 files changed, 154 insertions(+), 61 deletions(-) create mode 100644 BLAZAMGui/UI/Settings/JobsMonitor.razor create mode 100644 BLAZAMJobs/JobMonitor.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index c76dbdc9..11c7bbf9 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.21.1741 + 2024.07.21.2146 false BLAZAM False @@ -116,6 +116,7 @@
+ diff --git a/BLAZAM/Pages/Home.razor b/BLAZAM/Pages/Home.razor index 537f80b7..6938204e 100644 --- a/BLAZAM/Pages/Home.razor +++ b/BLAZAM/Pages/Home.razor @@ -49,7 +49,7 @@ { get { - IJob job = new Job("Test Job"); + IJob job = new Job("Test Job",requestingUser:CurrentUser.State.Username); IJob job2 = new Job("Nested Job"); IJobStep step1 = new JobStep("Regular Step Passes", (step) => { @@ -66,13 +66,13 @@ IJobStep step5 = new JobStep("Nested Step Fails", (step) => { Task.Delay(2000).Wait(); return false; }); IJobStep step6 = new JobStep("Nested Step Throws", bool(step) => { Task.Delay(2000).Wait(); throw new ApplicationException("Test exception"); }); - job.Steps.Add(step1); - job.Steps.Add(step2); - job.Steps.Add(step3); - job2.Steps.Add(step4); - job2.Steps.Add(step5); - job2.Steps.Add(step6); - job.Steps.Add((IJobStep)job2); + job.AddStep(step1); + job.AddStep(step2); + job.AddStep(step3); + job2.AddStep(step4); + job2.AddStep(step5); + job2.AddStep(step6); + job.AddStep((IJobStep)job2); return job; } } diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index 66d48649..ee27072e 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -789,10 +789,10 @@ public virtual IJob CommitChanges(IJob? commitJob = null) DirectoryEntry.CommitChanges(); return true; }); - commitJob.Steps.Add(propertyStep); + commitJob.AddStep(propertyStep); } - commitJob.Steps.Add(commitStep); + commitJob.AddStep(commitStep); } else @@ -814,7 +814,7 @@ public virtual IJob CommitChanges(IJob? commitJob = null) DirectoryEntry.Properties[p.Key].Value = p.Value; return true; }); - commitJob.Steps.Add(propertyStep); + commitJob.AddStep(propertyStep); } } @@ -822,7 +822,8 @@ public virtual IJob CommitChanges(IJob? commitJob = null) //Inject custom commit steps foreach (var step in CommitSteps) { - commitJob.Steps.Add(step); + commitJob.AddStep(step); + commitJob.AddStep(step); } @@ -832,22 +833,23 @@ public virtual IJob CommitChanges(IJob? commitJob = null) { foreach (var step in PostCommitSteps) { - commitJob.Steps.Add(step); + commitJob.AddStep(step); } //commitJob.Steps.Add(CommitStep); } } - commitJob.Steps.Add(commitStep); + commitJob.AddStep(commitStep); + commitJob.AddStep(commitStep); if (NewEntry) { if (PostCommitSteps.Count > 0) { foreach (var step in PostCommitSteps) { - commitJob.Steps.Add(step); + commitJob.AddStep(step); } - commitJob.Steps.Add(commitStep); + commitJob.AddStep(commitStep); } } diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor index 216fa95c..2e617b57 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor @@ -3,7 +3,11 @@ @inherits AppComponentBase @if (readItems.Count > 0 || unreadItems.Count > 0) { - + @{ var icon = Icons.Material.Filled.Notifications; @@ -15,7 +19,7 @@ color = Color.Warning; } - + @@ -23,10 +27,13 @@ - + @foreach (var item in unreadItems.OrderByDescending(x => x.UpdatedAt)) { - + @item.Title @@ -42,7 +49,7 @@ { foreach (var item in readItems.OrderByDescending(x => x.UpdatedAt)) { - + @@ -120,14 +127,15 @@ } private async void MarkAllRead() { - foreach(var newsItem in unreadItems) + foreach (var newsItem in unreadItems) { - try{ + try + { CurrentUser.State.ReadNewsItems.Add(new ReadNewsItem { NewsItemId = newsItem.Id, NewsItemUpdatedAt = newsItem.UpdatedAt, User = CurrentUser.State.Preferences }); } catch { - + } } await CurrentUser.State.SaveUserSettings(); diff --git a/BLAZAMGui/UI/Settings/DatabaseStatus.razor b/BLAZAMGui/UI/Settings/DatabaseStatus.razor index 58cbd7a7..cb19a013 100644 --- a/BLAZAMGui/UI/Settings/DatabaseStatus.razor +++ b/BLAZAMGui/UI/Settings/DatabaseStatus.razor @@ -54,7 +54,7 @@ @code { - #nullable disable warnings +#nullable disable warnings protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); @@ -66,30 +66,30 @@ } async void Export() { - - MemoryStream memoryStream = new MemoryStream(); - IJob exportJob = new Job(AppLocalization["Export Database"], CurrentUser.Username); - IJobStep exportData = new JobStep(AppLocalization["Export Data"], (step) => - { - Context.Export("export"); - return true; + MemoryStream memoryStream = new MemoryStream(); - }); - IJobStep packageData = new JobStep(AppLocalization["Prepare Files"], (step) => + IJob exportJob = new Job(AppLocalization["Export Database"], CurrentUser.Username); + IJobStep exportData = new JobStep(AppLocalization["Export Data"], (step) => { - ZipArchive exportZip = new ZipArchive(memoryStream, ZipArchiveMode.Create); - var exportDir = new SystemDirectory("export"); - exportZip.AddToZip(exportDir, exportDir.Path); - memoryStream.SaveTo(new SystemFile("export/" + DatabaseCache.ApplicationSettings.AppName + "-" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".zip")); + Context.Export("export"); return true; }); - exportJob.Steps.Add(exportData); - exportJob.Steps.Add(packageData); - exportJob.ShowJobDetailsDialog(MessageService); - await InvokeAsync(StateHasChanged); - await exportJob.RunAsync(); + IJobStep packageData = new JobStep(AppLocalization["Prepare Files"], (step) => + { + ZipArchive exportZip = new ZipArchive(memoryStream, ZipArchiveMode.Create); + var exportDir = new SystemDirectory("export"); + exportZip.AddToZip(exportDir, exportDir.Path); + memoryStream.SaveTo(new SystemFile("export/" + DatabaseCache.ApplicationSettings.AppName + "-" + DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".zip")); + return true; + + }); + exportJob.AddStep(exportData); + exportJob.AddStep(packageData); + exportJob.ShowJobDetailsDialog(MessageService); + await InvokeAsync(StateHasChanged); + await exportJob.RunAsync(); } diff --git a/BLAZAMGui/UI/Settings/JobsMonitor.razor b/BLAZAMGui/UI/Settings/JobsMonitor.razor new file mode 100644 index 00000000..f43e2eb0 --- /dev/null +++ b/BLAZAMGui/UI/Settings/JobsMonitor.razor @@ -0,0 +1,25 @@ +@if (JobMonitor.AllJobs.Count > 0) +{ + + + + + + + + + + + + +} + +@code { + protected override void OnInitialized() + { + base.OnInitialized(); + JobMonitor.OnUpdate += async () => { await InvokeAsync(StateHasChanged); }; + } +} \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/SystemSettings.razor b/BLAZAMGui/UI/Settings/SystemSettings.razor index b4229730..1f430666 100644 --- a/BLAZAMGui/UI/Settings/SystemSettings.razor +++ b/BLAZAMGui/UI/Settings/SystemSettings.razor @@ -28,7 +28,7 @@ @AppLocalization["Data Collection Settings"] - + @@ -61,7 +61,7 @@ - + Download Logs @@ -78,9 +78,10 @@ + + @AppLocalization["Jobs Monitor"] - - + diff --git a/BLAZAMJobs/BLAZAMJobs.csproj b/BLAZAMJobs/BLAZAMJobs.csproj index 0fc399c5..e0a6bcc6 100644 --- a/BLAZAMJobs/BLAZAMJobs.csproj +++ b/BLAZAMJobs/BLAZAMJobs.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + BLAZAM.Jobs
diff --git a/BLAZAMJobs/IJob.cs b/BLAZAMJobs/IJob.cs index 0a603cd8..293d4fbc 100644 --- a/BLAZAMJobs/IJob.cs +++ b/BLAZAMJobs/IJob.cs @@ -12,8 +12,8 @@ public interface IJob : IJobStepBase { - - + bool NestedJob { get; set; } + Guid Id { get; } /// /// The time to run this job. Execution will wait until this time arrives. /// @@ -30,7 +30,7 @@ public interface IJob : IJobStepBase /// /// Some steps may be 's themselves /// - IList Steps { get; set; } + IList Steps { get; } /// /// A list of all failed steps @@ -52,6 +52,8 @@ public interface IJob : IJobStepBase /// IList PassedSteps { get; } + void AddStep(IJobStep step); + /// diff --git a/BLAZAMJobs/Job.cs b/BLAZAMJobs/Job.cs index 99062032..c1401364 100644 --- a/BLAZAMJobs/Job.cs +++ b/BLAZAMJobs/Job.cs @@ -15,7 +15,9 @@ public class Job : JobStepBase, IJob, IJobStep public string? User { get; set; } - public IList Steps { get; set; } = new List(); + private IList _steps = new List(); + + public IList Steps => _steps; public DateTime ScheduledRunTime { @@ -31,7 +33,8 @@ public DateTime ScheduledRunTime public IList PassedSteps { get; protected set; } = new List(); - + public Guid Id{ get; set; } + public bool NestedJob { get; set; } = false; public Job(string? title = null, string? requestingUser = null, CancellationTokenSource? externalCancellationToken = null) { @@ -41,6 +44,8 @@ public Job(string? title = null, string? requestingUser = null, CancellationToke { cancellationTokenSource = externalCancellationToken; } + Id= Guid.NewGuid(); + JobMonitor.AddJob(this); } @@ -63,7 +68,17 @@ public override bool Run() return Execute(); } + public void AddStep(IJobStep step) + { + if (Steps.Contains(step)) return; + if(User != null && step is IJob jobStep) + { + jobStep.User = User; + jobStep.NestedJob = true; + } + Steps.Add(step); + } private bool Execute() { var cancelToken = cancellationTokenSource.Token; @@ -161,7 +176,14 @@ public override void Cancel() } } - + public override bool Equals(object? obj) + { + if(obj is IJob job) + { + return job.Id.Equals(Id); + } + return false; + } } diff --git a/BLAZAMJobs/JobMonitor.cs b/BLAZAMJobs/JobMonitor.cs new file mode 100644 index 00000000..0a4d604b --- /dev/null +++ b/BLAZAMJobs/JobMonitor.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.Jobs +{ + public static class JobMonitor + { + public static AppEvent? OnUpdate { get; set; } + private static List Jobs = new List(); + public static List AllJobs => Jobs.ToList(); + public static List RunningJobs => Jobs.Where(x => x.Result == JobResult.Running).ToList(); + 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; + + + public static void AddJob(IJob job) + { + if(Jobs.Contains(job)) return; + if (Jobs.Count == _maxJobs) Jobs.RemoveAt(_maxJobs - 1); + Jobs.Add(job); + job.OnProgressUpdated += (progress)=>{ OnUpdate?.Invoke(); }; + OnUpdate?.Invoke(); + } + + } +} diff --git a/BLAZAMUpdate/ApplicationUpdate.cs b/BLAZAMUpdate/ApplicationUpdate.cs index 0cbc1f0a..09666920 100644 --- a/BLAZAMUpdate/ApplicationUpdate.cs +++ b/BLAZAMUpdate/ApplicationUpdate.cs @@ -188,13 +188,13 @@ public IJob GetUpdateJob() var stagingCheckStep = new JobStep("Check prepared files", (step) => { return UpdateStagingDirectory.Exists; }); var bakupStep = new JobStep("Create backup", Backup); var updateUpdaterStep = new JobStep("Apply Files", InitiateFileCopy); - updateJob.Steps.Add(cleanDownloadStep); - updateJob.Steps.Add(downloadStep); - updateJob.Steps.Add(cleanStageStep); - updateJob.Steps.Add(stageStep); - updateJob.Steps.Add(stagingCheckStep); - updateJob.Steps.Add(bakupStep); - updateJob.Steps.Add(updateUpdaterStep); + updateJob.AddStep(cleanDownloadStep); + updateJob.AddStep(downloadStep); + updateJob.AddStep(cleanStageStep); + updateJob.AddStep(stageStep); + updateJob.AddStep(stagingCheckStep); + updateJob.AddStep(bakupStep); + updateJob.AddStep(updateUpdaterStep); return updateJob; From 9876b77b9322146358051fbaa064c3163aadd5f2 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 21 Jul 2024 23:09:42 -0400 Subject: [PATCH 047/116] Allow step reuse --- BLAZAMJobs/Job.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/BLAZAMJobs/Job.cs b/BLAZAMJobs/Job.cs index c1401364..fb03d411 100644 --- a/BLAZAMJobs/Job.cs +++ b/BLAZAMJobs/Job.cs @@ -70,7 +70,6 @@ public override bool Run() } public void AddStep(IJobStep step) { - if (Steps.Contains(step)) return; if(User != null && step is IJob jobStep) { jobStep.User = User; From 9af5699f162c48f68c2aa41a5edeb093475952cc Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 22 Jul 2024 00:16:09 -0400 Subject: [PATCH 048/116] .net 8 update v2 --- BLAZAM.Tests/BLAZAM.Tests.csproj | 6 ++-- BLAZAM/BLAZAM.csproj | 35 +++++++++---------- .../BLAZAMActiveDirectory.csproj | 2 +- BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 18 +++++----- BLAZAMCommon/BLAZAMCommon.csproj | 18 +++++----- BLAZAMDatabase/BLAZAMDatabase.csproj | 20 +++++------ BLAZAMEmail/BLAZAMEmail.csproj | 4 +-- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 6 ++-- BLAZAMFileSystem/BLAZAMFileSystem.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 14 ++++---- BLAZAMGui/UI/Chat/ChatRoomMessage.razor | 15 +++++--- BLAZAMGui/UI/Chat/OtherViewersButton.razor | 2 +- .../CurrentUserDashboardWidgets.razor | 4 +-- BLAZAMGui/UI/DirectoryEntryViewHeader.razor | 3 +- .../UI/Groups/AssignToModalContent.razor | 24 ++++++++----- BLAZAMGui/UI/Groups/MemberOfList.razor | 3 +- .../UI/Inputs/ADAutoCompleteResult.razor | 12 +++++-- BLAZAMGui/UI/Inputs/DynamicMudInput.razor | 2 +- .../UI/Inputs/UnsavedChangesPrompt.razor | 2 +- BLAZAMGui/UI/Modals/AuditEntryChanges.razor | 2 +- .../UI/Outputs/ApplicationNewsProvider.razor | 6 ++-- BLAZAMGui/UI/Outputs/StatusCheck.razor | 5 ++- .../Notifications/NotificationSettings.razor | 2 +- BLAZAMJobs/BLAZAMJobs.csproj | 2 +- BLAZAMLocalization/BLAZAMLocalization.csproj | 2 +- BLAZAMLoggers/BLAZAMLogger.csproj | 6 ++-- BLAZAMNav/BLAZAMNav.csproj | 2 +- .../BLAZAMNotifications.csproj | 4 +-- BLAZAMServices/BLAZAMServices.csproj | 4 +-- BLAZAMSession/BLAZAMSession.csproj | 2 +- BLAZAMStatic/BLAZAMStatic.csproj | 2 +- BLAZAMThemes/ApplicationTheme.cs | 2 +- BLAZAMThemes/BLAZAMThemes.csproj | 6 ++-- BLAZAMUpdate/BLAZAMUpdate.csproj | 4 +-- PlaywrightTests/PlaywrightTests.csproj | 2 +- 35 files changed, 133 insertions(+), 112 deletions(-) diff --git a/BLAZAM.Tests/BLAZAM.Tests.csproj b/BLAZAM.Tests/BLAZAM.Tests.csproj index 08426028..56fe8b1a 100644 --- a/BLAZAM.Tests/BLAZAM.Tests.csproj +++ b/BLAZAM.Tests/BLAZAM.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable @@ -10,8 +10,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 11c7bbf9..f26f17a8 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 enable enable false @@ -57,31 +57,30 @@ - + - - - - - - - - - - + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - + + + - + diff --git a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj index 30c6322c..67767ef3 100644 --- a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj +++ b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.ActiveDirectory diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 6bbe6bfe..86ef5e1f 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable @@ -9,15 +9,15 @@ - - - - - + + + + + - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 8c1d33f6..b8c2e6b1 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Common @@ -20,18 +20,18 @@ - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index 5663a9ab..96b778a4 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -1,25 +1,25 @@  - net6.0 + net8.0 enable enable BLAZAM.Database - - - - - - - + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/BLAZAMEmail/BLAZAMEmail.csproj b/BLAZAMEmail/BLAZAMEmail.csproj index 2197dd71..efa20288 100644 --- a/BLAZAMEmail/BLAZAMEmail.csproj +++ b/BLAZAMEmail/BLAZAMEmail.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable BLAZAM.Email @@ -9,7 +9,7 @@ - + diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index bafe9f20..bda58f80 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable BLAZAM.EmailMessage @@ -13,8 +13,8 @@ - - + + diff --git a/BLAZAMFileSystem/BLAZAMFileSystem.csproj b/BLAZAMFileSystem/BLAZAMFileSystem.csproj index f88022e7..057484f2 100644 --- a/BLAZAMFileSystem/BLAZAMFileSystem.csproj +++ b/BLAZAMFileSystem/BLAZAMFileSystem.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable BLAZAM.FileSystem diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index e135ad9a..73057bee 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Gui @@ -24,13 +24,13 @@ - - - - - + + + + + - + diff --git a/BLAZAMGui/UI/Chat/ChatRoomMessage.razor b/BLAZAMGui/UI/Chat/ChatRoomMessage.razor index 9d01338a..68d10cb5 100644 --- a/BLAZAMGui/UI/Chat/ChatRoomMessage.razor +++ b/BLAZAMGui/UI/Chat/ChatRoomMessage.razor @@ -25,9 +25,13 @@ { - @Message.User.Username + + @Message.User.Username + @Message.Message - + @@ -41,11 +45,12 @@ else @Message.Message - + @Message.User.Username - + diff --git a/BLAZAMGui/UI/Chat/OtherViewersButton.razor b/BLAZAMGui/UI/Chat/OtherViewersButton.razor index 38e6ea20..93244692 100644 --- a/BLAZAMGui/UI/Chat/OtherViewersButton.razor +++ b/BLAZAMGui/UI/Chat/OtherViewersButton.razor @@ -13,7 +13,7 @@ Start Chat } - + Other Viewers: @foreach (var user in OtherViewers) { diff --git a/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor b/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor index c812516b..de386ce3 100644 --- a/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor +++ b/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor @@ -16,7 +16,7 @@ - - - diff --git a/BLAZAMGui/UI/Groups/AssignToModalContent.razor b/BLAZAMGui/UI/Groups/AssignToModalContent.razor index 0e7af1c4..9984014d 100644 --- a/BLAZAMGui/UI/Groups/AssignToModalContent.razor +++ b/BLAZAMGui/UI/Groups/AssignToModalContent.razor @@ -54,15 +54,15 @@ } @AppLocalization["or"] - + - - @if (CopyFrom != null) + + @if (CopyFrom != null) { @@ -72,7 +72,10 @@ @if (CopyFrom.MemberOf.Any(g => existingGroups.Contains(g))) { Already a member of... - + @foreach (var group in CopyFrom.MemberOf.Where(g => existingGroups.Contains(g))) { @@ -89,7 +92,10 @@ @if (CopyFrom.MemberOf.Any(g => !existingGroups.Contains(g))) { Will be added to... - + @foreach (var group in CopyFrom.MemberOf.Where(g => !existingGroups.Contains(g))) { diff --git a/BLAZAMGui/UI/Groups/MemberOfList.razor b/BLAZAMGui/UI/Groups/MemberOfList.razor index a41ba925..5ecb4ab2 100644 --- a/BLAZAMGui/UI/Groups/MemberOfList.razor +++ b/BLAZAMGui/UI/Groups/MemberOfList.razor @@ -4,9 +4,8 @@ @if (Model.MemberOf.Count > 0) { @foreach (IADGroup g in Model.MemberOf.Where(group => group.CanRead).OrderBy(g => g.CanonicalName)) { diff --git a/BLAZAMGui/UI/Inputs/ADAutoCompleteResult.razor b/BLAZAMGui/UI/Inputs/ADAutoCompleteResult.razor index 7d6edafd..28f692a8 100644 --- a/BLAZAMGui/UI/Inputs/ADAutoCompleteResult.razor +++ b/BLAZAMGui/UI/Inputs/ADAutoCompleteResult.razor @@ -36,12 +36,20 @@ @if (lockoutBadgeVisible) { - + } @if (disabledBadgeVisible) { - + } diff --git a/BLAZAMGui/UI/Inputs/DynamicMudInput.razor b/BLAZAMGui/UI/Inputs/DynamicMudInput.razor index fdfd3d80..59b24ebe 100644 --- a/BLAZAMGui/UI/Inputs/DynamicMudInput.razor +++ b/BLAZAMGui/UI/Inputs/DynamicMudInput.razor @@ -38,7 +38,7 @@ case "Boolean": diff --git a/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor b/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor index 17512ac1..6e1ee1b6 100644 --- a/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor +++ b/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor @@ -21,7 +21,7 @@ - + Unsaved Changes diff --git a/BLAZAMGui/UI/Modals/AuditEntryChanges.razor b/BLAZAMGui/UI/Modals/AuditEntryChanges.razor index 336aa825..6576fce0 100644 --- a/BLAZAMGui/UI/Modals/AuditEntryChanges.razor +++ b/BLAZAMGui/UI/Modals/AuditEntryChanges.razor @@ -2,7 +2,7 @@ @foreach (var change in Changes) { - + @((MarkupString)change.Value) } diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor index 2e617b57..87c76bc5 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor @@ -33,7 +33,7 @@ + OnClick="@((args)=>{ShowNews(item);newsMenu?.OpenMenuAsync(new());})"> @item.Title @@ -49,7 +49,7 @@ { foreach (var item in readItems.OrderByDescending(x => x.UpdatedAt)) { - + @@ -122,7 +122,7 @@ if (firstRender && unreadItems.Count > 0) { - newsMenu?.OpenMenu(new()); + newsMenu?.OpenMenuAsync(new()); } } private async void MarkAllRead() diff --git a/BLAZAMGui/UI/Outputs/StatusCheck.razor b/BLAZAMGui/UI/Outputs/StatusCheck.razor index 4baad88d..fb0db9e3 100644 --- a/BLAZAMGui/UI/Outputs/StatusCheck.razor +++ b/BLAZAMGui/UI/Outputs/StatusCheck.razor @@ -8,7 +8,10 @@ } else { - @Text + @Text } diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor index 9e4b1a39..63b284d4 100644 --- a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -32,7 +32,7 @@ await base.OnInitializedAsync(); Users = await Context.UserSettings.ToListAsync(); } - private async Task> SearchUsers(string value) + private async Task> SearchUsers(string value,CancellationToken token) { if (value == null) value = String.Empty; return Users.Where(x => x.Username.Contains(value)); diff --git a/BLAZAMJobs/BLAZAMJobs.csproj b/BLAZAMJobs/BLAZAMJobs.csproj index e0a6bcc6..6343425a 100644 --- a/BLAZAMJobs/BLAZAMJobs.csproj +++ b/BLAZAMJobs/BLAZAMJobs.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable BLAZAM.Jobs diff --git a/BLAZAMLocalization/BLAZAMLocalization.csproj b/BLAZAMLocalization/BLAZAMLocalization.csproj index 5c37bba1..db9fe4a4 100644 --- a/BLAZAMLocalization/BLAZAMLocalization.csproj +++ b/BLAZAMLocalization/BLAZAMLocalization.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Localization diff --git a/BLAZAMLoggers/BLAZAMLogger.csproj b/BLAZAMLoggers/BLAZAMLogger.csproj index b7fa8f9c..00678e9f 100644 --- a/BLAZAMLoggers/BLAZAMLogger.csproj +++ b/BLAZAMLoggers/BLAZAMLogger.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Logger @@ -9,9 +9,9 @@ - + - + diff --git a/BLAZAMNav/BLAZAMNav.csproj b/BLAZAMNav/BLAZAMNav.csproj index 66b3ad4a..b934e5db 100644 --- a/BLAZAMNav/BLAZAMNav.csproj +++ b/BLAZAMNav/BLAZAMNav.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Nav diff --git a/BLAZAMNotifications/BLAZAMNotifications.csproj b/BLAZAMNotifications/BLAZAMNotifications.csproj index 44298634..0beef6e1 100644 --- a/BLAZAMNotifications/BLAZAMNotifications.csproj +++ b/BLAZAMNotifications/BLAZAMNotifications.csproj @@ -1,14 +1,14 @@  - net6.0 + net8.0 enable enable BLAZAM.Notifications - + diff --git a/BLAZAMServices/BLAZAMServices.csproj b/BLAZAMServices/BLAZAMServices.csproj index 19291ced..f06982a7 100644 --- a/BLAZAMServices/BLAZAMServices.csproj +++ b/BLAZAMServices/BLAZAMServices.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Services @@ -9,7 +9,7 @@ - + diff --git a/BLAZAMSession/BLAZAMSession.csproj b/BLAZAMSession/BLAZAMSession.csproj index c1cb444d..549819a4 100644 --- a/BLAZAMSession/BLAZAMSession.csproj +++ b/BLAZAMSession/BLAZAMSession.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Session diff --git a/BLAZAMStatic/BLAZAMStatic.csproj b/BLAZAMStatic/BLAZAMStatic.csproj index a771c162..17911521 100644 --- a/BLAZAMStatic/BLAZAMStatic.csproj +++ b/BLAZAMStatic/BLAZAMStatic.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable BLAZAM.Static diff --git a/BLAZAMThemes/ApplicationTheme.cs b/BLAZAMThemes/ApplicationTheme.cs index 5c0bced0..083d76c8 100644 --- a/BLAZAMThemes/ApplicationTheme.cs +++ b/BLAZAMThemes/ApplicationTheme.cs @@ -57,7 +57,7 @@ public MudTheme Theme { return new MudTheme { - Palette = lightPalette, + PaletteLight = lightPalette, PaletteDark = darkPalette, }; diff --git a/BLAZAMThemes/BLAZAMThemes.csproj b/BLAZAMThemes/BLAZAMThemes.csproj index 2ede2c12..ea50aae3 100644 --- a/BLAZAMThemes/BLAZAMThemes.csproj +++ b/BLAZAMThemes/BLAZAMThemes.csproj @@ -1,15 +1,15 @@ - net6.0 + net8.0 enable enable BLAZAM.Themes - - + + diff --git a/BLAZAMUpdate/BLAZAMUpdate.csproj b/BLAZAMUpdate/BLAZAMUpdate.csproj index 069c8553..dcd9b647 100644 --- a/BLAZAMUpdate/BLAZAMUpdate.csproj +++ b/BLAZAMUpdate/BLAZAMUpdate.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Update @@ -10,7 +10,7 @@ - + diff --git a/PlaywrightTests/PlaywrightTests.csproj b/PlaywrightTests/PlaywrightTests.csproj index 75b48e6a..6ed4a984 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From cd34971b2c17c8cbb4df82cea77e2283d167864d Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 22 Jul 2024 00:16:23 -0400 Subject: [PATCH 049/116] Missed one file --- BlazamUpdate/BLAZAMUpdate.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BlazamUpdate/BLAZAMUpdate.csproj b/BlazamUpdate/BLAZAMUpdate.csproj index 069c8553..dcd9b647 100644 --- a/BlazamUpdate/BLAZAMUpdate.csproj +++ b/BlazamUpdate/BLAZAMUpdate.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable enable BLAZAM.Update @@ -10,7 +10,7 @@ - + From d768b243e63dae522ad42be345bf5c2b1296560e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:39:41 +0000 Subject: [PATCH 050/116] Bump MailKit from 4.6.0 to 4.7.1.1 Bumps [MailKit](https://github.com/jstedfast/MailKit) from 4.6.0 to 4.7.1.1. - [Changelog](https://github.com/jstedfast/MailKit/blob/master/ReleaseNotes.md) - [Commits](https://github.com/jstedfast/MailKit/compare/4.6.0...4.7.1.1) --- updated-dependencies: - dependency-name: MailKit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMEmail/BLAZAMEmail.csproj | 2 +- BLAZAMServices/BLAZAMServices.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 11c7bbf9..d5dc01de 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -57,7 +57,7 @@ - + diff --git a/BLAZAMEmail/BLAZAMEmail.csproj b/BLAZAMEmail/BLAZAMEmail.csproj index 2197dd71..8366bd8f 100644 --- a/BLAZAMEmail/BLAZAMEmail.csproj +++ b/BLAZAMEmail/BLAZAMEmail.csproj @@ -9,7 +9,7 @@ - + diff --git a/BLAZAMServices/BLAZAMServices.csproj b/BLAZAMServices/BLAZAMServices.csproj index 19291ced..1c02493a 100644 --- a/BLAZAMServices/BLAZAMServices.csproj +++ b/BLAZAMServices/BLAZAMServices.csproj @@ -9,7 +9,7 @@ - + From 6d3c46233a5ecaf04c1b41ae9eb1374c8bc7b943 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 22 Jul 2024 17:00:45 -0400 Subject: [PATCH 051/116] Revert Dev and Nightly branch update to v1 --- BLAZAMUpdate/ApplicationReleaseBranches.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BLAZAMUpdate/ApplicationReleaseBranches.cs b/BLAZAMUpdate/ApplicationReleaseBranches.cs index 4e970e18..99b35d9b 100644 --- a/BLAZAMUpdate/ApplicationReleaseBranches.cs +++ b/BLAZAMUpdate/ApplicationReleaseBranches.cs @@ -3,7 +3,7 @@ public class ApplicationReleaseBranches { public const string Stable = "Release"; - public const string Nightly = "Nightly1"; - public const string Dev = "Dev1"; + public const string Nightly = "Nightly"; + public const string Dev = "Dev"; } } \ No newline at end of file From 23e27fbcb1f78d822dbb9de3648e4039344b91e2 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 22 Jul 2024 20:09:11 -0400 Subject: [PATCH 052/116] Update test --- BLAZAM/BLAZAM.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 11c7bbf9..2bcfbe13 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.21.2146 + 2024.07.23.0006 false BLAZAM False @@ -156,3 +156,4 @@ + From a85daae2b35f6308c1abb68a8777be714590650c Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 14:14:10 -0400 Subject: [PATCH 053/116] Bump Microsoft.AspNetCore.Identity.UI from 6.0.30 to 6.0.32 --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index dcde2638..a47f4271 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -59,7 +59,7 @@ - + From 4424f357a9b5846876172e994b922581d173fc2a Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 14:15:04 -0400 Subject: [PATCH 054/116] Bump Microsoft.VisualStudio.Web.CodeGeneration.Design from 6.0.16 to 6.0.17 --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index a47f4271..32343efa 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -77,7 +77,7 @@ - + From 785779487abf74f7cf3ecfbf8a926df77ea153fa Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 14:16:38 -0400 Subject: [PATCH 055/116] Bump Microsoft.Playwright.NUnit from 1.44.0 to 1.45.1 --- PlaywrightTests/PlaywrightTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlaywrightTests/PlaywrightTests.csproj b/PlaywrightTests/PlaywrightTests.csproj index 75b48e6a..0518ae38 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From e759797ba019b82e69119b3eacc3de4b4bc3305c Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 14:27:43 -0400 Subject: [PATCH 056/116] Update all other dependencies --- BLAZAM.Tests/BLAZAM.Tests.csproj | 4 ++-- BLAZAM/BLAZAM.csproj | 12 ++++++------ BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 4 ++-- BLAZAMCommon/BLAZAMCommon.csproj | 4 ++-- BLAZAMDatabase/BLAZAMDatabase.csproj | 2 +- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 4 ++-- BLAZAMGui/BLAZAMGui.csproj | 6 +++--- BLAZAMLoggers/BLAZAMLogger.csproj | 4 ++-- BlazamUpdate/BLAZAMUpdate.csproj | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/BLAZAM.Tests/BLAZAM.Tests.csproj b/BLAZAM.Tests/BLAZAM.Tests.csproj index 08426028..86d716a5 100644 --- a/BLAZAM.Tests/BLAZAM.Tests.csproj +++ b/BLAZAM.Tests/BLAZAM.Tests.csproj @@ -10,8 +10,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 32343efa..b5c4d01d 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -60,9 +60,9 @@ - - - + + + @@ -75,16 +75,16 @@ - + - + - + diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 6bbe6bfe..0a8f41bf 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -16,8 +16,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 8c1d33f6..ef1c3db0 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -20,7 +20,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index 5663a9ab..4d35f064 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -18,7 +18,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index bafe9f20..e6af1ffa 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -13,7 +13,7 @@ - + diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index e135ad9a..ed4643a2 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -24,13 +24,13 @@ - + - + - + diff --git a/BLAZAMLoggers/BLAZAMLogger.csproj b/BLAZAMLoggers/BLAZAMLogger.csproj index b7fa8f9c..475406fc 100644 --- a/BLAZAMLoggers/BLAZAMLogger.csproj +++ b/BLAZAMLoggers/BLAZAMLogger.csproj @@ -9,9 +9,9 @@ - + - + diff --git a/BlazamUpdate/BLAZAMUpdate.csproj b/BlazamUpdate/BLAZAMUpdate.csproj index 069c8553..111a5779 100644 --- a/BlazamUpdate/BLAZAMUpdate.csproj +++ b/BlazamUpdate/BLAZAMUpdate.csproj @@ -10,7 +10,7 @@ - + From 75e9100e9af86f948d59420ed447d9c791ac2c91 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 14:29:50 -0400 Subject: [PATCH 057/116] Update Octokit --- BLAZAM/BLAZAM.csproj | 4 ++-- BLAZAMUpdate/BLAZAMUpdate.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index b5c4d01d..50d9e8bc 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.23.0006 + 2024.07.23.1828 false BLAZAM False diff --git a/BLAZAMUpdate/BLAZAMUpdate.csproj b/BLAZAMUpdate/BLAZAMUpdate.csproj index 069c8553..111a5779 100644 --- a/BLAZAMUpdate/BLAZAMUpdate.csproj +++ b/BLAZAMUpdate/BLAZAMUpdate.csproj @@ -10,7 +10,7 @@ - + From 8a2d4897b34b0ac44ec36b6f96b9cb89a74d94d6 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 14:35:54 -0400 Subject: [PATCH 058/116] Remove redundant group post creation triggers --- BLAZAM/Pages/Groups/ConfirmNewGroup.razor | 4 ++++ BLAZAM/Pages/Groups/CreateGroup.razor | 9 +-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/BLAZAM/Pages/Groups/ConfirmNewGroup.razor b/BLAZAM/Pages/Groups/ConfirmNewGroup.razor index 8bdc049a..01839885 100644 --- a/BLAZAM/Pages/Groups/ConfirmNewGroup.razor +++ b/BLAZAM/Pages/Groups/ConfirmNewGroup.razor @@ -1,4 +1,6 @@ @inherits AppComponentBase +@inject OUNotificationService OUNotificationService + Confirm Group Creation @if (Group != null) @@ -41,6 +43,8 @@ } await AuditLogger.Group.Created(Group); + _ = OUNotificationService.PostAsync(Group, NotificationType.Create); + var commitJob = Group.CommitChanges(); await Confirmed.InvokeAsync(Group); } diff --git a/BLAZAM/Pages/Groups/CreateGroup.razor b/BLAZAM/Pages/Groups/CreateGroup.razor index 245f7242..9c017f3f 100644 --- a/BLAZAM/Pages/Groups/CreateGroup.razor +++ b/BLAZAM/Pages/Groups/CreateGroup.razor @@ -1,7 +1,6 @@ @page "/groups/create" @inherits TabbedAppComponentBase @attribute [Authorize] -@inject OUNotificationService OUNotificationService Create Group @@ -54,7 +53,7 @@ - + @@ -121,10 +120,4 @@ await InvokeAsync(StateHasChanged); } - async Task GroupCreated(IADGroup ou) - { - await AuditLogger.Group.Created(ou); - _ = OUNotificationService.PostAsync(ou, NotificationType.Create); - - } } From b22c88678f7ee2a623cc00d092f50824708d9823 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 16:52:00 -0400 Subject: [PATCH 059/116] Fix for first OU not being alphabetical in tree views #386 --- BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index cd7dd547..21f49fe1 100644 --- a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs +++ b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs @@ -43,7 +43,7 @@ public static IEnumerable MoveToTop(this IEnumerable mathingItems=new List(); - for (int x =1; x < list.Count(); x++) + for (int x =0; x < list.Count(); x++) { if (matchingPredicate.Invoke(list[x])) From a187fc3e0c996338430d5134a797c6a3ada2f7f5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 16:54:05 -0400 Subject: [PATCH 060/116] Unused code from another project --- .../Helpers/ActiveDirectoryHelpers.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index 21f49fe1..6a5df47b 100644 --- a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs +++ b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs @@ -63,15 +63,7 @@ public static IEnumerable MoveToTop(this IEnumerable Date: Tue, 23 Jul 2024 16:55:56 -0400 Subject: [PATCH 061/116] Move OU create audit and notification triggers --- BLAZAM/Pages/OU/ConfirmNewOU.razor | 4 ++++ BLAZAM/Pages/OU/CreateOU.razor | 8 +------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/BLAZAM/Pages/OU/ConfirmNewOU.razor b/BLAZAM/Pages/OU/ConfirmNewOU.razor index 6b436a8a..59de0d9d 100644 --- a/BLAZAM/Pages/OU/ConfirmNewOU.razor +++ b/BLAZAM/Pages/OU/ConfirmNewOU.razor @@ -1,4 +1,6 @@ @inherits AppComponentBase +@inject OUNotificationService OUNotificationService + Confirm OU Creation @if (OU != null) @@ -27,6 +29,8 @@ { await OU.CommitChangesAsync(); SnackBarService.Success("OU created"); + await AuditLogger.OU.Created(OU); + _ = OUNotificationService.PostAsync(OU, NotificationType.Create); await Confirmed.InvokeAsync(OU); Nav.NavigateTo("/ou/create",true); } diff --git a/BLAZAM/Pages/OU/CreateOU.razor b/BLAZAM/Pages/OU/CreateOU.razor index f560aac8..2917594e 100644 --- a/BLAZAM/Pages/OU/CreateOU.razor +++ b/BLAZAM/Pages/OU/CreateOU.razor @@ -1,7 +1,6 @@ @page "/ou/create" @inherits TabbedAppComponentBase @attribute [Authorize] -@inject OUNotificationService OUNotificationService Create OU @@ -37,7 +36,7 @@ - + @@ -118,10 +117,5 @@ await InvokeAsync(StateHasChanged); } - async Task OUCreated(IADOrganizationalUnit ou) - { - await AuditLogger.OU.Created(ou); - _ = OUNotificationService.PostAsync(ou, NotificationType.Create); - } } From e0dcb22915935a0f94ba9f9cd74052a29c9148e5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 23 Jul 2024 19:08:48 -0400 Subject: [PATCH 062/116] Detect group changes for notifications --- BLAZAM/Pages/Users/ViewUser.razor | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index 21741fc5..a90ec1d6 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -546,6 +546,7 @@ await RefreshEntryComponents(); try { + var changes = User.Changes; var jobResults = await User.CommitChangesAsync(); if (jobResults.Result == JobResult.Passed) @@ -553,8 +554,12 @@ await AuditLogger.User.Changed(User, changes); - if((changes.Count==1 && changes.First().Field==ActiveDirectoryFields.MemberOf.FieldName)==false) + if(changes.Any(c=>c.Field!=ActiveDirectoryFields.MemberOf.FieldName)) _ = OUNotificationService.PostAsync(User, NotificationType.Modify); + else + { + + } EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this user have been saved."); From dae1f90a1dc0c51630d805da1e80689d8e67ebc9 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 24 Jul 2024 17:03:41 -0400 Subject: [PATCH 063/116] Remove assign and unassign from User and Computer appropriate Object Actions --- BLAZAMDatabase/Models/Permissions/ObjectAction.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs index b655024b..fc4cd627 100644 --- a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs +++ b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs @@ -26,15 +26,14 @@ public bool IsActionAppropriateForObject(ActiveDirectoryObjectType type) switch (type) { case ActiveDirectoryObjectType.User: - return true; case ActiveDirectoryObjectType.Computer: switch (Name) { + case "Lock": + case "Unlock": case "Move": case "Delete": case "Create": - case "UnAssign": - case "Assign": case "Enable": case "Disable": case "Rename": From a1608808b48f6f1a896f3a914aae6780cd31dea4 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 24 Jul 2024 17:12:47 -0400 Subject: [PATCH 064/116] Add printer object actions --- BLAZAMDatabase/Models/Permissions/ObjectAction.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs index fc4cd627..4facce31 100644 --- a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs +++ b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs @@ -54,6 +54,7 @@ public bool IsActionAppropriateForObject(ActiveDirectoryObjectType type) default: return false; } + case ActiveDirectoryObjectType.Printer: case ActiveDirectoryObjectType.OU: switch (Name) { @@ -65,7 +66,7 @@ public bool IsActionAppropriateForObject(ActiveDirectoryObjectType type) default: return false; } - + default: return false; } From c79f61c0e108a2e30b843bc3e78679c2c23bd267 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 24 Jul 2024 17:13:10 -0400 Subject: [PATCH 065/116] Add Bitlock delete object action --- BLAZAMDatabase/Models/Permissions/ObjectAction.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs index 4facce31..31779f4b 100644 --- a/BLAZAMDatabase/Models/Permissions/ObjectAction.cs +++ b/BLAZAMDatabase/Models/Permissions/ObjectAction.cs @@ -66,7 +66,15 @@ public bool IsActionAppropriateForObject(ActiveDirectoryObjectType type) default: return false; } - + case ActiveDirectoryObjectType.BitLocker: + switch (Name) + { + case "Delete": + return true; + default: + return false; + } + default: return false; } From 651a51c135b3042b63ae129f1bcc7ffbed374df1 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 24 Jul 2024 18:38:00 -0400 Subject: [PATCH 066/116] Security update against potential DOS --- BLAZAMCommon/BLAZAMCommon.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 8c1d33f6..c5ae69ca 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -33,7 +33,7 @@ - + From 12348d12d57b4146b18f1f5edaf8a430464bccbe Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 26 Jul 2024 19:15:51 -0400 Subject: [PATCH 067/116] Implement Email Notifications --- BLAZAM/GlobalUsings.cs | 3 +- .../Pages/Error/UnhandledExceptionPage.razor | 1 - BLAZAM/ProgramHelpers.cs | 12 --- .../BLAZAMActiveDirectory.csproj | 1 + BLAZAMDatabase/Context/DatabaseContextBase.cs | 3 - .../Notifications/NotificationSubscription.cs | 5 -- BLAZAMEmail/BLAZAMEmail.csproj | 4 + .../EntryCreatedEmailMessage.razor | 28 ++++++ .../EntryDeletedEmailMessage.razor | 28 ++++++ .../EntryEditedEmailMessage.razor | 28 ++++++ .../EntryGroupAssignmentEmailMessage.razor | 28 ++++++ BLAZAMGui/UI/AppComponentBase.razor.cs | 10 +-- BLAZAMGui/UI/AppModalContentBase.razor | 3 +- .../Settings/ManualApplicationUpdater.razor | 1 - BLAZAMJobs/BLAZAMJobs.csproj | 5 ++ BLAZAMJobs/Job.cs | 5 +- .../NotificationTypeExtentions.cs | 18 ++-- BLAZAMServices/BLAZAMServices.csproj | 1 + .../Background}/EmailService.cs | 30 ++++--- .../Background/OUNotificationService.cs | 46 +++++++--- BLAZAMSession/ApplicationUserState.cs | 12 +-- BLAZAMSession/ApplicationUserStateService.cs | 8 +- BLAZAMSession/BLAZAMSession.csproj | 1 - BLAZAMUpdate/ApplicationUpdate.cs | 11 ++- BLAZAMUpdate/Services/UpdateService.cs | 86 +++++-------------- 25 files changed, 230 insertions(+), 148 deletions(-) create mode 100644 BLAZAMEmailMessage/Email/Notifications/EntryCreatedEmailMessage.razor create mode 100644 BLAZAMEmailMessage/Email/Notifications/EntryDeletedEmailMessage.razor create mode 100644 BLAZAMEmailMessage/Email/Notifications/EntryEditedEmailMessage.razor create mode 100644 BLAZAMEmailMessage/Email/Notifications/EntryGroupAssignmentEmailMessage.razor rename {BLAZAMEmail/Services => BLAZAMServices/Background}/EmailService.cs (92%) diff --git a/BLAZAM/GlobalUsings.cs b/BLAZAM/GlobalUsings.cs index 7079d615..f292a6c8 100644 --- a/BLAZAM/GlobalUsings.cs +++ b/BLAZAM/GlobalUsings.cs @@ -1,5 +1,6 @@ global using BLAZAM.Logger; global using BLAZAM.FileSystem; global using BLAZAM.Helpers; -global using BLAZAM.Common.Exceptions; +global using BLAZAM.Services.Background; + diff --git a/BLAZAM/Pages/Error/UnhandledExceptionPage.razor b/BLAZAM/Pages/Error/UnhandledExceptionPage.razor index c4fb7dc9..52ca979d 100644 --- a/BLAZAM/Pages/Error/UnhandledExceptionPage.razor +++ b/BLAZAM/Pages/Error/UnhandledExceptionPage.razor @@ -1,4 +1,3 @@ -@using BLAZAM.Email.Services; @inject EmailService email @inject ApplicationInfo ApplicationInfo @inject IAppDatabaseFactory factory diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs index 384bdc39..7a2f7b7d 100644 --- a/BLAZAM/ProgramHelpers.cs +++ b/BLAZAM/ProgramHelpers.cs @@ -1,34 +1,22 @@  using BLAZAM.Common.Data.Services; using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Localization; using MudBlazor.Services; using System.Globalization; using MudBlazor; -using BLAZAM.Server.Data; -using BLAZAM.Update.Services; -using BLAZAM.Update; using BLAZAM.Database.Context; -using BLAZAM.ActiveDirectory.Interfaces; -using BLAZAM.ActiveDirectory; using BLAZAM.Session.Interfaces; using BLAZAM.Notifications.Services; using BLAZAM.Common.Data; -using BLAZAM.Services.Background; -using BLAZAM.Email.Services; using BLAZAM.Services; using BLAZAM.Services.Duo; -using BLAZAM.Server.Data.Services; using System.Diagnostics; using System.Reflection; using BLAZAM.Services.Chat; using BLAZAM.Services.Audit; -using BLAZAM.Common; using BLAZAM.Nav; using BLAZAM.Session; using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Mvc.RazorPages; -using Org.BouncyCastle.Ocsp; using System.Management; namespace BLAZAM.Server diff --git a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj index 30c6322c..5d630802 100644 --- a/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj +++ b/BLAZAMActiveDirectory/BLAZAMActiveDirectory.csproj @@ -15,6 +15,7 @@ + diff --git a/BLAZAMDatabase/Context/DatabaseContextBase.cs b/BLAZAMDatabase/Context/DatabaseContextBase.cs index d4323bb1..f0fcbe1a 100644 --- a/BLAZAMDatabase/Context/DatabaseContextBase.cs +++ b/BLAZAMDatabase/Context/DatabaseContextBase.cs @@ -11,15 +11,12 @@ using BLAZAM.Logger; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.Configuration; using BLAZAM.Database.Models.Chat; using BLAZAM.Server.Data; -using Microsoft.IdentityModel.Tokens; using System.Data; using BLAZAM.FileSystem; -using Microsoft.EntityFrameworkCore.ChangeTracking; using BLAZAM.Database.Models.Notifications; namespace BLAZAM.Database.Context diff --git a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs index 4def18ee..e699b4a3 100644 --- a/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs +++ b/BLAZAMDatabase/Models/Notifications/NotificationSubscription.cs @@ -1,9 +1,4 @@ using BLAZAM.Database.Models.User; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BLAZAM.Database.Models.Notifications { diff --git a/BLAZAMEmail/BLAZAMEmail.csproj b/BLAZAMEmail/BLAZAMEmail.csproj index 2197dd71..a517d824 100644 --- a/BLAZAMEmail/BLAZAMEmail.csproj +++ b/BLAZAMEmail/BLAZAMEmail.csproj @@ -18,4 +18,8 @@ + + + + diff --git a/BLAZAMEmailMessage/Email/Notifications/EntryCreatedEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/EntryCreatedEmailMessage.razor new file mode 100644 index 00000000..9abc47db --- /dev/null +++ b/BLAZAMEmailMessage/Email/Notifications/EntryCreatedEmailMessage.razor @@ -0,0 +1,28 @@ +@using BLAZAM.Helpers +@using System.Security +@inherits NotificationTemplateComponent + + + @AppLocalization["Active Directory object created"] + + + + EntryName + AppLocalization[" has been created."]) +
+ + +
+ + +@code{ + [Parameter] + public string EntryName { get; set; } + + public override string Render() => new ComponentRenderer() + .UseLayout() + .AddServiceProvider(ApplicationInfo.services) + .Set(c => c.EntryName, EntryName).Render(); +} + + + diff --git a/BLAZAMEmailMessage/Email/Notifications/EntryDeletedEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/EntryDeletedEmailMessage.razor new file mode 100644 index 00000000..ef094124 --- /dev/null +++ b/BLAZAMEmailMessage/Email/Notifications/EntryDeletedEmailMessage.razor @@ -0,0 +1,28 @@ +@using BLAZAM.Helpers +@using System.Security +@inherits NotificationTemplateComponent + + + @AppLocalization["Object deleted"] + + + + @( EntryName + AppLocalization[" has been deltted."]) +
+ + +
+ + +@code{ + [Parameter] + public string EntryName { get; set; } + + public override string Render() => new ComponentRenderer() + .UseLayout() + .AddServiceProvider(ApplicationInfo.services) + .Set(c => c.EntryName, EntryName).Render(); +} + + + diff --git a/BLAZAMEmailMessage/Email/Notifications/EntryEditedEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/EntryEditedEmailMessage.razor new file mode 100644 index 00000000..8ca483dd --- /dev/null +++ b/BLAZAMEmailMessage/Email/Notifications/EntryEditedEmailMessage.razor @@ -0,0 +1,28 @@ +@using BLAZAM.Helpers +@using System.Security +@inherits NotificationTemplateComponent + + + @AppLocalization["Entry modified"] + + + + @(EntryName + AppLocalization[" has been modified."]) +
+ + +
+ + +@code{ + [Parameter] + public string EntryName { get; set; } + + public override string Render() => new ComponentRenderer() + .UseLayout() + .AddServiceProvider(ApplicationInfo.services) + .Set(c => c.EntryName, EntryName).Render(); +} + + + diff --git a/BLAZAMEmailMessage/Email/Notifications/EntryGroupAssignmentEmailMessage.razor b/BLAZAMEmailMessage/Email/Notifications/EntryGroupAssignmentEmailMessage.razor new file mode 100644 index 00000000..ee922d5f --- /dev/null +++ b/BLAZAMEmailMessage/Email/Notifications/EntryGroupAssignmentEmailMessage.razor @@ -0,0 +1,28 @@ +@using BLAZAM.Helpers +@using System.Security +@inherits NotificationTemplateComponent + + + @AppLocalization["Group membership changed"] + + + + @(AppLocalization["he password for "] + EntryName + AppLocalization[" has been changed."]) +
+ + +
+ + +@code{ + [Parameter] + public string EntryName { get; set; } + + public override string Render() => new ComponentRenderer() + .UseLayout() + .AddServiceProvider(ApplicationInfo.services) + .Set(c => c.EntryName, EntryName).Render(); +} + + + diff --git a/BLAZAMGui/UI/AppComponentBase.razor.cs b/BLAZAMGui/UI/AppComponentBase.razor.cs index 55ec62a9..e1f08866 100644 --- a/BLAZAMGui/UI/AppComponentBase.razor.cs +++ b/BLAZAMGui/UI/AppComponentBase.razor.cs @@ -1,9 +1,7 @@ using BLAZAM.ActiveDirectory; -using BLAZAM.Email.Services; using BLAZAM.Services.Audit; using BLAZAM.Services.Chat; -using BLAZAM.Common; using BLAZAM.Nav; namespace BLAZAM.Gui.UI @@ -44,8 +42,7 @@ public class AppComponentBase : ComponentBase,IDisposable [Inject] public ICurrentUserStateService CurrentUser { get; set; } - // protected IApplicationUserState? CurrentUser => UserStateService.CurrentUserState; - + [Inject] protected AuditLogger AuditLogger { get; set; } @@ -85,7 +82,6 @@ public class AppComponentBase : ComponentBase,IDisposable protected override void OnInitialized() { base.OnInitialized(); - //Nav = new AppNavigationManager(BaseNav); try { Context = DbFactory.CreateDbContext(); @@ -151,9 +147,7 @@ protected void Refresh(bool forceReload = false) public virtual void Dispose() { - //Remove for issue #235, Dependency Injection automatically - //disposes of objects after they are no longer needed. - //Context?.Dispose(); + //This object requires no further disposal } public async Task CopyToClipboard(string? text) diff --git a/BLAZAMGui/UI/AppModalContentBase.razor b/BLAZAMGui/UI/AppModalContentBase.razor index ac3755ef..bc2027f1 100644 --- a/BLAZAMGui/UI/AppModalContentBase.razor +++ b/BLAZAMGui/UI/AppModalContentBase.razor @@ -1,5 +1,4 @@ -@using BLAZAM.Email.Services; -@using BLAZAM.Services.Chat; +@using BLAZAM.Services.Chat; @code { diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index 68ba1148..4e786d44 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -186,7 +186,6 @@ { MessageService.ShowMessage(output.ToDialogParameters(), AppLocalization["Update"]); await output.RunAsync(); - // SnackBarService.Success("Update started successfully. The web application will restart and update momentarily."); } await InvokeAsync(StateHasChanged); diff --git a/BLAZAMJobs/BLAZAMJobs.csproj b/BLAZAMJobs/BLAZAMJobs.csproj index e0a6bcc6..0981eca5 100644 --- a/BLAZAMJobs/BLAZAMJobs.csproj +++ b/BLAZAMJobs/BLAZAMJobs.csproj @@ -7,6 +7,11 @@ BLAZAM.Jobs
+ + + + + diff --git a/BLAZAMJobs/Job.cs b/BLAZAMJobs/Job.cs index fb03d411..42e2d2f2 100644 --- a/BLAZAMJobs/Job.cs +++ b/BLAZAMJobs/Job.cs @@ -1,7 +1,4 @@ -using BLAZAM.Common.Data; -using BLAZAM.Database.Models.User; -using BLAZAM.Session.Interfaces; -using Microsoft.AspNetCore.Components; + namespace BLAZAM.Jobs { diff --git a/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs b/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs index 975e4efb..87e21875 100644 --- a/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs +++ b/BLAZAMNotifications/Notifications/NotificationTypeExtentions.cs @@ -1,9 +1,4 @@ using BLAZAM.Database.Models.Notifications; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BLAZAM.Notifications.Notifications { @@ -17,6 +12,19 @@ public static class NotificationTypeExtentions case NotificationType.PasswordChange: notificationTemplate = new PasswordChangedEmailMessage(); break; + case NotificationType.Create: + notificationTemplate = new EntryCreatedEmailMessage(); + break; + case NotificationType.Delete: + notificationTemplate = new EntryDeletedEmailMessage(); + break; + case NotificationType.Modify: + notificationTemplate = new EntryEditedEmailMessage(); + break; + case NotificationType.GroupAssignment: + notificationTemplate = new EntryGroupAssignmentEmailMessage(); + break; + } if(notificationTemplate != null) { diff --git a/BLAZAMServices/BLAZAMServices.csproj b/BLAZAMServices/BLAZAMServices.csproj index 19291ced..168cc399 100644 --- a/BLAZAMServices/BLAZAMServices.csproj +++ b/BLAZAMServices/BLAZAMServices.csproj @@ -12,6 +12,7 @@ + diff --git a/BLAZAMEmail/Services/EmailService.cs b/BLAZAMServices/Background/EmailService.cs similarity index 92% rename from BLAZAMEmail/Services/EmailService.cs rename to BLAZAMServices/Background/EmailService.cs index 164ff8f4..799a5bc1 100644 --- a/BLAZAMEmail/Services/EmailService.cs +++ b/BLAZAMServices/Background/EmailService.cs @@ -5,28 +5,37 @@ using MailKit.Security; using Microsoft.AspNetCore.Components; using MimeKit; -using MimeKit.Text; using MimeKit.Utils; using BLAZAM.Database.Models; using BLAZAM.Database.Context; using BLAZAM.Helpers; using BLAZAM.Common.Exceptions; -using BLAZAM.Logger; using BLAZAM.EmailMessage; using BLAZAM.EmailMessage.Email; using BLAZAM.Common.Data; using BLAZAM.Static; -using PreMailer.Net; using BLAZAM.FileSystem; using BLAZAM.EmailMessage.Email.Base; -namespace BLAZAM.Email.Services +namespace BLAZAM.Services.Background { public class EmailService { public static EmailService? Instance { get; set; } private IAppDatabaseFactory Factory { get; set; } + public bool IsConfigured + { + get + { + EmailSettings? settings = GetSettings(); + if (settings != null && settings.Valid()) + { + return true; + } + return false; + } + } public EmailService(IAppDatabaseFactory factory) { @@ -48,7 +57,7 @@ public EmailService(IAppDatabaseFactory factory) /// renders it, and returns the raw HTML ///
/// - /// The provided can not have any Blazorise components, only base Blazor + /// The provided can use basic MudBlazor components and Blazor components /// /// /// @@ -122,9 +131,10 @@ private MimeMessage BuildMessage(string subject, string to, string body, string? { var email = new MimeMessage(); - EmailSettings? settings = GetSettings(); - if (settings != null && settings.Valid()) + if (IsConfigured) { + EmailSettings? settings = GetSettings(); + if (settings.UseSMTPAuth && settings.FromAddress.IsNullOrEmpty()) email.From.Add(MailboxAddress.Parse(settings.SMTPUsername)); else email.From.Add(MailboxAddress.Parse(settings.FromAddress)); @@ -165,7 +175,7 @@ public string PrepareHTMLForEmail(string body) { SystemFile css = new SystemFile(ApplicationInfo.applicationRoot + "\\wwwroot\\lib\\mudblazor\\css\\mudblazor.min.css"); var preMailer = new PreMailer.Net.PreMailer(body); - body = preMailer.MoveCssInline(stripIdAndClassAttributes: true,css:css.ReadAllText()).Html; + body = preMailer.MoveCssInline(stripIdAndClassAttributes: true, css: css.ReadAllText()).Html; return body; } @@ -220,7 +230,7 @@ public async Task SendMessage(string subject, NotificationTemplateComponen var client = await GetSmtpClientAsync(); - var message = BuildMessage(subject, to,body.Render(), cc, bcc); + var message = BuildMessage(subject, to, body.Render(), cc, bcc); return await TrySend(client, message); } @@ -230,7 +240,7 @@ public async Task SendMessage(string subject, NotificationTemplateComponen } - catch(Exception ex) + catch (Exception ex) { throw ex; } diff --git a/BLAZAMServices/Background/OUNotificationService.cs b/BLAZAMServices/Background/OUNotificationService.cs index ddedaf88..1853a728 100644 --- a/BLAZAMServices/Background/OUNotificationService.cs +++ b/BLAZAMServices/Background/OUNotificationService.cs @@ -2,17 +2,14 @@ using BLAZAM.Database.Context; using BLAZAM.Database.Models.Notifications; using BLAZAM.Database.Models.User; +using BLAZAM.EmailMessage.Email.Base; +using BLAZAM.EmailMessage.Email.Notifications; +using BLAZAM.Helpers; using BLAZAM.Localization; using BLAZAM.Logger; +using BLAZAM.Notifications.Notifications; using BLAZAM.Notifications.Services; -using BLAZAM.Session.Interfaces; -using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.Localization; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BLAZAM.Services.Background { @@ -21,12 +18,14 @@ public class OUNotificationService private IAppDatabaseFactory _databaseFactory; private readonly INotificationPublisher _notificationPublisher; private readonly IStringLocalizer _appLocalization; + private readonly EmailService _emailService; - public OUNotificationService(IAppDatabaseFactory databaseFactory,INotificationPublisher notificationPublisher, IStringLocalizerappLocalization) + public OUNotificationService(IAppDatabaseFactory databaseFactory,INotificationPublisher notificationPublisher, IStringLocalizerappLocalization,EmailService emailService) { _databaseFactory = databaseFactory; _notificationPublisher = notificationPublisher; _appLocalization = appLocalization; + _emailService=emailService; } private IDatabaseContext Context => _databaseFactory.CreateDbContext(); public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType notificationType) @@ -37,6 +36,7 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti notificationTitle = _appLocalization[source.ObjectType.ToString()] + " "; string notificationBody; + NotificationTemplateComponent? emailMessage=null; notificationBody = "" + source.CanonicalName + " "; switch (notificationType) @@ -44,26 +44,30 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti case NotificationType.Create: notificationTitle += _appLocalization["Created"]; notificationBody += _appLocalization["was created at"] + source.Created.Value.ToLocalTime(); - + emailMessage = NotificationType.Create.ToNotification(); break; case NotificationType.Delete: notificationTitle += _appLocalization["Deleted"]; notificationBody += _appLocalization["was deleted at"] + source.LastChanged.Value.ToLocalTime(); + emailMessage = NotificationType.Delete.ToNotification(); break; case NotificationType.Modify: notificationTitle += _appLocalization["Modified"]; notificationBody += _appLocalization["was modified at"] + source.LastChanged.Value.ToLocalTime(); + emailMessage = NotificationType.Modify.ToNotification(); break; case NotificationType.GroupAssignment: notificationTitle += _appLocalization["Group Membership Changed"]; notificationBody += _appLocalization["was modified at"] + source.LastChanged.Value.ToLocalTime(); + emailMessage = NotificationType.GroupAssignment.ToNotification(); break; case NotificationType.PasswordChange: notificationTitle += _appLocalization["Password Reset"]; notificationBody += _appLocalization["had a password reset at"] + source.LastChanged.Value.ToLocalTime(); + emailMessage = NotificationType.PasswordChange.ToNotification(); break; @@ -74,8 +78,12 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti notification.Dismissable = true; notification.Created = DateTime.Now; notification.Level = NotificationLevel.Info; - - foreach (var user in Context.UserSettings.ToList()) + var _emailConfigured = false; + if (_emailService.IsConfigured) + { + _emailConfigured = true; + } + foreach (var user in Context.UserSettings.ToList()) { var effectiveInAppSubscriptions = CalculateEffectiveInAppSubscriptions(user, source); var effectiveEmailSubscriptions = CalculateEffectiveEmailSubscriptions(user, source); @@ -83,6 +91,22 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti { _notificationPublisher.PublishNotification(user, notification); } + if (effectiveEmailSubscriptions.NotificationTypes.Any(x => x.NotificationType == notificationType)) + { + if (emailMessage != null) + { + if (_emailConfigured && !user.Email.IsNullOrEmpty()) + { + await _emailService.SendMessage(notificationTitle, emailMessage, user.Email); + + } + } + else + { + var error = new ApplicationException(); + Loggers.SystemLogger.Error("Email message template was not found! {@Error}",error); + } + } } } public NotificationSubscription CalculateEffectiveEmailSubscriptions(AppUser user, IDirectoryEntryAdapter ou) diff --git a/BLAZAMSession/ApplicationUserState.cs b/BLAZAMSession/ApplicationUserState.cs index 1cb17ea5..c1a893ef 100644 --- a/BLAZAMSession/ApplicationUserState.cs +++ b/BLAZAMSession/ApplicationUserState.cs @@ -7,7 +7,6 @@ using BLAZAM.Database.Models.User; using BLAZAM.Helpers; using BLAZAM.Logger; -using BLAZAM.Notifications.Services; using BLAZAM.Session.Interfaces; using Microsoft.AspNetCore.Authentication; using Microsoft.EntityFrameworkCore; @@ -78,20 +77,13 @@ public IList? Notifications public DateTime lastDataRefresh; public AppUser? userSettings { get; set; } - private readonly INotificationPublisher _notificationPublisher; private readonly IAppDatabaseFactory _dbFactory; - public ApplicationUserState(IAppDatabaseFactory factory, INotificationPublisher notificationPublisher) + public ApplicationUserState(IAppDatabaseFactory factory) { - _notificationPublisher = notificationPublisher; _dbFactory = factory; - //userSettings = new(); - _notificationPublisher.OnNotificationPublished += (notifications) => - { - if (notifications.Select(n => n.User).Contains(Preferences)) - GetUserSettingFromDB(); - }; + OnSettingsChanged += (state) => { if (Id == state.Id) { diff --git a/BLAZAMSession/ApplicationUserStateService.cs b/BLAZAMSession/ApplicationUserStateService.cs index 3a2ed11d..c604010f 100644 --- a/BLAZAMSession/ApplicationUserStateService.cs +++ b/BLAZAMSession/ApplicationUserStateService.cs @@ -3,7 +3,6 @@ using BLAZAM.Common.Data.Services; using BLAZAM.Database.Context; using BLAZAM.Logger; -using BLAZAM.Notifications.Services; using BLAZAM.Session.Interfaces; using Microsoft.AspNetCore.Components.Server.Circuits; using Microsoft.AspNetCore.Http; @@ -24,7 +23,6 @@ namespace BLAZAM.Server.Data.Services ///
public class ApplicationUserStateService : IApplicationUserStateService { - private INotificationPublisher _notificationPublisher; public static IApplicationUserStateService Instance { get; private set; } @@ -68,10 +66,8 @@ public class ApplicationUserStateService : IApplicationUserStateService /// An HTTP Context Accessor to get the current ClaimsPrincipal of the current session. /// This Principal is persisted via the browser authentication cookie /// Database Context Factory for accessing the Authentication Setting - SessionTimeout - public ApplicationUserStateService(IHttpContextAccessor httpContextAccessor, IAppDatabaseFactory factory, - INotificationPublisher notificationPublisher) + public ApplicationUserStateService(IHttpContextAccessor httpContextAccessor, IAppDatabaseFactory factory) { - _notificationPublisher = notificationPublisher; Instance = this; _httpContextAccessor = httpContextAccessor; _factory = factory; @@ -240,7 +236,7 @@ public void RemoveUserState(IApplicationUserState state) public IApplicationUserState CreateUserState(ClaimsPrincipal user) { - return new ApplicationUserState(_factory, _notificationPublisher) { User = user }; + return new ApplicationUserState(_factory) { User = user }; } } } diff --git a/BLAZAMSession/BLAZAMSession.csproj b/BLAZAMSession/BLAZAMSession.csproj index c1cb444d..1c18bc9b 100644 --- a/BLAZAMSession/BLAZAMSession.csproj +++ b/BLAZAMSession/BLAZAMSession.csproj @@ -10,7 +10,6 @@ - diff --git a/BLAZAMUpdate/ApplicationUpdate.cs b/BLAZAMUpdate/ApplicationUpdate.cs index 09666920..2f3fcf3c 100644 --- a/BLAZAMUpdate/ApplicationUpdate.cs +++ b/BLAZAMUpdate/ApplicationUpdate.cs @@ -188,6 +188,7 @@ public IJob GetUpdateJob() var stagingCheckStep = new JobStep("Check prepared files", (step) => { return UpdateStagingDirectory.Exists; }); var bakupStep = new JobStep("Create backup", Backup); var updateUpdaterStep = new JobStep("Apply Files", InitiateFileCopy); + var waitForRestart = new JobStep("Wait for completion...",Wait); updateJob.AddStep(cleanDownloadStep); updateJob.AddStep(downloadStep); updateJob.AddStep(cleanStageStep); @@ -207,8 +208,14 @@ public IJob GetUpdateJob() throw new ApplicationUpdateException("An unknown error caused the update to fail."); } - - private async Task InitiateFileCopy(JobStep? step) + private async Task Wait(JobStep? step) + { + while (true) + { + await Task.Delay(1000); + } + } + private async Task InitiateFileCopy(JobStep? step) { //All prerequisites met diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index f4572c78..b06fabac 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -1,18 +1,15 @@  using Octokit; -using BLAZAM.Common; using BLAZAM.Update.Exceptions; using BLAZAM.Logger; using BLAZAM.Helpers; using BLAZAM.Common.Data; using BLAZAM.Database.Context; using System.Security.Principal; -using System.Reflection.Metadata.Ecma335; using System.Diagnostics; using BLAZAM.Localization; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.Localization; -using System.Net.WebSockets; namespace BLAZAM.Update.Services { @@ -49,7 +46,7 @@ public class UpdateService : UpdateServiceBase protected readonly IHttpClientFactory httpClientFactory; private readonly ApplicationInfo _applicationInfo; - public UpdateService(IHttpClientFactory _clientFactory, ApplicationInfo applicationInfo, IAppDatabaseFactory? dbFactory = null, IStringLocalizer appLocalization=null) + public UpdateService(IHttpClientFactory _clientFactory, ApplicationInfo applicationInfo, IAppDatabaseFactory? dbFactory = null, IStringLocalizer appLocalization = null) { _dbFactory = dbFactory; httpClientFactory = _clientFactory; @@ -108,7 +105,8 @@ private async Task GetReleases() latestBranchRelease = branchReleases.FirstOrDefault(); //Store all other releases for use later AvailableUpdates.Clear(); - try { + try + { var betaStableReleases = releases.Where(r => r.TagName.Contains("Stable", StringComparison.OrdinalIgnoreCase)); foreach (var release in betaStableReleases) @@ -125,7 +123,7 @@ private async Task GetReleases() { Loggers.UpdateLogger.Error("Error trying to get beta releases {@Error}", ex); } - + foreach (var release in stableReleases) { //Get the release filename to prepare a version object @@ -139,63 +137,18 @@ private async Task GetReleases() var latestBranchUpdate = EncapsulateUpdate(latestBranchRelease, SelectedBranch); if (latestBranchUpdate.Branch != ApplicationReleaseBranches.Stable && latestBranchUpdate.Branch != "Stable") { - if (!AvailableUpdates.Contains(latestBranchUpdate)) - { - AvailableUpdates.Add(latestBranchUpdate); - } - + if (!AvailableUpdates.Contains(latestBranchUpdate)) + { + AvailableUpdates.Add(latestBranchUpdate); + } + } IncompatibleUpdates = AvailableUpdates.Where(x => !x.PassesPrerequisiteChecks).ToList(); foreach (var release in IncompatibleUpdates) { AvailableUpdates.Remove(release); } - ////Override branch if stable has more recent release - //if (latestStableUpdate!=null) - //{ - // if(latestBranchUpdate!=null) - // { - // if (latestStableUpdate.Version.NewerThan(latestBranchUpdate.Version)) - // { - // LatestUpdate = latestStableUpdate; - - // } - // else - // { - // LatestUpdate = latestBranchUpdate; - - // } - - // } - // else - // { - // LatestUpdate = latestStableUpdate; - - // } - - //} - //if (Debugger.IsAttached) - //{ - // ApplicationUpdate? testUpdate = EncapsulateUpdate(latestRelease, SelectedBranch); - - // testUpdate.PreRequisiteChecks.Add(new(() => { - // if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) - // { - // testUpdate.PrequisiteMessage = "ASP NET Core 8 Runtime is missing."; - // return false; - - // } - // if (ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCoreHosting()) - // { - // testUpdate.PrequisiteMessage = "ASP NET Core 8 Web Hosting Bundle is missing."; - // return false; - - // } - // return true; - // })); - // testUpdate.Version = new ApplicationVersion("1.0.0.2024.07.01.0000"); - // LatestUpdate = testUpdate; - //} + } /// @@ -212,9 +165,9 @@ private async Task SetBranch() { using var context = await _dbFactory.CreateDbContextAsync(); SelectedBranch = context.AppSettings.FirstOrDefault()?.UpdateBranch; - if(SelectedBranch == "Stable") + if (SelectedBranch == "Stable") { - context.AppSettings.FirstOrDefault().UpdateBranch= ApplicationReleaseBranches.Stable; + context.AppSettings.FirstOrDefault().UpdateBranch = ApplicationReleaseBranches.Stable; SelectedBranch = ApplicationReleaseBranches.Stable; context.SaveChanges(); } @@ -240,7 +193,7 @@ private async Task SetBranch() releaseVersion = new ApplicationVersion(filename.Substring(filename.IndexOf("-v") + 2)); - + if (releaseToEncapsulate != null && releaseVersion != null) @@ -253,13 +206,14 @@ private async Task SetBranch() }; var update = new ApplicationUpdate(_applicationInfo, _dbFactory) { Release = release }; - if(releaseVersion.NewerThan(new ApplicationVersion("0.9.99"))) + if (releaseVersion.NewerThan(new ApplicationVersion("0.9.99"))) { - update.PreRequisiteChecks.Add(new(() => { - if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) + update.PreRequisiteChecks.Add(new(() => + { + if (!ApplicationInfo.isUnderIIS && !PrerequisiteChecker.CheckForAspCore()) { - if(AppLocalization!=null) - update.PrequisiteMessage = AppLocalization["ASP NET Core 8 Runtime is missing."]; + if (AppLocalization != null) + update.PrequisiteMessage = AppLocalization["ASP NET Core 8 Runtime is missing."]; else update.PrequisiteMessage = "ASP NET Core 8 Runtime is missing."; @@ -354,7 +308,7 @@ private bool TestCustomCredentials() private bool TestDirectoryCredentials() { - if(_dbFactory == null)return false; + if (_dbFactory == null) return false; using var context = _dbFactory.CreateDbContext(); //Prepare impersonation WindowsImpersonation? impersonation = null; From 970ad0f91857d68f8939810f891eb3e92539d9a5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:03:25 -0400 Subject: [PATCH 068/116] Self Notification Subscription Management --- BLAZAMGui/Layouts/AppUserButton.razor | 9 +++ .../EditNotificationSubscriptionRow.razor | 15 +++-- .../NotificaionSubscriptionEditor.razor | 34 +++++++++++ .../Notifications/NotificationSettings.razor | 29 +-------- .../OUNotificationSubscriptions.razor | 60 ++++++++++++++++--- 5 files changed, 108 insertions(+), 39 deletions(-) create mode 100644 BLAZAMGui/UI/Settings/Notifications/NotificaionSubscriptionEditor.razor diff --git a/BLAZAMGui/Layouts/AppUserButton.razor b/BLAZAMGui/Layouts/AppUserButton.razor index 385c5510..5ca02aa6 100644 --- a/BLAZAMGui/Layouts/AppUserButton.razor +++ b/BLAZAMGui/Layouts/AppUserButton.razor @@ -34,6 +34,9 @@ @AppLocalization["Profile Settings"] + + @AppLocalization["Notification Settings"] + @AppLocalization["Documentation"] @@ -58,8 +61,14 @@ + + + + + @code { AppModal? profileModal; + AppModal? notificationsModal; /// /// Indicates whether the notification panel is open /// diff --git a/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor b/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor index 4c12b319..ba3436dd 100644 --- a/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor +++ b/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor @@ -1,4 +1,4 @@ - +@inject IStringLocalizer AppLocalization @foreach (var type in Enum.GetValues(typeof(NotificationType))) { @@ -11,7 +11,6 @@ ValueChanged=@((bool val)=>{ToggleType(originalEnum,val);}) Value="@(Subscription.NotificationTypes.FirstOrDefault(x=>x.NotificationType==originalEnum)!=null)" /> - } @@ -29,9 +28,13 @@ @if (Subscription.Id == 0) { - + + @AppLocalization["Create"] + } else @@ -40,10 +43,12 @@ diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificaionSubscriptionEditor.razor b/BLAZAMGui/UI/Settings/Notifications/NotificaionSubscriptionEditor.razor new file mode 100644 index 00000000..8785e10c --- /dev/null +++ b/BLAZAMGui/UI/Settings/Notifications/NotificaionSubscriptionEditor.razor @@ -0,0 +1,34 @@ + + + + + @if (_selectedOU != null) + { + + + + } + + + + +@code{ + [Parameter] + public AppUser User {get;set;} + + IDirectoryEntryAdapter? _selectedOU = null; + + + private async void ouChanged(IDirectoryEntryAdapter entry) + { + var ou = (IADOrganizationalUnit)entry; + if (ou != null) + { + _selectedOU = ou; + await InvokeAsync(StateHasChanged); + } + } + +} \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor index 9e4b1a39..1a050404 100644 --- a/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor +++ b/BLAZAMGui/UI/Settings/Notifications/NotificationSettings.razor @@ -1,5 +1,5 @@ @inherits AppComponentBase -

@AppLocalization["Managee Notifications"]

+

@AppLocalization["Manage Notifications"]

@if (_selectedUser != null) { - - - - - @if (_selectedOU != null) - { - - - - } - - - + } @code { - IDirectoryEntryAdapter? _selectedOU = null; IList Users = new List(); AppUser? _selectedUser = null; protected override async Task OnInitializedAsync() @@ -37,15 +22,7 @@ if (value == null) value = String.Empty; return Users.Where(x => x.Username.Contains(value)); } - private async void ouChanged(IDirectoryEntryAdapter entry) - { - var ou = (IADOrganizationalUnit)entry; - if (ou != null) - { - _selectedOU = ou; - await InvokeAsync(StateHasChanged); - } - } + diff --git a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor index 1351b69f..9f3343fb 100644 --- a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor +++ b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor @@ -2,28 +2,52 @@ @inject OUNotificationService ouNotificationService + + + @(AppLocalization["Notification Settings for "]+_ou.CanonicalName) + + + + + + @AppLocalization["Events"] + + + @AppLocalization["Delivery"] + + + @AppLocalization[" "] + + + @AppLocalization[" "] + + - + @{ + bool first = true; + } @foreach (var type in Enum.GetValues(typeof(NotificationType))) { var originalEnum = (NotificationType)type; - + @originalEnum.ToString() + first=false; + } - + @AppLocalization["In App"] @AppLocalization["To Email"] - + @AppLocalization["Block"] - + @AppLocalization["Save"] @@ -37,10 +61,24 @@ + OnDeleted="DeleteExisting" /> } } + else + { + + + + @AppLocalization["No subscriptions are set for this OU"] + + + } + + + + + @@ -50,10 +88,16 @@ - - @AppLocalization["Effective Notification Settings"] + + + + + + + @(AppLocalization["Effective Notification Settings for "]+_ou.CanonicalName) + From 6d523d241edba21b840173bbd9fb58350e118c88 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:09:30 -0400 Subject: [PATCH 069/116] App news improvemnts --- BLAZAMGui/UI/Modals/AppNewsItemDialog.razor | 12 ++++++------ BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/BLAZAMGui/UI/Modals/AppNewsItemDialog.razor b/BLAZAMGui/UI/Modals/AppNewsItemDialog.razor index 2cadf069..997a7ca4 100644 --- a/BLAZAMGui/UI/Modals/AppNewsItemDialog.razor +++ b/BLAZAMGui/UI/Modals/AppNewsItemDialog.razor @@ -1,7 +1,7 @@ @using ApplicationNews @inherits AppComponentBase - + @((MarkupString)Item.Body) @@ -12,11 +12,11 @@ @if (!Item.Link.IsNullOrEmpty()) { @AppLocalization["Link"] + Href="@Item.Link" + Target="_blank">@Item.Link } - - + + @@ -42,7 +42,7 @@ private async void Acknowledge() { var existingReadItem = CurrentUser.State.ReadNewsItems.FirstOrDefault(x => x.NewsItemId == Item.Id); - if (existingReadItem!=null) + if (existingReadItem != null) { existingReadItem.NewsItemUpdatedAt = Item.UpdatedAt; } diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor index 2e617b57..f9b40b15 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor @@ -27,7 +27,7 @@ - + Blazam @AppLocalization["News"] @foreach (var item in unreadItems.OrderByDescending(x => x.UpdatedAt)) { @item.Title - @if (item.Link != null) + @* @if (item.Link != null) { @item.Link - } + } *@ } From c2efaa1c8509b1bc7792c2c2683aea132377e91b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:10:10 -0400 Subject: [PATCH 070/116] Auto Update registers actions as Jobs --- BLAZAMUpdate/Services/AutoUpdateService.cs | 113 ++++++++++++--------- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/BLAZAMUpdate/Services/AutoUpdateService.cs b/BLAZAMUpdate/Services/AutoUpdateService.cs index fc8073fc..ca6f959d 100644 --- a/BLAZAMUpdate/Services/AutoUpdateService.cs +++ b/BLAZAMUpdate/Services/AutoUpdateService.cs @@ -181,41 +181,47 @@ private void CleanDirectories(object? state) private async void CheckForUpdate(object? state) { - try - { - var appSettings = (await factory.CreateDbContextAsync()).AppSettings.FirstOrDefault(); + IJob updateCheckJob = new Job("Check for Update"); + IJobStep checkForUpdateStep = new JobStep("Execute", async(step) => { + try + { + var appSettings = (await factory.CreateDbContextAsync()).AppSettings.FirstOrDefault(); - Loggers.UpdateLogger.Information("Checking for automatic update"); + Loggers.UpdateLogger.Information("Checking for automatic update"); - var latestUpdate = await updateService.GetUpdates(); - if (latestUpdate != null && latestUpdate.Version.NewerThan(_applicationInfo.RunningVersion)) - { - IsUpdateAvailable = true; - if (appSettings.AutoUpdate && appSettings.AutoUpdateTime != null) + var latestUpdate = await updateService.GetUpdates(); + if (latestUpdate != null && latestUpdate.Version.NewerThan(_applicationInfo.RunningVersion)) { - if (latestUpdate.PassesPrerequisiteChecks) - ScheduleUpdate(appSettings.AutoUpdateTime.Value, latestUpdate); - else + IsUpdateAvailable = true; + if (appSettings.AutoUpdate && appSettings.AutoUpdateTime != null) { - Loggers.UpdateLogger.Warning("Update failed prerequisite check, cancelling scheduling {@Error}", latestUpdate.PrequisiteMessage); + if (latestUpdate.PassesPrerequisiteChecks) + ScheduleUpdate(appSettings.AutoUpdateTime.Value, latestUpdate); + else + { + Loggers.UpdateLogger.Warning("Update failed prerequisite check, cancelling scheduling {@Error}", latestUpdate.PrequisiteMessage); + } } + + } + else + { + IsUpdateAvailable = false; + Cancel(); + Loggers.UpdateLogger.Information("No new updates found."); + } } - else + catch (Exception ex) { - IsUpdateAvailable = false; - Cancel(); - Loggers.UpdateLogger.Information("No new updates found."); - + Loggers.UpdateLogger.Error("Error while checking for auto update {@Error}", ex); } - - } - catch (Exception ex) - { - Loggers.UpdateLogger.Error("Error while checking for auto update {@Error}", ex); - } + return true; + }); + updateCheckJob.AddStep(checkForUpdateStep); + await updateCheckJob.RunAsync(); } public void Cancel() { @@ -227,44 +233,51 @@ public void Cancel() public void ScheduleUpdate(TimeSpan updateTimeOfDay, ApplicationUpdate updateToInstall) { - try + IJob scheduleUpdatteJob = new Job("Schedule Update"); + IJobStep scheduleStep = new JobStep("Execute", async (step) => { - bool justScheduled = ScheduledUpdateTime == DateTime.MinValue && ScheduledUpdate != updateToInstall; - if (ScheduledUpdate != updateToInstall) + try { - Loggers.UpdateLogger.Information("New update found: " + updateToInstall.Version); + bool justScheduled = ScheduledUpdateTime == DateTime.MinValue && ScheduledUpdate != updateToInstall; + if (ScheduledUpdate != updateToInstall) + { + Loggers.UpdateLogger.Information("New update found: " + updateToInstall.Version); - //Update availabled - var now = DateTime.Now; - ScheduledUpdateTime = new DateTime(now.Year, now.Month, now.Day, updateTimeOfDay.Hours, updateTimeOfDay.Minutes, updateTimeOfDay.Seconds); + //Update availabled + var now = DateTime.Now; + ScheduledUpdateTime = new DateTime(now.Year, now.Month, now.Day, updateTimeOfDay.Hours, updateTimeOfDay.Minutes, updateTimeOfDay.Seconds); - //Check if we're past the scheduled time this day - if (ScheduledUpdateTime < now) - { - ScheduledUpdateTime = ScheduledUpdateTime.AddDays(1); - } + //Check if we're past the scheduled time this day + if (ScheduledUpdateTime < now) + { + ScheduledUpdateTime = ScheduledUpdateTime.AddDays(1); + } - TimeSpan timeUntilUpdate = ScheduledUpdateTime - now; + TimeSpan timeUntilUpdate = ScheduledUpdateTime - now; - ScheduledUpdate = updateToInstall; + ScheduledUpdate = updateToInstall; - autoUpdateApplyTimer = new Timer(Update, null, (int)timeUntilUpdate.TotalMilliseconds, Timeout.Infinite); - Loggers.UpdateLogger.Information("Auto-update scheduled: " + timeUntilUpdate.TotalMinutes + "mins from now at " + ScheduledUpdateTime); - if (justScheduled) - { - Loggers.UpdateLogger.Debug("Update just scheduled"); - OnAutoUpdateQueued?.Invoke(ScheduledUpdateTime); + autoUpdateApplyTimer = new Timer(Update, null, (int)timeUntilUpdate.TotalMilliseconds, Timeout.Infinite); + Loggers.UpdateLogger.Information("Auto-update scheduled: " + timeUntilUpdate.TotalMinutes + "mins from now at " + ScheduledUpdateTime); + if (justScheduled) + { + Loggers.UpdateLogger.Debug("Update just scheduled"); + OnAutoUpdateQueued?.Invoke(ScheduledUpdateTime); - } + } + } } - } - catch (Exception ex) - { - Loggers.UpdateLogger.Error("Error during auto update scheduling {@Error}", ex); - } + catch (Exception ex) + { + Loggers.UpdateLogger.Error("Error during auto update scheduling {@Error}", ex); + } + return true; + }); + scheduleUpdatteJob.AddStep(scheduleStep); + scheduleUpdatteJob.Run(); } private async void Update(object? state) From e9a04b7155012297f28357c2837deae17225187e Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:10:28 -0400 Subject: [PATCH 071/116] Async refresh modal --- BLAZAMGui/UI/AppModal.razor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BLAZAMGui/UI/AppModal.razor.cs b/BLAZAMGui/UI/AppModal.razor.cs index 0e5b1dbf..f570d415 100644 --- a/BLAZAMGui/UI/AppModal.razor.cs +++ b/BLAZAMGui/UI/AppModal.razor.cs @@ -131,9 +131,9 @@ protected override void OnInitialized() /// /// Re-renders the modal with the latest property values /// - public void RefreshView() + public async Task RefreshView() { - InvokeAsync(StateHasChanged); + await InvokeAsync(StateHasChanged); } /// From c6a062e7276e6eab865788d54d73ddb0c913f386 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:10:58 -0400 Subject: [PATCH 072/116] Fix for unable to save email in user profile settings --- .../Modals/AppUserProfileModalContent.razor | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor b/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor index 7e7ce0b8..21dee518 100644 --- a/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor +++ b/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor @@ -27,9 +27,9 @@ @if (CurrentUser.State.Preferences.ProfilePicture != null) { @@ -57,10 +57,37 @@ await CurrentUser.State.SaveUserSettings(); + @code { [CascadingParameter] public MainLayout mainLayout { get; set; } + protected override void OnInitialized() + { + base.OnInitialized(); + Modal.SetYesText(AppLocalization["Save"]); + Modal.OnYes += SaveSettings; + Modal.YesEnabled = () => { return !LoadingData; }; + } + private async void SaveSettings() + { + LoadingData = true; + await Modal.RefreshView(); + if (await CurrentUser.State.SaveUserSettings()) + { + SnackBarService.Success(AppLocalization["Settings saved"]); + + } + else + { + SnackBarService.Warning(AppLocalization["Failed to save settings"]); + + } + LoadingData = false; + await Modal.RefreshView(); + + + } #nullable disable warnings async Task UploadProfilePicture(IBrowserFile profilePictureFile) { @@ -69,7 +96,6 @@ await CurrentUser.State.SaveUserSettings(); if (rawBytes != null) { CurrentUser.State.Preferences.ProfilePicture = rawBytes.ReizeRawImage(100, true); - await CurrentUser.State.SaveUserSettings(); } } } From 2e26663ffe7b4305caca3c8d4d1d1a2bf6c75b43 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:11:13 -0400 Subject: [PATCH 073/116] Default user to System --- BLAZAMJobs/Job.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAMJobs/Job.cs b/BLAZAMJobs/Job.cs index 42e2d2f2..100a04a3 100644 --- a/BLAZAMJobs/Job.cs +++ b/BLAZAMJobs/Job.cs @@ -10,7 +10,7 @@ public class Job : JobStepBase, IJob, IJobStep private DateTime scheduledRunTime = DateTime.Now; private Timer? runScheduler; - public string? User { get; set; } + public string? User { get; set; } = "System"; private IList _steps = new List(); From 13927000913a9062579dc4a830ace29d3806cba5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:11:33 -0400 Subject: [PATCH 074/116] Global import for notifications gui --- BLAZAMGui/_Imports.razor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BLAZAMGui/_Imports.razor b/BLAZAMGui/_Imports.razor index 22f193b6..b7d7a6de 100644 --- a/BLAZAMGui/_Imports.razor +++ b/BLAZAMGui/_Imports.razor @@ -33,6 +33,8 @@ @using BLAZAM.Logger @using BLAZAM.Notifications.Services +@using BLAZAM.Gui.UI.Settings.Notifications + @using BLAZAM.Services @using BLAZAM.Services.Background @using BLAZAM.Session.Interfaces From 8ef57956553ffa6c353af2a4fe0fc22f49180f7d Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:22:44 -0400 Subject: [PATCH 075/116] Increment version --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 50d9e8bc..406f4410 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.23.1828 + 2024.07.27.1821 false BLAZAM False From 95c06990851f7663b5f7886673a932cb8799449d Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:32:42 -0400 Subject: [PATCH 076/116] Fix for possible email exception on email setttings page --- BLAZAMGui/UI/Settings/EmailSettings.razor | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BLAZAMGui/UI/Settings/EmailSettings.razor b/BLAZAMGui/UI/Settings/EmailSettings.razor index 10186cdd..0cd7544b 100644 --- a/BLAZAMGui/UI/Settings/EmailSettings.razor +++ b/BLAZAMGui/UI/Settings/EmailSettings.razor @@ -134,7 +134,8 @@ //message.User = user; //var html = message.Render(); //emailPreview = EmailService.PrepareHTMLForEmail(html); - emailPreview = EmailService.BuildMessage("BLAZAM Test Email", "to@test.com").HtmlBody; + if(EmailService.IsConfigured) + emailPreview = EmailService.BuildMessage("BLAZAM Test Email", "to@test.com").HtmlBody; LoadingData = false; await InvokeAsync(StateHasChanged); From 6b6c6a3808e362ec96ce90264e1df7237be66120 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 14:47:55 -0400 Subject: [PATCH 077/116] Fix for null insertion error when creating mulitiple notification subscriptions sequentially --- BLAZAMGui/UI/Settings/EmailSettings.razor | 4 ++-- .../Settings/Notifications/OUNotificationSubscriptions.razor | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/BLAZAMGui/UI/Settings/EmailSettings.razor b/BLAZAMGui/UI/Settings/EmailSettings.razor index 0cd7544b..5f501815 100644 --- a/BLAZAMGui/UI/Settings/EmailSettings.razor +++ b/BLAZAMGui/UI/Settings/EmailSettings.razor @@ -91,7 +91,7 @@ Send Test Email - @if (ApplicationInfo.InDebugMode) + @if (ApplicationInfo.InDebugMode && emailPreview!=null) { @code { #nullable disable warnings - string emailPreview; + string? emailPreview=null; BLAZAM.Database.Models.EmailSettings settings = new BLAZAM.Database.Models.EmailSettings(); string testRecipient; protected override async Task OnInitializedAsync() diff --git a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor index 9f3343fb..3eb3f19d 100644 --- a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor +++ b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor @@ -261,6 +261,8 @@ if (changes > 0) { newSubscription = new(); + newSubscription.UserId = User.Id; + newSubscription.OU = ou.DN; SnackBarService.Success(AppLocalization["Saved notification subscription"]); UpdateSubscriptions(); From bbf37e5b969681c47b2af0dd973ed2df486e7a3b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 15:51:57 -0400 Subject: [PATCH 078/116] Fully functional email notifications --- .../CurrentUserDashboardWidgets.razor | 35 ++++++++---- BLAZAMGui/UI/Dashboard/Widgets/AllWidgets.cs | 2 +- .../Widgets/ChangedEntriesWidget.razor | 2 +- .../Widgets/ChangedPasswordsWidget.razor | 44 +++++++++++++- .../Widgets/DeletedEntriesWidget.razor | 13 +---- BLAZAMGui/UI/Dashboard/Widgets/Widget.razor | 12 ++++ .../OUNotificationSubscriptions.razor | 2 +- BLAZAMServices/Background/EmailService.cs | 8 ++- .../Background/OUNotificationService.cs | 57 ++++++++++--------- 9 files changed, 119 insertions(+), 56 deletions(-) diff --git a/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor b/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor index c812516b..4fe38219 100644 --- a/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor +++ b/BLAZAMGui/UI/Dashboard/CurrentUserDashboardWidgets.razor @@ -40,18 +40,33 @@ @{ - var widget = allWidgets.First(w => w.WidgetType == context.WidgetType); - } - - - @widget.Title - - {await RemoveWidget(context);}) /> - - - + Widget? widget =null; + try + { + widget = allWidgets.First(w => w.WidgetType == context.WidgetType); + + } + catch + { + + } + if (widget != null) + { + + + @widget.Title + + {await RemoveWidget(context);}) /> + + + + + + } + } + } diff --git a/BLAZAMGui/UI/Dashboard/Widgets/AllWidgets.cs b/BLAZAMGui/UI/Dashboard/Widgets/AllWidgets.cs index 5b4caa78..defb9304 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/AllWidgets.cs +++ b/BLAZAMGui/UI/Dashboard/Widgets/AllWidgets.cs @@ -41,7 +41,7 @@ public static List Available(IApplicationUserState? applicationUser) widgets.Add(new NewComputersWidget() { WidgetType = DashboardWidgetType.NewComputers, Title = "Computers created in the last 14 days" }); if (applicationUser.IsSuperAdmin) { - widgets.Add(new ChangedPasswordsWidget() { WidgetType = DashboardWidgetType.PasswordsChanged, Title = "Password Changed" }); + //widgets.Add(new ChangedPasswordsWidget() { WidgetType = DashboardWidgetType.PasswordsChanged, Title = "Password Changed" }); widgets.Add(new DeletedEntriesWidget() { WidgetType = DashboardWidgetType.DeletedEntries, Title = "Entries deleted in the last 14 days" }); } diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor index 019aa729..9f65b1cd 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor @@ -57,7 +57,7 @@ { var search = new ADSearch(); - search.Fields.Changed = DateTime.Now.AddDays(-1); + search.Fields.PasswordLastSet = DateTime.Now.AddDays(-1).ToFileTimeUtc().ToString(); changdEntries = (await search.SearchAsync()).Where(x => x.CanRead).ToList(); LoadingData = false; await InvokeAsync(StateHasChanged); diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor index 78b06042..9d654d68 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor @@ -1,8 +1,46 @@ @inherits Widget @attribute [Authorize] -
-

User passwords changed in the last 90 days

+ + + + + + @context.Item?.CanonicalName + + + + + + @(((IADUser)context.Item).PasswordLastSet) + + + + + + + + + + + + + +@*
+
@foreach (var user in LockedUsers) @@ -21,7 +59,7 @@ }
-
+
*@ @code { List LockedUsers = new(); diff --git a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor index fe93b838..8bb5a0d7 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor @@ -56,16 +56,7 @@ } - void RowClicked(DataGridRowClickEventArgs args) - { - if (args.Item != null) - { - GoTo(args.Item); - } - } + - void GoTo(IDirectoryEntryAdapter args) - { - Nav.NavigateTo(args.SearchUri); - } + } diff --git a/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor b/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor index 36fb0916..175da2ed 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor @@ -5,4 +5,16 @@ public RenderFragment? WidgetContent { get; set; } public string Title{ get; set; } public DashboardWidgetType WidgetType{ get; set; } + + protected virtual void RowClicked(DataGridRowClickEventArgs args) + { + if (args.Item != null) + { + GoTo(args.Item); + } + } + protected virtual void GoTo(IDirectoryEntryAdapter args) + { + Nav.NavigateTo(args.SearchUri); + } } diff --git a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor index 3eb3f19d..ec471f73 100644 --- a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor +++ b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor @@ -262,7 +262,7 @@ { newSubscription = new(); newSubscription.UserId = User.Id; - newSubscription.OU = ou.DN; + newSubscription.OU = OU.DN; SnackBarService.Success(AppLocalization["Saved notification subscription"]); UpdateSubscriptions(); diff --git a/BLAZAMServices/Background/EmailService.cs b/BLAZAMServices/Background/EmailService.cs index 799a5bc1..57415d20 100644 --- a/BLAZAMServices/Background/EmailService.cs +++ b/BLAZAMServices/Background/EmailService.cs @@ -16,6 +16,7 @@ using BLAZAM.Static; using BLAZAM.FileSystem; using BLAZAM.EmailMessage.Email.Base; +using System.Configuration; namespace BLAZAM.Services.Background { @@ -135,9 +136,10 @@ private MimeMessage BuildMessage(string subject, string to, string body, string? { EmailSettings? settings = GetSettings(); - if (settings.UseSMTPAuth && settings.FromAddress.IsNullOrEmpty()) email.From.Add(MailboxAddress.Parse(settings.SMTPUsername)); - else email.From.Add(MailboxAddress.Parse(settings.FromAddress)); - + if (settings.UseSMTPAuth && settings.FromAddress.IsNullOrEmpty()) email.Sender=MailboxAddress.Parse(settings.SMTPUsername); + else email.Sender=MailboxAddress.Parse(settings.FromAddress); + if(!settings.FromName.IsNullOrEmpty()) email.Sender.Name = settings.FromName; + email.From.Add(email.Sender); if (to != null) email.To.Add(MailboxAddress.Parse(to)); if (cc != null) email.Cc.Add(MailboxAddress.Parse(cc)); if (bcc != null) email.Bcc.Add(MailboxAddress.Parse(bcc)); diff --git a/BLAZAMServices/Background/OUNotificationService.cs b/BLAZAMServices/Background/OUNotificationService.cs index 1853a728..1dc895dc 100644 --- a/BLAZAMServices/Background/OUNotificationService.cs +++ b/BLAZAMServices/Background/OUNotificationService.cs @@ -20,12 +20,12 @@ public class OUNotificationService private readonly IStringLocalizer _appLocalization; private readonly EmailService _emailService; - public OUNotificationService(IAppDatabaseFactory databaseFactory,INotificationPublisher notificationPublisher, IStringLocalizerappLocalization,EmailService emailService) + public OUNotificationService(IAppDatabaseFactory databaseFactory, INotificationPublisher notificationPublisher, IStringLocalizer appLocalization, EmailService emailService) { _databaseFactory = databaseFactory; _notificationPublisher = notificationPublisher; _appLocalization = appLocalization; - _emailService=emailService; + _emailService = emailService; } private IDatabaseContext Context => _databaseFactory.CreateDbContext(); public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType notificationType) @@ -36,7 +36,7 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti notificationTitle = _appLocalization[source.ObjectType.ToString()] + " "; string notificationBody; - NotificationTemplateComponent? emailMessage=null; + NotificationTemplateComponent? emailMessage = null; notificationBody = "" + source.CanonicalName + " "; switch (notificationType) @@ -44,33 +44,40 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti case NotificationType.Create: notificationTitle += _appLocalization["Created"]; notificationBody += _appLocalization["was created at"] + source.Created.Value.ToLocalTime(); - emailMessage = NotificationType.Create.ToNotification(); + var createdMessage = NotificationType.Create.ToNotification(); + createdMessage.EntryName = source.CanonicalName; + emailMessage = createdMessage; break; - case NotificationType.Delete: + case NotificationType.Delete: notificationTitle += _appLocalization["Deleted"]; notificationBody += _appLocalization["was deleted at"] + source.LastChanged.Value.ToLocalTime(); - emailMessage = NotificationType.Delete.ToNotification(); - + 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.Value.ToLocalTime(); - emailMessage = NotificationType.Modify.ToNotification(); - + var editedMessage = NotificationType.Modify.ToNotification(); + editedMessage.EntryName = source.CanonicalName; + emailMessage = editedMessage; break; case NotificationType.GroupAssignment: notificationTitle += _appLocalization["Group Membership Changed"]; notificationBody += _appLocalization["was modified at"] + source.LastChanged.Value.ToLocalTime(); - emailMessage = NotificationType.GroupAssignment.ToNotification(); - + + 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.Value.ToLocalTime(); - emailMessage = NotificationType.PasswordChange.ToNotification(); - + var passwordChangeMessage = NotificationType.PasswordChange.ToNotification(); + passwordChangeMessage.EntryName = source.CanonicalName; + emailMessage = passwordChangeMessage; break; - + } var notification = new NotificationMessage(); notification.Title = notificationTitle; @@ -78,18 +85,15 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti notification.Dismissable = true; notification.Created = DateTime.Now; notification.Level = NotificationLevel.Info; - var _emailConfigured = false; - if (_emailService.IsConfigured) - { - _emailConfigured = true; - } - foreach (var user in Context.UserSettings.ToList()) + var _emailConfigured = _emailService.IsConfigured; + + foreach (var user in Context.UserSettings.ToList()) { var effectiveInAppSubscriptions = CalculateEffectiveInAppSubscriptions(user, source); var effectiveEmailSubscriptions = CalculateEffectiveEmailSubscriptions(user, source); if (effectiveInAppSubscriptions.NotificationTypes.Any(x => x.NotificationType == notificationType)) { - _notificationPublisher.PublishNotification(user, notification); + await _notificationPublisher.PublishNotification(user, notification); } if (effectiveEmailSubscriptions.NotificationTypes.Any(x => x.NotificationType == notificationType)) { @@ -104,7 +108,7 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti else { var error = new ApplicationException(); - Loggers.SystemLogger.Error("Email message template was not found! {@Error}",error); + Loggers.SystemLogger.Error("Email message template was not found! {@Error}", error); } } } @@ -159,7 +163,8 @@ public NotificationSubscription CalculateEffectiveEmailSubscriptions(AppUser use } } - }catch (Exception ex) + } + catch (Exception ex) { Loggers.SystemLogger.Error("Error while parsing users for notification broadcast {@Error}", ex); } @@ -179,7 +184,7 @@ public NotificationSubscription CalculateEffectiveInAppSubscriptions(AppUser use effectiveInAppSubscription.OU = ou.DN; effectiveInAppSubscription.User = user; effectiveInAppSubscription.InApp = true; - + var userSubscriptions = context.NotificationSubscriptions.Where(x => x.DeletedAt == null && x.UserId == user.Id).ToList(); userSubscriptions = userSubscriptions.OrderBy(x => x.OU).ToList(); foreach (var sub in userSubscriptions) @@ -195,7 +200,7 @@ public NotificationSubscription CalculateEffectiveInAppSubscriptions(AppUser use effectiveInAppSubscription.NotificationTypes.RemoveAll(x => x.NotificationType == type.NotificationType); } } - + } else { @@ -209,7 +214,7 @@ public NotificationSubscription CalculateEffectiveInAppSubscriptions(AppUser use } } } - + } From c64c24f5a54ea700a9f0de15ae6a5bc87e339d48 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 15:57:01 -0400 Subject: [PATCH 079/116] Increment minor version --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 406f4410..977c18f3 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -5,7 +5,7 @@ enable enable false - 0.9.4 + 0.9.5 2024.07.27.1821 false BLAZAM From 5fc4fd8e351f068c61e2892f3d7d9885e79d4234 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 16:04:35 -0400 Subject: [PATCH 080/116] Update dependencies --- BLAZAM/BLAZAM.csproj | 6 +++--- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 4 ++-- BLAZAMJobs/BLAZAMJobs.csproj | 2 +- BLAZAMNotifications/BLAZAMNotifications.csproj | 2 +- BLAZAMThemes/BLAZAMThemes.csproj | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 977c18f3..4bc3c025 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.07.27.1821 + 2024.07.27.2003 false BLAZAM False @@ -78,8 +78,8 @@ - - + + diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index e6af1ffa..84a8390e 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -14,7 +14,7 @@ - + diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index ed4643a2..0222df55 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -27,8 +27,8 @@ - - + + diff --git a/BLAZAMJobs/BLAZAMJobs.csproj b/BLAZAMJobs/BLAZAMJobs.csproj index 0981eca5..b7983acf 100644 --- a/BLAZAMJobs/BLAZAMJobs.csproj +++ b/BLAZAMJobs/BLAZAMJobs.csproj @@ -8,7 +8,7 @@ - + diff --git a/BLAZAMNotifications/BLAZAMNotifications.csproj b/BLAZAMNotifications/BLAZAMNotifications.csproj index 44298634..23703469 100644 --- a/BLAZAMNotifications/BLAZAMNotifications.csproj +++ b/BLAZAMNotifications/BLAZAMNotifications.csproj @@ -8,7 +8,7 @@ - + diff --git a/BLAZAMThemes/BLAZAMThemes.csproj b/BLAZAMThemes/BLAZAMThemes.csproj index 2ede2c12..21aee388 100644 --- a/BLAZAMThemes/BLAZAMThemes.csproj +++ b/BLAZAMThemes/BLAZAMThemes.csproj @@ -8,8 +8,8 @@ - - + + From b4fc86b21614b9edd3bad87dace6ea17639f1c82 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 16:24:24 -0400 Subject: [PATCH 081/116] Remove unused class --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMUpdate/GithubArtifacts.cs | 32 -------------------------------- 2 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 BLAZAMUpdate/GithubArtifacts.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 4bc3c025..9c7647fa 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.07.27.2003 + 2024.07.27.2017 false BLAZAM False diff --git a/BLAZAMUpdate/GithubArtifacts.cs b/BLAZAMUpdate/GithubArtifacts.cs deleted file mode 100644 index ed3d7f95..00000000 --- a/BLAZAMUpdate/GithubArtifacts.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace BLAZAM.Update -{ - public class WorkflowRun - { - public int id { get; set; } - public int repository_id { get; set; } - public int head_repository_id { get; set; } - public string head_branch { get; set; } - public string head_sha { get; set; } - } - - public class Artifact - { - public int id { get; set; } - public string node_id { get; set; } - public string name { get; set; } - public int size_in_bytes { get; set; } - public string url { get; set; } - public string archive_download_url { get; set; } - public bool expired { get; set; } - public DateTime created_at { get; set; } - public DateTime expires_at { get; set; } - public DateTime updated_at { get; set; } - public WorkflowRun workflow_run { get; set; } - } - - public class ArtifactResponse - { - public int total_count { get; set; } - public List artifacts { get; set; } - } -} From c8a636a315d7c71e148c3da575393e271c4ce5e5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 27 Jul 2024 16:25:18 -0400 Subject: [PATCH 082/116] Remove unused class --- BLAZAMUpdate/GithubArtifacts.cs | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 BLAZAMUpdate/GithubArtifacts.cs diff --git a/BLAZAMUpdate/GithubArtifacts.cs b/BLAZAMUpdate/GithubArtifacts.cs deleted file mode 100644 index ed3d7f95..00000000 --- a/BLAZAMUpdate/GithubArtifacts.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace BLAZAM.Update -{ - public class WorkflowRun - { - public int id { get; set; } - public int repository_id { get; set; } - public int head_repository_id { get; set; } - public string head_branch { get; set; } - public string head_sha { get; set; } - } - - public class Artifact - { - public int id { get; set; } - public string node_id { get; set; } - public string name { get; set; } - public int size_in_bytes { get; set; } - public string url { get; set; } - public string archive_download_url { get; set; } - public bool expired { get; set; } - public DateTime created_at { get; set; } - public DateTime expires_at { get; set; } - public DateTime updated_at { get; set; } - public WorkflowRun workflow_run { get; set; } - } - - public class ArtifactResponse - { - public int total_count { get; set; } - public List artifacts { get; set; } - } -} From 6b6f98dcdf8a305f72608828ff82c4baa178d223 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:42:02 +0000 Subject: [PATCH 083/116] Bump Serilog from 4.0.0 to 4.0.1 Bumps [Serilog](https://github.com/serilog/serilog) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/serilog/serilog/releases) - [Commits](https://github.com/serilog/serilog/compare/v4.0.0...v4.0.1) --- updated-dependencies: - dependency-name: Serilog dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- BLAZAMFileSystem/BLAZAMFileSystem.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAMFileSystem/BLAZAMFileSystem.csproj b/BLAZAMFileSystem/BLAZAMFileSystem.csproj index f88022e7..560cb10b 100644 --- a/BLAZAMFileSystem/BLAZAMFileSystem.csproj +++ b/BLAZAMFileSystem/BLAZAMFileSystem.csproj @@ -8,7 +8,7 @@ - + From 7f07b59ee151fa6d713282781c7f16f9c65302dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:49:19 +0000 Subject: [PATCH 084/116] Bump NUnit3TestAdapter from 4.5.0 to 4.6.0 Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.5.0 to 4.6.0. - [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases) - [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.5.0...V4.6.0) --- updated-dependencies: - dependency-name: NUnit3TestAdapter dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- PlaywrightTests/PlaywrightTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlaywrightTests/PlaywrightTests.csproj b/PlaywrightTests/PlaywrightTests.csproj index 0518ae38..f819c833 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 8db28de8187d10e71031f260dfb8a3d4db82524c Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 30 Jul 2024 17:43:51 -0400 Subject: [PATCH 085/116] Update README --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d06aa330..066338b1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ # BLAZAM -## Introducing Blazam's new Logo - +## Version 1.0.1 Release Notice +Blazam will be officially released with the next update or two. + +Please ensure .NET Core 8 Runtimes are installed for service-type installations, +and .NET Core Web Hosting Bundle for IIS-type installations. + +[https://dotnet.microsoft.com/en-us/download/dotnet/8.0](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) ## Website [blazam.org](https://blazam.org) From 9e191278265f141973ee5c8d7ea1452876a19ccd Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 30 Jul 2024 19:33:28 -0400 Subject: [PATCH 086/116] MudBlazor update progress --- BLAZAM/BLAZAM.csproj | 3 ++- BLAZAM/Pages/Computers/ViewComputer.razor | 14 ++++++------- BLAZAM/Pages/Configure/Fields.razor | 2 +- BLAZAM/Pages/Configure/Templates.razor | 4 ++-- BLAZAM/Pages/Groups/ViewGroup.razor | 12 +++++------ BLAZAM/Pages/OU/ViewOU.razor | 4 ++-- BLAZAM/Pages/Printers/ViewPrinter.razor | 4 ++-- BLAZAM/Pages/Users/ConfirmNewUser.razor | 4 ++-- BLAZAM/Pages/Users/ViewUser.razor | 20 +++++++++--------- BLAZAMGui/Layouts/AppUserButton.razor | 4 ++-- BLAZAMGui/Layouts/MainLayout.razor | 2 +- BLAZAMGui/UI/AppModal.razor.cs | 21 ++++++++++--------- BLAZAMGui/UI/Computers/ComputerSessions.razor | 2 +- .../UI/Computers/ComputerSharedPrinters.razor | 2 +- .../UI/Groups/GroupMembersDataGrid.razor | 2 +- BLAZAMGui/UI/Search/SearchPageHeader.razor | 2 +- .../UI/SessionExpirationWarningProvider.razor | 4 ++-- .../UI/Settings/ApplicationSettings.razor | 2 +- .../UploadCertificateModalContent.razor | 12 +++++------ .../Permissions/AddPrivilegeLevelModal.razor | 2 +- .../Settings/Permissions/DelegateEditor.razor | 4 ++-- .../Permissions/DelegateListItem.razor | 4 ++-- .../Permissions/EditAccessLevel.razor | 2 +- .../Templates/EditDirectoryTemplate.razor | 2 +- .../Users/UploadThumbnailModalContent.razor | 6 +++--- BLAZAMUpdate/ApplicationReleaseBranches.cs | 4 ++-- 26 files changed, 73 insertions(+), 71 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 1edb1973..8356b2b2 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -77,13 +77,14 @@ + - + diff --git a/BLAZAM/Pages/Computers/ViewComputer.razor b/BLAZAM/Pages/Computers/ViewComputer.razor index 57493522..8bfb526a 100644 --- a/BLAZAM/Pages/Computers/ViewComputer.razor +++ b/BLAZAM/Pages/Computers/ViewComputer.razor @@ -12,17 +12,17 @@ + OnShowHistory="@(()=>{ChangeHistoryModal?.ShowAsync();})" /> @@ -67,7 +67,7 @@
- {AssignToModal?.Show();}) Model="Computer" /> + {AssignToModal?.ShowAsync();}) Model="Computer" /> diff --git a/BLAZAM/Pages/Configure/Fields.razor b/BLAZAM/Pages/Configure/Fields.razor index e7f4d1e5..71759fa5 100644 --- a/BLAZAM/Pages/Configure/Fields.razor +++ b/BLAZAM/Pages/Configure/Fields.razor @@ -13,7 +13,7 @@ Fields - + diff --git a/BLAZAM/Pages/Configure/Templates.razor b/BLAZAM/Pages/Configure/Templates.razor index 7547c912..ff001dba 100644 --- a/BLAZAM/Pages/Configure/Templates.razor +++ b/BLAZAM/Pages/Configure/Templates.razor @@ -59,7 +59,7 @@ @if (SelectedCategory != null && SelectedCategory != "All") { - {RenameModal?.Show();}) + {RenameModal?.ShowAsync();}) Color="Color.Tertiary" Class="align-middle" Icon="@Icons.Material.Filled.ChangeCircle" /> @@ -88,7 +88,7 @@ { - {RestoreModal?.Show();}) + {RestoreModal?.ShowAsync();}) Color="Color.Warning" Class="align-middle" Icon="@Icons.Material.Filled.RestoreFromTrash" /> diff --git a/BLAZAM/Pages/Groups/ViewGroup.razor b/BLAZAM/Pages/Groups/ViewGroup.razor index 882a4695..14f60eb5 100644 --- a/BLAZAM/Pages/Groups/ViewGroup.razor +++ b/BLAZAM/Pages/Groups/ViewGroup.razor @@ -11,13 +11,13 @@ diff --git a/BLAZAM/Pages/OU/ViewOU.razor b/BLAZAM/Pages/OU/ViewOU.razor index 8c9c3587..f87cf197 100644 --- a/BLAZAM/Pages/OU/ViewOU.razor +++ b/BLAZAM/Pages/OU/ViewOU.razor @@ -8,8 +8,8 @@ diff --git a/BLAZAM/Pages/Printers/ViewPrinter.razor b/BLAZAM/Pages/Printers/ViewPrinter.razor index b8774ad1..4ba172e8 100644 --- a/BLAZAM/Pages/Printers/ViewPrinter.razor +++ b/BLAZAM/Pages/Printers/ViewPrinter.razor @@ -13,8 +13,8 @@ diff --git a/BLAZAM/Pages/Users/ConfirmNewUser.razor b/BLAZAM/Pages/Users/ConfirmNewUser.razor index bd179e9c..f975a1cd 100644 --- a/BLAZAM/Pages/Users/ConfirmNewUser.razor +++ b/BLAZAM/Pages/Users/ConfirmNewUser.razor @@ -171,7 +171,7 @@ else } Print -Test +Test @@ -240,7 +240,7 @@ else { if (DirectoryTemplate.EffectiveAskForAlternateEmail == true || User.Email.IsNullOrEmpty()) { - SendWelcomeModal?.Show(); + SendWelcomeModal?.ShowAsync(); } else { diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index a90ec1d6..f814a8af 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -20,16 +20,16 @@ @@ -108,7 +108,7 @@ } @if (showRemoveThumbnail && User?.CanEditField(ActiveDirectoryFields.Thumbnail) == true) { - {UploadThumbnailModal?.Show();}) + {UploadThumbnailModal?.ShowAsync();}) Style="position:absolute !important;width:40px;height:40px;padding:2px;top:10px;right:10px" Color=Color.Primary Icon="@Icons.Material.Filled.Upload" /> @@ -167,7 +167,7 @@ { @AppLocalization["Groups"] - {AssignToModal?.Show();}) Model="User" /> + {AssignToModal?.ShowAsync();}) Model="User" /> @@ -267,7 +267,7 @@ { @AppLocalization["Log On To"] @@ -278,7 +278,7 @@ { @AppLocalization["Logon Hours"] diff --git a/BLAZAMGui/Layouts/AppUserButton.razor b/BLAZAMGui/Layouts/AppUserButton.razor index 5ca02aa6..f565d22f 100644 --- a/BLAZAMGui/Layouts/AppUserButton.razor +++ b/BLAZAMGui/Layouts/AppUserButton.razor @@ -31,10 +31,10 @@ } - + @AppLocalization["Profile Settings"] - + @AppLocalization["Notification Settings"] diff --git a/BLAZAMGui/Layouts/MainLayout.razor b/BLAZAMGui/Layouts/MainLayout.razor index fcf72a3d..23bc56ff 100644 --- a/BLAZAMGui/Layouts/MainLayout.razor +++ b/BLAZAMGui/Layouts/MainLayout.razor @@ -55,7 +55,7 @@ await InvokeAsync(StateHasChanged); OnClick="@(()=>{_devDrawerOpen=!_devDrawerOpen;InvokeAsync(StateHasChanged);})">Dev Panel Data Browser + OnClick="@(()=>{dataBrowser?.ShowAsync();})">Data Browser diff --git a/BLAZAMGui/UI/AppModal.razor.cs b/BLAZAMGui/UI/AppModal.razor.cs index f570d415..eba6f739 100644 --- a/BLAZAMGui/UI/AppModal.razor.cs +++ b/BLAZAMGui/UI/AppModal.razor.cs @@ -34,7 +34,7 @@ public bool AllowClose { if (Options == null) Options = new(); - Options.DisableBackdropClick = !value; + Options.BackdropClick = value; Options.CloseButton = value; Options.CloseOnEscapeKey = value; } @@ -72,7 +72,7 @@ public bool LoadingData public OnYesEvent OnYes { get; set; } public void SetOnYes(OnYesEvent onYes) { - OnYes=onYes; + OnYes = onYes; } [Parameter] public string YesText { get; set; } @@ -100,18 +100,19 @@ public void SetCancelText(string text) [Parameter] public EventCallback? ModalChanged { get; set; } + /// /// Indicates whether this modal is currently shown /// [Parameter] public bool IsShown { - get => Modal.IsVisible; + get => Modal.Visible; set { - if (value == Modal.IsVisible) + if (value == Modal.Visible) return; - Modal.IsVisible = value; + Modal.Visible = value; IsShownChanged.InvokeAsync(value); } } @@ -123,10 +124,10 @@ public bool IsShown protected override void OnInitialized() { base.OnInitialized(); - YesText = AppLocalization["Ok"]; + YesText = AppLocalization["Ok"]; if (Options == null) Options = new(); - AllowClose=true; + AllowClose = true; } /// /// Re-renders the modal with the latest property values @@ -139,12 +140,12 @@ public async Task RefreshView() /// /// Show this modal /// - public IDialogReference? Show() + public async Task ShowAsync() { IsShown = true; - return Modal?.Show(null,Options); + return await Modal?.ShowAsync(null, Options); } @@ -154,7 +155,7 @@ public async Task RefreshView() public void Close() { IsShown = false; - Modal?.Close(); + Modal?.CloseAsync(); } private void YesClicked() { diff --git a/BLAZAMGui/UI/Computers/ComputerSessions.razor b/BLAZAMGui/UI/Computers/ComputerSessions.razor index a5761f6a..c63a89dd 100644 --- a/BLAZAMGui/UI/Computers/ComputerSessions.razor +++ b/BLAZAMGui/UI/Computers/ComputerSessions.razor @@ -27,7 +27,7 @@ { { sessionToMessage=context.Item; - sessionMessageModal?.Show(); + sessionMessageModal?.ShowAsync(); })>Send Message } diff --git a/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor b/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor index 6bd35f5e..9b19a293 100644 --- a/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor +++ b/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor @@ -10,7 +10,7 @@ {_registerPrintersModal.Show();}) + OnClick=@(()=>{_registerPrintersModal.ShowAsync();}) IconSize="Size.Medium" Class="mt-0">@AppLocalization["Register printers with Active Directory"] } diff --git a/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor b/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor index 0f10222a..657e6ed2 100644 --- a/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor +++ b/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor @@ -86,7 +86,7 @@ + OnClick="@(()=>{AssignMemberModal.ShowAsync();})" /> } {InvokeAsync(OnInitializedAsync);}) Group="Group" /> diff --git a/BLAZAMGui/UI/Search/SearchPageHeader.razor b/BLAZAMGui/UI/Search/SearchPageHeader.razor index 4119c466..5fa63ba6 100644 --- a/BLAZAMGui/UI/Search/SearchPageHeader.razor +++ b/BLAZAMGui/UI/Search/SearchPageHeader.razor @@ -16,7 +16,7 @@ - Search + Search diff --git a/BLAZAMGui/UI/SessionExpirationWarningProvider.razor b/BLAZAMGui/UI/SessionExpirationWarningProvider.razor index 295045e0..7a3a9628 100644 --- a/BLAZAMGui/UI/SessionExpirationWarningProvider.razor +++ b/BLAZAMGui/UI/SessionExpirationWarningProvider.razor @@ -22,7 +22,7 @@ if (ExpiredModal != null) { ExpiredModal.AllowClose = false; - ExpiredModal.Show(); + ExpiredModal.ShowAsync(); } } string formattedTimeLeft = ""; @@ -83,7 +83,7 @@ var timeLeft = _ticket?.Properties.ExpiresUtc - DateTime.UtcNow; if (timeLeft > TimeSpan.FromSeconds(0) && timeLeft < TimeSpan.FromMinutes(2) && ExpirationWarningModal?.IsShown == false) { - await InvokeAsync(() => { ExpirationWarningModal.Show(); }); + await InvokeAsync(() => { ExpirationWarningModal.ShowAsync(); }); } } diff --git a/BLAZAMGui/UI/Settings/ApplicationSettings.razor b/BLAZAMGui/UI/Settings/ApplicationSettings.razor index 2608c5c8..6d603716 100644 --- a/BLAZAMGui/UI/Settings/ApplicationSettings.razor +++ b/BLAZAMGui/UI/Settings/ApplicationSettings.razor @@ -81,7 +81,7 @@ @if (!ApplicationInfo.IsUnderIIS || ApplicationInfo.InDebugMode) { - @if(SelectedCertType=="PFX"){ - + Upload PFX - + @if (context != null) { @@ -32,7 +32,7 @@ else { - + Upload Certificate - + @if (context != null) { @@ -54,7 +54,7 @@ - + Upload Key - + @if (context != null) { diff --git a/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor b/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor index 3a0e2296..05b5a019 100644 --- a/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor +++ b/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor @@ -7,7 +7,7 @@ @bind-SelectedResult=@selectedDelegate CustomResultsFilter="(result)=>result.ObjectType==ActiveDirectoryObjectType.User|| result.ObjectType==ActiveDirectoryObjectType.Group" /> - + Will have complete and total acceess to the application if enabled diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor index f05155a4..b9250548 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateEditor.razor @@ -10,7 +10,7 @@ @bind-Value="@DelegateFilter" /> + OnClick="(()=>{trashModal.ShowAsync();})"> @@ -28,7 +28,7 @@ } } - + @AppLocalization["Create New Delegation Target"] diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor index c51dec9f..130c3ac5 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor @@ -7,7 +7,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor b/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor index bd7ee078..1b41aa33 100644 --- a/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor +++ b/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor @@ -66,7 +66,7 @@ @if (objectMap.ObjectType == ActiveDirectoryObjectType.User && objectMap.ObjectAccessLevelId != ObjectAccessLevels.Deny.Id) { - + } diff --git a/BLAZAMGui/UI/Settings/Templates/EditDirectoryTemplate.razor b/BLAZAMGui/UI/Settings/Templates/EditDirectoryTemplate.razor index 84289a41..1dfc0928 100644 --- a/BLAZAMGui/UI/Settings/Templates/EditDirectoryTemplate.razor +++ b/BLAZAMGui/UI/Settings/Templates/EditDirectoryTemplate.razor @@ -37,7 +37,7 @@ await ParentTemplateChanged(null); Adornment="Adornment.End" AdornmentIcon="@Icons.Material.Filled.Add" AdornmentColor="@Color.Success" - OnAdornmentClick="@(()=>{categoryModal.Show();})" + OnAdornmentClick="@(()=>{categoryModal.ShowAsync();})" Values="@(categories.Count>1?categories:new List())" ValueChanged="@((value)=>{DirectoryTemplate.Category=value;})" @bind-Text=DirectoryTemplate.Category diff --git a/BLAZAMGui/UI/Users/UploadThumbnailModalContent.razor b/BLAZAMGui/UI/Users/UploadThumbnailModalContent.razor index 1fa91261..96d7c21c 100644 --- a/BLAZAMGui/UI/Users/UploadThumbnailModalContent.razor +++ b/BLAZAMGui/UI/Users/UploadThumbnailModalContent.razor @@ -10,16 +10,16 @@ @AppLocalization["Upload Thumbnail Photo"] - + Upload Files - + diff --git a/BLAZAMUpdate/ApplicationReleaseBranches.cs b/BLAZAMUpdate/ApplicationReleaseBranches.cs index 99b35d9b..4e970e18 100644 --- a/BLAZAMUpdate/ApplicationReleaseBranches.cs +++ b/BLAZAMUpdate/ApplicationReleaseBranches.cs @@ -3,7 +3,7 @@ public class ApplicationReleaseBranches { public const string Stable = "Release"; - public const string Nightly = "Nightly"; - public const string Dev = "Dev"; + public const string Nightly = "Nightly1"; + public const string Dev = "Dev1"; } } \ No newline at end of file From 0887ba1eb2d6547f55b313f060d3e09e46daa996 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 31 Jul 2024 15:46:14 -0400 Subject: [PATCH 087/116] Template TreeView update --- BLAZAM/Pages/Configure/Templates.razor | 43 ++++++++++++++++--- BLAZAMGui/Helper/GuiHelpers.cs | 13 ++++++ BLAZAMGui/UI/Inputs/MudContextMenu.razor | 10 ++--- .../Outputs/TemplateInheritanceTreeView.razor | 35 +++++++-------- 4 files changed, 71 insertions(+), 30 deletions(-) diff --git a/BLAZAM/Pages/Configure/Templates.razor b/BLAZAM/Pages/Configure/Templates.razor index ff001dba..de016443 100644 --- a/BLAZAM/Pages/Configure/Templates.razor +++ b/BLAZAM/Pages/Configure/Templates.razor @@ -50,7 +50,7 @@ @@ -84,7 +84,7 @@ } - @if (Templates?.Any(t => t.DeletedAt != null)==true) + @if (Templates?.Any(t => t.DeletedAt != null) == true) { @@ -94,7 +94,7 @@ Icon="@Icons.Material.Filled.RestoreFromTrash" /> } - + @@ -127,7 +127,7 @@ - @@ -185,7 +185,7 @@ template.Category = newCategoryName; } } - if (SelectedTemplate!=null && SelectedTemplate.Category == SelectedCategory) + if (SelectedTemplate != null && SelectedTemplate.Category == SelectedCategory) SelectedTemplate.Category = newCategoryName; if (Context != null && await Context.SaveChangesAsync() > 0) { @@ -203,8 +203,10 @@ SelectedTemplate = new(); TemplateIdParameter = null; SelectedTemplate = new(); - Nav.NavigateTo("/templates/0",true); + Nav.NavigateTo("/templates/0", true); } + + [Obsolete] private HashSet CreateTemplateHash { get @@ -216,6 +218,22 @@ } } + private IReadOnlyCollection> CreateTemplateTreeItemData + { + get + + { + List> treeData = new(); + + var rootTemplates = Templates.Where(t => t.ParentTemplate == null && t.DeletedAt == null).ToTreeItemData(); + + treeData = RecursiveFillTreeViewItems(treeData); + return treeData; + + } + } + + [Obsolete] private HashSet RecursiveFill(HashSet setToFill) { @@ -230,6 +248,19 @@ } return setToFill; } + private List> RecursiveFillTreeViewItems(List> setToFill) + { + foreach (var template in setToFill) + { + if (Templates.Any(t => t.ParentTemplateId == template.Value.Id)) + { + var children = Templates.Where(t => t.ParentTemplateId == template.Value.Id && t.DeletedAt == null).ToTreeItemData(); + children = RecursiveFillTreeViewItems(children); + template.Children = children; + } + } + return setToFill; + } private async Task DeleteTemplate() { if (SelectedTemplate != null) diff --git a/BLAZAMGui/Helper/GuiHelpers.cs b/BLAZAMGui/Helper/GuiHelpers.cs index 53de2c8f..ddeacb49 100644 --- a/BLAZAMGui/Helper/GuiHelpers.cs +++ b/BLAZAMGui/Helper/GuiHelpers.cs @@ -1,4 +1,5 @@ using ApplicationNews; +using BLAZAM.Database.Models.Templates; using BLAZAM.Gui.UI.Modals; using Microsoft.AspNetCore.Components.Forms; using MudBlazor; @@ -40,6 +41,18 @@ public static async Task ShowNewsItemDialog(this NewsItem item return (await dialogService.ShowMessage(dialogParams, item.Title,options:options)); } + + public static List> ToTreeItemData(this IEnumerable items) + { + List> treeData = new(); + + items.ForEach(x => + { + treeData.Add(new() { Value = x }); + + }); + return treeData; + } } } diff --git a/BLAZAMGui/UI/Inputs/MudContextMenu.razor b/BLAZAMGui/UI/Inputs/MudContextMenu.razor index f7b947dc..61e3d997 100644 --- a/BLAZAMGui/UI/Inputs/MudContextMenu.razor +++ b/BLAZAMGui/UI/Inputs/MudContextMenu.razor @@ -15,27 +15,27 @@ [Parameter] public bool IsMenuShown { - get { return contextMenu?.IsOpen ?? false; } + get { return contextMenu?.Open ?? false; } set { if (value) { if (!IsMenuShown) { - contextMenu?.OpenMenu(null); + contextMenu?.OpenMenuAsync(null); } } else { if (IsMenuShown) { - contextMenu?.CloseMenu(); + contextMenu?.OpenMenuAsync(null); } } } } [Parameter] - public EventCallback IsMenuShownChanged { get => contextMenu.IsOpenChanged; set => contextMenu.IsOpenChanged = value; } + public EventCallback IsMenuShownChanged { get => contextMenu.OpenChanged; set => contextMenu.OpenChanged = value; } [Parameter] public RenderFragment ChildContent { get; set; } [Parameter] @@ -47,7 +47,7 @@ private async void ShowContextMenu(MouseEventArgs? args = null) { // contextMenu?.Activate(activator, args); - contextMenu?.OpenMenu(args); + contextMenu?.OpenMenuAsync(args); await InvokeAsync(StateHasChanged); } } diff --git a/BLAZAMGui/UI/Outputs/TemplateInheritanceTreeView.razor b/BLAZAMGui/UI/Outputs/TemplateInheritanceTreeView.razor index deb64b5d..df0cd246 100644 --- a/BLAZAMGui/UI/Outputs/TemplateInheritanceTreeView.razor +++ b/BLAZAMGui/UI/Outputs/TemplateInheritanceTreeView.razor @@ -10,23 +10,20 @@ Hover="true" Class="py-3" SelectedValueChanged=SelectedTemplateChanged - MaxHeight="400px" - Color="Color.Success"> - - - - - - - @context.Name + MaxHeight="400px"> + + + + + + + @context.Value.Name @@ -55,7 +52,7 @@ /// The hashset of all templates, starting at the root templates that have no parents /// [Parameter] - public HashSet RootTemplate { get; set; } = new HashSet(); + public IReadOnlyCollection> RootTemplate { get; set; } = new List>(); /// /// The already or recently selected template @@ -80,5 +77,5 @@ await InvokeAsync(StateHasChanged); } - + } From 26d7fcc9c6e19511e24379e3304d7385f34ffe7f Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 2 Aug 2024 17:47:28 -0400 Subject: [PATCH 088/116] Implement proper encyption salting --- BLAZAM/BLAZAM.csproj | 4 +- BLAZAMCommon/Data/Encryption.cs | 134 +++++++++++++++--- .../UI/Settings/AuthenticationSetting.razor | 5 +- 3 files changed, 123 insertions(+), 20 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 2bcfbe13..d98f3758 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,7 +6,7 @@ enable false 0.9.4 - 2024.07.23.0006 + 2024.08.02.2145 false BLAZAM False diff --git a/BLAZAMCommon/Data/Encryption.cs b/BLAZAMCommon/Data/Encryption.cs index cfa69159..cd8704b9 100644 --- a/BLAZAMCommon/Data/Encryption.cs +++ b/BLAZAMCommon/Data/Encryption.cs @@ -1,5 +1,7 @@ using BLAZAM.Helpers; using Newtonsoft.Json; +using System; +using System.ComponentModel; using System.Security.Cryptography; using System.Text; @@ -7,10 +9,19 @@ namespace BLAZAM.Common.Data { public class Encryption { - private const string Salt = "BLAZAM_SALT"; + private const string OldSalt = "BLAZAM_SALT"; public static Encryption Instance; + private void SetSalt(int maximumSaltLength = 32) + { + var salt = new byte[maximumSaltLength]; + using (var random = new RNGCryptoServiceProvider()) + { + random.GetNonZeroBytes(salt); + } + Salt = salt; + } /// /// String used to generate the key bytes @@ -24,13 +35,14 @@ public class Encryption /// /// The size of the key in bits /// - public int KeySize { get; set; } + private int KeySize { get; set; } /// /// The key that is bits long and was /// generated from the /// public byte[] Key { get; set; } + private byte[] Salt { get; set; } @@ -42,7 +54,7 @@ public class Encryption /// processed into a repeatable generated private key /// How large a key to generate in bits /// - /// Thows an exception when no keySeedString is provided. + /// Throws an exception when no keySeedString is provided. public Encryption(string? keySeedString, int keySize = 256) { Instance = this; @@ -51,7 +63,9 @@ public Encryption(string? keySeedString, int keySize = 256) if (keySeedString == null || keySeedString == "") return; KeySeedString = keySeedString; KeySize = keySize; - GenerateKeyFromSeedString(); + SetSalt(); + GenerateOldKeyFromSeedString(); + GenerateKeyFromSeedString(Salt); } /// @@ -62,14 +76,31 @@ public Encryption(string? keySeedString, int keySize = 256) /// Sets the local value to the newly generated key /// /// The key based on the - private byte[] GenerateKeyFromSeedString() + [Obsolete("This method uses the old static salt value, use the parametrized version instead.")] + private byte[] GenerateOldKeyFromSeedString() { // Use a key derivation function to generate a repeatable key - var salt = Encoding.UTF8.GetBytes(Salt); + // var salt = GetSalt(11); + var salt = Encoding.UTF8.GetBytes(OldSalt); var keyGenerator = new Rfc2898DeriveBytes(KeySeedString, salt, 1000); Key = keyGenerator.GetBytes(KeySize / 8); return Key; } + /// + /// Generates a key of the configured key size, seeding the + /// key from the appsettings configuration value "EncryptionKey" + /// + /// + /// Sets the local value to the newly generated key + /// + /// The key based on the + private byte[] GenerateKeyFromSeedString(byte[] salt) + { + // Use a key derivation function to generate a repeatable key + var keyGenerator = new Rfc2898DeriveBytes(KeySeedString, salt, 1000); + + return keyGenerator.GetBytes(KeySize / 8); ; + } /// /// Decrypts cipher-text @@ -79,17 +110,21 @@ private byte[] GenerateKeyFromSeedString() /// /// /// - public T? DecryptObject(string? cipherText) + private T? DecryptSaltedObject(string? cipherText) { - if (cipherText == null) return default; + try { - byte[] buffer = Convert.FromBase64String(cipherText); + var saltCipherArray = cipherText.Split(','); + byte[] buffer = Convert.FromBase64String(saltCipherArray[1]); + byte[] cipherSalt = Convert.FromBase64String(saltCipherArray[0]); + var key = GenerateKeyFromSeedString(cipherSalt); + byte[] iv = buffer.Take(16).ToArray(); buffer = buffer.Skip(16).ToArray(); using Aes aes = Aes.Create(); - aes.Key = Key; + aes.Key = GenerateKeyFromSeedString(cipherSalt); aes.IV = iv; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using MemoryStream memoryStream = new MemoryStream(buffer); @@ -107,7 +142,7 @@ private byte[] GenerateKeyFromSeedString() catch (FormatException) { //If any issues occur while creating - //the decrypted text, return the "encypted" + //the decrypted text, return the "encrypted" //text if (cipherText is T tText) { @@ -115,6 +150,67 @@ private byte[] GenerateKeyFromSeedString() } } throw new ApplicationException("Unable to decrypt cipherText"); + + } + /// + /// Decrypts cipher-text + /// + /// The serializable type that should + /// represent the decrypted cipher object + /// + /// + /// + public T? DecryptObject(string? cipherText) + { + + if (cipherText == null) return default; + + try + { + var newDecrypted = DecryptSaltedObject(cipherText); + if (newDecrypted != null) return newDecrypted; + + throw new ApplicationException("Unable to decrypt cipherText"); + + + } + catch + { + try + { + byte[] buffer = Convert.FromBase64String(cipherText); + + byte[] iv = buffer.Take(16).ToArray(); + buffer = buffer.Skip(16).ToArray(); + using Aes aes = Aes.Create(); + aes.Key = Key; + aes.IV = iv; + ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); + using MemoryStream memoryStream = new MemoryStream(buffer); + + using CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); + + using StreamReader streamReader = new StreamReader(cryptoStream); + + return JsonConvert.DeserializeObject(streamReader.ReadToEnd()); + + + + + } + catch (FormatException) + { + //If any issues occur while creating + //the decrypted text, return the "encypted" + //text + if (cipherText is T tText) + { + return tText; + } + } + } + + throw new ApplicationException("Unable to decrypt cipherText"); } /// /// Encrypt any serializable object @@ -126,14 +222,14 @@ public string EncryptObject(object obj) Random rand = new Random(); int ivSeed = rand.Next(0, 65535); - var salt = Encoding.UTF8.GetBytes(Salt); + var salt = Encoding.UTF8.GetBytes(OldSalt); var keyGenerator = new Rfc2898DeriveBytes(ivSeed.ToByteArray(), salt, 1000); byte[] iv = keyGenerator.GetBytes(16); byte[] encryptedBytes; using Aes aes = Aes.Create(); - aes.Key = Key; + aes.Key = GenerateKeyFromSeedString(Salt); aes.IV = iv; ICryptoTransform encryptor = aes.CreateEncryptor(); using (MemoryStream memoryStream = new MemoryStream()) @@ -151,14 +247,20 @@ public string EncryptObject(object obj) encryptedBytes = memoryStream.ToArray(); - var encryptedMessage = iv; + + for (int i = 0; i < encryptedBytes.Length; i++) { - encryptedMessage = encryptedMessage.Append(encryptedBytes[i]).ToArray(); + encryptedMessage = encryptedMessage.Append(encryptedBytes[i]).ToArray(); } - return Convert.ToBase64String(encryptedMessage); + var cipherText = Convert.ToBase64String(encryptedMessage); + cipherText = Convert.ToBase64String(Salt) + "," + cipherText; + + + + return cipherText; } } diff --git a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor index c1d666f0..d6ee50d2 100644 --- a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor +++ b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor @@ -114,7 +114,7 @@ } catch { - + } await InvokeAsync(StateHasChanged); } @@ -126,7 +126,8 @@ } protected override async void Save() { - if (!newAdminPassword.Equals(adminPasswordInDb)) + var decryptedPass = adminPasswordInDb.Decrypt(); + if (!newAdminPassword.Equals(adminPasswordInDb) || decryptedPass.Equals(adminPasswordInDb)) { settings.AdminPassword = newAdminPassword.Encrypt(); From ec7b0e5d9f2d1cfa64b5008efecceb98d3d622a1 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 3 Aug 2024 12:33:18 -0400 Subject: [PATCH 089/116] Skip checks pre install finalization --- .../Middleware/HttpsRedirectionMiddleware.cs | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/BLAZAM/Middleware/HttpsRedirectionMiddleware.cs b/BLAZAM/Middleware/HttpsRedirectionMiddleware.cs index bd736569..14dad9d3 100644 --- a/BLAZAM/Middleware/HttpsRedirectionMiddleware.cs +++ b/BLAZAM/Middleware/HttpsRedirectionMiddleware.cs @@ -1,4 +1,5 @@ -using BLAZAM.Database.Context; +using BLAZAM.Common.Data; +using BLAZAM.Database.Context; using BLAZAM.Services.Background; namespace BLAZAM.Server.Middleware @@ -7,41 +8,47 @@ public class HttpsRedirectionMiddleware { private readonly RequestDelegate _next; private readonly ConnMonitor _monitor; + private readonly ApplicationInfo _applicationInfo; public HttpsRedirectionMiddleware( RequestDelegate next, - ConnMonitor monitor) + ConnMonitor monitor, + ApplicationInfo applicationInfo) { _next = next; _monitor = monitor; + _applicationInfo = applicationInfo; } public async Task InvokeAsync(HttpContext context) { bool forceHttps; // If the value is not cached, retrieve it from the database. - - try - { - forceHttps = DatabaseCache.ApplicationSettings.ForceHTTPS; - }catch (NullReferenceException ex) + if (_applicationInfo.InstallationCompleted) { - Loggers.SystemLogger.Warning("Error while checking database cache for Force HTTPS {@Error}", ex); - forceHttps = false; - } + try + { + forceHttps = DatabaseCache.ApplicationSettings.ForceHTTPS; + } + catch (NullReferenceException ex) + { + Loggers.SystemLogger.Warning("Error while checking database cache for Force HTTPS {@Error}", ex); + forceHttps = false; + } - // If the ForceHttps flag is set to true, redirect to HTTPS. - if (forceHttps - && !context.Request.IsHttps) - { - string httpsUrl = "https://" + context.Request.Host + context.Request.Path; - context.Response.Redirect(httpsUrl); - return; - } + // If the ForceHttps flag is set to true, redirect to HTTPS. + if (forceHttps + && !context.Request.IsHttps) + { + string httpsUrl = "https://" + context.Request.Host + context.Request.Path; + context.Response.Redirect(httpsUrl); + return; + } + } // If the ForceHttps flag is not set or if the request is already HTTPS, proceed with the request. await _next(context); } From bdec6473f31fc119c49b054c40efeb909de49617 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 3 Aug 2024 12:35:17 -0400 Subject: [PATCH 090/116] Fix for service installations failing to start when no SSL cert is provided --- BLAZAM/Program.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/BLAZAM/Program.cs b/BLAZAM/Program.cs index 3f1cbc12..07e6e089 100644 --- a/BLAZAM/Program.cs +++ b/BLAZAM/Program.cs @@ -201,7 +201,11 @@ private static void SetupKestrel(WebApplicationBuilder builder) dbSettings = kestrelContext.AppSettings.FirstOrDefault(); var certBytes = dbSettings.SSLCertificateCipher.Decrypt(); - cert = new X509Certificate2(certBytes); + if(certBytes!= null) + { + cert = new X509Certificate2(certBytes); + + } } catch (Exception ex) From 373002fa38a052d54e0262c0d8613988acca9635 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 3 Aug 2024 12:35:44 -0400 Subject: [PATCH 091/116] Skip UserSeedService pre install finalization --- BLAZAM/ProgramHelpers.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs index 7a2f7b7d..db0bfce8 100644 --- a/BLAZAM/ProgramHelpers.cs +++ b/BLAZAM/ProgramHelpers.cs @@ -344,8 +344,10 @@ private static void PreloadServices() } try { - var context = Program.AppInstance.Services.GetRequiredService(); - + if (ApplicationInfo.installationCompleted) + { + var context = Program.AppInstance.Services.GetRequiredService(); + } } catch (Exception ex) From 38ba62d6d8a5b33336367d6cf787e20e7b64e11b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 3 Aug 2024 12:36:15 -0400 Subject: [PATCH 092/116] Don't throw for missing CurrentUser --- BLAZAMActiveDirectory/ActiveDirectoryContext.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs index d1a22f51..b2671ad7 100644 --- a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs +++ b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs @@ -29,7 +29,8 @@ public IApplicationUserState? CurrentUser get { if (currentUser != null) return currentUser; - throw new ApplicationException("Current User State was not provided to this directory entry"); + //throw new ApplicationException("Current User State was not provided to this directory entry"); + return null; } set => currentUser = value; } @@ -53,7 +54,7 @@ private AuthenticationTypes AuthType { ConnectionSettings = ad; - Loggers.ActiveDirectryLogger.Information("Active Directory settings found in database. {@DirectorySettings}", ad); + //Loggers.ActiveDirectryLogger.Information("Active Directory settings found in database. {@DirectorySettings}", ad); //We need to determine what security options to use when authenticating //based on the settings in the DB From 95cbd3b64e455684e4a3288b1d7f7d23fd8ea6d7 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 3 Aug 2024 12:36:54 -0400 Subject: [PATCH 093/116] Rename CurrentUserStateService source file --- ...urentUserStateService.cs => CurrentUserStateService.cs} | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) rename BLAZAMSession/{CurentUserStateService.cs => CurrentUserStateService.cs} (86%) diff --git a/BLAZAMSession/CurentUserStateService.cs b/BLAZAMSession/CurrentUserStateService.cs similarity index 86% rename from BLAZAMSession/CurentUserStateService.cs rename to BLAZAMSession/CurrentUserStateService.cs index 05409148..05fe78c6 100644 --- a/BLAZAMSession/CurentUserStateService.cs +++ b/BLAZAMSession/CurrentUserStateService.cs @@ -46,13 +46,15 @@ public CurrentUserStateService(IApplicationUserStateService applicationUserState private void RetryGetCurrentUserState(object? state = null) { - + Loggers.SystemLogger.Information("Attempting to get user state from HTTPContext {UserName}", _httpContextAccessor.HttpContext?.User?.Identity?.Name); try { State = _applicationUserStateService.GetUserState(_httpContextAccessor.HttpContext?.User); if (State != null && State.IsAuthenticated) + { State.IPAddress = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress?.ToString(); - _retryTimer?.Dispose(); + _retryTimer?.Dispose(); + } } catch (Exception ex) @@ -60,6 +62,7 @@ private void RetryGetCurrentUserState(object? state = null) Loggers.SystemLogger.Error("Error trying to get current user state {@Error}", ex); return; } + Loggers.SystemLogger.Information("State Null:{StateNull} Username:{StateUsername}",State==null,State?.Username); } From a34fdd475caa5ccef19da69f75eaf9db4e2468e1 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 3 Aug 2024 17:37:14 -0400 Subject: [PATCH 094/116] Allow null decryption --- BLAZAMCommon/Data/Encryption.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BLAZAMCommon/Data/Encryption.cs b/BLAZAMCommon/Data/Encryption.cs index cd8704b9..f9a41b70 100644 --- a/BLAZAMCommon/Data/Encryption.cs +++ b/BLAZAMCommon/Data/Encryption.cs @@ -133,8 +133,8 @@ private byte[] GenerateKeyFromSeedString(byte[] salt) using StreamReader streamReader = new StreamReader(cryptoStream); - return JsonConvert.DeserializeObject(streamReader.ReadToEnd()); - + var decrypted= JsonConvert.DeserializeObject(streamReader.ReadToEnd()); + return decrypted; @@ -168,7 +168,7 @@ private byte[] GenerateKeyFromSeedString(byte[] salt) try { var newDecrypted = DecryptSaltedObject(cipherText); - if (newDecrypted != null) return newDecrypted; + return newDecrypted; throw new ApplicationException("Unable to decrypt cipherText"); From e746ddb43b7c164e39a61673df4ce73e48d227b2 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 4 Aug 2024 13:40:46 -0400 Subject: [PATCH 095/116] Audit completed --- BLAZAM/Pages/Computers/ViewBitLocker.razor | 2 + BLAZAM/Pages/Users/ViewUser.razor | 21 ++++- .../Adapters/GroupableDirectoryAdapter.cs | 4 +- .../GroupMembershipChange.cs | 5 +- .../Interfaces/IGroupableDirectoryModel.cs | 6 +- .../ScopedActiveDirectoryContext.cs | 5 + BLAZAMDatabase/DatabaseConnectionString.cs | 29 +++++- BLAZAMGui/UI/Groups/AssignedGroup.razor | 2 +- BLAZAMGui/UI/Groups/GroupMember.razor | 2 +- BLAZAMGui/UI/Groups/MemberOfList.razor | 2 +- BLAZAMGui/UI/Modals/AuditEntryChanges.razor | 93 ++++++++++++++----- .../UI/Modals/ChangeHistoryModalContent.razor | 3 + .../UI/Settings/ApplicationSettings.razor | 4 +- BLAZAMServices/Audit/AuditActions.cs | 6 ++ BLAZAMServices/Audit/AuditLogger.cs | 4 + BLAZAMServices/Audit/BitLockerAudit.cs | 23 +++++ BLAZAMServices/Audit/GroupAudit.cs | 21 ++++- BLAZAMServices/Audit/UserAudit.cs | 16 +++- 18 files changed, 205 insertions(+), 43 deletions(-) create mode 100644 BLAZAMServices/Audit/BitLockerAudit.cs diff --git a/BLAZAM/Pages/Computers/ViewBitLocker.razor b/BLAZAM/Pages/Computers/ViewBitLocker.razor index 7017a736..3a27a010 100644 --- a/BLAZAM/Pages/Computers/ViewBitLocker.razor +++ b/BLAZAM/Pages/Computers/ViewBitLocker.razor @@ -32,6 +32,8 @@ _computer = (IADComputer)BitLocker.GetParent(); LoadingData = false; + await AuditLogger.Searched(BitLocker); + await RefreshEntryComponents(); } diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index a90ec1d6..c64b87f5 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -548,18 +548,29 @@ { var changes = User.Changes; + var assignTo = User.ToAssignTo; + var unassignFrom = User.ToUnassignFrom; var jobResults = await User.CommitChangesAsync(); if (jobResults.Result == JobResult.Passed) { + foreach(var assignment in assignTo) + { + await AuditLogger.User.Assigned(assignment.Member, assignment.Group); + await AuditLogger.Group.MemberAdded(assignment.Group, assignment.Member); + } - await AuditLogger.User.Changed(User, changes); - if(changes.Any(c=>c.Field!=ActiveDirectoryFields.MemberOf.FieldName)) - _ = OUNotificationService.PostAsync(User, NotificationType.Modify); - else + foreach (var assignment in unassignFrom) { - + await AuditLogger.User.Unassigned(assignment.Member, assignment.Group); + await AuditLogger.Group.MemberRemoved(assignment.Group, assignment.Member); + } + if (changes.Any(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName)) + { + _ = OUNotificationService.PostAsync(User, NotificationType.Modify); + await AuditLogger.User.Changed(User, changes.Where(c => c.Field != ActiveDirectoryFields.MemberOf.FieldName).ToList()); } + EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this user have been saved."); diff --git a/BLAZAMActiveDirectory/Adapters/GroupableDirectoryAdapter.cs b/BLAZAMActiveDirectory/Adapters/GroupableDirectoryAdapter.cs index cb7d7d60..e357c062 100644 --- a/BLAZAMActiveDirectory/Adapters/GroupableDirectoryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/GroupableDirectoryAdapter.cs @@ -11,8 +11,8 @@ namespace BLAZAM.ActiveDirectory.Adapters public class GroupableDirectoryAdapter : DirectoryEntryAdapter, IGroupableDirectoryAdapter { - protected List ToAssignTo = new List(); - protected List ToUnassignFrom = new List(); + public List ToAssignTo { get; protected set; } = new List(); + public List ToUnassignFrom { get; protected set; } = new List(); public virtual bool CanAssign => HasActionPermission(ObjectActions.Assign); diff --git a/BLAZAMActiveDirectory/GroupMembershipChange.cs b/BLAZAMActiveDirectory/GroupMembershipChange.cs index 9f26cb15..01d52e2e 100644 --- a/BLAZAMActiveDirectory/GroupMembershipChange.cs +++ b/BLAZAMActiveDirectory/GroupMembershipChange.cs @@ -2,6 +2,7 @@ namespace BLAZAM.ActiveDirectory { + public enum GroupMembershipAction { Assign,Unassign} /// /// Used to store membership changes for auditing purposes /// @@ -9,11 +10,13 @@ public class GroupMembershipChange { public IGroupableDirectoryAdapter Member { get; } public IADGroup Group { get; } + public GroupMembershipAction Action { get; } - public GroupMembershipChange(IGroupableDirectoryAdapter member, IADGroup group) + public GroupMembershipChange(IGroupableDirectoryAdapter member, IADGroup group,GroupMembershipAction action) { Member = member; Group = group; + Action = action; } } } diff --git a/BLAZAMActiveDirectory/Interfaces/IGroupableDirectoryModel.cs b/BLAZAMActiveDirectory/Interfaces/IGroupableDirectoryModel.cs index 53e85de1..d9197f7d 100644 --- a/BLAZAMActiveDirectory/Interfaces/IGroupableDirectoryModel.cs +++ b/BLAZAMActiveDirectory/Interfaces/IGroupableDirectoryModel.cs @@ -1,4 +1,5 @@ -using System.DirectoryServices; +using BLAZAM.ActiveDirectory.Adapters; +using System.DirectoryServices; namespace BLAZAM.ActiveDirectory.Interfaces { @@ -23,7 +24,8 @@ public interface IGroupableDirectoryAdapter : IDirectoryEntryAdapter /// Indicates whether the current web user can unassign to/from this /// bool CanUnassign { get; } - + List ToUnassignFrom { get; } + List ToAssignTo { get; } void AssignTo(IADGroup group); bool IsAMemberOf(IADGroup group); diff --git a/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs index fed3385a..a1f018ca 100644 --- a/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs +++ b/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs @@ -13,6 +13,11 @@ public class ScopedActiveDirectoryContext public IActiveDirectoryContext Context { get; } + /// + /// Creates a new scoped to the current Blazor session + /// + /// The system based context factory + /// The current user public ScopedActiveDirectoryContext(IActiveDirectoryContextFactory contextFactory, ICurrentUserStateService currentUser) { _contextFactory = contextFactory; diff --git a/BLAZAMDatabase/DatabaseConnectionString.cs b/BLAZAMDatabase/DatabaseConnectionString.cs index 3d19e434..b6e37340 100644 --- a/BLAZAMDatabase/DatabaseConnectionString.cs +++ b/BLAZAMDatabase/DatabaseConnectionString.cs @@ -4,8 +4,12 @@ namespace BLAZAM.Common.Data.Database { public enum DatabaseType { SQL, MySQL, SQLite } + /// + /// Represents a .NET ConnectionString + /// public class DatabaseConnectionString { + public DatabaseConnectionString(string connectionString) { Value = connectionString; @@ -17,9 +21,23 @@ public DatabaseConnectionString(string? connectionString, DatabaseType dbType) //ConnectionString = ConnectionString.Replace("%temp%", Path.GetTempPath().Substring(0, Path.GetTempPath().Length-1)); DatabaseType = dbType; } + /// + /// The type of database calculated from this ConnectionString + /// public DatabaseType DatabaseType; + + /// + /// Returns true if the ends with ".db" + /// public bool FileBased => ServerAddress.EndsWith(".db"); + /// + /// Returns a file that points to the . + /// This should only be used for SQLite. + /// public SystemFile File => new(ServerAddress); + /// + /// The full ConnectionString to the database + /// public string? Value { get; set; } public string AddressComponent { @@ -50,6 +68,9 @@ public string AddressComponent throw new ApplicationException("Connection String missing a Server or Data Source parameter"); } } + /// + /// Returns the database connected to based on the full ConnectionString + /// public string Database { get @@ -88,7 +109,9 @@ public string Database throw new ApplicationException("Connection String missing a Database or Initial Catalog parameter"); } } - + /// + /// The server IP or hostname as defined in the ConnectionString + /// public string ServerAddress { get @@ -120,6 +143,10 @@ public string ServerAddress } + + /// + /// The database server port as defined in the ConnectionString + /// public int ServerPort { get diff --git a/BLAZAMGui/UI/Groups/AssignedGroup.razor b/BLAZAMGui/UI/Groups/AssignedGroup.razor index 30ec5b67..c5c42469 100644 --- a/BLAZAMGui/UI/Groups/AssignedGroup.razor +++ b/BLAZAMGui/UI/Groups/AssignedGroup.razor @@ -91,7 +91,7 @@ Member.UnassignFrom(Group); SnackBarService.Warning(Member.CanonicalName + " removed from " + Group.CanonicalName + ". Don't forget to save your changes."); - await OnGroupMembershipChange.InvokeAsync(new GroupMembershipChange(Member, Group)); + await OnGroupMembershipChange.InvokeAsync(new GroupMembershipChange(Member, Group,GroupMembershipAction.Unassign)); } diff --git a/BLAZAMGui/UI/Groups/GroupMember.razor b/BLAZAMGui/UI/Groups/GroupMember.razor index ecf1cd39..a0b1f1cf 100644 --- a/BLAZAMGui/UI/Groups/GroupMember.razor +++ b/BLAZAMGui/UI/Groups/GroupMember.razor @@ -29,7 +29,7 @@ { Group.UnassignMember(Member); - await OnGroupMembershipChange.InvokeAsync(new GroupMembershipChange(Member, Group)); + await OnGroupMembershipChange.InvokeAsync(new GroupMembershipChange(Member, Group,GroupMembershipAction.Unassign)); // Notifications.Success("Removed from " + Group.DisplayName, "Sucess", options => options.IntervalBeforeClose = 5000); diff --git a/BLAZAMGui/UI/Groups/MemberOfList.razor b/BLAZAMGui/UI/Groups/MemberOfList.razor index a41ba925..8c5ea7a9 100644 --- a/BLAZAMGui/UI/Groups/MemberOfList.razor +++ b/BLAZAMGui/UI/Groups/MemberOfList.razor @@ -28,7 +28,7 @@ @if (EditMode) { - + } diff --git a/BLAZAMGui/UI/Modals/AuditEntryChanges.razor b/BLAZAMGui/UI/Modals/AuditEntryChanges.razor index 336aa825..80584f67 100644 --- a/BLAZAMGui/UI/Modals/AuditEntryChanges.razor +++ b/BLAZAMGui/UI/Modals/AuditEntryChanges.razor @@ -1,4 +1,5 @@ @using BLAZAM.Database.Models.Audit +@inject IStringLocalizer AppLocalization @foreach (var change in Changes) { @@ -22,67 +23,117 @@ { if (!AuditEntry.BeforeAction.IsNullOrEmpty()) { - foreach (var str in AuditEntry.BeforeAction.Split(";")) + if (AuditEntry.BeforeAction?.Contains(";") == true) { - if (!str.IsNullOrEmpty()) + foreach (var str in AuditEntry.BeforeAction.Split(";")) { - var data = str.Split("="); - var attr = data.FirstOrDefault(); - if (attr != null) + if (!str.IsNullOrEmpty()) { + var data = str.Split("="); + var attr = data.FirstOrDefault(); + if (attr != null) + { - Changes.Add(attr, null); + Changes.Add(attr, null); + } } } } + else + { + Changes.Add(AppLocalization["Action"], null); + } + } + else if (!AuditEntry.AfterAction.IsNullOrEmpty()) + { + if (AuditEntry.AfterAction?.Contains(";") == true) + { + foreach (var str in AuditEntry.AfterAction.Split(";")) + { + if (!str.IsNullOrEmpty()) + { + var data = str.Split("="); + var attr = data.FirstOrDefault(); + if (attr != null) + { + + Changes.Add(attr, null); + } + } + } + } + else + { + Changes.Add(AppLocalization["Action"], null); + } } - foreach(var attr in Changes.Keys) + foreach (var attr in Changes.Keys) { try { - var matchingBeforeAction = AuditEntry.BeforeAction.Split(";").FirstOrDefault(s => s.StartsWith(attr)); string? beforeValue = null; try { - beforeValue = matchingBeforeAction.Split("=")[1]; + if (AuditEntry.BeforeAction?.Contains(";") == true) + { + var matchingBeforeAction = AuditEntry.BeforeAction.Split(";").FirstOrDefault(s => s.StartsWith(attr)); + + beforeValue = matchingBeforeAction.Split("=")[1]; + } + else + { + beforeValue = AuditEntry.BeforeAction; + } + } catch { } - string? matchingAfterAction=null; - string? afterValue=null; - try{ - matchingAfterAction = AuditEntry.AfterAction.Split(";").FirstOrDefault(s => s.StartsWith(attr)); - afterValue = matchingAfterAction.Split("=")[1]; + string? matchingAfterAction = null; + string? afterValue = null; + try + { + + if (AuditEntry.AfterAction?.Contains(";") == true) + { + matchingAfterAction = AuditEntry.AfterAction.Split(";").FirstOrDefault(s => s.StartsWith(attr)); + + afterValue = matchingAfterAction.Split("=")[1]; + } + else + { + afterValue = AuditEntry.AfterAction; + } + } catch { } string outputString = beforeValue ?? ""; - if (afterValue==null || !afterValue.Contains(beforeValue)) + if (afterValue == null || beforeValue == null || !afterValue.Contains(beforeValue)) { outputString = "" + outputString + ""; } if (!afterValue.IsNullOrEmpty()) { - + if (!beforeValue.IsNullOrEmpty()) - outputString += "" + afterValue.Replace(beforeValue, "")+""; - else + outputString += "" + afterValue.Replace(beforeValue, "") + ""; + else outputString += "" + afterValue + ""; } - + Changes[attr] = outputString; } catch { - + } - + } } } diff --git a/BLAZAMGui/UI/Modals/ChangeHistoryModalContent.razor b/BLAZAMGui/UI/Modals/ChangeHistoryModalContent.razor index 3d910bfb..cb2939ec 100644 --- a/BLAZAMGui/UI/Modals/ChangeHistoryModalContent.razor +++ b/BLAZAMGui/UI/Modals/ChangeHistoryModalContent.razor @@ -49,11 +49,14 @@ protected override async Task OnInitializedAsync() { Modal.Options.FullWidth = true; + Modal.Options.CloseButton = true; await base.OnInitializedAsync(); _events = await Context.DirectoryEntryAuditLogs.Where(l => l.Action != AuditActions.Computer_Searched && l.Action != AuditActions.User_Searched && l.Action != AuditActions.Group_Searched && l.Action != AuditActions.OU_Searched + && l.Action != AuditActions.Printer_Searched + && l.Action != AuditActions.BitLocker_Searched && l.Sid.Equals(Model.SID.ToSidString())).OrderByDescending(l => l.Timestamp).ToListAsync(); if (Model.Created.HasValue) { diff --git a/BLAZAMGui/UI/Settings/ApplicationSettings.razor b/BLAZAMGui/UI/Settings/ApplicationSettings.razor index 2608c5c8..dec63f0a 100644 --- a/BLAZAMGui/UI/Settings/ApplicationSettings.razor +++ b/BLAZAMGui/UI/Settings/ApplicationSettings.razor @@ -31,7 +31,7 @@ - + @* @@ -42,7 +42,7 @@ - + *@ diff --git a/BLAZAMServices/Audit/AuditActions.cs b/BLAZAMServices/Audit/AuditActions.cs index 3f01fea8..7ffbbc40 100644 --- a/BLAZAMServices/Audit/AuditActions.cs +++ b/BLAZAMServices/Audit/AuditActions.cs @@ -35,6 +35,8 @@ public class AuditActions public const string Group_Searched = "Group Searched"; public const string Group_Assigned = "Group Assigned"; public const string Group_Unassigned = "Group Unassigned"; + public const string Group_Member_Added = "Group Member Added"; + public const string Group_Member_Removed = "Group Member Removed"; public const string Group_Created = "Group Created"; public const string Group_Deleted = "Group Deleted"; public const string Group_Moved = "Group Moved"; @@ -56,6 +58,10 @@ public class AuditActions public const string Printer_Moved = "Printer Moved"; public const string Printer_Edited = "Printer Edited"; + + //BitLocker Actions + public const string BitLocker_Searched = "BitLocker Searched"; + //Settings Actions public const string Settings_Edited = "Settings Edited"; diff --git a/BLAZAMServices/Audit/AuditLogger.cs b/BLAZAMServices/Audit/AuditLogger.cs index 7a095fdb..8090f0e5 100644 --- a/BLAZAMServices/Audit/AuditLogger.cs +++ b/BLAZAMServices/Audit/AuditLogger.cs @@ -20,6 +20,7 @@ public class AuditLogger public OUAudit OU; public PrinterAudit Printer; public LogonAudit Logon; + public BitLockerAudit BitLocker; public AuditLogger(IAppDatabaseFactory factory, IApplicationUserStateService userStateService) { @@ -30,6 +31,7 @@ public AuditLogger(IAppDatabaseFactory factory, IApplicationUserStateService use OU = new OUAudit(factory, userStateService); Printer = new PrinterAudit(factory, userStateService); Logon = new LogonAudit(factory, userStateService); + BitLocker = new BitLockerAudit(factory, userStateService); } public async Task Searched(IDirectoryEntryAdapter searchedEntry) { @@ -43,6 +45,8 @@ public async Task Searched(IDirectoryEntryAdapter searchedEntry) await OU.Searched(searchedEntry); else if (searchedEntry is IADPrinter) await Printer.Searched(searchedEntry); + else if (searchedEntry is IADBitLockerRecovery) + await BitLocker.Searched(searchedEntry); } } diff --git a/BLAZAMServices/Audit/BitLockerAudit.cs b/BLAZAMServices/Audit/BitLockerAudit.cs new file mode 100644 index 00000000..f655b55d --- /dev/null +++ b/BLAZAMServices/Audit/BitLockerAudit.cs @@ -0,0 +1,23 @@ +using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.Database.Context; +using BLAZAM.Session.Interfaces; + +namespace BLAZAM.Services.Audit +{ + public class BitLockerAudit : DirectoryAudit + { + public BitLockerAudit(IAppDatabaseFactory factory, + IApplicationUserStateService userStateService) : base(factory, userStateService) + { + } + + + public override async Task Searched(IDirectoryEntryAdapter searchedOU) + => await Log(c => c.DirectoryEntryAuditLogs, + AuditActions.BitLocker_Searched, + searchedOU); + + + + } +} \ No newline at end of file diff --git a/BLAZAMServices/Audit/GroupAudit.cs b/BLAZAMServices/Audit/GroupAudit.cs index 277a5368..142ec3bb 100644 --- a/BLAZAMServices/Audit/GroupAudit.cs +++ b/BLAZAMServices/Audit/GroupAudit.cs @@ -23,7 +23,7 @@ await Log(c => c.DirectoryEntryAuditLogs, AuditActions.Group_Assigned, member, null, - "Assigned to" + parent.DN); + "Assigned to " + parent.DN); await Log(c => c.DirectoryEntryAuditLogs, AuditActions.Group_Assigned, parent, @@ -31,6 +31,25 @@ await Log(c => c.DirectoryEntryAuditLogs, "Added member " + member.DN); return true; } + public async Task MemberAdded(IDirectoryEntryAdapter parent,IDirectoryEntryAdapter member) + { + await Log(c => c.DirectoryEntryAuditLogs, + AuditActions.Group_Member_Added, + parent, + null, + "Added member " + member.DN); + return true; + } + public async Task MemberRemoved(IDirectoryEntryAdapter parent, IDirectoryEntryAdapter member) + { + await Log(c => c.DirectoryEntryAuditLogs, + AuditActions.Group_Member_Added, + parent, + null, + "Removed member " + member.DN); + return true; + } + public override async Task Changed(IDirectoryEntryAdapter changedGroup, List changes) { diff --git a/BLAZAMServices/Audit/UserAudit.cs b/BLAZAMServices/Audit/UserAudit.cs index 3d971eb4..322f4608 100644 --- a/BLAZAMServices/Audit/UserAudit.cs +++ b/BLAZAMServices/Audit/UserAudit.cs @@ -31,12 +31,18 @@ await Log(c => c.DirectoryEntryAuditLogs, AuditActions.User_Assigned, member, null, - "Assigned to" + parent.DN); + "Assigned to " + parent.DN); + + return true; + } + public async Task Unassigned(IDirectoryEntryAdapter member, IDirectoryEntryAdapter parent) + { await Log(c => c.DirectoryEntryAuditLogs, - AuditActions.User_Assigned, - parent, - null, - "Added member " + member.DN); + AuditActions.User_Unassigned, + member, + null, + "Unassigned from " + parent.DN); + return true; } From f339bf6de8e0808fd30d572f882fdf6ee5e0ef22 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 5 Aug 2024 18:10:00 -0400 Subject: [PATCH 096/116] Update all MudBlazor components except TreeViews --- BLAZAM/App.razor | 1 + BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Privacy.razor | 64 +++++++++---------- BLAZAMGui/Helper/GuiHelpers.cs | 2 +- BLAZAMGui/UI/Inputs/AppCloseButton.razor | 18 +++--- BLAZAMGui/UI/Inputs/MudSelectList.razor | 2 +- .../UI/Inputs/TreeViews/ADTreeView.razor | 5 +- .../UI/Inputs/TreeViews/ADTreeView.razor.cs | 10 +-- .../UI/Inputs/TreeViews/OUTreeView.razor | 36 ++--------- .../UI/Inputs/TreeViews/OUTreeView.razor.cs | 10 +-- .../UI/Inputs/TreeViews/OUTreeViewBase.cs | 11 ++-- .../Modals/AppUserProfileModalContent.razor | 7 +- .../UI/Outputs/Jobs/JobResultDialog.razor | 2 +- .../UI/SessionExpirationWarningProvider.razor | 4 +- .../UI/Settings/ApplicationSettings.razor | 11 ++-- .../UI/Settings/AuthenticationSetting.razor | 4 +- BLAZAMGui/UI/Settings/EmailSettings.razor | 6 +- .../UploadCertificateModalContent.razor | 9 +-- .../Permissions/AddPrivilegeLevelModal.razor | 4 +- BLAZAMGui/UI/Settings/UpdateSettings.razor | 4 +- 20 files changed, 90 insertions(+), 122 deletions(-) diff --git a/BLAZAM/App.razor b/BLAZAM/App.razor index 5f93cde9..13743b8e 100644 --- a/BLAZAM/App.razor +++ b/BLAZAM/App.razor @@ -59,6 +59,7 @@ + diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 2e7c4093..b35765b6 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.07.27.2017 + 2024.08.05.2205 false BLAZAM False diff --git a/BLAZAM/Pages/Privacy.razor b/BLAZAM/Pages/Privacy.razor index 85a4a3eb..8e336039 100644 --- a/BLAZAM/Pages/Privacy.razor +++ b/BLAZAM/Pages/Privacy.razor @@ -6,27 +6,27 @@ This privacy policy explains how BLAZAM collects, uses, and protects your person What information do we collect? We collect two types of information from you: personal information and non-personal information. - - + + Personal information is any information that can be used to identify you, such as your name, email address, or IP address. We only collect a minimum of personal information that includes IP addresses, Server DNS Names, Operating system Versions, Windows account names, any information available in the connected directory, all of which you voluntarily provide to us when you use our services. - - + + Non-personal information is any information that cannot be used to identify you, such as your browser type, device type, or usage statistics. We collect non-personal information automatically when you use our app, using cookies and other similar technologies. - - + + How do we use your information? We use your information for the following purposes: - - To provide and improve our app, and to deliver the services you request. - To respond to your inquiries, and assist with updates to the app. - To monitor and analyze our app performance, and to detect and prevent errors, fraud, and security issues. - To comply with our legal obligations, enforce our terms of service, and protect our rights and interests. - + + To provide and improve our app, and to deliver the services you request. + To respond to your inquiries, and assist with updates to the app. + To monitor and analyze our app performance, and to detect and prevent errors, fraud, and security issues. + To comply with our legal obligations, enforce our terms of service, and protect our rights and interests. + @@ -34,18 +34,18 @@ We use your information for the following purposes: How do we share your information? We do not sell, rent, or trade your personal information with any third parties, except as described below: - - + + We may share your information with our service providers, such as Google Analytics 4 (GA4) who helps us with our app operation, maintenance, and analytics. GA4 only has access to the information they need to perform their tasks, and they are obligated to protect your information and use it only for the purposes we specify. - - + + We may share your information with law enforcement, government authorities, or other parties, if we believe it is necessary to comply with a legal obligation, to protect our rights and interests, or to prevent or stop illegal or harmful activities. - - + + We may share your information with other parties, with your consent or at your direction. - + - + How do we protect your information? We take reasonable measures to protect your information from unauthorized access, use, disclosure, alteration, or destruction. However, no method of transmission or storage is completely secure, and we cannot guarantee the absolute security of your information. You are responsible for keeping your password and account details confidential, and for notifying us of any unauthorized or suspicious activity on your account. @@ -57,23 +57,23 @@ We may also use other similar technologies, such as web beacons, pixels, or loca How do we respect your choices and rights? You have the following choices and rights regarding your information: - - + + You can access, update, correct, or delete your personal information at any time by contacting us. - - + + You can opt out of Google Analytics 4 by installing the Google Analytics opt-out browser add-on. - - + + You can request a copy of your personal information that we hold by contacting us. - - + + You can object to or restrict our processing of your personal information, or withdraw your consent, by contacting us. - - + + You can lodge a complaint with a data protection authority, if you believe we have violated your privacy rights. - - + + diff --git a/BLAZAMGui/Helper/GuiHelpers.cs b/BLAZAMGui/Helper/GuiHelpers.cs index ddeacb49..bff4dab8 100644 --- a/BLAZAMGui/Helper/GuiHelpers.cs +++ b/BLAZAMGui/Helper/GuiHelpers.cs @@ -53,6 +53,6 @@ public static List> ToTreeItemData(this IEnumerable items) }); return treeData; } - + } } diff --git a/BLAZAMGui/UI/Inputs/AppCloseButton.razor b/BLAZAMGui/UI/Inputs/AppCloseButton.razor index 087d72b2..8b4216d1 100644 --- a/BLAZAMGui/UI/Inputs/AppCloseButton.razor +++ b/BLAZAMGui/UI/Inputs/AppCloseButton.razor @@ -1,18 +1,16 @@ @inherits MudIcon + Color="@Color" + Disabled=@Disabled + Size=@Size + IconClass="ma-0" + Style=@(Style+"width:min-content;height:min-content;min-width:0") + Tag=@Tag + StartIcon="@Icons.Material.Filled.Close" + @onclick=@OnClick /> @code { [Parameter] public EventCallback OnClick { get; set; } - [Parameter] - public bool Disabled{ get; set; } } \ No newline at end of file diff --git a/BLAZAMGui/UI/Inputs/MudSelectList.razor b/BLAZAMGui/UI/Inputs/MudSelectList.razor index d9bf5daa..8745828d 100644 --- a/BLAZAMGui/UI/Inputs/MudSelectList.razor +++ b/BLAZAMGui/UI/Inputs/MudSelectList.razor @@ -23,7 +23,7 @@ } - + diff --git a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor index 1fe8047f..319c8797 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor +++ b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor @@ -9,9 +9,8 @@ Hover="true" Color="Color.Success" @bind-SelectedValue="SelectedEntry"> - + @* - + *@ diff --git a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs index 680421c6..a44335ed 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs @@ -26,7 +26,7 @@ public partial class ADTreeView : OUTreeViewBase - private HashSet? GetItems(IDirectoryEntryAdapter parent) + private IReadOnlyCollection>? GetItems(IDirectoryEntryAdapter parent) { if (parent.IsExpanded || parent.CachedChildren != null) { @@ -38,16 +38,16 @@ public partial class ADTreeView : OUTreeViewBase { items = items.Where(i => i.ObjectType == ActiveDirectoryObjectType.OU); } - var hashset = items.ToHashSet(); - return hashset; + var treeBranchh = items.ToTreeItemData(); + return treeBranchh; } return null; } - protected async Task> GetChildrenAsync(IDirectoryEntryAdapter parentNode) + protected async Task>> GetChildrenAsync(IDirectoryEntryAdapter parentNode) { return await Task.Run(() => { - return GetChildren(parentNode); + return GetChildren(parentNode).ToTreeItemData(); }); } diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor index 6d7a4775..4a11dbac 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor @@ -2,16 +2,15 @@ @Label - - - + - @* - @{ - string itemIcon = Icons.Material.Filled.Folder; - } - @if (context.IsExpanded) - { - itemIcon = Icons.Material.Filled.FolderOpen; - } - @if (Badge != null) - { - - - - @context.CanonicalName - - @EndAdornment?.Invoke(context) - - - } - else - { - - - @context.CanonicalName - @EndAdornment?.Invoke(context) - } - *@ - + *@ @if (RootOU == null || !RootOU.Any() || LoadingData) diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs index 5ccb5475..f7d0a867 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs @@ -16,22 +16,22 @@ public partial class OUTreeView:OUTreeViewBase [Parameter] public RenderFragment? EndAdornment { get; set; } - HashSet GetChildren(IDirectoryEntryAdapter context) + List> GetChildren(IDirectoryEntryAdapter context) { if (context is IADOrganizationalUnit ou) { if (ou.IsExpanded) { - return ou.TreeViewSubOUs.Where(o=>ShouldShowOU(o)).ToHashSet(); + return ou.TreeViewSubOUs.Where(o=>ShouldShowOU(o)).ToTreeItemData(); } else { - return ou.CachedTreeViewSubOUs.Where(o => ShouldShowOU(o)).ToHashSet(); + return ou.CachedTreeViewSubOUs.Where(o => ShouldShowOU(o)).ToTreeItemData(); } } - return new HashSet(); + return new List>(); } - async Task> GetChildrenAsync(IDirectoryEntryAdapter parentNode) + async Task>> GetChildrenAsync(IDirectoryEntryAdapter parentNode) { return await Task.Run(() => { diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs index d6abdf77..f900d339 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs @@ -31,7 +31,7 @@ public class OUTreeViewBase : AppComponentBase /// Defaults to the App Base root /// [Parameter] - public HashSet RootOU { get; set; } = new HashSet(); + public IReadOnlyCollection>? RootOU { get; set; } = new List>(); [Parameter] public IADOrganizationalUnit? StartingSelectedOU { @@ -112,7 +112,9 @@ protected async Task InitializeTreeView() TopLevel = new ADOrganizationalUnit(); TopLevel.Parse(directory: Directory, directoryEntry: Directory.GetDirectoryEntry()); _ = TopLevel.SubOUs; - RootOU = new HashSet() { TopLevel as IDirectoryEntryAdapter }; + var TopLevelList = new List() { TopLevel }; + // RootOU = new HashSet() { TopLevel as IDirectoryEntryAdapter }; + RootOU = TopLevelList.ToTreeItemData(); } if (StartingSelectedOU == null) { @@ -151,9 +153,10 @@ protected void OpenToSelected() { if (!SelectedEntry.Equals(RootOU)) { - IDirectoryEntryAdapter? firstThing = RootOU.First(); - if (firstThing is IADOrganizationalUnit openThis) + var firstThing = RootOU.First(); + if (firstThing.Value is IADOrganizationalUnit openThis) { + openThis.IsExpanded = true; while (openThis != null) { diff --git a/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor b/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor index 21dee518..9e8ab029 100644 --- a/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor +++ b/BLAZAMGui/UI/Modals/AppUserProfileModalContent.razor @@ -7,13 +7,12 @@ } - + + StartIcon="@Icons.Material.Filled.CloudUpload"> @if (CurrentUser.State.Preferences.ProfilePicture == null) { Upload Profile Icon @@ -38,7 +37,7 @@ } - + diff --git a/BLAZAMGui/UI/Outputs/Jobs/JobResultDialog.razor b/BLAZAMGui/UI/Outputs/Jobs/JobResultDialog.razor index 83e83225..d811f471 100644 --- a/BLAZAMGui/UI/Outputs/Jobs/JobResultDialog.razor +++ b/BLAZAMGui/UI/Outputs/Jobs/JobResultDialog.razor @@ -47,7 +47,7 @@ protected override void OnInitialized() { var newOptions = MudDialog.Options; - newOptions.DisableBackdropClick= true; + newOptions.BackdropClick = false; MudDialog.SetOptions(newOptions); diff --git a/BLAZAMGui/UI/SessionExpirationWarningProvider.razor b/BLAZAMGui/UI/SessionExpirationWarningProvider.razor index 7a3a9628..3ff64de8 100644 --- a/BLAZAMGui/UI/SessionExpirationWarningProvider.razor +++ b/BLAZAMGui/UI/SessionExpirationWarningProvider.razor @@ -54,10 +54,10 @@ YesText=@AppLocalization["Log In"] OnYes="@(()=>{Refresh();})" Options=@(new DialogOptions{ - ClassBackground="blur-background", + BackgroundClass="blur-background", CloseButton=false, CloseOnEscapeKey=false, - DisableBackdropClick=true})> + BackdropClick=false})> @AppLocalization["Your session has expired."] diff --git a/BLAZAMGui/UI/Settings/ApplicationSettings.razor b/BLAZAMGui/UI/Settings/ApplicationSettings.razor index b869abd7..f5ae0b2d 100644 --- a/BLAZAMGui/UI/Settings/ApplicationSettings.razor +++ b/BLAZAMGui/UI/Settings/ApplicationSettings.razor @@ -23,10 +23,10 @@ - + @@ -58,15 +58,14 @@ } - + + StartIcon="@Icons.Material.Filled.CloudUpload"> Upload Icon - + diff --git a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor index d6ee50d2..9e1ae53b 100644 --- a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor +++ b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor @@ -28,7 +28,7 @@ @@ -39,7 +39,7 @@ T="DuoUnreachableBehavior" Converter=@(new BehaviorConverter()) @bind-Value="@settings.DuoUnreachableBehavior" - UnCheckedColor="Color.Error" + UncheckedColor="Color.Error" Color="Color.Success" Disabled=@(duoHealthCheckResult!=true) /> diff --git a/BLAZAMGui/UI/Settings/EmailSettings.razor b/BLAZAMGui/UI/Settings/EmailSettings.razor index 5f501815..b007f21c 100644 --- a/BLAZAMGui/UI/Settings/EmailSettings.razor +++ b/BLAZAMGui/UI/Settings/EmailSettings.razor @@ -10,7 +10,7 @@ + UncheckedColor="Color.Error" /> @@ -33,7 +33,7 @@ @@ -43,7 +43,7 @@ diff --git a/BLAZAMGui/UI/Settings/Modals/UploadCertificateModalContent.razor b/BLAZAMGui/UI/Settings/Modals/UploadCertificateModalContent.razor index 5f250547..0676eb9c 100644 --- a/BLAZAMGui/UI/Settings/Modals/UploadCertificateModalContent.razor +++ b/BLAZAMGui/UI/Settings/Modals/UploadCertificateModalContent.razor @@ -10,8 +10,7 @@ + StartIcon="@Icons.Material.Filled.CloudUpload"> Upload PFX @@ -36,8 +35,7 @@ + StartIcon="@Icons.Material.Filled.CloudUpload"> Upload Certificate @@ -58,8 +56,7 @@ + StartIcon="@Icons.Material.Filled.CloudUpload"> Upload Key diff --git a/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor b/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor index 05b5a019..83233b03 100644 --- a/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor +++ b/BLAZAMGui/UI/Settings/Permissions/AddPrivilegeLevelModal.razor @@ -7,7 +7,7 @@ @bind-SelectedResult=@selectedDelegate CustomResultsFilter="(result)=>result.ObjectType==ActiveDirectoryObjectType.User|| result.ObjectType==ActiveDirectoryObjectType.Group" /> - + Will have complete and total acceess to the application if enabled @@ -37,7 +37,7 @@ Context.PermissionDelegate.Add(NewPermissionDelegate); await Context.SaveChangesAsync(); NewPermissionDelegate = new PermissionDelegate(); - Modal?.Close(); + Modal?.CloseAsync(); await DelegateAdded.InvokeAsync(); } catch (DbUpdateException ex) diff --git a/BLAZAMGui/UI/Settings/UpdateSettings.razor b/BLAZAMGui/UI/Settings/UpdateSettings.razor index 931e3bd7..212b3010 100644 --- a/BLAZAMGui/UI/Settings/UpdateSettings.razor +++ b/BLAZAMGui/UI/Settings/UpdateSettings.razor @@ -71,7 +71,7 @@ @if (settings.UseUpdateCredentials) { @@ -141,7 +141,7 @@ From 91476c1595e8deb72930017c8436b43605693d78 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 5 Aug 2024 18:29:40 -0400 Subject: [PATCH 097/116] Fix for assign only permissions on View Group page --- BLAZAM/Pages/Groups/ViewGroup.razor | 2 +- BLAZAMGui/UI/DirectoryEntryViewHeader.razor | 4 ++-- BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor | 2 +- BLAZAMSession/ApplicationUserState.cs | 1 + BLAZAMSession/Interfaces/IApplicationUserState.cs | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/BLAZAM/Pages/Groups/ViewGroup.razor b/BLAZAM/Pages/Groups/ViewGroup.razor index 14f60eb5..b52e2023 100644 --- a/BLAZAM/Pages/Groups/ViewGroup.razor +++ b/BLAZAM/Pages/Groups/ViewGroup.razor @@ -114,7 +114,7 @@ - @if (Group.CanEdit && Group.HasUnsavedChanges) + @if ((Group.CanEdit || Group.CanUnassign || Group.CanAssign) && Group.HasUnsavedChanges) { } diff --git a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor index 14554631..b06dfcf4 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor +++ b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor @@ -64,8 +64,8 @@ Icon="@Icons.Material.Filled.Edit" ToggledIcon="@Icons.Material.Filled.EditOff" ToggledColor="Color.Error" - Disabled=@(!DirectoryEntry.CanEdit) - ToggledTitle="End Edit" /> + Disabled=@(!DirectoryEntry.CanEdit && !CurrentUser.State.CanAssign) + /> @if (accountEntry != null && accountEntry.LockedOut) diff --git a/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor b/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor index 657e6ed2..22a5fa55 100644 --- a/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor +++ b/BLAZAMGui/UI/Groups/GroupMembersDataGrid.razor @@ -65,7 +65,7 @@ ShowOnClick=@(!cellContext.Item.CanUnassign) ShowOnHover=@(!cellContext.Item.CanUnassign) Text="You don't have permission to remove this group member"> - @AppLocalization["Remove"] diff --git a/BLAZAMSession/ApplicationUserState.cs b/BLAZAMSession/ApplicationUserState.cs index c1a893ef..4f32e288 100644 --- a/BLAZAMSession/ApplicationUserState.cs +++ b/BLAZAMSession/ApplicationUserState.cs @@ -328,6 +328,7 @@ public bool HasRole(string userRole) public bool HasComputerPrivilege => HasObjectReadPermissions(ActiveDirectoryObjectType.Computer); public bool CanUnlockUsers => HasObjectActionPermission(ActiveDirectoryObjectType.User,ObjectActions.Unlock); + public bool CanAssign => HasObjectActionPermission(ActiveDirectoryObjectType.Group, ObjectActions.Assign); public string DuoAuthState { get; set; } = ""; public List NotificationSubscriptions { get => userSettings?.NotificationSubscriptions; set { userSettings.NotificationSubscriptions=value; } } diff --git a/BLAZAMSession/Interfaces/IApplicationUserState.cs b/BLAZAMSession/Interfaces/IApplicationUserState.cs index 37c78007..10f92a73 100644 --- a/BLAZAMSession/Interfaces/IApplicationUserState.cs +++ b/BLAZAMSession/Interfaces/IApplicationUserState.cs @@ -79,6 +79,7 @@ public interface IApplicationUserState bool HasCreateOUPrivilege { get; } bool HasComputerPrivilege { get; } bool CanUnlockUsers { get; } + bool CanAssign { get; } string DuoAuthState { get; set; } IList? ReadNewsItems { get; } From 165d9de2506ad98c764af6c3c416adc389e0bcda Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 5 Aug 2024 19:10:10 -0400 Subject: [PATCH 098/116] TreeViews updated for latest MudBlazor --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMGui/Layouts/MainLayout.razor | 15 +---------- BLAZAMGui/UI/Chat/AppChat.razor | 21 ++++++++-------- .../UI/Computers/ComputerResourceCharts.razor | 25 +++++++++++++++---- BLAZAMGui/UI/DirectoryEntryViewHeader.razor | 12 ++++++--- .../UI/Inputs/TreeViews/ADTreeView.razor | 22 ++++++++-------- .../UI/Inputs/TreeViews/OUTreeView.razor | 17 ++++++------- .../UI/Inputs/TreeViews/OUTreeView.razor.cs | 9 +------ .../UI/Inputs/UnsavedChangesPrompt.razor | 4 +-- .../UI/Outputs/ApplicationNewsProvider.razor | 12 ++++++--- 10 files changed, 72 insertions(+), 67 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index b35765b6..d7a87c26 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.08.05.2205 + 2024.08.05.2304 false BLAZAM False diff --git a/BLAZAMGui/Layouts/MainLayout.razor b/BLAZAMGui/Layouts/MainLayout.razor index 23bc56ff..8e6c38b7 100644 --- a/BLAZAMGui/Layouts/MainLayout.razor +++ b/BLAZAMGui/Layouts/MainLayout.razor @@ -102,16 +102,6 @@ await InvokeAsync(StateHasChanged); - @* - - TODO Either break down chat to only page chat, or rebuild appchat - - - *@ @@ -175,9 +165,8 @@ await InvokeAsync(StateHasChanged); Header.OnRefreshRequested += (async () => { await InvokeAsync(StateHasChanged); }); - //StateHasChanged(); + InvokeAsync(StateHasChanged); - //Update(); } SetSubHeader? SubHeader; public void SetSubHeader(SetSubHeader? setSubHeader) @@ -186,9 +175,7 @@ await InvokeAsync(StateHasChanged); if (SubHeader != null) SubHeader.OnRefreshRequested += (async () => { await InvokeAsync(StateHasChanged); }); - //StateHasChanged(); InvokeAsync(StateHasChanged); - //Update(); } public void Update() => StateHasChanged(); diff --git a/BLAZAMGui/UI/Chat/AppChat.razor b/BLAZAMGui/UI/Chat/AppChat.razor index b47d8d4f..f42a17bb 100644 --- a/BLAZAMGui/UI/Chat/AppChat.razor +++ b/BLAZAMGui/UI/Chat/AppChat.razor @@ -62,12 +62,12 @@ { int unreadRoomMessageCount = Chat.GetUnreadMessages(currentUserState.Preferences, chatRoom).Count(); 0) - Origin=Origin.CenterLeft - Max="99" - Content="unreadRoomMessageCount" - Color="Color.Error"> + Overlap=true + Visible=@(unreadRoomMessageCount>0) + Origin=Origin.CenterLeft + Max="99" + Content="unreadRoomMessageCount" + Color="Color.Error"> @chatRoom.Name @@ -112,7 +112,8 @@ @if (ApplicationInfo.InDebugMode && IsAdmin) { - Delete All Chat Rooms + Delete All Chat Rooms } @@ -175,9 +176,9 @@ { await base.OnInitializedAsync(); - await Task.Run(async() => + await Task.Run(async () => { - + currentUserState = CurrentUser.State; if (ChatUri.IsNullOrEmpty()) @@ -234,7 +235,7 @@ }); }); - + } void SwitchTo(ChatRoom room) diff --git a/BLAZAMGui/UI/Computers/ComputerResourceCharts.razor b/BLAZAMGui/UI/Computers/ComputerResourceCharts.razor index fd54c206..d82ad16d 100644 --- a/BLAZAMGui/UI/Computers/ComputerResourceCharts.razor +++ b/BLAZAMGui/UI/Computers/ComputerResourceCharts.razor @@ -4,17 +4,32 @@ - + - - + + @if (showCPUChart) { - + } @if (showRAMChart) { - + } } else diff --git a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor index b06dfcf4..4893957c 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor +++ b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor @@ -37,10 +37,15 @@ @if (accountEntry?.LockedOut == true) { - + } - + @if (accountEntry != null) { @@ -64,8 +69,7 @@ Icon="@Icons.Material.Filled.Edit" ToggledIcon="@Icons.Material.Filled.EditOff" ToggledColor="Color.Error" - Disabled=@(!DirectoryEntry.CanEdit && !CurrentUser.State.CanAssign) - /> + Disabled=@(!DirectoryEntry.CanEdit && !CurrentUser.State.CanAssign) /> @if (accountEntry != null && accountEntry.LockedOut) diff --git a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor index 319c8797..181e4ffa 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor +++ b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor @@ -9,22 +9,22 @@ Hover="true" Color="Color.Success" @bind-SelectedValue="SelectedEntry"> - @* - + - *@ + diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor index 4a11dbac..232fd114 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor @@ -9,22 +9,21 @@ MaxHeight="400px" Color="Color.Primary" @bind-SelectedValue="SelectedEntry"> -@* + + EndText="@EndText?.Invoke(context.Value)"> - *@ + @if (RootOU == null || !RootOU.Any() || LoadingData) diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs index f7d0a867..b924d090 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor.cs @@ -19,15 +19,8 @@ public partial class OUTreeView:OUTreeViewBase List> GetChildren(IDirectoryEntryAdapter context) { if (context is IADOrganizationalUnit ou) - { - if (ou.IsExpanded) - { + { return ou.TreeViewSubOUs.Where(o=>ShouldShowOU(o)).ToTreeItemData(); - } - else - { - return ou.CachedTreeViewSubOUs.Where(o => ShouldShowOU(o)).ToTreeItemData(); - } } return new List>(); } diff --git a/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor b/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor index 6e1ee1b6..6598775c 100644 --- a/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor +++ b/BLAZAMGui/UI/Inputs/UnsavedChangesPrompt.razor @@ -8,14 +8,14 @@ diff --git a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor index 2a48d00b..232be018 100644 --- a/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor +++ b/BLAZAMGui/UI/Outputs/ApplicationNewsProvider.razor @@ -71,12 +71,18 @@ @AppLocalization["There is nothing new to see here"] } } - @if (readItems.Count > 0) + @if (readItems.Count > 0 || unreadItems.Count >0) { - + @if (readItems.Count > 0) + { + + } + @if (unreadItems.Count > 0) + { + @AppLocalization["Mark all read"] - + } } From 082c156ba4300d115e8d35dcb817405730e8112f Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 6 Aug 2024 17:07:48 -0400 Subject: [PATCH 099/116] Fix for changed entries widget showing wrong results --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index d7a87c26..a8d99594 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.08.05.2304 + 2024.08.06.2106 false BLAZAM False diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor index 9f65b1cd..019aa729 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor @@ -57,7 +57,7 @@ { var search = new ADSearch(); - search.Fields.PasswordLastSet = DateTime.Now.AddDays(-1).ToFileTimeUtc().ToString(); + search.Fields.Changed = DateTime.Now.AddDays(-1); changdEntries = (await search.SearchAsync()).Where(x => x.CanRead).ToList(); LoadingData = false; await InvokeAsync(StateHasChanged); From 6b8ff04eeea4373719dc6cb30c68bac2d401a770 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 6 Aug 2024 19:33:18 -0400 Subject: [PATCH 100/116] MudBlazor upgrade compled --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMGui/UI/DirectoryEntryViewHeader.razor | 2 +- BLAZAMGui/UI/Inputs/ADAutoComplete.razor | 2 +- BLAZAMGui/UI/Inputs/DynamicMudInput.razor | 54 ++++++++--------- BLAZAMGui/UI/Inputs/MudSelectList.razor | 10 +++- BLAZAMGui/UI/Settings/DirectorySettings.razor | 2 +- .../Permissions/DelegateListItem.razor | 31 ++++++---- .../Permissions/EditAccessLevel.razor | 60 +++++++++++-------- 8 files changed, 93 insertions(+), 70 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index a8d99594..fd416f87 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.08.06.2106 + 2024.08.06.2321 false BLAZAM False diff --git a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor index 4893957c..a3596aff 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor +++ b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor @@ -157,7 +157,7 @@ diff --git a/BLAZAMGui/UI/Inputs/ADAutoComplete.razor b/BLAZAMGui/UI/Inputs/ADAutoComplete.razor index 856bf818..c1c82cec 100644 --- a/BLAZAMGui/UI/Inputs/ADAutoComplete.razor +++ b/BLAZAMGui/UI/Inputs/ADAutoComplete.razor @@ -10,7 +10,7 @@ @bind-Text=@SearchTerm @ref=AutoComplete AutoFocus=@AutoFocus - SearchFuncWithCancel="@GetResults" + SearchFunc="@GetResults" DebounceInterval=500 ResetValueOnEmptyText="true" Validation="@Validation" diff --git a/BLAZAMGui/UI/Inputs/DynamicMudInput.razor b/BLAZAMGui/UI/Inputs/DynamicMudInput.razor index 59b24ebe..ddcb21f6 100644 --- a/BLAZAMGui/UI/Inputs/DynamicMudInput.razor +++ b/BLAZAMGui/UI/Inputs/DynamicMudInput.razor @@ -15,44 +15,42 @@ case "double": case "long": case "float": - + break; case "String": + HelperText="@HelperText" + Immediate=@Immediate + Clearable=@Clearable + Value=Value + ValueChanged="@((changed)=>{Value =changed;})" + Disabled=@Disabled + InputType="@InputType" /> break; case "Boolean": - - - @HelperText + + + @HelperText break; case "DateTime": {dateValue = date;}) - Disabled=@Disabled /> + HelperText="@HelperText" + Label="@Label" + Date="@dateValue" + DateChanged=@((date) =>{dateValue = date;}) + Disabled=@Disabled /> break; default: diff --git a/BLAZAMGui/UI/Inputs/MudSelectList.razor b/BLAZAMGui/UI/Inputs/MudSelectList.razor index 8745828d..5f4926b2 100644 --- a/BLAZAMGui/UI/Inputs/MudSelectList.razor +++ b/BLAZAMGui/UI/Inputs/MudSelectList.razor @@ -23,7 +23,8 @@ } - + @@ -42,17 +43,20 @@ @if (MultiSelection) { } @if (ToStringFunc != null) { - + @ToStringFunc.Invoke(val) } else { - + @val?.ToString() } diff --git a/BLAZAMGui/UI/Settings/DirectorySettings.razor b/BLAZAMGui/UI/Settings/DirectorySettings.razor index c91d8197..d1657dc6 100644 --- a/BLAZAMGui/UI/Settings/DirectorySettings.razor +++ b/BLAZAMGui/UI/Settings/DirectorySettings.razor @@ -108,7 +108,7 @@ - + diff --git a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor index 130c3ac5..6254fa38 100644 --- a/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor +++ b/BLAZAMGui/UI/Settings/Permissions/DelegateListItem.razor @@ -4,10 +4,13 @@ @Delegate.DelegateName - - - + + + @@ -27,14 +30,20 @@ - + - Save Changes - + Save Changes + @@ -44,7 +53,7 @@ @code { - #nullable disable warnings +#nullable disable warnings IDirectoryEntryAdapter? _delegateEntry; [Parameter] public PermissionDelegate Delegate { get; set; } @@ -52,15 +61,15 @@ public new IDatabaseContext Context { get; set; } [Parameter] - public EventCallback DelegateDeleted{ get; set; } + public EventCallback DelegateDeleted { get; set; } protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); _delegateEntry = Directory.FindEntryBySID(Delegate.DelegateSid); - if(_delegateEntry != null) + if (_delegateEntry != null) { - if(Delegate.DelegateName!= _delegateEntry.CanonicalName) + if (Delegate.DelegateName != _delegateEntry.CanonicalName) { Delegate.DelegateName = _delegateEntry.CanonicalName; var result = await Context.SaveChangesAsync(); @@ -68,7 +77,7 @@ } else { - Delegate.DelegateName = ("(" +Delegate.DelegateSid.ToSidString()+")").Trim(); + Delegate.DelegateName = ("(" + Delegate.DelegateSid.ToSidString() + ")").Trim(); var result = await Context.SaveChangesAsync(); } } diff --git a/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor b/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor index 1b41aa33..194d5934 100644 --- a/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor +++ b/BLAZAMGui/UI/Settings/Permissions/EditAccessLevel.razor @@ -26,7 +26,7 @@ var name = Enum.GetName(typeof(ActiveDirectoryObjectType), adObjectType); + OnClick="()=>AddObjectTypeAccess(adObjectType)"> @AppLocalization[name] @@ -49,15 +49,20 @@ @name - + @foreach (ObjectAccessLevel levelValue in ObjectAccessLevels.Levels) { - @AppLocalization[levelValue.Name] + @AppLocalization[levelValue.Name] } - + @@ -66,7 +71,9 @@ @if (objectMap.ObjectType == ActiveDirectoryObjectType.User && objectMap.ObjectAccessLevelId != ObjectAccessLevels.Deny.Id) { - + } @@ -79,18 +86,20 @@ + Elevation="0"> @name Actions - + @foreach (var action in actions.OrderBy(f => f.Name)) { if (action.IsActionAppropriateForObject(objectMap.ObjectType)) { - if (!WorkingModel.ActionMap.Any(a => a.ObjectType==objectMap.ObjectType && a.ObjectAction == action)) + if (!WorkingModel.ActionMap.Any(a => a.ObjectType == objectMap.ObjectType && a.ObjectAction == action)) { @@ -103,12 +112,13 @@ - + - - @AppLocalization["Deny"] - @AppLocalization["Allow"] + + @AppLocalization["Deny"] + @AppLocalization["Allow"] @@ -116,8 +126,8 @@ + Color="Color.Error" + OnClick="@(()=>{RemoveActionAccess(context.Item);})" /> @@ -127,22 +137,24 @@ + Elevation="0" + Items="@WorkingModel.FieldMap.Where(am=>am.ObjectType==objectMap.ObjectType)"> @name Fields - + @foreach (var field in fields.OrderBy(f => f.DisplayName)) { if (ShowField(field, objectMap.ObjectType)) { - var existingFieldAccess = WorkingModel.FieldMap.Where(m =>m.ObjectType.Equals(objectMap.ObjectType) - && ( m.Field?.Equals(field)==true - || m.CustomField?.Equals(field)==true)).FirstOrDefault(); + var existingFieldAccess = WorkingModel.FieldMap.Where(m => m.ObjectType.Equals(objectMap.ObjectType) + && (m.Field?.Equals(field) == true + || m.CustomField?.Equals(field) == true)).FirstOrDefault(); if (existingFieldAccess == null) { @@ -219,7 +231,7 @@ if (Model.Id > 0) buttonLabel = AppLocalization["Update Access Level"]; } -@buttonLabel +@buttonLabel @if (WorkingModel.Id != 0) { @AppLocalization["Delete Access Level"] @@ -233,7 +245,7 @@ get { return WorkingModel.ObjectMap.AsQueryable().Any(om => om.ObjectAccessLevelId > ObjectAccessLevels.Deny.Id); - + } } @@ -327,7 +339,7 @@ StateHasChanged(); } - private void AddFieldAccess(IActiveDirectoryField fieldToAdd,ActiveDirectoryObjectType objectType) + private void AddFieldAccess(IActiveDirectoryField fieldToAdd, ActiveDirectoryObjectType objectType) { if (fieldToAdd is ActiveDirectoryField adField) { @@ -335,7 +347,7 @@ { Field = adField, FieldAccessLevelId = FieldAccessLevels.Read.Id, - ObjectType=objectType + ObjectType = objectType }); } else if (fieldToAdd is CustomActiveDirectoryField customField) From 934d1c73900a4c71c572149bac320e2021479814 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 6 Aug 2024 20:02:46 -0400 Subject: [PATCH 101/116] Implement Per-Object permission mapping --- BLAZAM/BLAZAM.csproj | 2 +- .../Adapters/ADOrganizationalUnit.cs | 47 +----------------- .../Adapters/DirectoryEntryAdapter.cs | 48 +++++++++++++++++++ .../Interfaces/IADOrganizationalUnit.cs | 5 +- .../Interfaces/IDirectoryEntryAdapter.cs | 7 +++ .../Permissions/OUPermissionsEditor.razor | 24 +++++----- .../Permissions/PermissionMapper.razor | 11 +++-- 7 files changed, 76 insertions(+), 68 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index fd416f87..86d36fc4 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.08.06.2321 + 2024.08.06.2354 false BLAZAM False diff --git a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs index 62b8f171..3872e248 100644 --- a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs +++ b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs @@ -76,52 +76,7 @@ public string? Name SetProperty("name", value); } } - public List InheritedPermissionMappings - { - get - { - return AppliedPermissionMappings.Where(m => !m.OU.Equals(DN)).ToList(); - } - } - public List DirectPermissionMappings - { - get - { - - return AppliedPermissionMappings.Where(m => m.OU.Equals(DN)).ToList(); - - } - } - - private IQueryable _appliedPermissionMappings; - - public IQueryable AppliedPermissionMappings - { - get - { - if (_appliedPermissionMappings == null) - { - - _appliedPermissionMappings = DbFactory.CreateDbContext().PermissionMap.Include(m => m.PermissionDelegates).Where(m => DN.Contains(m.OU)).OrderByDescending(m => m.OU.Length); - } - return _appliedPermissionMappings; - } - } - private IQueryable _offspringPermissionMappings; - public IQueryable OffspringPermissionMappings - { - get - { - if (_offspringPermissionMappings == null) - { - - _offspringPermissionMappings = DbFactory.CreateDbContext().PermissionMap.Include(m => m.PermissionDelegates).Where(m => m.OU.Contains(DN) && m.OU != DN).OrderByDescending(m => m.OU.Length); - } - return _offspringPermissionMappings; - } - } - - + public virtual bool CanReadUsersInSubOus { get diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index ee27072e..17887aae 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -550,6 +550,54 @@ protected virtual bool HasActionPermission(ObjectAction action,ActiveDirectoryOb public virtual bool CanDelete { get => HasActionPermission(ObjectActions.Delete); } + public List InheritedPermissionMappings + { + get + { + return AppliedPermissionMappings.Where(m => !m.OU.Equals(DN)).ToList(); + } + } + public List DirectPermissionMappings + { + get + { + + return AppliedPermissionMappings.Where(m => m.OU.Equals(DN)).ToList(); + + } + } + + private IQueryable _appliedPermissionMappings; + + public IQueryable AppliedPermissionMappings + { + get + { + if (_appliedPermissionMappings == null) + { + + _appliedPermissionMappings = DbFactory.CreateDbContext().PermissionMap.Include(m => m.PermissionDelegates).Where(m => DN.Contains(m.OU)).OrderByDescending(m => m.OU.Length); + } + return _appliedPermissionMappings; + } + } + private IQueryable _offspringPermissionMappings; + public IQueryable OffspringPermissionMappings + { + get + { + if (_offspringPermissionMappings == null) + { + + _offspringPermissionMappings = DbFactory.CreateDbContext().PermissionMap.Include(m => m.PermissionDelegates).Where(m => m.OU.Contains(DN) && m.OU != DN).OrderByDescending(m => m.OU.Length); + } + return _offspringPermissionMappings; + } + } + + + + public virtual bool HasUnsavedChanges { get => hasUnsavedChanges; diff --git a/BLAZAMActiveDirectory/Interfaces/IADOrganizationalUnit.cs b/BLAZAMActiveDirectory/Interfaces/IADOrganizationalUnit.cs index e5773bf6..8c3e59b9 100644 --- a/BLAZAMActiveDirectory/Interfaces/IADOrganizationalUnit.cs +++ b/BLAZAMActiveDirectory/Interfaces/IADOrganizationalUnit.cs @@ -9,10 +9,7 @@ public interface IADOrganizationalUnit : IDirectoryEntryAdapter { string? Name { get; set; } - List InheritedPermissionMappings { get; } - IQueryable AppliedPermissionMappings { get; } - List DirectPermissionMappings { get; } - IQueryable OffspringPermissionMappings { get; } + IEnumerable SubOUs { get; } HashSet CachedTreeViewSubOUs { get;} diff --git a/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs index 5de65d5d..c5611f19 100644 --- a/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Interfaces/IDirectoryEntryAdapter.cs @@ -2,6 +2,7 @@ using BLAZAM.ActiveDirectory.Adapters; using BLAZAM.Common.Data; using BLAZAM.Database.Models; +using BLAZAM.Database.Models.Permissions; using BLAZAM.Jobs; using System.DirectoryServices; @@ -242,6 +243,12 @@ public interface IDirectoryEntryAdapter : IDisposable IEnumerable Children { get; } IEnumerable? CachedChildren { get; set; } + List InheritedPermissionMappings { get; } + IQueryable AppliedPermissionMappings { get; } + List DirectPermissionMappings { get; } + IQueryable OffspringPermissionMappings { get; } + + /// /// Sends all staged changes to the Active Directory server /// diff --git a/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor b/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor index bde7fc95..6cf0f440 100644 --- a/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor @@ -2,7 +2,7 @@ - @OU?.Name + @Node?.CanonicalName @if (inheritedMappings.Count > 0) { @@ -34,15 +34,15 @@ @code { #nullable disable warnings - IADOrganizationalUnit _ou; + IDirectoryEntryAdapter _node; [Parameter] - public IADOrganizationalUnit OU + public IDirectoryEntryAdapter Node { - get => _ou; set + get => _node; set { - if (_ou == value) return; - _ou = value; - OnOUChanged(_ou); + if (_node == value) return; + _node = value; + OnOUChanged(_node); } } @@ -57,10 +57,10 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - await OnOUChanged(OU); + await OnOUChanged(Node); } - async Task OnOUChanged(IADOrganizationalUnit? newOU) + async Task OnOUChanged(IDirectoryEntryAdapter? newOU) { if (Context != null && newOU != null) { @@ -69,13 +69,13 @@ } async Task RefreshData() { - appliedMappings = OU.DirectPermissionMappings; - inheritedMappings = OU.InheritedPermissionMappings; + appliedMappings = Node.DirectPermissionMappings; + inheritedMappings = Node.InheritedPermissionMappings; NewMapping = null; await InvokeAsync(StateHasChanged); } void AddNewMapping() { - NewMapping = new() { OU = OU.DN }; + NewMapping = new() { OU = Node.DN }; } } \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor b/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor index d85c1b18..0f02ca4c 100644 --- a/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor +++ b/BLAZAMGui/UI/Settings/Permissions/PermissionMapper.razor @@ -6,13 +6,15 @@ - - + - + @@ -45,7 +47,7 @@ @code { #nullable disable warnings - OUTreeView? OUTree { get; set; } + ADTreeView? OUTree { get; set; } IDirectoryEntryAdapter selectedNode; IDirectoryEntryAdapter SelectedNode { @@ -57,7 +59,6 @@ } } - IADOrganizationalUnit SelectedOU => SelectedNode as IADOrganizationalUnit; IList ExpandedNodes = new List(); HashSet ApplicationBaseOUs = new HashSet(); protected override async Task OnInitializedAsync() From 1d316369df49a6787e75d3dcfcda1bfd5564f06b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Tue, 6 Aug 2024 20:06:03 -0400 Subject: [PATCH 102/116] Build v1 dev --- .github/workflows/build-dev.yml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 8e6bfb8f..afcb0de1 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -1,10 +1,10 @@ -name: Build Dev +name: Build Dev v1 on: workflow_dispatch: push: branches: - - Beta-Dev + - v1-Dev jobs: @@ -15,10 +15,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - name: Setup .NET Core SDK 6 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.x - name: Setup .NET Core SDK 8 uses: actions/setup-dotnet@v1 with: @@ -67,8 +63,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: 'Dev' - name: 'Dev' + tag_name: 'v1-Dev' + name: 'v1-Dev' prerelease: true body: This release is highly unstable. Expect bugs and crashes on this branch. Developers Only! files: | From 9901f49d9cbbb62090cf62f2333a447d4b6b67c1 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 7 Aug 2024 16:41:11 -0400 Subject: [PATCH 103/116] Fix for error in Browse member when AD not connected --- .../UI/Inputs/TreeViews/ADTreeView.razor.cs | 29 +++++++++------ BLAZAMUpdate/Services/UpdateService.cs | 36 +++++++++++-------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs index a44335ed..d9d273f5 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor.cs @@ -26,22 +26,29 @@ public partial class ADTreeView : OUTreeViewBase - private IReadOnlyCollection>? GetItems(IDirectoryEntryAdapter parent) + private IReadOnlyCollection>? GetItems(IDirectoryEntryAdapter? parent) { - if (parent.IsExpanded || parent.CachedChildren != null) - { - - var items = parent.Children - .Where(c => (c.ObjectType == ActiveDirectoryObjectType.OU && ShouldShowOU(c)) || c.CanRead) - .MoveToTop(c => c.ObjectType == ActiveDirectoryObjectType.OU); - if (!ShowAllEntries) + try{ + if (parent.IsExpanded || parent.CachedChildren != null) { - items = items.Where(i => i.ObjectType == ActiveDirectoryObjectType.OU); + + var items = parent.Children + .Where(c => (c.ObjectType == ActiveDirectoryObjectType.OU && ShouldShowOU(c)) || c.CanRead) + .MoveToTop(c => c.ObjectType == ActiveDirectoryObjectType.OU); + if (!ShowAllEntries) + { + items = items.Where(i => i.ObjectType == ActiveDirectoryObjectType.OU); + } + var treeBranchh = items.ToTreeItemData(); + return treeBranchh; } - var treeBranchh = items.ToTreeItemData(); - return treeBranchh; + } + catch(Exception) { + return null; + } return null; + } protected async Task>> GetChildrenAsync(IDirectoryEntryAdapter parentNode) { diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index 84242ec3..cf72552c 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -105,33 +105,41 @@ private async Task GetReleases() latestBranchRelease = branchReleases.FirstOrDefault(); //Store all other releases for use later AvailableUpdates.Clear(); - try - { - var betaStableReleases = releases.Where(r => r.TagName.Contains("Stable", StringComparison.OrdinalIgnoreCase)); - foreach (var release in betaStableReleases) + var betaStableReleases = releases.Where(r => r.TagName.Contains("Stable", StringComparison.OrdinalIgnoreCase)); + + foreach (var release in betaStableReleases) + { + //Get the release filename to prepare a version object + var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); + //Create that version object + if (fn == null) continue; + try { - //Get the release filename to prepare a version object - var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); - //Create that version object - if (fn == null) continue; AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); } - } - catch (Exception ex) - { - Loggers.UpdateLogger.Error("Error trying to get beta releases {@Error}", ex); + catch (Exception ex) + { + Loggers.UpdateLogger.Error("Error trying to get beta releases {@Error}{@Release}", ex,release?.Name); + } } + foreach (var release in stableReleases) { //Get the release filename to prepare a version object var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); //Create that version object if (fn == null) continue; - AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); - + try + { + AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); + } + catch (Exception ex) + { + Loggers.UpdateLogger.Error("Error trying to get v1 releases {@Error}{@Release}", ex, release?.Name); + } } var latestBranchUpdate = EncapsulateUpdate(latestBranchRelease, SelectedBranch); From d4dd5b4a9bb2bee0042a9b505b2f401a4a9c19ef Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Wed, 7 Aug 2024 19:30:48 -0400 Subject: [PATCH 104/116] Warning squashing --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Computers/ViewBitLocker.razor | 14 +-- BLAZAM/Pages/Groups/CreateGroup.razor | 2 - BLAZAM/Pages/Login.razor | 12 +-- BLAZAM/Pages/OU/CreateOU.razor | 2 - BLAZAM/Pages/Users/ConfirmNewUser.razor | 8 +- BLAZAMActiveDirectory/Adapters/ADUser.cs | 6 +- .../Adapters/DirectoryEntryAdapter.cs | 3 +- .../Adapters/RemoteSession.cs | 4 +- BLAZAMActiveDirectory/Data/LogonHours.cs | 36 +------- BLAZAMActiveDirectory/GlobalSuppressions.cs | 1 + BLAZAMActiveDirectory/Searchers/ADSearcher.cs | 54 ----------- BLAZAMCommon/Data/Encryption.cs | 7 +- .../DirectoryConnectingIndicator.razor | 4 +- .../UI/Computers/ComputerSharedPrinters.razor | 2 +- .../UI/Inputs/TreeViews/ADTreeView.razor | 4 +- .../UI/Inputs/TreeViews/OUTreeViewBase.cs | 4 +- .../Settings/ActiveDirectoryStatusPanel.razor | 1 - .../UI/Settings/AuthenticationSetting.razor | 3 +- .../Settings/ManualApplicationUpdater.razor | 2 +- .../EditNotificationSubscriptionRow.razor | 2 +- .../OUNotificationSubscriptions.razor | 91 ++++++++++--------- .../Permissions/OUPermissionsEditor.razor | 2 +- .../Permissions/PermissionMapEditor.razor | 2 +- .../Background/OUNotificationService.cs | 10 +- BLAZAMUpdate/Services/AutoUpdateService.cs | 41 +++++---- BLAZAMUpdate/Services/UpdateService.cs | 63 +++++++------ 27 files changed, 159 insertions(+), 223 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 86d36fc4..4421343e 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 0.9.5 - 2024.08.06.2354 + 2024.08.07.2325 false BLAZAM False diff --git a/BLAZAM/Pages/Computers/ViewBitLocker.razor b/BLAZAM/Pages/Computers/ViewBitLocker.razor index 3a27a010..b70869a3 100644 --- a/BLAZAM/Pages/Computers/ViewBitLocker.razor +++ b/BLAZAM/Pages/Computers/ViewBitLocker.razor @@ -1,8 +1,6 @@ @using BLAZAM.Gui.UI.Computers @inherits DirectoryEntryViewBase -@{ - string _fieldMudStackClasses = "flex-wrap gap-10"; -} + @@ -21,18 +19,22 @@ @code { IADBitLockerRecovery? BitLocker=> DirectoryEntry as IADBitLockerRecovery; List _recoveries = new(); - IADComputer _computer; + IADComputer? _computer; protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); await InvokeAsync(StateHasChanged); + if (BitLocker != null) + { + + _computer = (IADComputer?)BitLocker.GetParent(); - _computer = (IADComputer)BitLocker.GetParent(); + await AuditLogger.Searched(BitLocker); + } LoadingData = false; - await AuditLogger.Searched(BitLocker); await RefreshEntryComponents(); } diff --git a/BLAZAM/Pages/Groups/CreateGroup.razor b/BLAZAM/Pages/Groups/CreateGroup.razor index 9c017f3f..2f834b27 100644 --- a/BLAZAM/Pages/Groups/CreateGroup.razor +++ b/BLAZAM/Pages/Groups/CreateGroup.razor @@ -3,7 +3,6 @@ @attribute [Authorize] Create Group - @@ -64,7 +63,6 @@ - diff --git a/BLAZAM/Pages/Login.razor b/BLAZAM/Pages/Login.razor index 856cafea..a42c2d5e 100644 --- a/BLAZAM/Pages/Login.razor +++ b/BLAZAM/Pages/Login.razor @@ -124,7 +124,6 @@ MudTextField _passwordTextField; bool attemptingSignIn = false; string redirectUrl; - AppModal? _mfaModal; bool DemoCustomLogin = false; LoginRequest LoginRequest = new(); protected override async Task OnInitializedAsync() @@ -133,7 +132,7 @@ redirectUrl = Nav.Uri; LoginRequest.ReturnUrl = Nav.Uri; var currentUri = new Uri(Nav.Uri); - LoginRequest.CallbackBaseUri = currentUri.Scheme+"://" + currentUri.Authority; + LoginRequest.CallbackBaseUri = currentUri.Scheme + "://" + currentUri.Authority; if (Monitor.AppReady != ServiceConnectionState.Up) Monitor.OnAppReadyChanged += AppReadyChanged; } @@ -150,7 +149,7 @@ { attemptingSignIn = true; await InvokeAsync(StateHasChanged); - LoginRequest? authenticationResult=null; + LoginRequest? authenticationResult = null; if (ValidateInput(LoginRequest)) try { @@ -165,7 +164,7 @@ attemptingSignIn = false; - if (authenticationResult!=null) + if (authenticationResult != null) { switch (authenticationResult.AuthenticationResult) @@ -198,7 +197,8 @@ break; case LoginResultStatus.MFARequested: attemptingSignIn = true; - Nav.NavigateTo(authenticationResult.MFARedirect); + if (authenticationResult != null && authenticationResult.MFARedirect!=null) + Nav.NavigateTo(authenticationResult.MFARedirect); break; case LoginResultStatus.OK: attemptingSignIn = true; @@ -214,7 +214,7 @@ } bool ValidateInput(LoginRequest? validationResult) { - if(validationResult == null) + if (validationResult == null) { validationResult = new(); } diff --git a/BLAZAM/Pages/OU/CreateOU.razor b/BLAZAM/Pages/OU/CreateOU.razor index 2917594e..fc2b1ba4 100644 --- a/BLAZAM/Pages/OU/CreateOU.razor +++ b/BLAZAM/Pages/OU/CreateOU.razor @@ -4,7 +4,6 @@ Create OU - @@ -46,7 +45,6 @@ - diff --git a/BLAZAM/Pages/Users/ConfirmNewUser.razor b/BLAZAM/Pages/Users/ConfirmNewUser.razor index f975a1cd..bb6f260a 100644 --- a/BLAZAM/Pages/Users/ConfirmNewUser.razor +++ b/BLAZAM/Pages/Users/ConfirmNewUser.razor @@ -236,7 +236,7 @@ else try { - if (DirectoryTemplate.EffectiveSendWelcomeEmail == true) + if (DirectoryTemplate?.EffectiveSendWelcomeEmail == true) { if (DirectoryTemplate.EffectiveAskForAlternateEmail == true || User.Email.IsNullOrEmpty()) { @@ -244,7 +244,7 @@ else } else { - SendWelcomeEmail(User.Email); + _=SendWelcomeEmail(User.Email); } } @@ -267,13 +267,13 @@ else { try{ NewUserWelcomeEmailMessage message = new NewUserWelcomeEmailMessage(); - message.Domain = User.Directory.ConnectionSettings.FQDN; + message.Domain = User.Directory.ConnectionSettings?.FQDN; message.Username = _username; message.Password = _userPassword; var html = message.Render(); await EmailService.SendMessage(AppLocalization["New Account Details"], message,to); SnackBarService.Info(AppLocalization["Welcome Email Sent to "] + to); - SendWelcomeModal.Close(); + SendWelcomeModal?.Close(); }catch (Exception ex) { Loggers.SystemLogger.Error("Error sending welcome email {@Error}", ex); diff --git a/BLAZAMActiveDirectory/Adapters/ADUser.cs b/BLAZAMActiveDirectory/Adapters/ADUser.cs index a25349a3..7260dc07 100644 --- a/BLAZAMActiveDirectory/Adapters/ADUser.cs +++ b/BLAZAMActiveDirectory/Adapters/ADUser.cs @@ -76,7 +76,7 @@ public LogonHours? LogonHours } set { - SetProperty(ActiveDirectoryFields.LogonHours.FieldName, value.EncodeLogonHours()); + SetProperty(ActiveDirectoryFields.LogonHours.FieldName, value?.EncodeLogonHours()); } } public string? MiddleName @@ -150,11 +150,11 @@ public string? HomeDirectory if (value == null || value == "") return; - PostCommitSteps.Add(new Jobs.JobStep("Create home directory", (JobStep? step) => + PostCommitSteps.Add(new JobStep("Create home directory", (JobStep step) => { return Directory.Impersonation.Run(() => { - if (HomeDirectory.IsNullOrEmpty()) return true; + if (HomeDirectory==null || HomeDirectory.IsNullOrEmpty()) return true; var homeDirectory = new SystemDirectory(HomeDirectory); if (!homeDirectory.Exists) homeDirectory.EnsureCreated(); diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index 17887aae..dd0d77ef 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -422,7 +422,7 @@ public virtual List? Classes public virtual void MoveTo(IADOrganizationalUnit parentOUToMoveTo) { - CommitSteps.Add(new Jobs.JobStep("Move to OU", (JobStep? step) => + CommitSteps.Add(new JobStep("Move to OU", (JobStep step) => { parentOUToMoveTo.EnsureDirectoryEntry(); if (parentOUToMoveTo.DirectoryEntry != null) @@ -543,6 +543,7 @@ public virtual bool CanEdit protected virtual bool HasActionPermission(ObjectAction action,ActiveDirectoryObjectType? objectType=null) { + if(CurrentUser==null)return false; if (objectType == null) objectType = ObjectType; return CurrentUser.HasActionPermission(DN,action, objectType.Value); } diff --git a/BLAZAMActiveDirectory/Adapters/RemoteSession.cs b/BLAZAMActiveDirectory/Adapters/RemoteSession.cs index 61399633..09f3cb3e 100644 --- a/BLAZAMActiveDirectory/Adapters/RemoteSession.cs +++ b/BLAZAMActiveDirectory/Adapters/RemoteSession.cs @@ -272,7 +272,7 @@ public override bool Equals(object? obj) { if (obj is IRemoteSession other) { - if (other.SessionId.Equals(SessionId) && other.Server.ServerName.Equals(Server.ServerName)) + if (other.SessionId.Equals(SessionId) && other.Server.ServerName.Equals(Server?.ServerName)) { return true; } @@ -282,7 +282,7 @@ public override bool Equals(object? obj) public override int GetHashCode() { - return (SessionId + Server.ServerName).GetHashCode(); + return (SessionId + Server?.ServerName).GetHashCode(); } public void Dispose() diff --git a/BLAZAMActiveDirectory/Data/LogonHours.cs b/BLAZAMActiveDirectory/Data/LogonHours.cs index 5a57a98e..ed8b56d0 100644 --- a/BLAZAMActiveDirectory/Data/LogonHours.cs +++ b/BLAZAMActiveDirectory/Data/LogonHours.cs @@ -34,7 +34,7 @@ public LogonHours() } } - public LogonHours(byte[] rawData) : this() + public LogonHours(byte[]? rawData) : this() { // Initialize schedule with default values (all true, meaning logon allowed) //for (int day = 0; day < 7; day++) @@ -44,39 +44,13 @@ public LogonHours(byte[] rawData) : this() // schedule[day, hour] = true; // } //} - DecodeLogonHours(rawData); - } - private void AdjustToTimeZoneOffset(ref DayOfWeek day, ref int hour) - { - if (0 > hour + timeZoneOffset) - { - if (day == DayOfWeek.Sunday) - { - day = DayOfWeek.Saturday; - } - else - { - day--; - } - hour = 24 + hour + timeZoneOffset; - } - else if (hour + timeZoneOffset > 23) + if(rawData !=null) { - if (day == DayOfWeek.Saturday) - { - day = DayOfWeek.Sunday; - } - else - { - day++; - } - hour = hour - 24 + timeZoneOffset; - } - else - { - hour=hour+ timeZoneOffset; + DecodeLogonHours(rawData); + } } + private void AdjustFromTimeZoneOffset(ref DayOfWeek day, ref int hour) { if (0 > hour - timeZoneOffset) diff --git a/BLAZAMActiveDirectory/GlobalSuppressions.cs b/BLAZAMActiveDirectory/GlobalSuppressions.cs index 8f6f8842..367c8a0e 100644 --- a/BLAZAMActiveDirectory/GlobalSuppressions.cs +++ b/BLAZAMActiveDirectory/GlobalSuppressions.cs @@ -63,3 +63,4 @@ [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntries)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.KeepAlive(System.Object)")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntry)~BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter")] +[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.GetParent~BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter")] diff --git a/BLAZAMActiveDirectory/Searchers/ADSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADSearcher.cs index 6535342f..48b3802c 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearcher.cs @@ -44,7 +44,6 @@ public ADSearcher(IActiveDirectoryContext directory) - DirectorySearcher searcher; try { @@ -65,59 +64,6 @@ public ADSearcher(IActiveDirectoryContext directory) - /* - * Obsoleete code from previous searcher method - searcher = new DirectorySearcher(Directory.GetDirectoryEntry(searchBaseDN)); - searcher.Filter = "(&(objectClass=*))"; - switch (searchType) - { - case ActiveDirectoryObjectType.Group: - searcher.Filter = "(&(objectCategory=group)(objectClass=group))"; - - break; - case ActiveDirectoryObjectType.User: - searcher.Filter = "(&(objectCategory=person)(objectClass=user))"; - if (enabledOnly == true) - { - searcher.Filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"; - } - break; - case ActiveDirectoryObjectType.Computer: - searcher.Filter = "(&(objectCategory=computer))"; - if (enabledOnly == true) - { - searcher.Filter = "(&(objectCategory=computer)(!userAccountControl:1.2.840.113556.1.4.803:=2))"; - } - break; - case ActiveDirectoryObjectType.OU: - searcher.Filter = "(&(objectCategory=organizationalUnit))"; - - break; - - - } - - - - - - - - searcher.SearchScope = searchScope; - searcher.PropertiesToLoad.Add("samaccountname"); - searcher.PropertiesToLoad.Add("distinguishedName"); - searcher.PropertiesToLoad.Add("objectSID"); - searcher.PropertiesToLoad.Add("objectclass"); - searcher.PropertiesToLoad.Add("cn"); - searcher.PropertiesToLoad.Add("name"); - searcher.SizeLimit = returnCount; - //searcher.Asynchronous = true; - //se.SizeLimit = returnCount; - searcher.Filter = searcher.Filter.Substring(0, searcher.Filter.Length - 1) + fieldQuery + ")"; - var result = searcher.FindAll(); - - //return result; - */ } catch (Exception ex) { diff --git a/BLAZAMCommon/Data/Encryption.cs b/BLAZAMCommon/Data/Encryption.cs index f9a41b70..60a55aff 100644 --- a/BLAZAMCommon/Data/Encryption.cs +++ b/BLAZAMCommon/Data/Encryption.cs @@ -15,10 +15,9 @@ public class Encryption private void SetSalt(int maximumSaltLength = 32) { var salt = new byte[maximumSaltLength]; - using (var random = new RNGCryptoServiceProvider()) - { - random.GetNonZeroBytes(salt); - } + + RandomNumberGenerator.Create().GetNonZeroBytes(salt); + Salt = salt; } diff --git a/BLAZAMGui/Layouts/DirectoryConnectingIndicator.razor b/BLAZAMGui/Layouts/DirectoryConnectingIndicator.razor index 90c5a451..1930a43f 100644 --- a/BLAZAMGui/Layouts/DirectoryConnectingIndicator.razor +++ b/BLAZAMGui/Layouts/DirectoryConnectingIndicator.razor @@ -3,10 +3,10 @@ { - + Connecting to Active Directory... Some features are disabled... - + } diff --git a/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor b/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor index 9b19a293..66e1da30 100644 --- a/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor +++ b/BLAZAMGui/UI/Computers/ComputerSharedPrinters.razor @@ -10,7 +10,7 @@ {_registerPrintersModal.ShowAsync();}) + OnClick=@(()=>{_registerPrintersModal?.ShowAsync();}) IconSize="Size.Medium" Class="mt-0">@AppLocalization["Register printers with Active Directory"] } diff --git a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor index 181e4ffa..cfe7689e 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor +++ b/BLAZAMGui/UI/Inputs/TreeViews/ADTreeView.razor @@ -15,8 +15,8 @@ LoadingIconColor="Color.Info" @bind-Expanded="@context.Expanded" @bind-Activated=context.Selected - Text="@context.Value.CanonicalName" - Icon="@context.Value.TypeIcon()" + Text="@context.Value?.CanonicalName" + Icon="@context.Value?.TypeIcon()" IconColor=@GetItemColor(context.Value) Class="minw-max w-100 overflow-x-auto" CanExpand=@(context.Value is IADOrganizationalUnit) diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs index f900d339..16cd1d16 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs @@ -87,9 +87,9 @@ public IDirectoryEntryAdapter? SelectedEntry /// Text to show at the end of the TreeView item /// [Parameter] - public Func? EndText { get; set; } + public Func? EndText { get; set; } - protected Color GetItemColor(IDirectoryEntryAdapter item) + protected Color GetItemColor(IDirectoryEntryAdapter? item) { if (item is IAccountDirectoryAdapter account) { diff --git a/BLAZAMGui/UI/Settings/ActiveDirectoryStatusPanel.razor b/BLAZAMGui/UI/Settings/ActiveDirectoryStatusPanel.razor index 51b87fc3..9bd24ac1 100644 --- a/BLAZAMGui/UI/Settings/ActiveDirectoryStatusPanel.razor +++ b/BLAZAMGui/UI/Settings/ActiveDirectoryStatusPanel.razor @@ -89,7 +89,6 @@ public EventCallback DirectoryConnected { get; set; } bool _monitoring = false; - bool _encryptedStatus; bool _portStatus; bool _credStatus; bool showProgress = true; diff --git a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor index 9e1ae53b..68463d52 100644 --- a/BLAZAMGui/UI/Settings/AuthenticationSetting.razor +++ b/BLAZAMGui/UI/Settings/AuthenticationSetting.razor @@ -166,8 +166,7 @@ private bool? OnSet(DuoUnreachableBehavior arg) { - if (arg == null) - return null; + try { return (int)arg == 1; diff --git a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor index 4e786d44..4f624041 100644 --- a/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor +++ b/BLAZAMGui/UI/Settings/ManualApplicationUpdater.razor @@ -90,7 +90,7 @@ @if (ShowAllUpdates) { - @foreach (var update in UpdateService.AvailableUpdates.Where(x => x.Version.OlderThan(LatestAvailableVersion.Version)).OrderBy(x => x.Version)) + @foreach (var update in UpdateService.AvailableUpdates.Where(x => x.Version.OlderThan(ApplicationInfo.RunningVersion)).OrderBy(x => x.Version)) { diff --git a/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor b/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor index ba3436dd..096c72b1 100644 --- a/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor +++ b/BLAZAMGui/UI/Settings/Notifications/EditNotificationSubscriptionRow.razor @@ -74,7 +74,7 @@ [Parameter] public EventCallback OnAdded { get; set; } - private async void ToggleType(NotificationType type, bool value) + private void ToggleType(NotificationType type, bool value) { if (!value) { diff --git a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor index ec471f73..42ccdd71 100644 --- a/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor +++ b/BLAZAMGui/UI/Settings/Notifications/OUNotificationSubscriptions.razor @@ -4,7 +4,7 @@ - @(AppLocalization["Notification Settings for "]+_ou.CanonicalName) + @(AppLocalization["Notification Settings for "]+_ou?.CanonicalName) @@ -96,7 +96,7 @@ - @(AppLocalization["Effective Notification Settings for "]+_ou.CanonicalName) + @(AppLocalization["Effective Notification Settings for "]+_ou?.CanonicalName) @@ -231,9 +231,9 @@ UpdateSubscriptions(); } - private async void ouChanged(IDirectoryEntryAdapter entry) + private async void ouChanged(IDirectoryEntryAdapter? entry) { - var ou = (IADOrganizationalUnit)entry; + var ou = (IADOrganizationalUnit?)entry; if (ou != null) { if (User != null) @@ -241,7 +241,7 @@ newSubscription.UserId = User.Id; newSubscription.OU = ou.DN; if (Context != null) - UpdateSubscriptions(); + await UpdateSubscriptions(); } } @@ -252,68 +252,77 @@ effectiveInAppSubscription = ouNotificationService.CalculateEffectiveInAppSubscriptions(User, OU); effectiveByEmailSubscription = ouNotificationService.CalculateEffectiveEmailSubscriptions(User, OU); return; - + } private async void AddSubscription() { - - var changes = await Context.SaveChangesAsync(); - if (changes > 0) + if (Context != null) { - newSubscription = new(); - newSubscription.UserId = User.Id; - newSubscription.OU = OU.DN; - SnackBarService.Success(AppLocalization["Saved notification subscription"]); - UpdateSubscriptions(); + var changes = await Context.SaveChangesAsync(); + if (changes > 0) + { + newSubscription = new(); + newSubscription.UserId = User.Id; + newSubscription.OU = OU?.DN; + SnackBarService.Success(AppLocalization["Saved notification subscription"]); + UpdateSubscriptions(); - } - else - { - SnackBarService.Warning(AppLocalization["Unable to save notification subscription"]); + } + else + { + SnackBarService.Warning(AppLocalization["Unable to save notification subscription"]); + } } - } private async void SaveExisting() { - var result = await Context.SaveChangesAsync(); - if (result > 0) + if (Context != null) { - SnackBarService.Success("Subscription saved."); - UpdateSubscriptions(); - } - else - { - SnackBarService.Warning("Subscription could not be saved."); + var result = await Context.SaveChangesAsync(); + if (result > 0) + { + SnackBarService.Success("Subscription saved."); + UpdateSubscriptions(); + } + else + { + SnackBarService.Warning("Subscription could not be saved."); + } } } private async void DeleteExisting(NotificationSubscription subscription) { - subscription.DeletedAt = DateTime.UtcNow; - var result = await Context.SaveChangesAsync(); - if (result > 0) + if (Context != null) { - SnackBarService.Success("Subscription deleted."); - } - else - { - SnackBarService.Warning("Subscription could not be deleted."); + subscription.DeletedAt = DateTime.UtcNow; + var result = await Context.SaveChangesAsync(); + if (result > 0) + { + SnackBarService.Success("Subscription deleted."); + } + else + { + SnackBarService.Warning("Subscription could not be deleted."); + } + UpdateSubscriptions(); } - UpdateSubscriptions(); - } - private async void UpdateSubscriptions() + private async Task UpdateSubscriptions() { - subscriptions = Context.NotificationSubscriptions.Include(x => x.NotificationTypes).Where(x => x.DeletedAt == null && x.UserId == User.Id && x.OU.Equals(OU.DN)).ToList(); + if (Context != null) + { + subscriptions = Context.NotificationSubscriptions.Include(x => x.NotificationTypes).Where(x => x.DeletedAt == null && x.UserId == User.Id && x.OU.Equals(OU.DN)).ToList(); - CalculateEffectiveSubscriptions(); - await InvokeAsync(StateHasChanged); + CalculateEffectiveSubscriptions(); + await InvokeAsync(StateHasChanged); + } } } \ No newline at end of file diff --git a/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor b/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor index 6cf0f440..9ad7c85b 100644 --- a/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/OUPermissionsEditor.razor @@ -42,7 +42,7 @@ { if (_node == value) return; _node = value; - OnOUChanged(_node); + _=OnOUChanged(_node); } } diff --git a/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor b/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor index a05dd4b0..b32233de 100644 --- a/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor +++ b/BLAZAMGui/UI/Settings/Permissions/PermissionMapEditor.razor @@ -135,7 +135,7 @@ { concatenatd += Directory.FindEntryBySID(sid) + ", "; } - catch (Exception ex) + catch (Exception) { concatenatd += sid.ToSidString()+", "; } diff --git a/BLAZAMServices/Background/OUNotificationService.cs b/BLAZAMServices/Background/OUNotificationService.cs index 1dc895dc..3eeca176 100644 --- a/BLAZAMServices/Background/OUNotificationService.cs +++ b/BLAZAMServices/Background/OUNotificationService.cs @@ -43,28 +43,28 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti { case NotificationType.Create: notificationTitle += _appLocalization["Created"]; - notificationBody += _appLocalization["was created at"] + source.Created.Value.ToLocalTime(); + 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.Value.ToLocalTime(); + 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.Value.ToLocalTime(); + 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 modified at"] + source.LastChanged.Value.ToLocalTime(); + notificationBody += _appLocalization["was modified at"] + source.LastChanged?.ToLocalTime(); var groupMembershipMessage = NotificationType.GroupAssignment.ToNotification(); groupMembershipMessage.EntryName = source.CanonicalName; @@ -72,7 +72,7 @@ public async Task PostAsync(IDirectoryEntryAdapter source, NotificationType noti break; case NotificationType.PasswordChange: notificationTitle += _appLocalization["Password Reset"]; - notificationBody += _appLocalization["had a password reset at"] + source.LastChanged.Value.ToLocalTime(); + notificationBody += _appLocalization["had a password reset at"] + source.LastChanged?.ToLocalTime(); var passwordChangeMessage = NotificationType.PasswordChange.ToNotification(); passwordChangeMessage.EntryName = source.CanonicalName; emailMessage = passwordChangeMessage; diff --git a/BLAZAMUpdate/Services/AutoUpdateService.cs b/BLAZAMUpdate/Services/AutoUpdateService.cs index ca6f959d..e4c38c95 100644 --- a/BLAZAMUpdate/Services/AutoUpdateService.cs +++ b/BLAZAMUpdate/Services/AutoUpdateService.cs @@ -186,33 +186,34 @@ private async void CheckForUpdate(object? state) try { var appSettings = (await factory.CreateDbContextAsync()).AppSettings.FirstOrDefault(); - - Loggers.UpdateLogger.Information("Checking for automatic update"); - - var latestUpdate = await updateService.GetUpdates(); - if (latestUpdate != null && latestUpdate.Version.NewerThan(_applicationInfo.RunningVersion)) + if (appSettings != null) { - IsUpdateAvailable = true; - if (appSettings.AutoUpdate && appSettings.AutoUpdateTime != null) + Loggers.UpdateLogger.Information("Checking for automatic update"); + + var latestUpdate = await updateService.GetUpdates(); + if (latestUpdate != null && latestUpdate.Version.NewerThan(_applicationInfo.RunningVersion)) { - if (latestUpdate.PassesPrerequisiteChecks) - ScheduleUpdate(appSettings.AutoUpdateTime.Value, latestUpdate); - else + IsUpdateAvailable = true; + if (appSettings.AutoUpdate && appSettings.AutoUpdateTime != null) { - Loggers.UpdateLogger.Warning("Update failed prerequisite check, cancelling scheduling {@Error}", latestUpdate.PrequisiteMessage); + if (latestUpdate.PassesPrerequisiteChecks) + ScheduleUpdate(appSettings.AutoUpdateTime.Value, latestUpdate); + else + { + Loggers.UpdateLogger.Warning("Update failed prerequisite check, cancelling scheduling {@Error}", latestUpdate.PrequisiteMessage); + } } - } - } - else - { - IsUpdateAvailable = false; - Cancel(); - Loggers.UpdateLogger.Information("No new updates found."); + } + else + { + IsUpdateAvailable = false; + Cancel(); + Loggers.UpdateLogger.Information("No new updates found."); + } } - } catch (Exception ex) { @@ -243,7 +244,7 @@ public void ScheduleUpdate(TimeSpan updateTimeOfDay, ApplicationUpdate updateToI { Loggers.UpdateLogger.Information("New update found: " + updateToInstall.Version); - //Update availabled + //Update available var now = DateTime.Now; ScheduledUpdateTime = new DateTime(now.Year, now.Month, now.Day, updateTimeOfDay.Hours, updateTimeOfDay.Minutes, updateTimeOfDay.Seconds); diff --git a/BLAZAMUpdate/Services/UpdateService.cs b/BLAZAMUpdate/Services/UpdateService.cs index cf72552c..75008cc6 100644 --- a/BLAZAMUpdate/Services/UpdateService.cs +++ b/BLAZAMUpdate/Services/UpdateService.cs @@ -110,46 +110,54 @@ private async Task GetReleases() foreach (var release in betaStableReleases) { - //Get the release filename to prepare a version object - var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); - //Create that version object - if (fn == null) continue; - try + if (release!=null) { - AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); + //Get the release filename to prepare a version object + var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); + //Create that version object + if (fn == null) continue; + try + { + AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); - } - catch (Exception ex) - { - Loggers.UpdateLogger.Error("Error trying to get beta releases {@Error}{@Release}", ex,release?.Name); + } + catch (Exception ex) + { + Loggers.UpdateLogger.Error("Error trying to get beta releases {@Error}{@Release}", ex, release?.Name); + } } } foreach (var release in stableReleases) { - //Get the release filename to prepare a version object - var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); - //Create that version object - if (fn == null) continue; - try + if (release != null) { - AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); - } - catch (Exception ex) - { - Loggers.UpdateLogger.Error("Error trying to get v1 releases {@Error}{@Release}", ex, release?.Name); + //Get the release filename to prepare a version object + var fn = Path.GetFileNameWithoutExtension(release?.Assets.FirstOrDefault()?.Name); + //Create that version object + if (fn == null) continue; + try + { + AvailableUpdates.Add(EncapsulateUpdate(release, ApplicationReleaseBranches.Stable)); + } + catch (Exception ex) + { + Loggers.UpdateLogger.Error("Error trying to get v1 releases {@Error}{@Release}", ex, release?.Name); + } } } - - var latestBranchUpdate = EncapsulateUpdate(latestBranchRelease, SelectedBranch); - if (latestBranchUpdate.Branch != ApplicationReleaseBranches.Stable && latestBranchUpdate.Branch != "Stable") + if (latestBranchRelease != null) { - if (!AvailableUpdates.Contains(latestBranchUpdate)) + var latestBranchUpdate = EncapsulateUpdate(latestBranchRelease, SelectedBranch); + if (latestBranchUpdate != null && latestBranchUpdate.Branch != ApplicationReleaseBranches.Stable && latestBranchUpdate.Branch != "Stable") { - AvailableUpdates.Add(latestBranchUpdate); - } + if (!AvailableUpdates.Contains(latestBranchUpdate)) + { + AvailableUpdates.Add(latestBranchUpdate); + } + } } IncompatibleUpdates = AvailableUpdates.Where(x => !x.PassesPrerequisiteChecks).ToList(); foreach (var release in IncompatibleUpdates) @@ -199,7 +207,8 @@ private async Task SetBranch() //Get the release filename to prepare a version object var filename = Path.GetFileNameWithoutExtension(releaseToEncapsulate?.Assets.FirstOrDefault()?.Name); //Create that version object - if (filename == null) throw new ApplicationUpdateException("Filename could not be retrieved from GitHub"); + if (filename == null) + throw new ApplicationUpdateException("Filename could not be retrieved from GitHub"); releaseVersion = new ApplicationVersion(filename.Substring(filename.IndexOf("-v") + 2)); From b539f87441ef57e384fc5dab122bbc3b2cfa813b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 8 Aug 2024 00:49:10 -0400 Subject: [PATCH 105/116] Rename tags --- .github/workflows/build-dev.yml | 2 +- .github/workflows/build-nightly.yml | 10 +++------- .github/workflows/release-stable.yml | 10 +++------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index afcb0de1..2dffd7c1 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -63,7 +63,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: 'v1-Dev' + tag_name: 'Dev1' name: 'v1-Dev' prerelease: true body: This release is highly unstable. Expect bugs and crashes on this branch. Developers Only! diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 91f03565..809f1ef1 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - Beta-Nightly + - v1-Nightly jobs: @@ -16,10 +16,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - name: Setup .NET Core SDK 6 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.x - name: Setup .NET Core SDK 8 uses: actions/setup-dotnet@v1 with: @@ -66,8 +62,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: 'Nightly' - name: 'Nightly' + tag_name: 'Nightly1' + name: 'v1-Nightly' prerelease: true body: This release is always the latest nightly release. These versions are unstable and may break your application. You've been warned. files: | diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index 8d8bf973..cf6ce54a 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -4,7 +4,7 @@ on: workflow_dispatch: push: branches: - - Beta-Stable + - v1-Stable jobs: @@ -16,10 +16,6 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - name: Setup .NET Core SDK 6 - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.x - name: Setup .NET Core SDK 8 uses: actions/setup-dotnet@v1 with: @@ -56,8 +52,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag_name: Stable-v${{ env.ASSEMBLY_VERSION }} - release_name: Stable - v${{ env.ASSEMBLY_VERSION }} + tag_name: Release-v${{ env.ASSEMBLY_VERSION }} + release_name: Release - v${{ env.ASSEMBLY_VERSION }} body: "" draft: true prerelease: true From ce89923e62192b7fec1ab06af0c7b2c83b254f9e Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 8 Aug 2024 17:13:41 -0400 Subject: [PATCH 106/116] Bump version to 1.0 --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 4421343e..96b35f29 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -5,7 +5,7 @@ enable enable false - 0.9.5 + 1.0.0 2024.08.07.2325 false BLAZAM From a745c581c9c8258f0c46cec98cdc198b996111f0 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 8 Aug 2024 18:58:35 -0400 Subject: [PATCH 107/116] Fix for possible privilege escalation in Blazam --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Recycle Bin/RecycleBin.razor | 2 +- BLAZAM/Pages/Search.razor | 6 ++--- BLAZAM/Pages/View.razor | 6 ++--- .../ActiveDirectoryContext.cs | 11 +++++----- BLAZAMActiveDirectory/Adapters/ADGroup.cs | 4 ++-- .../Adapters/DirectoryEntryAdapter.cs | 2 +- BLAZAMActiveDirectory/GlobalSuppressions.cs | 14 ++---------- .../Helpers/ActiveDirectoryHelpers.cs | 13 +++++------ .../Searchers/ADBitLockerSearcher.cs | 12 ++-------- .../Searchers/ADComputerSearcher.cs | 4 ++-- .../Searchers/ADGroupSearcher.cs | 12 +++++----- .../Searchers/ADOUSearcher.cs | 4 ++-- .../Searchers/ADPrinterSearcher.cs | 8 +++---- BLAZAMActiveDirectory/Searchers/ADSearch.cs | 22 ++++++++++++++++--- BLAZAMActiveDirectory/Searchers/ADSearcher.cs | 2 +- .../Searchers/ADUserSearcher.cs | 12 +++++----- .../Widgets/ChangedEntriesWidget.razor | 2 +- .../Widgets/DeletedEntriesWidget.razor | 2 +- BLAZAMGui/UI/DirectorySearchPage.razor | 4 ++-- BLAZAMGui/UI/Inputs/ADAutoComplete.razor | 2 +- BLAZAMGui/UI/Search/SearchPageHeader.razor | 4 ++-- BLAZAMServices/LoginPermissionApplicator.cs | 14 +++--------- 23 files changed, 76 insertions(+), 88 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 96b35f29..ad70ff6e 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.0.0 - 2024.08.07.2325 + 2024.08.08.2253 false BLAZAM False diff --git a/BLAZAM/Pages/Recycle Bin/RecycleBin.razor b/BLAZAM/Pages/Recycle Bin/RecycleBin.razor index c095ce93..6dddc0a1 100644 --- a/BLAZAM/Pages/Recycle Bin/RecycleBin.razor +++ b/BLAZAM/Pages/Recycle Bin/RecycleBin.razor @@ -73,7 +73,7 @@ { - var search = new ADSearch() { SearchRoot = Directory.GetDeleteObjectsEntry() }; + var search = new ADSearch(Directory) { SearchRoot = Directory.GetDeleteObjectsEntry() }; search.SearchDeleted = true; deletedObjects = await search.SearchAsync(); LoadingData = false; diff --git a/BLAZAM/Pages/Search.razor b/BLAZAM/Pages/Search.razor index 3e9cfd6b..2826247f 100644 --- a/BLAZAM/Pages/Search.razor +++ b/BLAZAM/Pages/Search.razor @@ -110,7 +110,7 @@ } - public ADSearch Searcher { get; set; } = new ADSearch(); + public ADSearch Searcher { get; set; } [CascadingParameter] @@ -130,7 +130,7 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - Searcher = new ADSearch(); + Searcher = new ADSearch(Directory); SearchService.SearchTerm = SearchTermParameter; Searcher.GeneralSearchTerm = SearchTermParameter; @@ -212,7 +212,7 @@ protected async Task InvokeSearch() { if (Searcher == null) - Searcher = new ADSearch(); + Searcher = new ADSearch(Directory); else Searcher.Cancel(); SearchService.SearchTerm = SearchTermParameter; diff --git a/BLAZAM/Pages/View.razor b/BLAZAM/Pages/View.razor index 8b255b32..869d92b5 100644 --- a/BLAZAM/Pages/View.razor +++ b/BLAZAM/Pages/View.razor @@ -110,7 +110,7 @@ } - public ADSearch Searcher { get; set; } = new ADSearch(); + public ADSearch Searcher { get; set; } [CascadingParameter] @@ -130,7 +130,7 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - Searcher = new ADSearch(); + Searcher = new ADSearch(Directory); SearchService.SearchTerm = SearchTermParameter; Searcher.GeneralSearchTerm = SearchTermParameter; @@ -196,7 +196,7 @@ protected async Task InvokeSearch() { if (Searcher == null) - Searcher = new ADSearch(); + Searcher = new ADSearch(Directory); else Searcher.Cancel(); SearchService.SearchTerm = SearchTermParameter; diff --git a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs index b2671ad7..20a5d956 100644 --- a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs +++ b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs @@ -38,7 +38,7 @@ public IApplicationUserState? CurrentUser private WmiFactory _wmiFactory; IEncryptionService _encryption; private INotificationPublisher _notificationPublisher; - public static ActiveDirectoryContext Instance; + public static ActiveDirectoryContext SystemInstance; public int FailedConnectionAttempts { get; set; } = 0; @@ -220,7 +220,6 @@ INotificationPublisher notificationPublisher _wmiFactory = new(this); _encryption = encryptionService; _notificationPublisher = notificationPublisher; - Instance = this; Factory = factory; UserStateService = userStateService; //UserStateService.UserStateAdded += PopulateUserStateDirectoryUser; @@ -241,7 +240,7 @@ public ActiveDirectoryContext(ActiveDirectoryContext activeDirectoryContextSeed) { _encryption = activeDirectoryContextSeed._encryption; _notificationPublisher = activeDirectoryContextSeed._notificationPublisher; - Instance = this; + SystemInstance = this; Factory = activeDirectoryContextSeed.Factory; UserStateService = activeDirectoryContextSeed.UserStateService; ConnectionSettings = activeDirectoryContextSeed.ConnectionSettings; @@ -376,7 +375,7 @@ public void Connect() //Perform Auth check Loggers.ActiveDirectryLogger.Information("Performing Active Directory connection test"); - var search = new ADSearch() + var search = new ADSearch(this) { ObjectTypeFilter = ActiveDirectoryObjectType.User, SearchRoot = RootDirectoryEntry, @@ -856,7 +855,7 @@ public bool RestoreTombstone(IDirectoryEntryAdapter model, IADOrganizationalUnit public IDirectoryEntryAdapter? FindEntryBySID(byte[] sid) => GetDirectoryEntryBySid(sid.ToSidString()); public IDirectoryEntryAdapter? GetDirectoryEntryBySid(string sid) { - var searcher = new ADSearch(); + var searcher = new ADSearch(this); searcher.SearchRoot = RootDirectoryEntry; searcher.Fields.SID = sid; var result = searcher.Search().FirstOrDefault(); @@ -865,7 +864,7 @@ public bool RestoreTombstone(IDirectoryEntryAdapter model, IADOrganizationalUnit public IDirectoryEntryAdapter? GetDirectoryEntryByDN(string dn) { - var searcher = new ADSearch(); + var searcher = new ADSearch(this); searcher.SearchRoot = RootDirectoryEntry; searcher.Fields.DN = dn; var result = searcher.Search().FirstOrDefault(); diff --git a/BLAZAMActiveDirectory/Adapters/ADGroup.cs b/BLAZAMActiveDirectory/Adapters/ADGroup.cs index 4ee6a728..38bd08b9 100644 --- a/BLAZAMActiveDirectory/Adapters/ADGroup.cs +++ b/BLAZAMActiveDirectory/Adapters/ADGroup.cs @@ -178,7 +178,7 @@ public IEnumerable NestedMembers { get { - ADSearch search = new ADSearch(); + ADSearch search = new ADSearch(Directory); search.Fields.NestedMemberOf = this; var result = search.Search(); return result; @@ -193,7 +193,7 @@ public List Members get { var temp = MembersAsStrings; - ADSearch search = new ADSearch(); + ADSearch search = new ADSearch(Directory); List members = new List(); temp?.ForEach(t => diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index dd0d77ef..71d15e5c 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -443,7 +443,7 @@ public virtual void MoveTo(IADOrganizationalUnit parentOUToMoveTo) { if (DirectoryEntry == null || DirectoryEntry.Parent == null) return null; - var parent = DirectoryEntry.Parent.Encapsulate(); + var parent = DirectoryEntry.Parent.Encapsulate(Directory); return parent; diff --git a/BLAZAMActiveDirectory/GlobalSuppressions.cs b/BLAZAMActiveDirectory/GlobalSuppressions.cs index 367c8a0e..2871db69 100644 --- a/BLAZAMActiveDirectory/GlobalSuppressions.cs +++ b/BLAZAMActiveDirectory/GlobalSuppressions.cs @@ -6,7 +6,6 @@ using System.Diagnostics.CodeAnalysis; [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Common.Data.Services.WmiFactory.CreateWmiConnection(System.String)~System.Management.ManagementScope")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.CommitChanges~BLAZAM.ActiveDirectory.DirectoryChangeResult")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.SetNewProperty(System.String,System.Object)")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.Connect")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.GetDeleteObjectsEntry~System.DirectoryServices.DirectoryEntry")] @@ -23,19 +22,14 @@ [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.FetchDirectoryEntry")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.DiscardChanges")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.Delete")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.Parse(System.DirectoryServices.DirectoryEntry,System.DirectoryServices.SearchResult,BLAZAM.ActiveDirectory.Interfaces.IActiveDirectoryContext)~System.Threading.Tasks.Task")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.GetParent~System.Threading.Tasks.Task{BLAZAM.ActiveDirectory.Interfaces.IADOrganizationalUnit}")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.MoveTo(BLAZAM.ActiveDirectory.Interfaces.IADOrganizationalUnit)~System.Boolean")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.Classes")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.ADSPath")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.Invoke(System.String,System.Object[])~System.Boolean")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.Changes")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.ADUser.SetHomeDirectoryPermissions")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.ADUser.SetPassword(System.Security.SecureString,System.Boolean)~System.Boolean")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Searchers.ADSearch.Search``2(System.Nullable{System.Threading.CancellationToken})~System.Collections.Generic.List{``1}")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Searchers.ADSearch.PerformSearch``2(System.DateTime,System.DirectoryServices.DirectorySearcher,System.Int32)")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Searchers.ADSearch.PrepareSearcher(System.DirectoryServices.DirectorySearcher)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Searchers.ADSearch.Encapsulate(System.DirectoryServices.SearchResultCollection)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Searchers.ADSearch.SearchScope")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~F:BLAZAM.ActiveDirectory.Searchers.ADSearch._searchResults")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.ADOrganizationalUnit.CreateGroup(System.String)~BLAZAM.ActiveDirectory.Interfaces.IADGroup")] @@ -48,19 +42,15 @@ [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.TryGetDomainControllers")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.commitStep")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.CommitChanges(BLAZAM.Jobs.IJob)~BLAZAM.Jobs.IJob")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Searchers.ADSearcher.SearchObjects(System.String,System.String,System.Nullable{BLAZAM.Common.Data.ActiveDirectoryObjectType},System.Int32,System.Nullable{System.Boolean},System.DirectoryServices.SearchScope)~System.DirectoryServices.SearchResultCollection")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.ADOrganizationalUnit.Children")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.Children")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.ActiveDirectoryContext.AuthType")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~P:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.HasChildren")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.MoveTo(BLAZAM.ActiveDirectory.Interfaces.IADOrganizationalUnit)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.GetParent~BLAZAM.ActiveDirectory.Interfaces.IADOrganizationalUnit")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.Authenticate_Alt(BLAZAM.Common.Data.LoginRequest)~BLAZAM.ActiveDirectory.Interfaces.IADUser")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.ADOrganizationalUnit.CreateOU(System.String)~BLAZAM.ActiveDirectory.Interfaces.IADOrganizationalUnit")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.ADOrganizationalUnit.CreatePrinter(System.String,System.String,System.String)~BLAZAM.ActiveDirectory.Interfaces.IADPrinter")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.ADOrganizationalUnit.CreatePrinter(BLAZAM.ActiveDirectory.Adapters.SharedPrinter)~BLAZAM.ActiveDirectory.Interfaces.IADPrinter")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.SearchResultCollection)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntries)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.ActiveDirectoryContext.KeepAlive(System.Object)")] -[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntry)~BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.ActiveDirectory.Adapters.DirectoryEntryAdapter.GetParent~BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter")] +[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.SearchResultCollection,BLAZAM.ActiveDirectory.Interfaces.IActiveDirectoryContext)~System.Collections.Generic.List{BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter}")] +[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Helpers.ActiveDirectoryHelpers.Encapsulate(System.DirectoryServices.DirectoryEntry,BLAZAM.ActiveDirectory.Interfaces.IActiveDirectoryContext)~BLAZAM.ActiveDirectory.Interfaces.IDirectoryEntryAdapter")] diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index 6a5df47b..430909ef 100644 --- a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs +++ b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs @@ -60,7 +60,6 @@ public static IEnumerable MoveToTop(this IEnumerablex.CanonicalName)); } return list.AsEnumerable(); - return default; } @@ -124,7 +123,7 @@ public static string FqdnToDn(string fqdn) /// /// /// A list of whose types correspond the directory object type they encapsulate - public static List Encapsulate(this SearchResultCollection r) + public static List Encapsulate(this SearchResultCollection r,IActiveDirectoryContext context) { List objects = new(); @@ -163,7 +162,7 @@ public static List Encapsulate(this SearchResultCollecti } if (thisObject != null) { - thisObject.Parse(directory: ActiveDirectoryContext.Instance, searchResult: sr); + thisObject.Parse(directory: context, searchResult: sr); objects.Add(thisObject); @@ -182,7 +181,7 @@ public static List Encapsulate(this SearchResultCollecti /// /// A whose types correspond the directory object type they encapsulate - public static IDirectoryEntryAdapter? Encapsulate(this DirectoryEntry sr) + public static IDirectoryEntryAdapter? Encapsulate(this DirectoryEntry sr, IActiveDirectoryContext context) { IDirectoryEntryAdapter? thisObject = null; @@ -214,7 +213,7 @@ public static List Encapsulate(this SearchResultCollecti } if (thisObject != null) { - thisObject.Parse(directory: ActiveDirectoryContext.Instance, directoryEntry: sr); + thisObject.Parse(directory: context, directoryEntry: sr); return thisObject; @@ -235,7 +234,7 @@ public static List Encapsulate(this SearchResultCollecti /// /// /// A list of whose types correspond the directory object type they encapsulate - public static List Encapsulate(this DirectoryEntries r) + public static List Encapsulate(this DirectoryEntries r, IActiveDirectoryContext context) { List objects = new(); @@ -245,7 +244,7 @@ public static List Encapsulate(this DirectoryEntries r) foreach (DirectoryEntry sr in r) { - var encapsulated = Encapsulate(sr); + var encapsulated = Encapsulate(sr,context); if(encapsulated != null) objects.Add(encapsulated); diff --git a/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs index 90f3a72d..caccb93b 100644 --- a/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADBitLockerSearcher.cs @@ -18,7 +18,7 @@ public List FindByRecoveryId(string searchTerm) { var searchFields = new ADSearchFields(); searchFields.BitLockerRecoveryId = searchTerm; - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.BitLocker, EnabledOnly = false, @@ -39,15 +39,7 @@ public List FindByComputer(IADComputer computer) { var children = computer.Children; return children.Where(c => c is IADBitLockerRecovery).Cast().ToList(); - var searchFields = new ADSearchFields(); - searchFields.CN = "*"+computer.DN; - return new ADSearch() - { - ObjectTypeFilter = ActiveDirectoryObjectType.BitLocker, - EnabledOnly = false, - Fields = searchFields - - }.Search(); + } public async Task> FindByComputerAsync(IADComputer computer) diff --git a/BLAZAMActiveDirectory/Searchers/ADComputerSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADComputerSearcher.cs index 1c935ebb..1afc91c6 100644 --- a/BLAZAMActiveDirectory/Searchers/ADComputerSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADComputerSearcher.cs @@ -23,7 +23,7 @@ public async Task> FindByStringAsync(string searchTerm, bool i } public List FindByString(string searchTerm, bool ignoreDisabled = true) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Computer, EnabledOnly = ignoreDisabled, @@ -45,7 +45,7 @@ public List FindNewComputers(int maxAgeInDays = 14, bool ignoreDisa { var threeMonthsAgo = DateTime.Today - TimeSpan.FromDays(maxAgeInDays); - var results = new ADSearch() + var results = new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Computer, EnabledOnly = ignoreDisabledComputers, diff --git a/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs index d102d24d..7917995f 100644 --- a/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs @@ -38,7 +38,7 @@ public async Task> FindGroupByStringAsync(string searchTerm, bool /// All groups with the distinguished name fragment in their own distinguished name public List FindGroupByDN(string dn) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Group, EnabledOnly = false, @@ -54,7 +54,7 @@ public List FindGroupByDN(string dn) public List FindGroupByString(string searchTerm, bool exactMatch = false) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Group, GeneralSearchTerm = searchTerm, @@ -78,7 +78,7 @@ public async Task> FindNewGroupsAsync(int maxAgeInDays = 14) { var threeMonthsAgo = DateTime.Today - TimeSpan.FromDays(maxAgeInDays); - var results = new ADSearch() + var results = new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Group, Fields = new() @@ -104,7 +104,7 @@ public async Task> FindNewGroupsAsync(int maxAgeInDays = 14) public IADGroup? FindGroupBySID(string groupSID) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Group, Fields = new() @@ -133,7 +133,7 @@ public List FindGroupsByDN(List? list) foreach (string groupDN in list) { - var group = new ADSearch() + var group = new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Group, Fields = new() @@ -195,7 +195,7 @@ public List GetGroupMembers(IADGroup group) public bool IsAMemberOf(IADGroup group, IGroupableDirectoryAdapter? userOrGroup, bool v, bool ignoreDisabledUsers = true) { - return new ADSearch() + return new ADSearch(Directory) { Fields = new() { diff --git a/BLAZAMActiveDirectory/Searchers/ADOUSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADOUSearcher.cs index f845eaec..2e432136 100644 --- a/BLAZAMActiveDirectory/Searchers/ADOUSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADOUSearcher.cs @@ -9,7 +9,7 @@ namespace BLAZAM.ActiveDirectory.Searchers public class ADOUSearcher : ADSearcher, IADOUSearcher { - protected ADSearch NewSearch { get { return new ADSearch() { ObjectTypeFilter = ActiveDirectoryObjectType.OU }; } } + protected ADSearch NewSearch { get { return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.OU }; } } public IADOrganizationalUnit GetApplicationRootOU() { @@ -77,7 +77,7 @@ public List FindNewOUs(int maxAgeInDays = 14) { var threeMonthsAgo = DateTime.Today - TimeSpan.FromDays(maxAgeInDays); - var results = new ADSearch() + var results = new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.OU, Fields = new() diff --git a/BLAZAMActiveDirectory/Searchers/ADPrinterSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADPrinterSearcher.cs index be2fb59f..52b2926d 100644 --- a/BLAZAMActiveDirectory/Searchers/ADPrinterSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADPrinterSearcher.cs @@ -22,7 +22,7 @@ public async Task> FindPrintersByStringAsync(string? searchTerm public List FindPrintersByString(string? searchTerm, bool? ignoreDisabledPrinters = true, bool exactMatch = false) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Printer, EnabledOnly = ignoreDisabledPrinters, @@ -33,7 +33,7 @@ public List FindPrintersByString(string? searchTerm, bool? ignoreDis } public IADPrinter? FindPrinterByName(string? searchTerm, bool? ignoreDisabledPrinters = true) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Printer, EnabledOnly = ignoreDisabledPrinters, @@ -62,7 +62,7 @@ public List FindNewPrinters(int maxAgeInDays = 14, bool? ignoreDisab { var threeMonthsAgo = DateTime.Today - TimeSpan.FromDays(maxAgeInDays); - var results = new ADSearch() + var results = new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Printer, EnabledOnly = ignoreDisabledPrinters, @@ -99,7 +99,7 @@ public List FindChangedPrinters(bool? ignoreDisabledPrinters = true, public IADPrinter? FindPrintersByContainerName(string? searchTerm, bool? ignoreDisabledPrinters = true, bool exactMatch = false) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.Printer, EnabledOnly = ignoreDisabledPrinters, diff --git a/BLAZAMActiveDirectory/Searchers/ADSearch.cs b/BLAZAMActiveDirectory/Searchers/ADSearch.cs index 19477354..17cc507b 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearch.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearch.cs @@ -81,6 +81,12 @@ public class ADSearch : SearchBase public List Results { get; set; } = new(); public string LdapQuery { get; private set; } public bool SearchDeleted { get; set; } = false; + private IActiveDirectoryContext? _currentUserActiveDirectoryContext; + + public ADSearch(IActiveDirectoryContext? currentUserActiveDirectoryContext) + { + _currentUserActiveDirectoryContext = currentUserActiveDirectoryContext; + } public async Task> SearchAsync(CancellationToken? token = null) where T : I, IDirectoryEntryAdapter, new() { @@ -119,7 +125,7 @@ public async Task> SearchAsync() DirectorySearcher searcher; try { - SearchRoot ??= ActiveDirectoryContext.Instance.GetDirectoryEntry(DatabaseCache.ActiveDirectorySettings?.ApplicationBaseDN); + SearchRoot ??= ActiveDirectoryContext.SystemInstance.GetDirectoryEntry(DatabaseCache.ActiveDirectorySettings?.ApplicationBaseDN); var pageOffset = 1; searcher = new DirectorySearcher(SearchRoot) @@ -369,11 +375,21 @@ public void Cancel() cancellationToken = new CancellationToken(true); } + + + private void AddResults(SearchResultCollection lastResults) where T : I, IDirectoryEntryAdapter, new() { + List last = new(); + if (_currentUserActiveDirectoryContext != null) + { + last = lastResults.Encapsulate(_currentUserActiveDirectoryContext); - - var last = lastResults.Encapsulate(); + } + else + { + last = lastResults.Encapsulate(ActiveDirectoryContext.SystemInstance); + } Results.AddRange(last); ResultsCollected?.Invoke(last); diff --git a/BLAZAMActiveDirectory/Searchers/ADSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADSearcher.cs index 48b3802c..6ae9c5f4 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearcher.cs @@ -50,7 +50,7 @@ public ADSearcher(IActiveDirectoryContext directory) - ADSearch search = new ADSearch(); + ADSearch search = new ADSearch(Directory); search.ObjectTypeFilter = searchType; search.SearchRoot = Directory.GetDirectoryEntry(searchBaseDN); diff --git a/BLAZAMActiveDirectory/Searchers/ADUserSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADUserSearcher.cs index 9a2a01ea..4687f4b1 100644 --- a/BLAZAMActiveDirectory/Searchers/ADUserSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADUserSearcher.cs @@ -23,7 +23,7 @@ public async Task> FindUsersByStringAsync(string? searchTerm, bool public List FindUsersByString(string? searchTerm, bool? ignoreDisabledUsers = true, bool exactMatch = false) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.User, EnabledOnly = ignoreDisabledUsers, @@ -34,7 +34,7 @@ public List FindUsersByString(string? searchTerm, bool? ignoreDisabledU } public IADUser? FindUserByUsername(string? searchTerm, bool? ignoreDisabledUsers = true) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.User, EnabledOnly = ignoreDisabledUsers, @@ -58,7 +58,7 @@ public async Task> FindLockedOutUsersAsync(bool? ignoreDisabledUse public List FindLockedOutUsers(bool? ignoreDisabledUsers = true) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.User, EnabledOnly = ignoreDisabledUsers, @@ -85,7 +85,7 @@ public List FindNewUsers(int maxAgeInDays = 14, bool? ignoreDisabledUse { var threeMonthsAgo = DateTime.Today - TimeSpan.FromDays(maxAgeInDays); - var results = new ADSearch() + var results = new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.User, EnabledOnly = ignoreDisabledUsers, @@ -139,7 +139,7 @@ public List FindChangedUsers(bool? ignoreDisabledUsers = true, int days public IADUser? FindUserBySID(string? sid) { if (sid == null) return null; - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.User, EnabledOnly = false, @@ -152,7 +152,7 @@ public List FindChangedUsers(bool? ignoreDisabledUsers = true, int days public IADUser? FindUsersByContainerName(string? searchTerm, bool? ignoreDisabledUsers = true, bool exactMatch = false) { - return new ADSearch() + return new ADSearch(Directory) { ObjectTypeFilter = ActiveDirectoryObjectType.User, EnabledOnly = ignoreDisabledUsers, diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor index 019aa729..bcc87f2b 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor @@ -56,7 +56,7 @@ Task.Run(async () => { - var search = new ADSearch(); + var search = new ADSearch(Directory); search.Fields.Changed = DateTime.Now.AddDays(-1); changdEntries = (await search.SearchAsync()).Where(x => x.CanRead).ToList(); LoadingData = false; diff --git a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor index 8bb5a0d7..8486b658 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor @@ -47,7 +47,7 @@ { await base.OnInitializedAsync(); - var search = new ADSearch() { SearchRoot = Directory.GetDeleteObjectsEntry() }; + var search = new ADSearch(Directory) { SearchRoot = Directory.GetDeleteObjectsEntry() }; search.SearchDeleted = true; search.Fields.Changed = DateTime.Now.AddDays(-14); deletedObjects = await search.SearchAsync(); diff --git a/BLAZAMGui/UI/DirectorySearchPage.razor b/BLAZAMGui/UI/DirectorySearchPage.razor index 5d0a05c7..77867685 100644 --- a/BLAZAMGui/UI/DirectorySearchPage.razor +++ b/BLAZAMGui/UI/DirectorySearchPage.razor @@ -31,7 +31,7 @@ } - public ADSearch Searcher { get; set; } = new(); + public ADSearch Searcher { get; set; } @@ -64,7 +64,7 @@ protected override async Task OnInitializedAsync() { - Searcher = new ADSearch(); + Searcher = new ADSearch(Directory); Searcher.GeneralSearchTerm = SearchTermParameter; await base.OnInitializedAsync(); SearchDisabledObjects = UserStateService?.CurrentUserState?.Preferences?.SearchDisabledUsers == true; diff --git a/BLAZAMGui/UI/Inputs/ADAutoComplete.razor b/BLAZAMGui/UI/Inputs/ADAutoComplete.razor index c1c82cec..66ec431d 100644 --- a/BLAZAMGui/UI/Inputs/ADAutoComplete.razor +++ b/BLAZAMGui/UI/Inputs/ADAutoComplete.razor @@ -217,7 +217,7 @@ { SearchResults = new List(); - var search = new ADSearch(); + var search = new ADSearch(Directory); search.ObjectTypeFilter = SearchObjectType; search.GeneralSearchTerm = searchText.Replace(" ", "*"); diff --git a/BLAZAMGui/UI/Search/SearchPageHeader.razor b/BLAZAMGui/UI/Search/SearchPageHeader.razor index 5fa63ba6..0a455da7 100644 --- a/BLAZAMGui/UI/Search/SearchPageHeader.razor +++ b/BLAZAMGui/UI/Search/SearchPageHeader.razor @@ -43,7 +43,7 @@ }; - public ADSearch Searcher { get; set; } = new ADSearch(); + public ADSearch Searcher { get; set; } @@ -57,7 +57,7 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - + Searcher = new(Directory); Searcher.ResultsCollected += ((batch) => { InvokeAsync(StateHasChanged); }); Searcher.OnSearchCompleted += (() => { diff --git a/BLAZAMServices/LoginPermissionApplicator.cs b/BLAZAMServices/LoginPermissionApplicator.cs index fe182ddd..275e932e 100644 --- a/BLAZAMServices/LoginPermissionApplicator.cs +++ b/BLAZAMServices/LoginPermissionApplicator.cs @@ -20,22 +20,14 @@ public PermissionApplicator(IApplicationUserStateService userStateService, IAppD _userStateService = userStateService; _factory = factory; _directory = directory; - //directory.OnNewLoginUser += LoadPermissionsForNewLoginUser; - //ProgramEvents.PermissionsChanged += PermissionsChanged; } - // For every user that logs in, load their permissions - //private async void LoadPermissionsForNewLoginUser(IApplicationUserState value) - //{ - // if (value.DirectoryUser != null) - // await LoadPermissions(value.DirectoryUser); - - //} + /// - /// Reads the current database settings and applys the assign permissions for the + /// Reads the current database settings and applies the assign permissions for the /// provided directory user /// /// @@ -47,7 +39,7 @@ public async Task LoadPermissions(IApplicationUserState webUser, IADUser directo var cursor = await Context.PermissionDelegate.Include(pl => pl.PermissionsMaps).ToListAsync(); foreach (var l in cursor) { - var permissiondelegate = ActiveDirectoryContext.Instance.FindEntryBySID(l.DelegateSid); + var permissiondelegate = ActiveDirectoryContext.SystemInstance.FindEntryBySID(l.DelegateSid); if (permissiondelegate != null) { if (permissiondelegate is IADGroup && directoryUser.IsAMemberOf(permissiondelegate as IADGroup) From 3ccd3a66b9495c61dc75212172125434161e076d Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Thu, 8 Aug 2024 19:46:49 -0400 Subject: [PATCH 108/116] Add security updates to release notes --- .github/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/release.yml b/.github/release.yml index 61e0b57b..53b51fe5 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -16,6 +16,9 @@ changelog: - title: Exciting New Features 🎉 labels: - enhancement + - title: Security Updates 🔐 + labels: + - security - title: Fixes 🏗 labels: - bug From 237983ff8878aede907e40f7e0e37f827e665ed6 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 03:02:14 -0400 Subject: [PATCH 109/116] Remove unused project --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMExtensions/BLAZAMExtensions.csproj | 21 ----- BLAZAMExtensions/CommonExtensionMethods.cs | 22 ----- BLAZAMExtensions/NetworkTools.cs | 63 ------------- BLAZAMExtensions/StringHelpers.cs | 100 --------------------- 5 files changed, 1 insertion(+), 207 deletions(-) delete mode 100644 BLAZAMExtensions/BLAZAMExtensions.csproj delete mode 100644 BLAZAMExtensions/CommonExtensionMethods.cs delete mode 100644 BLAZAMExtensions/NetworkTools.cs delete mode 100644 BLAZAMExtensions/StringHelpers.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index ad70ff6e..086d0782 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.0.0 - 2024.08.08.2253 + 2024.08.09.0701 false BLAZAM False diff --git a/BLAZAMExtensions/BLAZAMExtensions.csproj b/BLAZAMExtensions/BLAZAMExtensions.csproj deleted file mode 100644 index 0d751fdd..00000000 --- a/BLAZAMExtensions/BLAZAMExtensions.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - net6.0 - enable - enable - BLAZAM.Extensions - - - - - - - - - - - - - - diff --git a/BLAZAMExtensions/CommonExtensionMethods.cs b/BLAZAMExtensions/CommonExtensionMethods.cs deleted file mode 100644 index 7e474900..00000000 --- a/BLAZAMExtensions/CommonExtensionMethods.cs +++ /dev/null @@ -1,22 +0,0 @@ - -using BLAZAM.FileSystem; -using System.Collections; -using System.IO.Compression; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Security.Principal; - -namespace BLAZAM.Extensions - -{ - public static class CommonExtensions - { - - - - - - - - } -} diff --git a/BLAZAMExtensions/NetworkTools.cs b/BLAZAMExtensions/NetworkTools.cs deleted file mode 100644 index 45a8f462..00000000 --- a/BLAZAMExtensions/NetworkTools.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Net; -using System.Net.NetworkInformation; -using System.Net.Sockets; - -namespace BLAZAM.Extensions -{ - public class NetworkTools - { - - public static bool PingHost(string hostNameOrAddress) - { - bool pingable = false; - Ping pinger = new Ping(); - try - { - PingReply reply = pinger.Send(hostNameOrAddress, 1000, new byte[32]); - pingable = reply.Status == IPStatus.Success; - } - catch (PingException) - { - // Ignore exception and return false - } - return pingable; - } - - public static bool IsPortOpen(string hostNameOrAddress, int port) - { - return IsAnyPortOpen(hostNameOrAddress, new int[] { port }); - } - public static bool IsAnyPortOpen(string hostNameOrAddress, int[] ports) - { - bool portOpen = false; - IPAddress ip; - IPAddress.TryParse(hostNameOrAddress, out ip); - - foreach (int port in ports) - { - using (TcpClient client = new TcpClient()) - { - try - { - if (ip != null) - client.Connect(ip, port); - else - client.Connect(hostNameOrAddress, port); - portOpen = true; - break; - } - catch (SocketException) - { - // Ignore exception and try the next port or return false - } - finally - { - client.Close(); - } - } - } - - return portOpen; - } - } -} diff --git a/BLAZAMExtensions/StringHelpers.cs b/BLAZAMExtensions/StringHelpers.cs deleted file mode 100644 index 3aa17bbc..00000000 --- a/BLAZAMExtensions/StringHelpers.cs +++ /dev/null @@ -1,100 +0,0 @@ - -using Microsoft.AspNetCore.Components; -using System.Net; -using System.Runtime.InteropServices; -using System.Security; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -namespace BLAZAM.Helpers -{ - public static class StringHelpers - { - public static MarkupString ToMarkupString(this string input) - { - return (MarkupString)input.Replace("\r\n","
").Replace("\n","
"); - } - public static int GetAppHashCode(this string input) - { - unchecked // Overflow is fine, just wrap - { - int hash = 17; - foreach (char c in input) - { - hash = hash * 23 + c; - } - return hash; - } - } - - public static bool IsNullOrEmpty(this string? str) - { - return str == null || str.Length < 1; - } - - public static bool IsUrlLocalToHost(this string url) - { - if (url.StartsWith("https://localhost")) return true; - if (url == "") return true; - return url[0] == '/' && (url.Length == 1 || - url[1] != '/' && url[1] != '\\') || // "/" or "/foo" but not "//" or "/\" - url.Length > 1 && - url[0] == '~' && url[1] == '/'; // "~/" or "~/foo" - } - - public static string ToPlainText(this SecureString? secureString) - { - if (secureString == null) return string.Empty; - IntPtr bstrPtr = Marshal.SecureStringToBSTR(secureString); - try - { - var plainText = Marshal.PtrToStringBSTR(bstrPtr); - if (plainText == null) - plainText = string.Empty; - return plainText; - - } - finally - { - Marshal.ZeroFreeBSTR(bstrPtr); - } - } - public static SecureString ToSecureString(this string plainText) - { - return new NetworkCredential("", plainText).SecurePassword; - } - - public static string? ToPrettyOu(this string? ou) - { - if (ou == null) return null; - var ouComponents = Regex.Matches(ou, @"OU=([^,]*)") - .Select(m => m.Groups[1].Value) - .ToList(); - ouComponents.Reverse(); - return "/"+string.Join("/", ouComponents); - } - public static string FqdnToDN(this string fqdn) - { - // Split the FQDN into its domain components - string[] domainComponents = fqdn.Split('.'); - - - - // Build the DN by appending each reversed domain component as a RDN (relative distinguished name) - StringBuilder dnBuilder = new StringBuilder(); - foreach (string dc in domainComponents) - { - dnBuilder.Append("DC="); - dnBuilder.Append(dc); - dnBuilder.Append(","); - } - - // Remove the last comma - dnBuilder.Length--; - - // Return the DN - return dnBuilder.ToString(); - } - } -} From b4e82fa492f666d6c9ee7dda6c2ebd9fa97a7dac Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 12:26:31 -0400 Subject: [PATCH 110/116] Bump MudBlazor to 7.6.0 --- BLAZAM/BLAZAM.csproj | 4 ++-- BLAZAMEmailMessage/BLAZAMEmailMessage.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 2 +- BLAZAMJobs/BLAZAMJobs.csproj | 2 +- BLAZAMNotifications/BLAZAMNotifications.csproj | 2 +- BLAZAMThemes/BLAZAMThemes.csproj | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 086d0782..7490a662 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -77,7 +77,7 @@ - + diff --git a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj index d6a17c55..10fa9813 100644 --- a/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj +++ b/BLAZAMEmailMessage/BLAZAMEmailMessage.csproj @@ -14,7 +14,7 @@ - + diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index 73057bee..42e649ee 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -27,7 +27,7 @@ - + diff --git a/BLAZAMJobs/BLAZAMJobs.csproj b/BLAZAMJobs/BLAZAMJobs.csproj index 0a866c09..f6fc644d 100644 --- a/BLAZAMJobs/BLAZAMJobs.csproj +++ b/BLAZAMJobs/BLAZAMJobs.csproj @@ -8,7 +8,7 @@ - + diff --git a/BLAZAMNotifications/BLAZAMNotifications.csproj b/BLAZAMNotifications/BLAZAMNotifications.csproj index 0beef6e1..8c756e5e 100644 --- a/BLAZAMNotifications/BLAZAMNotifications.csproj +++ b/BLAZAMNotifications/BLAZAMNotifications.csproj @@ -8,7 +8,7 @@ - + diff --git a/BLAZAMThemes/BLAZAMThemes.csproj b/BLAZAMThemes/BLAZAMThemes.csproj index ea50aae3..0664ec01 100644 --- a/BLAZAMThemes/BLAZAMThemes.csproj +++ b/BLAZAMThemes/BLAZAMThemes.csproj @@ -8,7 +8,7 @@ - + From b492e1817a8741ccdad4fe31989fcc6e05dfe8bf Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 12:31:44 -0400 Subject: [PATCH 111/116] Bump NUnit.Analyzers to 4.3.0 --- PlaywrightTests/PlaywrightTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlaywrightTests/PlaywrightTests.csproj b/PlaywrightTests/PlaywrightTests.csproj index 6507573b..74ade667 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -13,7 +13,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 800b4fc5f8ade25e22673941254e4b698e4727ef Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 12:32:36 -0400 Subject: [PATCH 112/116] Bump Microsoft.Playwright.NUnit to 1.45.1 --- PlaywrightTests/PlaywrightTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PlaywrightTests/PlaywrightTests.csproj b/PlaywrightTests/PlaywrightTests.csproj index 74ade667..f41fc636 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 2472058d4e618d1179e96e982801d300a7466588 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 12:33:35 -0400 Subject: [PATCH 113/116] Bump Serilog.AspNetCore to 8.0.2 --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMCommon/BLAZAMCommon.csproj | 2 +- BLAZAMLoggers/BLAZAMLogger.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 7490a662..52635dec 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -82,7 +82,7 @@ - + diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 48403bfd..f1aed1eb 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -32,7 +32,7 @@ - + diff --git a/BLAZAMLoggers/BLAZAMLogger.csproj b/BLAZAMLoggers/BLAZAMLogger.csproj index 00678e9f..051e4500 100644 --- a/BLAZAMLoggers/BLAZAMLogger.csproj +++ b/BLAZAMLoggers/BLAZAMLogger.csproj @@ -8,7 +8,7 @@ - + From e72486bc6142190dc9fcdf2c30bfd5f90d75ea5b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 13:00:40 -0400 Subject: [PATCH 114/116] Code cleanup --- BLAZAM.Tests/BLAZAM.Tests.csproj | 4 ---- BLAZAM/BLAZAM.csproj | 8 ++----- BLAZAM/Program.cs | 2 -- .../ActiveDirectoryContext.cs | 3 --- .../ActiveDirectoryContextFactory.cs | 6 ------ BLAZAMActiveDirectory/Adapters/ADUser.cs | 9 +------- .../ScopedActiveDirectoryContext.cs | 1 - BLAZAMActiveDirectory/Searchers/ADSearch.cs | 14 +------------ BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj | 5 ----- BLAZAMCommon/BLAZAMCommon.csproj | 1 - BLAZAMCommon/Data/Encryption.cs | 2 -- BLAZAMDatabase/BLAZAMDatabase.csproj | 1 - BLAZAMFileSystem/SystemDirectory.cs | 5 +---- BLAZAMGui/BLAZAMGui.csproj | 1 - BLAZAMNav/AppNavigationManager.cs | 5 ----- .../AppAuthenticationStateProvider.cs | 21 ++++++------------- PlaywrightTests/PlaywrightTests.csproj | 4 ---- 17 files changed, 11 insertions(+), 81 deletions(-) diff --git a/BLAZAM.Tests/BLAZAM.Tests.csproj b/BLAZAM.Tests/BLAZAM.Tests.csproj index 56fe8b1a..06b50808 100644 --- a/BLAZAM.Tests/BLAZAM.Tests.csproj +++ b/BLAZAM.Tests/BLAZAM.Tests.csproj @@ -15,10 +15,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 52635dec..a20b6a33 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -6,7 +6,7 @@ enable false 1.0.0 - 2024.08.09.0701 + 2024.08.09.1658 false BLAZAM False @@ -58,12 +58,8 @@ - - - - diff --git a/BLAZAM/Program.cs b/BLAZAM/Program.cs index 07e6e089..c6f466b5 100644 --- a/BLAZAM/Program.cs +++ b/BLAZAM/Program.cs @@ -6,12 +6,10 @@ using Serilog; using BLAZAM.Common.Data; using BLAZAM.Server; -using BLAZAM.Services.Background; using System.Net; using BLAZAM.Database.Context; using System.Diagnostics; using System.Security.Cryptography.X509Certificates; -using System.Net.WebSockets; using BLAZAM.Database.Models; namespace BLAZAM diff --git a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs index 20a5d956..f8c98829 100644 --- a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs +++ b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs @@ -2,7 +2,6 @@ using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.ActiveDirectory.Searchers; using BLAZAM.Common.Data; -using BLAZAM.Common.Data.Database; using BLAZAM.Common.Data.Services; using BLAZAM.Database.Context; using BLAZAM.Database.Models; @@ -13,11 +12,9 @@ using System.DirectoryServices; using System.DirectoryServices.Protocols; using System.Net; -using System.Security.Claims; using BLAZAM.Helpers; using System.DirectoryServices.ActiveDirectory; using System.Security.Cryptography; -using System.Diagnostics.Eventing.Reader; using System.Security.Principal; namespace BLAZAM.ActiveDirectory diff --git a/BLAZAMActiveDirectory/ActiveDirectoryContextFactory.cs b/BLAZAMActiveDirectory/ActiveDirectoryContextFactory.cs index 29c5a278..2afb829f 100644 --- a/BLAZAMActiveDirectory/ActiveDirectoryContextFactory.cs +++ b/BLAZAMActiveDirectory/ActiveDirectoryContextFactory.cs @@ -1,14 +1,8 @@ using BLAZAM.ActiveDirectory.Interfaces; -using BLAZAM.Common.Data.Database; using BLAZAM.Common.Data.Services; using BLAZAM.Database.Context; using BLAZAM.Notifications.Services; using BLAZAM.Session.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BLAZAM.ActiveDirectory { diff --git a/BLAZAMActiveDirectory/Adapters/ADUser.cs b/BLAZAMActiveDirectory/Adapters/ADUser.cs index 7260dc07..f84f82ec 100644 --- a/BLAZAMActiveDirectory/Adapters/ADUser.cs +++ b/BLAZAMActiveDirectory/Adapters/ADUser.cs @@ -1,7 +1,5 @@ -using BLAZAM.ActiveDirectory; -using BLAZAM.ActiveDirectory.Data; +using BLAZAM.ActiveDirectory.Data; using BLAZAM.ActiveDirectory.Interfaces; -using BLAZAM.Common.Data; using BLAZAM.Database.Models; using BLAZAM.FileSystem; using BLAZAM.Helpers; @@ -9,11 +7,6 @@ using BLAZAM.Logger; using Microsoft.IdentityModel.Tokens; using System.ComponentModel.DataAnnotations; -using System.DirectoryServices.AccountManagement; -using System.DirectoryServices.ActiveDirectory; -using System.DirectoryServices.Protocols; -using System.Net; -using System.Security; using System.Security.AccessControl; using System.Text; diff --git a/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs index a1f018ca..be5f8d79 100644 --- a/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs +++ b/BLAZAMActiveDirectory/ScopedActiveDirectoryContext.cs @@ -1,5 +1,4 @@ using BLAZAM.ActiveDirectory.Interfaces; -using BLAZAM.Common.Data.Services; using BLAZAM.Session.Interfaces; namespace BLAZAM.ActiveDirectory diff --git a/BLAZAMActiveDirectory/Searchers/ADSearch.cs b/BLAZAMActiveDirectory/Searchers/ADSearch.cs index 17cc507b..9d1fd2de 100644 --- a/BLAZAMActiveDirectory/Searchers/ADSearch.cs +++ b/BLAZAMActiveDirectory/Searchers/ADSearch.cs @@ -2,23 +2,11 @@ using BLAZAM.ActiveDirectory.Adapters; using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Common.Data; -using BLAZAM.Common.Data.Database; using BLAZAM.Database.Context; using BLAZAM.Helpers; using BLAZAM.Logger; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.IdentityModel.Tokens; -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; using System.DirectoryServices; -using System.DirectoryServices.Protocols; -using System.Drawing.Printing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BLAZAM.ActiveDirectory.Searchers { @@ -61,7 +49,7 @@ public class ADSearch : SearchBase /// /// Indicates whether the search is single level or recursive default is recursive /// - public System.DirectoryServices.SearchScope SearchScope { get; set; } = System.DirectoryServices.SearchScope.Subtree; + public SearchScope SearchScope { get; set; } = SearchScope.Subtree; /// /// The realtime results of this search. diff --git a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj index 86ef5e1f..7615bcf5 100644 --- a/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj +++ b/BLAZAMCommon.Tests/BLAZAMCommon.Tests.csproj @@ -10,7 +10,6 @@ - @@ -21,10 +20,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index f1aed1eb..8245c649 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -22,7 +22,6 @@ - diff --git a/BLAZAMCommon/Data/Encryption.cs b/BLAZAMCommon/Data/Encryption.cs index 60a55aff..f59fa5ae 100644 --- a/BLAZAMCommon/Data/Encryption.cs +++ b/BLAZAMCommon/Data/Encryption.cs @@ -1,7 +1,5 @@ using BLAZAM.Helpers; using Newtonsoft.Json; -using System; -using System.ComponentModel; using System.Security.Cryptography; using System.Text; diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index 96b778a4..83b03b80 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -9,7 +9,6 @@ - diff --git a/BLAZAMFileSystem/SystemDirectory.cs b/BLAZAMFileSystem/SystemDirectory.cs index eede4516..6f819f83 100644 --- a/BLAZAMFileSystem/SystemDirectory.cs +++ b/BLAZAMFileSystem/SystemDirectory.cs @@ -1,14 +1,11 @@  using Serilog; -using System.IO; -using System.Security.Permissions; -using System.Security; namespace BLAZAM.FileSystem { /// - /// Represents a diretory in the filesystem + /// Represents a directory in the filesystem /// public class SystemDirectory : FileSystemBase { diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index 42e649ee..71a957ec 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -25,7 +25,6 @@ - diff --git a/BLAZAMNav/AppNavigationManager.cs b/BLAZAMNav/AppNavigationManager.cs index 7368b2b3..93266478 100644 --- a/BLAZAMNav/AppNavigationManager.cs +++ b/BLAZAMNav/AppNavigationManager.cs @@ -6,11 +6,6 @@ using Microsoft.AspNetCore.Components.Routing; using Microsoft.Extensions.Localization; using Microsoft.JSInterop; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BLAZAM.Nav { diff --git a/BLAZAMServices/AppAuthenticationStateProvider.cs b/BLAZAMServices/AppAuthenticationStateProvider.cs index 277092cd..0d11ad57 100644 --- a/BLAZAMServices/AppAuthenticationStateProvider.cs +++ b/BLAZAMServices/AppAuthenticationStateProvider.cs @@ -1,15 +1,10 @@ using BLAZAM.Common.Data; using BLAZAM.Common.Data.Services; -using BLAZAM.Server.Data.Services; using BLAZAM.Common.Exceptions; using DuoUniversal; using Microsoft.AspNetCore.Components.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using System.Diagnostics; using System.Security.Claims; using BLAZAM.Helpers; -using BLAZAM.Common.Data.Database; using Microsoft.AspNetCore.Authentication.Cookies; using BLAZAM.Database.Context; using BLAZAM.ActiveDirectory.Interfaces; @@ -17,12 +12,8 @@ using Microsoft.AspNetCore.Http; using BLAZAM.Services.Duo; using BLAZAM.Server.Helpers; -using BLAZAM.Logger; using BLAZAM.Services.Audit; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.AspNetCore.Components; -using BLAZAM.Nav; -using System.Net.WebSockets; using BLAZAM.Database.Models; namespace BLAZAM.Services @@ -116,10 +107,10 @@ public override Task GetAuthenticationStateAsync() } /// - /// Creates an annonymous ClaimsPrincipal to handle authentication + /// Creates an anonymous ClaimsPrincipal to handle authentication /// before login. /// - /// An unauthenticated annonymous User ClaimsPrincipal + /// An unauthenticated anonymous User ClaimsPrincipal private ClaimsPrincipal GetAnonymous(string? sessionId = null, string? mfaToken = null) { @@ -304,7 +295,7 @@ public async Task Login(LoginRequest loginReq) /// Polls the active directory to either authenticate credentials or simply lookup /// a user depending on if the LoginRequest is for impersonation /// - /// The parameteres passed from the login attempt + /// The parameters passed from the login attempt /// A fully processed ClaimsPrincipal representing the Web user data applied depending on /// database permission tables /// @@ -377,7 +368,7 @@ private async Task PerformDuoAuthentication(LoginRequest loginReq) /// actually make the ClaimsIdentity inside the principal. ///
/// The user found in Active Directory that matches the LoginRequest Username - /// The parameteres passed from the login attempt + /// 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) @@ -529,8 +520,8 @@ public Task SetUser(ClaimsPrincipal claimsPrincipal) return task; } /// - /// This may not be entirely neccessary the way I am implementin authentication and authorization - /// Though, this likey is needed to remove the cookie to actually signout? + /// This may not be entirely necessary the way I am implementing authentication and authorization + /// Though, this likely is needed to remove the cookie to actually sign out. /// /// /// diff --git a/PlaywrightTests/PlaywrightTests.csproj b/PlaywrightTests/PlaywrightTests.csproj index f41fc636..f7b7ad6c 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -18,10 +18,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - all - runtime; build; native; contentfiles; analyzers; buildtransitive -
From 6ca2a3c361f0364aed447ac6bf21f8f25b36f048 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 13:18:18 -0400 Subject: [PATCH 115/116] Minor improvements --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Users/ViewUser.razor | 12 +++---- BLAZAMActiveDirectory/Adapters/ADGroup.cs | 4 +-- .../Searchers/ADGroupSearcher.cs | 4 +-- BLAZAMCommon/Data/ApplicationVersion.cs | 2 +- BLAZAMJobs/Job.cs | 32 +++++++++++++------ 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index a20b6a33..63184ea6 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.0.0 - 2024.08.09.1658 + 2024.08.09.1713 false BLAZAM False diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index 32b65f36..79ca9a23 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -71,7 +71,7 @@ } - + @if (LogonHoursModal?.IsShown == true) { @@ -272,8 +272,8 @@ @AppLocalization["Log On To"] - } - + } + @if (User.CanReadField(ActiveDirectoryFields.LogonHours)) { c.Field != ActiveDirectoryFields.MemberOf.FieldName).ToList()); } - + EditMode = false; Nav.WarnOnNavigation = false; SnackBarService.Success("The changes made to this user have been saved."); diff --git a/BLAZAMActiveDirectory/Adapters/ADGroup.cs b/BLAZAMActiveDirectory/Adapters/ADGroup.cs index 38bd08b9..cc80b098 100644 --- a/BLAZAMActiveDirectory/Adapters/ADGroup.cs +++ b/BLAZAMActiveDirectory/Adapters/ADGroup.cs @@ -224,7 +224,7 @@ public List Members } } /// - /// Removes a memeber from this group + /// Removes a member from this group /// /// The user or group to remove public void UnassignMember(IGroupableDirectoryAdapter member) @@ -238,7 +238,7 @@ public void UnassignMember(IGroupableDirectoryAdapter member) } /// - /// Assigns a memeber to this group + /// Assigns a member to this group /// /// public void AssignMember(IGroupableDirectoryAdapter member) diff --git a/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs b/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs index 7917995f..2257292d 100644 --- a/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs +++ b/BLAZAMActiveDirectory/Searchers/ADGroupSearcher.cs @@ -205,9 +205,7 @@ public bool IsAMemberOf(IADGroup group, IGroupableDirectoryAdapter? userOrGroup, ExactMatch = false }.Search().Count>0; - string UserSearchFieldsQuery = "(&(memberOf:1.2.840.113556.1.4.1941:=" + group.DN + ")(distinguishedName=" + userOrGroup.DN + "))"; - return SearchObjects(UserSearchFieldsQuery, userOrGroup.ObjectType, 50, ignoreDisabledUsers)?.Count > 0; - + } } } diff --git a/BLAZAMCommon/Data/ApplicationVersion.cs b/BLAZAMCommon/Data/ApplicationVersion.cs index be4a4839..9501cbc7 100644 --- a/BLAZAMCommon/Data/ApplicationVersion.cs +++ b/BLAZAMCommon/Data/ApplicationVersion.cs @@ -144,7 +144,7 @@ public override int GetHashCode() return Version.GetHashCode(); } - public override string? ToString() + public override string ToString() { return Version; } diff --git a/BLAZAMJobs/Job.cs b/BLAZAMJobs/Job.cs index 100a04a3..eba0f3cc 100644 --- a/BLAZAMJobs/Job.cs +++ b/BLAZAMJobs/Job.cs @@ -2,17 +2,18 @@ namespace BLAZAM.Jobs { + /// - /// + /// A flexible multi step Job that can have actions as trackable steps. /// - public class Job : JobStepBase, IJob, IJobStep + public class Job : JobStepBase, IJob, IJobStep, IEquatable { private DateTime scheduledRunTime = DateTime.Now; private Timer? runScheduler; public string? User { get; set; } = "System"; - private IList _steps = new List(); + private IList _steps = []; public IList Steps => _steps; @@ -172,13 +173,26 @@ public override void Cancel() } } - public override bool Equals(object? obj) + + public bool Equals(IJob? other) { - if(obj is IJob job) - { - return job.Id.Equals(Id); - } - return false; + return other is not null && + Id.Equals(other.Id); + } + + public override int GetHashCode() + { + return HashCode.Combine(Id); + } + + public static bool operator ==(Job? left, IJob? right) + { + return left.Equals(right); + } + + public static bool operator !=(Job? left, IJob? right) + { + return !(left == right); } } From e7b26273f7ef198bd3d62d0f2e2c8d0fab8410d5 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 9 Aug 2024 13:22:48 -0400 Subject: [PATCH 116/116] Deploy nightly to demo site --- .github/workflows/deploy-demo.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/deploy-demo.yml b/.github/workflows/deploy-demo.yml index ed442e95..a4d4eaf8 100644 --- a/.github/workflows/deploy-demo.yml +++ b/.github/workflows/deploy-demo.yml @@ -7,7 +7,7 @@ name: Build and deploy ASP.Net Core app to Azure Web App - blazam on: push: branches: - - Beta-Nightly + - v1-Nightly workflow_dispatch: jobs: @@ -17,11 +17,6 @@ jobs: steps: - uses: actions/checkout@v2 - - - name: Set up .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.x - name: Setup .NET Core SDK 8 uses: actions/setup-dotnet@v1 with: