From 3528f3f41e74c461b5eae1202638e389e28b38f6 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Fri, 29 Nov 2024 17:24:52 -0500 Subject: [PATCH 01/14] Remove old class --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/Users/ViewUser.razor | 2 +- .../Adapters/DirectoryEntryAdapter.cs | 2 +- .../Adapters/SharedPrinter.cs | 3 +- .../Adapters/WmiConnection.cs | 3 +- .../Helpers/ActiveDirectoryHelpers.cs | 17 ++++- BLAZAMActiveDirectory/Helpers/WmiHelpers.cs | 27 +++++++ BLAZAMCommon/Helpers/DirectoryTools.cs | 74 ------------------- BLAZAMCommon/Helpers/StringHelpers.cs | 3 +- .../Widgets/ChangedEntriesWidget.razor | 3 + .../Widgets/ChangedPasswordsWidget.razor | 5 +- .../Widgets/DeletedEntriesWidget.razor | 3 + .../Widgets/DisabledUsersWidget.razor | 2 +- .../Dashboard/Widgets/FavoritesWidget.razor | 3 + .../UI/Dashboard/Widgets/LockedOutUsers.razor | 3 + .../Widgets/NewEntriesWidgetDataGrid.razor | 3 + BLAZAMGui/UI/Dashboard/Widgets/Widget.razor | 26 +------ BLAZAMGui/UI/DirectoryEntryViewHeader.razor | 4 +- 18 files changed, 74 insertions(+), 111 deletions(-) create mode 100644 BLAZAMActiveDirectory/Helpers/WmiHelpers.cs delete mode 100644 BLAZAMCommon/Helpers/DirectoryTools.cs diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 335b2728..314a41ae 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.0 - 2024.11.29.1745 + 2024.11.29.2223 false BLAZAM True diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor index c3671339..37008165 100644 --- a/BLAZAM/Pages/Users/ViewUser.razor +++ b/BLAZAM/Pages/Users/ViewUser.razor @@ -86,7 +86,7 @@ {showRemoveThumbnail=true;}) @onmouseleave=@(()=>{showRemoveThumbnail=false;})> diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index d78db9de..4d301c35 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -473,7 +473,7 @@ public virtual void MoveTo(IADOrganizationalUnit parentOUToMoveTo) HasUnsavedChanges = true; } - public virtual string? OU { get => DirectoryTools.DnToOu(DN) ?? DirectoryTools.DnToOu(ADSPath); } + public virtual string? OU { get => DN.DnToOu() ?? ADSPath.DnToOu(); } public IDirectoryEntryAdapter? GetParent() { diff --git a/BLAZAMActiveDirectory/Adapters/SharedPrinter.cs b/BLAZAMActiveDirectory/Adapters/SharedPrinter.cs index d103e7a0..78c0ebc5 100644 --- a/BLAZAMActiveDirectory/Adapters/SharedPrinter.cs +++ b/BLAZAMActiveDirectory/Adapters/SharedPrinter.cs @@ -1,4 +1,5 @@ -using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.ActiveDirectory.Helpers; +using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Helpers; using System; using System.Collections.Generic; diff --git a/BLAZAMActiveDirectory/Adapters/WmiConnection.cs b/BLAZAMActiveDirectory/Adapters/WmiConnection.cs index d20bbeb4..11089270 100644 --- a/BLAZAMActiveDirectory/Adapters/WmiConnection.cs +++ b/BLAZAMActiveDirectory/Adapters/WmiConnection.cs @@ -1,4 +1,5 @@ -using BLAZAM.ActiveDirectory.Interfaces; +using BLAZAM.ActiveDirectory.Helpers; +using BLAZAM.ActiveDirectory.Interfaces; using BLAZAM.Helpers; using BLAZAM.Logger; using System.Management; diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index b8897bfb..3221f255 100644 --- a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs +++ b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs @@ -87,7 +87,7 @@ public static string FqdnToDn(string fqdn) return dnBuilder.ToString(); } - public static string? DnToOu(string? dN) + public static string? DnToOu(this string? dN) { if (dN == null) return null; var ouComponents = Regex.Matches(dN, @"OU=([^,]+)") @@ -97,7 +97,15 @@ public static string FqdnToDn(string fqdn) return string.Join(",", ouComponents); } - + public static string? ToPrettyOu(this IADOrganizationalUnit? ou) + { + if (ou == null) return null; + var ouComponents = Regex.Matches(ou.DN, @"OU=([^,]*)") + .Select(m => m.Groups[1].Value) + .ToList(); + ouComponents.Reverse(); + return "/" + string.Join("/", ouComponents); + } public static string? ParentOU(string? dN) { @@ -252,5 +260,10 @@ public static List Encapsulate(this DirectoryEntries r, } return objects; } + + + + + } } diff --git a/BLAZAMActiveDirectory/Helpers/WmiHelpers.cs b/BLAZAMActiveDirectory/Helpers/WmiHelpers.cs new file mode 100644 index 00000000..8daf5dfc --- /dev/null +++ b/BLAZAMActiveDirectory/Helpers/WmiHelpers.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Management; +using System.Text; +using System.Threading.Tasks; + +namespace BLAZAM.ActiveDirectory.Helpers +{ + public static class WmiHelpers + { + public static T? GetPropertyValue(this ManagementObject? mo, string propertyName) + { + var value = mo.GetPropertyValue(propertyName); + if (value is T) { return (T)value; } + return default; + try + { + return (T)value; + } + catch + { + return default; + } + } + } +} diff --git a/BLAZAMCommon/Helpers/DirectoryTools.cs b/BLAZAMCommon/Helpers/DirectoryTools.cs deleted file mode 100644 index 94e787f4..00000000 --- a/BLAZAMCommon/Helpers/DirectoryTools.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Management; -using System.Runtime.CompilerServices; -using System.Text; -using System.Text.RegularExpressions; - -namespace BLAZAM.Helpers -{ - public static class DirectoryTools - { - public static T? GetPropertyValue(this ManagementObject? mo, string propertyName) - { - var value = mo.GetPropertyValue(propertyName); - if (value is T) { return (T)value; } - return default; - try - { - return (T)value; - } - catch - { - return default; - } - } - public static string FqdnToDn(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(); - } - - public static string? DnToOu(string? dN) - { - if (dN == null) return null; - var ouComponents = Regex.Matches(dN, @"OU=([^,]+)") - .Select(m => m.Value) - .ToList(); - - return string.Join(",", ouComponents); - } - - public static string? ParentOU(string? dN) - { - return dN.Substring(dN.IndexOf("OU=")); - } - - public static string? PrettifyOu(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); - } - - - } -} diff --git a/BLAZAMCommon/Helpers/StringHelpers.cs b/BLAZAMCommon/Helpers/StringHelpers.cs index 7339664e..5238fa3c 100644 --- a/BLAZAMCommon/Helpers/StringHelpers.cs +++ b/BLAZAMCommon/Helpers/StringHelpers.cs @@ -95,7 +95,8 @@ public static SecureString ToSecureString(this string plainText) .ToList(); ouComponents.Reverse(); return "/" + string.Join("/", ouComponents); - } + } + public static string FqdnToDN(this string fqdn) { // Split the FQDN into its domain components diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor index c25b7082..73868a8c 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedEntriesWidget.razor @@ -55,6 +55,9 @@ + + @AppLocalization["No matching entries"] + diff --git a/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor index f48ccc6e..3c83663c 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/ChangedPasswordsWidget.razor @@ -45,7 +45,10 @@ - + + + @AppLocalization["No matching entries"] + diff --git a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor index 490d7ebc..d625326c 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/DeletedEntriesWidget.razor @@ -39,6 +39,9 @@ + + @AppLocalization["No matching entries"] + diff --git a/BLAZAMGui/UI/Dashboard/Widgets/DisabledUsersWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/DisabledUsersWidget.razor index 874f985d..5c16dddd 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/DisabledUsersWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/DisabledUsersWidget.razor @@ -13,7 +13,7 @@ @user.DisplayName
@user.SamAccountName
- @DirectoryTools.PrettifyOu(user.OU)
+ @user.OU.ToPrettyOu()
@user.LastChanged
diff --git a/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor index 9061fd41..98db90e0 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/FavoritesWidget.razor @@ -55,6 +55,9 @@ + + @AppLocalization["You have no favorites"] + diff --git a/BLAZAMGui/UI/Dashboard/Widgets/LockedOutUsers.razor b/BLAZAMGui/UI/Dashboard/Widgets/LockedOutUsers.razor index 23b9cfc6..9ab2c2c6 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/LockedOutUsers.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/LockedOutUsers.razor @@ -48,6 +48,9 @@ + + @AppLocalization["No user are locked out"] + @code { diff --git a/BLAZAMGui/UI/Dashboard/Widgets/NewEntriesWidgetDataGrid.razor b/BLAZAMGui/UI/Dashboard/Widgets/NewEntriesWidgetDataGrid.razor index 867ab3ca..fe6f9c16 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/NewEntriesWidgetDataGrid.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/NewEntriesWidgetDataGrid.razor @@ -50,6 +50,9 @@ + + @AppLocalization["No matching entries"] + diff --git a/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor b/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor index b666948c..440f68c8 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/Widget.razor @@ -1,31 +1,7 @@ @inherits DatabaseComponentBase @code { - protected List _timeSpan_Days = new List - { - TimeSpan.FromDays(1), - TimeSpan.FromDays(5), - TimeSpan.FromDays(14), - TimeSpan.FromDays(30), - TimeSpan.FromDays(90), - TimeSpan.FromDays(180), - TimeSpan.FromDays(360) - - }; - protected List _timeSpan_Hours = new List - { - TimeSpan.FromHours(1), - TimeSpan.FromHours(4), - TimeSpan.FromHours(8), - TimeSpan.FromHours(12), - TimeSpan.FromHours(24), - TimeSpan.FromHours(48), - TimeSpan.FromHours(72) - - }; - - - + [Parameter] public RenderFragment? WidgetContent { get; set; } [Parameter] diff --git a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor index 8507d61b..c40c4dc9 100644 --- a/BLAZAMGui/UI/DirectoryEntryViewHeader.razor +++ b/BLAZAMGui/UI/DirectoryEntryViewHeader.razor @@ -39,9 +39,9 @@ else @DirectoryEntry.CanonicalName } - @if (!DirectoryEntry.OU.IsNullOrEmpty()) + @if (DirectoryEntry.OU!=null) { - @DirectoryTools.PrettifyOu(DirectoryEntry.OU) + @DirectoryEntry.OU.ToPrettyOu() } From d188f078e0586db714045db30b0cf940903d1f5f Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 30 Nov 2024 14:29:27 -0500 Subject: [PATCH 02/14] Show last logon for stale items --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMGui/BLAZAMGui.csproj | 3 + .../Widgets/StaleComputersWidget.razor | 2 +- .../Widgets/StaleEntriesWidgetDataGrid.razor | 62 +++++++++++++++++++ .../Dashboard/Widgets/StaleUsersWidget.razor | 2 +- 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 BLAZAMGui/UI/Dashboard/Widgets/StaleEntriesWidgetDataGrid.razor diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 314a41ae..8f029bc0 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.0 - 2024.11.29.2223 + 2024.11.30.1920 false BLAZAM True diff --git a/BLAZAMGui/BLAZAMGui.csproj b/BLAZAMGui/BLAZAMGui.csproj index fe6e51f2..3a225830 100644 --- a/BLAZAMGui/BLAZAMGui.csproj +++ b/BLAZAMGui/BLAZAMGui.csproj @@ -48,6 +48,9 @@ + + true + true diff --git a/BLAZAMGui/UI/Dashboard/Widgets/StaleComputersWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/StaleComputersWidget.razor index c5020014..6bf98440 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/StaleComputersWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/StaleComputersWidget.razor @@ -1,7 +1,7 @@  @inherits Widget @attribute [Authorize] - +@inject IStringLocalizer AppLocalization +@typeparam T where T : IAccountDirectoryAdapter + + + + + + + + + + + @context.Item?.CanonicalName + + + + + + + + + + + + + + @if (context.Item?.Created != null) + { + + @context.Item.LastLogonTime?.ToLocalTime() + } + + + + + + + + @AppLocalization["No matching entries"] + + + + +@code { +#nullable disable warnings + +} \ No newline at end of file diff --git a/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor b/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor index bbcb3708..7cf91f68 100644 --- a/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor +++ b/BLAZAMGui/UI/Dashboard/Widgets/StaleUsersWidget.razor @@ -1,7 +1,7 @@  @inherits Widget @attribute [Authorize] - Date: Sat, 30 Nov 2024 15:42:43 -0500 Subject: [PATCH 03/14] Comments and minor ui fixes --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/API/Data/NewUserDetails.cs | 4 +- BLAZAM/Pages/API/v1/ApiController.cs | 19 +++++--- BLAZAM/Pages/API/v1/Templates.cs | 46 ++++++++----------- BLAZAM/Pages/Home.razor | 2 +- BLAZAM/Pages/Users/CreateUser.razor | 13 ++---- .../Adapters/DirectoryEntryAdapter.cs | 2 + .../Helpers/ActiveDirectoryHelpers.cs | 28 +++++++++++ .../UI/Groups/RenameGroupModalContent.razor | 4 +- .../UI/Inputs/TreeViews/OUTreeViewBase.cs | 1 + BLAZAMGui/UI/Users/NewTemplateUser.razor | 22 ++------- 11 files changed, 77 insertions(+), 66 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 8f029bc0..c01dc06c 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.0 - 2024.11.30.1920 + 2024.11.30.2035 false BLAZAM True diff --git a/BLAZAM/Pages/API/Data/NewUserDetails.cs b/BLAZAM/Pages/API/Data/NewUserDetails.cs index 3bf3d981..05087499 100644 --- a/BLAZAM/Pages/API/Data/NewUserDetails.cs +++ b/BLAZAM/Pages/API/Data/NewUserDetails.cs @@ -37,12 +37,12 @@ public class NewUserDetails /// The fields to set for this user. Template field with values will also /// be applied. /// - public List? Fields { get; set; } + public List? Fields { get; set; } = new(); /// /// A list of group SID's to assign for this user. Template groups will also /// be applied. /// - public List? Groups { get; set; } + public List? Groups { get; set; } = new(); /// /// If the template is set to send a welcome email, and requests a destination, will be sent diff --git a/BLAZAM/Pages/API/v1/ApiController.cs b/BLAZAM/Pages/API/v1/ApiController.cs index 639716a8..dadb2ba4 100644 --- a/BLAZAM/Pages/API/v1/ApiController.cs +++ b/BLAZAM/Pages/API/v1/ApiController.cs @@ -22,6 +22,10 @@ namespace BLAZAM.Pages.API.v1 public class ApiController : Controller { private DateTime _startTime = DateTime.Now; + + /// + /// A string dictionary that contains the base of the response. + /// protected Dictionary ResponseData = new(); /// /// A factory for connections @@ -31,6 +35,9 @@ public class ApiController : Controller /// The API audit logger /// protected readonly AuditLogger AuditLogger; + /// + /// + /// protected readonly IApplicationUserStateService UserStateService; /// @@ -56,11 +63,9 @@ public ApiController(IApplicationUserStateService applicationUserStateService, A ResponseData.Add("IP Address", httpContextAccessor?.HttpContext?.Connection?.RemoteIpAddress?.ToString()); } - //[HttpGet("badrequest")] // Add a route attribute - //public IActionResult BadRequest() - //{ - // return new BadRequestResult(); - //} + /// + /// The current API users Active Directory connection + /// protected IActiveDirectoryContext Directory { get; } /// /// A unique ID for the execution of this controller @@ -72,8 +77,8 @@ public ApiController(IApplicationUserStateService applicationUserStateService, A /// Returns a JSON response with the data and footer /// fields appended /// - /// - /// + /// A JSON serializable object + /// A new containing the protected IActionResult FormatData(dynamic data) { ResponseData.Add("Data", data); diff --git a/BLAZAM/Pages/API/v1/Templates.cs b/BLAZAM/Pages/API/v1/Templates.cs index 5dd9d4e4..8de69477 100644 --- a/BLAZAM/Pages/API/v1/Templates.cs +++ b/BLAZAM/Pages/API/v1/Templates.cs @@ -39,7 +39,8 @@ public Templates(NotificationGenerationService ouNotificationService, EmailServi /// - /// Executes a user creation template. Any required fields will need to be provided in form data. + /// Executes a user creation template. Any required fields will need to be + /// provided in post body data. /// /// /// /// Sample request: @@ -51,7 +52,7 @@ public Templates(NotificationGenerationService ouNotificationService, EmailServi /// "fields": [ /// { /// "FieldName": "l", - /// "FieldValue": "Boston" + /// "FieldValue": "Boston" /// } /// ] /// "groups": [ @@ -73,19 +74,19 @@ public Templates(NotificationGenerationService ouNotificationService, EmailServi public async Task Execute(int templateId, [FromBody] NewUserDetails newUserDetails) { - //newUserDetails.Fields.Add(new() { FieldName = "test", FieldValue = "val" }); - //var test = JsonConvert.SerializeObject(newUserDetails); var context = await DbFactory.CreateDbContextAsync(); var template = await context.DirectoryTemplates.Include(t => t.ParentTemplate).FirstOrDefaultAsync(t => t.Id == templateId); if (template != null) { + //Check if the request has the required fields for this template if (template.HasRequiredFields()) { var requiredFields = template.EffectiveFieldValues.Where(fv => fv.Required).ToList(); foreach (var field in requiredFields) { + //If any are missing return an error with explanation if (!newUserDetails.Fields.Any(f => f.FieldName.Equals(field.FieldName, StringComparison.InvariantCultureIgnoreCase))) { return new BadRequestObjectResult(field.FieldName + " is a required field"); @@ -94,6 +95,7 @@ public async Task Execute(int templateId, [FromBody] NewUserDetai } } + //Prepare new user name var newUserName = new NewUserName() { GivenName = newUserDetails.FirstName, @@ -101,30 +103,22 @@ public async Task Execute(int templateId, [FromBody] NewUserDetai Surname = newUserDetails.LastName }; + //Generate IADUser var newUser = template.GenerateTemplateUser(newUserName, Directory); + + //Override username if provided if (!newUserDetails.Username.IsNullOrEmpty()) { newUser.SamAccountName = newUserDetails.Username; } + + //Store password in memory for later var password = newUser.NewPassword.ToPlainText().ToSecureString(); - foreach (var fieldValue in template.EffectiveFieldValues) - { - try - { - if (fieldValue.Field != null && fieldValue.Value != null) - if (fieldValue.Field.FieldName.ToLower() == "homedirectory") - newUser.HomeDirectory = template.ReplaceVariables(fieldValue.Value, newUserName, newUser.SamAccountName); - else - newUser.NewEntryProperties[fieldValue.Field.FieldName] = template.ReplaceVariables(fieldValue.Value, newUserName, newUser.SamAccountName); - else if (fieldValue.CustomField != null && fieldValue.Value != null) - newUser.NewEntryProperties[fieldValue.CustomField.FieldName] = template.ReplaceVariables(fieldValue.Value, newUserName, newUser.SamAccountName); - } - catch (Exception ex) - { - Loggers.ActiveDirectoryLogger.Error("Could not set value for " + fieldValue.Field?.FieldName + ": " + fieldValue.Value?.ToString() + " {@Error}", ex); - } - } + //Set each field in template + template.PopulateFields(newUser, newUserName); + + //Set API provided fields if (newUserDetails.Fields != null) { foreach (var field in newUserDetails.Fields) @@ -146,6 +140,8 @@ public async Task Execute(int templateId, [FromBody] NewUserDetai newUser.SetCustomProperty(field.FieldName,value) ; } } + + //Set API provided groups if (newUserDetails.Groups != null) { foreach (var groupSid in newUserDetails.Groups) @@ -163,12 +159,11 @@ public async Task Execute(int templateId, [FromBody] NewUserDetai } } - + //Prepare commit job IJob createUserJob = new Job(AppLocalization["Create User"]); createUserJob.StopOnFailedStep = true; - //createUserJob.ShowJobDetailsDialog(MessageService); - //_username = User.SamAccountName; - //_userPassword = User.NewPassword; + + //Commmit var result = await newUser.CommitChangesAsync(createUserJob); if (result.FailedSteps.Count == 0) { @@ -208,7 +203,6 @@ public async Task Execute(int templateId, [FromBody] NewUserDetai { return new NotFoundObjectResult(templateId); } - return new BadRequestResult(); } diff --git a/BLAZAM/Pages/Home.razor b/BLAZAM/Pages/Home.razor index f25ab474..c174571d 100644 --- a/BLAZAM/Pages/Home.razor +++ b/BLAZAM/Pages/Home.razor @@ -12,7 +12,7 @@ @if (MOTD.HasValue && MOTD.Value.ToString() != "") { - + @MOTD.Value diff --git a/BLAZAM/Pages/Users/CreateUser.razor b/BLAZAM/Pages/Users/CreateUser.razor index 438e3420..05eefedd 100644 --- a/BLAZAM/Pages/Users/CreateUser.razor +++ b/BLAZAM/Pages/Users/CreateUser.razor @@ -24,8 +24,6 @@ @if (TemplateCategories != null && Templates != null && Templates.Count(t => t.DeletedAt == null && t.Visible) > 0) { - @* *@ { @@ -203,7 +201,6 @@ @AppLocalization["OU"] - @* *@ @@ -242,10 +239,10 @@ selectedStep=6; OnClick="@(()=>{SelectedStep=4;})">Back @AppLocalization["Next"] diff --git a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs index 4d301c35..b94bc7c6 100644 --- a/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs +++ b/BLAZAMActiveDirectory/Adapters/DirectoryEntryAdapter.cs @@ -473,6 +473,8 @@ public virtual void MoveTo(IADOrganizationalUnit parentOUToMoveTo) HasUnsavedChanges = true; } + + public virtual string? OU { get => DN.DnToOu() ?? ADSPath.DnToOu(); } public IDirectoryEntryAdapter? GetParent() diff --git a/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs b/BLAZAMActiveDirectory/Helpers/ActiveDirectoryHelpers.cs index 3221f255..67aea4d5 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.Database.Models.Templates; using BLAZAM.Logger; using Microsoft.Extensions.DependencyInjection; using System; @@ -86,7 +87,34 @@ public static string FqdnToDn(string fqdn) // Return the DN return dnBuilder.ToString(); } + /// + /// Populates the fields of the provided + /// with the values set within this + /// + /// This template + /// The user to set the template fields for + /// The new user's name details + public static void PopulateFields(this DirectoryTemplate template,IADUser user,NewUserName newUserName) + { + foreach (var fieldValue in template.EffectiveFieldValues) + { + try + { + if (fieldValue.Field != null && fieldValue.Value != null) + if (fieldValue.Field.FieldName.ToLower() == "homedirectory") + user.HomeDirectory = template.ReplaceVariables(fieldValue.Value, newUserName, user.SamAccountName); + else + user.NewEntryProperties[fieldValue.Field.FieldName] = template.ReplaceVariables(fieldValue.Value, newUserName, user.SamAccountName); + else if (fieldValue.CustomField != null && fieldValue.Value != null) + user.NewEntryProperties[fieldValue.CustomField.FieldName] = template.ReplaceVariables(fieldValue.Value, newUserName, user.SamAccountName); + } + catch (Exception ex) + { + Loggers.ActiveDirectoryLogger.Error("Could not set value for " + fieldValue.Field?.FieldName + ": " + fieldValue.Value?.ToString() + " {@Error}", ex); + } + } + } public static string? DnToOu(this string? dN) { if (dN == null) return null; diff --git a/BLAZAMGui/UI/Groups/RenameGroupModalContent.razor b/BLAZAMGui/UI/Groups/RenameGroupModalContent.razor index 98331cb3..08ce51e1 100644 --- a/BLAZAMGui/UI/Groups/RenameGroupModalContent.razor +++ b/BLAZAMGui/UI/Groups/RenameGroupModalContent.razor @@ -1,5 +1,5 @@ @inherits AppModalContent -
+ @*
*@ @if (Group.CanEditField(ActiveDirectoryFields.SAMAccountName)) { @@ -12,7 +12,7 @@ } -
+ @*
*@ @if (Group.CanEditField(ActiveDirectoryFields.Mail)) { diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs index 8d0899c6..6bd33c5c 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeViewBase.cs @@ -187,6 +187,7 @@ protected void OpenToSelected() var child = openThis.SubOUs.Where(c => SelectedEntry.DN.Contains(c.DN) && !SelectedEntry.DN.Equals(c.DN)).FirstOrDefault(); if (child != null) { + child.IsExpanded = true; _ = (child as IADOrganizationalUnit)?.TreeViewSubOUs; diff --git a/BLAZAMGui/UI/Users/NewTemplateUser.razor b/BLAZAMGui/UI/Users/NewTemplateUser.razor index bc5feed1..2c2477f4 100644 --- a/BLAZAMGui/UI/Users/NewTemplateUser.razor +++ b/BLAZAMGui/UI/Users/NewTemplateUser.razor @@ -350,7 +350,7 @@ @code { -#nullable disable warnings + #nullable disable warnings MudForm form; [Parameter] @@ -364,24 +364,8 @@ protected override async Task OnInitializedAsync() { await base.OnInitializedAsync(); - foreach (var fieldValue in DirectoryTemplate.EffectiveFieldValues) - { - try - { - if (fieldValue.Field != null && fieldValue.Value != null) - if (fieldValue.Field.FieldName.ToLower() == "homedirectory") - User.HomeDirectory = DirectoryTemplate.ReplaceVariables(fieldValue.Value, NewUserName, User.SamAccountName); - else - User.NewEntryProperties[fieldValue.Field.FieldName] = DirectoryTemplate.ReplaceVariables(fieldValue.Value, NewUserName, User.SamAccountName); - else if (fieldValue.CustomField != null && fieldValue.Value != null) - User.NewEntryProperties[fieldValue.CustomField.FieldName] = DirectoryTemplate.ReplaceVariables(fieldValue.Value, NewUserName, User.SamAccountName); - } - catch (Exception ex) - { - Loggers.ActiveDirectoryLogger.Error("Could not set value for " + fieldValue.Field?.FieldName + ": " + fieldValue.Value?.ToString() + " {@Error}", ex); - } - - } + DirectoryTemplate.PopulateFields(User,NewUserName); + } bool InDirectoryTemplate(IActiveDirectoryField field) From d92005b0f7442013cdacf11d158119e2a79cd487 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 30 Nov 2024 16:29:18 -0500 Subject: [PATCH 04/14] Fix for open to current OU --- BLAZAM/BLAZAM.csproj | 2 +- .../UI/Inputs/TreeViews/OUTreeView.razor | 4 +- .../UI/Inputs/TreeViews/OUTreeViewBase.cs | 60 ++++++++++++++----- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index c01dc06c..1080ad02 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.0 - 2024.11.30.2035 + 2024.11.30.2123 false BLAZAM True diff --git a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor index a61e9d5c..e66f477a 100644 --- a/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor +++ b/BLAZAMGui/UI/Inputs/TreeViews/OUTreeView.razor @@ -3,7 +3,7 @@ @Label } OpenToSelected(); + LoadingData = false; + InvokeAsync(StateHasChanged); }); - LoadingData = false; - await InvokeAsync(StateHasChanged); } @@ -174,30 +175,34 @@ protected void OpenToSelected() if (StartRootExpanded && RootOU != null && RootOU.Count > 0) { RootOU.First().Expanded = true; - RootOU.First().Children = GetChildren(RootOU.First().Value); + RootOU.First().Children = GetChildren(RootOU.First()); if (SelectedEntry != null && !SelectedEntry.Equals(RootOU.First().Value)) { var firstThing = RootOU.First(); - if (firstThing.Value is IADOrganizationalUnit openThis) + if (firstThing is TreeItemData openThis) { - openThis.IsExpanded = true; + openThis.Expanded = true; + while (openThis != null) { - var child = openThis.SubOUs.Where(c => SelectedEntry.DN.Contains(c.DN) && !SelectedEntry.DN.Equals(c.DN)).FirstOrDefault(); + openThis.Children = GetChildren(openThis); + var child = openThis.Children.Where( + c => SelectedEntry.DN.Contains(c.Value.DN) + && !SelectedEntry.DN.Equals(c.Value.DN) + ).FirstOrDefault(); if (child != null) { - - child.IsExpanded = true; - _ = (child as IADOrganizationalUnit)?.TreeViewSubOUs; - openThis = child as IADOrganizationalUnit; + child.Expanded = true; + + openThis = child; } else { - var matchingOU = openThis.SubOUs.Where(c => SelectedEntry.DN.Equals(c.DN)).FirstOrDefault(); + var matchingOU = openThis.Children.Where(c => SelectedEntry.DN.Equals(c.Value.DN)).FirstOrDefault(); if (matchingOU != null) - matchingOU.IsSelected = true; + matchingOU.Selected = true; break; } @@ -238,15 +243,38 @@ protected bool ShouldShowOU(IDirectoryEntryAdapter entry) } - protected List> GetChildren(IDirectoryEntryAdapter context) + protected List> GetChildren(TreeItemData context) + { + if (context.Children?.Count > 0) + { + return context.Children; + } + if (context.Value is IADOrganizationalUnit ou) + { + return GetOUChildren(ou); + } + return new List>(); + } + + protected List> GetOUChildren(IDirectoryEntryAdapter ou) { - if (context is IADOrganizationalUnit ou) + if (ou is IADOrganizationalUnit context) { - return ou.TreeViewSubOUs.Where(o => ShouldShowOU(o)).ToTreeItemData(); + return context.TreeViewSubOUs.Where(o => ShouldShowOU(o)).ToTreeItemData(); } return new List>(); + + } + protected async Task?>> GetOUChildrenAsync(IDirectoryEntryAdapter parentNode) + { + return await Task.Run(() => + { + return GetOUChildren(parentNode); + + + }); } - protected async Task>> GetChildrenAsync(IDirectoryEntryAdapter parentNode) + protected async Task?>> GetChildrenAsync(TreeItemData parentNode) { return await Task.Run(() => { From 64c6664dc05793be149a12cb7f4efc595594493a Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 30 Nov 2024 16:46:14 -0500 Subject: [PATCH 05/14] Comments --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/Pages/API/v1/Templates.cs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 1080ad02..1c3340a4 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.0 - 2024.11.30.2123 + 2024.11.30.2133 false BLAZAM True diff --git a/BLAZAM/Pages/API/v1/Templates.cs b/BLAZAM/Pages/API/v1/Templates.cs index 8de69477..cbdd0f6e 100644 --- a/BLAZAM/Pages/API/v1/Templates.cs +++ b/BLAZAM/Pages/API/v1/Templates.cs @@ -22,6 +22,10 @@ namespace BLAZAM.Pages.API.v1 { + /// + /// Template API endpoints provide listing of templates + /// and execution to create users. + /// public class Templates : ApiController { private IAppDatabaseFactory _appDatabaseFactory; @@ -42,7 +46,7 @@ public Templates(NotificationGenerationService ouNotificationService, EmailServi /// Executes a user creation template. Any required fields will need to be /// provided in post body data. ///
- /// /// + /// /// Sample request: /// /// POST /api/v1/templates/execute/2 From 890d43824e486de3bb8440f8ec25a67a0fea7e4b Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sat, 30 Nov 2024 17:44:39 -0500 Subject: [PATCH 06/14] Increment Version --- BLAZAM/BLAZAM.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 1c3340a4..2905c48f 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -5,7 +5,7 @@ enable enable false - 1.2.0 + 1.2.1 2024.11.30.2133 false BLAZAM From ad92ba1aca4484211b9aba6ed027545be1479168 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 1 Dec 2024 10:55:35 -0500 Subject: [PATCH 07/14] Fix for error creating API tokens with a short encryption seed string --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAM/ProgramHelpers.cs | 196 ++++++++++-------- BLAZAMCommon/Data/ApplicationInfo.cs | 20 +- .../Layouts/AppUserApiModalContent.razor | 8 +- .../UI/Outputs/UserApiTokenDataGrid.razor | 6 +- BLAZAMServices/JwtTokenService.cs | 8 +- 6 files changed, 126 insertions(+), 114 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 2905c48f..58ed3619 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.1 - 2024.11.30.2133 + 2024.12.01.1549 false BLAZAM True diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs index a796bd9b..5fecbe24 100644 --- a/BLAZAM/ProgramHelpers.cs +++ b/BLAZAM/ProgramHelpers.cs @@ -176,11 +176,12 @@ public static WebApplicationBuilder InjectServices(this WebApplicationBuilder bu options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, // Important: Validate the signing key - IssuerSigningKey = ApplicationInfo.tokenKey, + IssuerSigningKey = new SymmetricSecurityKey (Encryption.Instance.Key), ValidateIssuer = false, ValidateAudience = false, ValidateActor = false, - ValidateLifetime = true + ValidateLifetime = true, + }; options.Events = new JwtAuthenticationEventsHandler( builder.Services.BuildServiceProvider().GetRequiredService(), @@ -234,12 +235,12 @@ public static WebApplicationBuilder InjectServices(this WebApplicationBuilder bu .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes .AddPolicyHandler(GetWebhookRetryPolicy()); - builder.Services.AddHttpClient(HttpClientNames.WebHookHttpClientNoSSLCheckName) - .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes - .AddPolicyHandler(GetWebhookRetryPolicy()).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler - { - ServerCertificateCustomValidationCallback = (m, c, ch, e) => true - }); + builder.Services.AddHttpClient(HttpClientNames.WebHookHttpClientNoSSLCheckName) + .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes + .AddPolicyHandler(GetWebhookRetryPolicy()).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (m, c, ch, e) => true + }); //Also keeping this here for a possible future API, though this would be for internal use //builder.Services.AddTransient(); @@ -351,32 +352,47 @@ public static WebApplicationBuilder InjectServices(this WebApplicationBuilder bu builder.Services.AddSwaggerGen(c => { - c.SwaggerDoc("v1", new OpenApiInfo { Title = "Blazam API", - Version = "v1" , - Description="The official Blazam API documentation. Authorization is required for API access.", - License=new OpenApiLicense() { Name="MIT License", Url= new Uri("https://github.com/Blazam-App/BLAZAM/blob/v1-Dev/LICENSE") }, - Contact=new() { Email = "support@blazam.org", - Name="Blazam Support", - Url=new("https://blazam.org/support") }, - TermsOfService=new Uri("https://blazam.org/tos") - }); - - // Add descriptions using XML comments - var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; - c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); - - // Configure Swagger to use JWT Bearer authorization - //c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - //{ - // Description = "JWT Authorization header using the Bearer scheme.Example: \"Authorization: Bearer {token}\"", - // Name = "Authorization", - // In = ParameterLocation.Header, - // Type = SecuritySchemeType.Http, - // Scheme = "bearer", - // BearerFormat = "JWT" - //}); + c.SwaggerDoc("v1", new OpenApiInfo + { + Title = "Blazam API", + Version = "v1", + Description = "The official Blazam API documentation. Authorization is required for API access.", + License = new OpenApiLicense() { Name = "MIT License", Url = new Uri("https://github.com/Blazam-App/BLAZAM/blob/v1-Dev/LICENSE") }, + Contact = new() + { + Email = "support@blazam.org", + Name = "Blazam Support", + Url = new("https://blazam.org/support") + }, + TermsOfService = new Uri("https://blazam.org/tos") }); + // Add descriptions using XML comments + var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; + c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); + + // Configure Swagger to use JWT Bearer authorization + var jwtSecurityScheme = new OpenApiSecurityScheme + { + Description = "JWT Authorization header using the Bearer scheme.Example: \"Authorization: Bearer {token}\"", + Name = "Authorization", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + Scheme = JwtBearerDefaults.AuthenticationScheme, + BearerFormat = "JWT", + Reference = new OpenApiReference + { + Id = JwtBearerDefaults.AuthenticationScheme, + Type = ReferenceType.SecurityScheme + } + }; + + c.AddSecurityDefinition(jwtSecurityScheme.Reference.Id, jwtSecurityScheme); + c.AddSecurityRequirement(new OpenApiSecurityRequirement() { + { jwtSecurityScheme,Array.Empty() } + }); + }); + builder.Host.UseWindowsService(); @@ -384,84 +400,84 @@ public static WebApplicationBuilder InjectServices(this WebApplicationBuilder bu return builder; } - public static void PreRun(this WebApplication application) + public static void PreRun(this WebApplication application) + { + //Setup Seq logging if allowed by admin + try { - //Setup Seq logging if allowed by admin - try + var context = Program.AppInstance.Services.GetRequiredService().CreateDbContext(); + if (context != null && context.AppSettings.FirstOrDefault()?.SendLogsToDeveloper != null) { - var context = Program.AppInstance.Services.GetRequiredService().CreateDbContext(); - if (context != null && context.AppSettings.FirstOrDefault()?.SendLogsToDeveloper != null) - { - Loggers.SendToSeqServer = context.AppSettings.FirstOrDefault().SendLogsToDeveloper; - - } + Loggers.SendToSeqServer = context.AppSettings.FirstOrDefault().SendLogsToDeveloper; } - catch (Exception ex) - { - Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); - } - PreloadServices(); } - static IAsyncPolicy GetWebhookRetryPolicy() + catch (Exception ex) { - var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5); + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + PreloadServices(); + + } + static IAsyncPolicy GetWebhookRetryPolicy() + { + var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5); - return HttpPolicyExtensions - .HandleTransientHttpError() - .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) - .WaitAndRetryAsync(delay); + return HttpPolicyExtensions + .HandleTransientHttpError() + .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound) + .WaitAndRetryAsync(delay); + } + private static void PreloadServices() + { + try + { + var context = Program.AppInstance.Services.GetRequiredService(); } - private static void PreloadServices() + catch (Exception ex) { - try - { - var context = Program.AppInstance.Services.GetRequiredService(); - } - catch (Exception ex) + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + try + { + if (ApplicationInfo.installationCompleted) { - Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + var context = Program.AppInstance.Services.GetRequiredService(); } - try - { - if (ApplicationInfo.installationCompleted) - { - var context = Program.AppInstance.Services.GetRequiredService(); - } - } - catch (Exception ex) + } + catch (Exception ex) + { + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + try + { + if (ApplicationInfo.installationCompleted) { - Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + var context = Program.AppInstance.Services.GetRequiredService(); + context.Initialize(); } - try - { - if (ApplicationInfo.installationCompleted) - { - var context = Program.AppInstance.Services.GetRequiredService(); - context.Initialize(); - } - } - catch (Exception ex) - { - Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); - } - try + } + catch (Exception ex) + { + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + try + { + if (ApplicationInfo.installationCompleted) { - if (ApplicationInfo.installationCompleted) - { - var context = Program.AppInstance.Services.GetRequiredService(); - - } + var context = Program.AppInstance.Services.GetRequiredService(); } - catch (Exception ex) - { - Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); - } } + catch (Exception ex) + { + Loggers.SystemLogger.Error(ex.Message + " {@Error}", ex); + } + } } +} diff --git a/BLAZAMCommon/Data/ApplicationInfo.cs b/BLAZAMCommon/Data/ApplicationInfo.cs index 10ad5712..4db9320d 100644 --- a/BLAZAMCommon/Data/ApplicationInfo.cs +++ b/BLAZAMCommon/Data/ApplicationInfo.cs @@ -78,19 +78,7 @@ public class ApplicationInfo ///
public static IServiceProvider services; - /// - /// A symmetric key version of the encryption key - /// for use with API signing - /// - public static SymmetricSecurityKey tokenKey { get { - - var keyString = configuration.GetValue("EncryptionKey"); - var keyBytes = Encoding.ASCII.GetBytes(keyString); - return new SymmetricSecurityKey(keyBytes); - } } - - - + /// /// The running Blazam version /// @@ -173,11 +161,7 @@ public static bool installationCompleted /// Unique ID for this machine /// public Guid InstallationId { get => installationId; set => installationId = value; } - /// - /// A symmetric key version of the encryption key - /// for use with API signing - /// - public SymmetricSecurityKey TokenKey { get => tokenKey; } + /// /// Use only for UnitTests diff --git a/BLAZAMGui/Layouts/AppUserApiModalContent.razor b/BLAZAMGui/Layouts/AppUserApiModalContent.razor index bd8fd032..d4fa8cf3 100644 --- a/BLAZAMGui/Layouts/AppUserApiModalContent.razor +++ b/BLAZAMGui/Layouts/AppUserApiModalContent.razor @@ -1,6 +1,12 @@ @inherits AppModalContent - @AppLocalization["Click to view API documentation"]. + + @AppLocalization["Click to view API documentation"]. + @code{ diff --git a/BLAZAMGui/UI/Outputs/UserApiTokenDataGrid.razor b/BLAZAMGui/UI/Outputs/UserApiTokenDataGrid.razor index 9036acad..ffcf401d 100644 --- a/BLAZAMGui/UI/Outputs/UserApiTokenDataGrid.razor +++ b/BLAZAMGui/UI/Outputs/UserApiTokenDataGrid.razor @@ -23,7 +23,11 @@ @AppLocalization["Forever"] - @AppLocalization["Generate New API Token"] + + @AppLocalization["Generate New API Token"] + @code { List _tokens = new(); diff --git a/BLAZAMServices/JwtTokenService.cs b/BLAZAMServices/JwtTokenService.cs index 9f1a3a06..abd284f1 100644 --- a/BLAZAMServices/JwtTokenService.cs +++ b/BLAZAMServices/JwtTokenService.cs @@ -18,12 +18,14 @@ namespace BLAZAM.Services { public class JwtTokenService { + private readonly IEncryptionService _encryptionService; private readonly ICurrentUserStateService _currentUserStateService; private readonly ApplicationInfo _applicationInfo; - public JwtTokenService(ApplicationInfo applicationInfo, ICurrentUserStateService currentUserStateService) + public JwtTokenService(IEncryptionService encryptionService, ApplicationInfo applicationInfo, ICurrentUserStateService currentUserStateService) { + _encryptionService = encryptionService; _currentUserStateService = currentUserStateService; _applicationInfo = applicationInfo; } @@ -51,7 +53,7 @@ public string GenerateJwtToken(TimeSpan? lifetime=null) IssuedAt = DateTime.UtcNow, Issuer = DatabaseCache.ApplicationSettings.AppName, Expires = (DateTime.UtcNow+lifetime.Value), // Set expiration - SigningCredentials = new SigningCredentials(_applicationInfo.TokenKey, SecurityAlgorithms.HmacSha256Signature) + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encryption.Instance.Key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); var jwtToken = tokenHandler.WriteToken(token); @@ -72,7 +74,7 @@ public ClaimsPrincipal DecodeJwtToken(string tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, - IssuerSigningKey = _applicationInfo.TokenKey, + IssuerSigningKey = new SymmetricSecurityKey(Encryption.Instance.Key), ValidateIssuer = false, ValidateAudience = false, ClockSkew = TimeSpan.Zero // Set clock skew to zero From 7be9b2e13f951441e5cc7332ab7e884a498304dc Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Sun, 1 Dec 2024 12:12:09 -0500 Subject: [PATCH 08/14] Disable menu tests temporarily until test id's are placed --- PlaywrightTests/UnitTest1.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/PlaywrightTests/UnitTest1.cs b/PlaywrightTests/UnitTest1.cs index 15c7d4a6..bd7f7aad 100644 --- a/PlaywrightTests/UnitTest1.cs +++ b/PlaywrightTests/UnitTest1.cs @@ -36,17 +36,17 @@ public async Task MainMenuTest() await OpenRecycleBin(); - await OpenConfigureSubMenu(); + //await OpenConfigureSubMenu(); - await OpenSettingsPages(); + //await OpenSettingsPages(); - await OpenManageNotifications(); + //await OpenManageNotifications(); - await OpenPermissions(); + //await OpenPermissions(); - await OpenFields(); + //await OpenFields(); - await OpenTemplates(); + //await OpenTemplates(); // Expects the URL to contain intro. From 414b09ea07533a233995896659b9df2207bee3ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:02:21 +0000 Subject: [PATCH 09/14] Bump System.DirectoryServices.Protocols from 8.0.0 to 9.0.0 Bumps [System.DirectoryServices.Protocols](https://github.com/dotnet/runtime) from 8.0.0 to 9.0.0. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v8.0.0...v9.0.0) --- updated-dependencies: - dependency-name: System.DirectoryServices.Protocols dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- BLAZAMCommon/BLAZAMCommon.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 28ce8faf..08bd5a46 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -36,7 +36,7 @@ - + From 2595cd515646cf5de7fd1da2c9513e46d6f68faf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:05:45 +0000 Subject: [PATCH 10/14] Bump Microsoft.Extensions.Configuration.Binder from 8.0.2 to 9.0.0 Bumps [Microsoft.Extensions.Configuration.Binder](https://github.com/dotnet/runtime) from 8.0.2 to 9.0.0. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v8.0.2...v9.0.0) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Configuration.Binder dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMCommon/BLAZAMCommon.csproj | 2 +- BLAZAMDatabase/BLAZAMDatabase.csproj | 2 +- BLAZAMLoggers/BLAZAMLogger.csproj | 2 +- BlazamUpdate/BLAZAMUpdate.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 63e64f34..a400e594 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -63,7 +63,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/BLAZAMCommon/BLAZAMCommon.csproj b/BLAZAMCommon/BLAZAMCommon.csproj index 28ce8faf..aacebc52 100644 --- a/BLAZAMCommon/BLAZAMCommon.csproj +++ b/BLAZAMCommon/BLAZAMCommon.csproj @@ -29,7 +29,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/BLAZAMDatabase/BLAZAMDatabase.csproj b/BLAZAMDatabase/BLAZAMDatabase.csproj index dffcc9a5..db8f45a5 100644 --- a/BLAZAMDatabase/BLAZAMDatabase.csproj +++ b/BLAZAMDatabase/BLAZAMDatabase.csproj @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/BLAZAMLoggers/BLAZAMLogger.csproj b/BLAZAMLoggers/BLAZAMLogger.csproj index 3791abb8..0540d4f0 100644 --- a/BLAZAMLoggers/BLAZAMLogger.csproj +++ b/BLAZAMLoggers/BLAZAMLogger.csproj @@ -8,7 +8,7 @@ - + diff --git a/BlazamUpdate/BLAZAMUpdate.csproj b/BlazamUpdate/BLAZAMUpdate.csproj index 22b60fb8..5a9a030f 100644 --- a/BlazamUpdate/BLAZAMUpdate.csproj +++ b/BlazamUpdate/BLAZAMUpdate.csproj @@ -8,7 +8,7 @@ - + From b533928954255f3c14582e022e211ceee2cb7c6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:06:19 +0000 Subject: [PATCH 11/14] Bump Swashbuckle.AspNetCore.SwaggerUI from 7.0.0 to 7.1.0 Bumps [Swashbuckle.AspNetCore.SwaggerUI](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) from 7.0.0 to 7.1.0. - [Release notes](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases) - [Commits](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/compare/v7.0.0...v7.1.0) --- updated-dependencies: - dependency-name: Swashbuckle.AspNetCore.SwaggerUI dependency-type: direct:production update-type: version-update:semver-minor ... 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 63e64f34..11ca3e4f 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -77,7 +77,7 @@ - + From 2f782532f8a782d1682697fc50b8a1abfa378e35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:08:21 +0000 Subject: [PATCH 12/14] Bump Microsoft.Playwright.NUnit and NUnit Bumps [Microsoft.Playwright.NUnit](https://github.com/microsoft/playwright-dotnet) and [NUnit](https://github.com/nunit/nunit). These dependencies needed to be updated together. Updates `Microsoft.Playwright.NUnit` from 1.48.0 to 1.49.0 - [Release notes](https://github.com/microsoft/playwright-dotnet/releases) - [Commits](https://github.com/microsoft/playwright-dotnet/compare/v1.48.0...v1.49.0) Updates `NUnit` from 4.2.2 to 3.13.2 - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/4.2.2...v3.13.2) --- updated-dependencies: - dependency-name: Microsoft.Playwright.NUnit dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-major ... 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 94a45023..52fe65eb 100644 --- a/PlaywrightTests/PlaywrightTests.csproj +++ b/PlaywrightTests/PlaywrightTests.csproj @@ -17,7 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From eb8a2e93acab3e117767666e5f36ba60aeac51ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:13:05 +0000 Subject: [PATCH 13/14] Bump Microsoft.Extensions.Logging.Abstractions from 8.0.2 to 9.0.0 Bumps [Microsoft.Extensions.Logging.Abstractions](https://github.com/dotnet/runtime) from 8.0.2 to 9.0.0. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v8.0.2...v9.0.0) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Logging.Abstractions dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- BLAZAMServices/BLAZAMServices.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BLAZAMServices/BLAZAMServices.csproj b/BLAZAMServices/BLAZAMServices.csproj index 83cbac7a..b6617ee8 100644 --- a/BLAZAMServices/BLAZAMServices.csproj +++ b/BLAZAMServices/BLAZAMServices.csproj @@ -13,7 +13,7 @@ - + From b59d310bc45b43902f43045df4d6fce2e99c20b7 Mon Sep 17 00:00:00 2001 From: Chris Jacobsen Date: Mon, 2 Dec 2024 17:54:59 -0500 Subject: [PATCH 14/14] Change to alert/snackbar colors --- BLAZAM/BLAZAM.csproj | 2 +- BLAZAMThemes/ApplicationTheme.cs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj index 58ed3619..d78c5b66 100644 --- a/BLAZAM/BLAZAM.csproj +++ b/BLAZAM/BLAZAM.csproj @@ -6,7 +6,7 @@ enable false 1.2.1 - 2024.12.01.1549 + 2024.12.02.2252 false BLAZAM True diff --git a/BLAZAMThemes/ApplicationTheme.cs b/BLAZAMThemes/ApplicationTheme.cs index 63e38b7e..b7a43f3e 100644 --- a/BLAZAMThemes/ApplicationTheme.cs +++ b/BLAZAMThemes/ApplicationTheme.cs @@ -24,10 +24,10 @@ public ApplicationTheme() DarkContrastText = System.Drawing.Color.WhiteSmoke.ToHex(), DrawerText = System.Drawing.Color.WhiteSmoke.ToHex(), Background = "#efefef", - Info = "#46a9ef", - Success = System.Drawing.Color.ForestGreen.ToHex(), - Warning = "#ff9900", - Error = System.Drawing.Color.Red.ToHex(), + //Info = "#46a9ef", + //Success = System.Drawing.Color.ForestGreen.ToHex(), + //Warning = "#ff9900", + //Error = System.Drawing.Color.Red.ToHex(), TextDisabled = System.Drawing.Color.DarkGray.ToHex(), White = System.Drawing.Color.White.ToHex() }; @@ -39,10 +39,10 @@ public ApplicationTheme() Surface = "#545960", Background = "#383b40", DrawerText = "#c7c7c7", - Info = "#1b8f7e", - Success = "#5fad00", - Warning = "#ffc270", - Error = "#f60066", + //Info = "#1b8f7e", + //Success = "#5fad00", + //Warning = "#ffc270", + //Error = "#f60066", TextDisabled = System.Drawing.Color.DarkGray.ToHex(), White = System.Drawing.Color.WhiteSmoke.ToHex(), HoverOpacity = 0.25,