diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index dd84ea78..c35e897f 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -2,7 +2,7 @@
name: Bug report
about: Create a report to help us improve
title: ''
-labels: ''
+labels: 'bug'
assignees: ''
---
@@ -10,29 +10,19 @@ assignees: ''
**Describe the bug**
A clear and concise description of what the bug is.
-**To Reproduce**
+**To Reproduce (Required for complex issues)**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
**Screenshots**
If applicable, add screenshots to help explain your problem.
-**Desktop (please complete the following information):**
- - OS: [e.g. iOS]
- - Browser [e.g. chrome, safari]
- - Version [e.g. 22]
-
-**Smartphone (please complete the following information):**
- - Device: [e.g. iPhone6]
- - OS: [e.g. iOS8.1]
- - Browser [e.g. stock browser, safari]
- - Version [e.g. 22]
+**Environment (please complete the following information):**
+ - Blazam Version
+ - Running under IIS/Service
**Additional context**
Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbcbbe7d..df81be2b 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -13,8 +13,5 @@ A clear and concise description of what the problem is. Ex. I'm always frustrate
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
-
**Additional context**
Add any other context or screenshots about the feature request here.
diff --git a/BLAZAM.Tests/BLAZAM.Tests.csproj b/BLAZAM.Tests/BLAZAM.Tests.csproj
index b1da1ddf..b619ce32 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.Tests/Updates/UpdateTests.cs b/BLAZAM.Tests/Updates/UpdateTests.cs
index f5d6838a..e3d8bd75 100644
--- a/BLAZAM.Tests/Updates/UpdateTests.cs
+++ b/BLAZAM.Tests/Updates/UpdateTests.cs
@@ -34,17 +34,17 @@ public async void Update_Returns_ValidDownload()
await latest.Download(null);
Assert.True(latest?.UpdateFile.Exists);
- Update_Stages_OK(latest);
- Update_Cleanup_OK(latest);
+ await Update_Stages_OK(latest);
+ await Update_Cleanup_OK(latest);
}
- private async void Update_Stages_OK(ApplicationUpdate latest)
+ private async Task Update_Stages_OK(ApplicationUpdate latest)
{
await latest.ExtractFiles(null);
Assert.True(latest.UpdateStagingDirectory.Files.Count > 2);
}
- private async void Update_Cleanup_OK(ApplicationUpdate latest)
+ private async Task Update_Cleanup_OK(ApplicationUpdate latest)
{
await latest.CleanStaging(null);
diff --git a/BLAZAM/BLAZAM.csproj b/BLAZAM/BLAZAM.csproj
index 1b5e37ea..034430a0 100644
--- a/BLAZAM/BLAZAM.csproj
+++ b/BLAZAM/BLAZAM.csproj
@@ -5,8 +5,8 @@
enable
enable
false
- 0.9.1
- 2024.04.13.2102
+ 0.9.2
+ 2024.05.01.2331
false
BLAZAM
False
@@ -26,6 +26,7 @@
+
@@ -55,35 +56,35 @@
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
+
-
+
@@ -108,6 +109,12 @@
+
+
+ PreserveNewest
+
+
+
True
diff --git a/BLAZAM/GlobalSuppressions.cs b/BLAZAM/GlobalSuppressions.cs
new file mode 100644
index 00000000..4b46ad14
--- /dev/null
+++ b/BLAZAM/GlobalSuppressions.cs
@@ -0,0 +1,8 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "", Scope = "member", Target = "~M:BLAZAM.Server.ProgramHelpers.GetInstallationId~System.Guid")]
diff --git a/BLAZAM/Pages/Groups/CreateGroup.razor b/BLAZAM/Pages/Groups/CreateGroup.razor
index 8c02e303..d8f07fb8 100644
--- a/BLAZAM/Pages/Groups/CreateGroup.razor
+++ b/BLAZAM/Pages/Groups/CreateGroup.razor
@@ -11,7 +11,7 @@
+ SelectedEntryChanged="OUSelected">
@*
@context.Name
*@
@@ -73,7 +73,7 @@
int selectedStep;
-
+
@@ -89,17 +89,20 @@
templates = await Context?.DirectoryTemplates.ToListAsync();
await InvokeAsync(StateHasChanged);
}
- async void OUSelected(IADOrganizationalUnit ou)
+ async void OUSelected(IDirectoryEntryAdapter entry)
{
- if (parentOU == null)
+ if (entry is IADOrganizationalUnit ou)
{
+ if (parentOU == null)
+ {
+ parentOU = ou;
+ return;
+ }
parentOU = ou;
- return;
- }
- parentOU = ou;
- await InvokeAsync(StateHasChanged);
+ await InvokeAsync(StateHasChanged);
+ }
}
async void CreateNewGroup()
diff --git a/BLAZAM/Pages/Home.razor b/BLAZAM/Pages/Home.razor
index 4fe2f0cb..537f80b7 100644
--- a/BLAZAM/Pages/Home.razor
+++ b/BLAZAM/Pages/Home.razor
@@ -26,14 +26,7 @@
@if (ApplicationInfo.InDebugMode)
{
-
-
-
- Test Item
- Test Item
- Test Item
-
-
+
Run Test Job
}
diff --git a/BLAZAM/Pages/Install/InstallDatabase.razor b/BLAZAM/Pages/Install/InstallDatabase.razor
index cdb32f18..9ee1aff4 100644
--- a/BLAZAM/Pages/Install/InstallDatabase.razor
+++ b/BLAZAM/Pages/Install/InstallDatabase.razor
@@ -86,7 +86,7 @@ else
await InvokeAsync(StateHasChanged);
try
{
- if (await DbFactory.ApplyDatabaseMigrations(true))
+ if (await DbFactory.ApplyDatabaseMigrationsAsync(true))
{
Completed = true;
await InvokeAsync(StepCompleted.InvokeAsync);
diff --git a/BLAZAM/Pages/OU/CreateOU.razor b/BLAZAM/Pages/OU/CreateOU.razor
index 8dc500cc..4c003f85 100644
--- a/BLAZAM/Pages/OU/CreateOU.razor
+++ b/BLAZAM/Pages/OU/CreateOU.razor
@@ -11,7 +11,7 @@
+ SelectedEntryChanged="OUSelected">
@*
@context.Name
*@
@@ -84,19 +84,23 @@
return false;
}
*/
- async void OUSelected(IADOrganizationalUnit ou)
+ async void OUSelected(IDirectoryEntryAdapter entry)
{
- if (parentOU == null)
+ if (entry is IADOrganizationalUnit ou)
{
+ if (parentOU == null)
+ {
+ parentOU = ou;
+ return;
+ }
parentOU = ou;
- return;
- }
- parentOU = ou;
- await InvokeAsync(StateHasChanged);
+ await InvokeAsync(StateHasChanged);
+ }
}
+
async void CreateNewOU()
{
LoadingData = true;
diff --git a/BLAZAM/Pages/Users/CreateUser.razor b/BLAZAM/Pages/Users/CreateUser.razor
index d453f05d..3baaa676 100644
--- a/BLAZAM/Pages/Users/CreateUser.razor
+++ b/BLAZAM/Pages/Users/CreateUser.razor
@@ -122,14 +122,18 @@
@AppLocalization["OU"]
-
+ @* *@
+
Back
- Next
+ Next
@@ -214,15 +218,17 @@ newUser?.StagePasswordChange(customConfirmPassword.ToSecureString());
await InvokeAsync(StateHasChanged);
}
- async void OUSelected(IADOrganizationalUnit ou)
+ async void OUSelected(IDirectoryEntryAdapter entry)
{
- if (selectedOU == null)
+ if (entry is IADOrganizationalUnit ou)
{
- selectedOU = ou;
- return;
+ if(ou.CanCreateUser)
+ selectedOU = ou;
+ else
+ {
+ SnackBarService.Warning(AppLocalization["You do not have permission to create users in that location"]);
+ }
}
- selectedOU = ou;
-
await InvokeAsync(StateHasChanged);
}
@@ -264,7 +270,9 @@ newUser?.StagePasswordChange(customConfirmPassword.ToSecureString());
newUser.DisplayName = SelectedTemplate.GenerateDisplayName(newUserName);
//newUser.SetPassword(SelectedTemplate.GeneratePassword().ToSecureString(),false);
//newUser.CanonicalName = SelectedTemplate.GenerateDisplayName(newUserName);
- newUser.StagePasswordChange(SelectedTemplate.GeneratePassword().ToSecureString(), true);
+ newUser.StagePasswordChange(SelectedTemplate.GeneratePassword().ToSecureString());
+ if (SelectedTemplate.EffectiveRequirePasswordChange == true)
+ newUser.StageRequirePasswordChange(true);
if (!newUserName.GivenName.IsNullOrEmpty())
newUser.GivenName = newUserName.GivenName;
if (!newUserName.MiddleName.IsNullOrEmpty())
@@ -334,5 +342,13 @@ newUser?.StagePasswordChange(customConfirmPassword.ToSecureString());
SelectedStep = 1;
await InvokeAsync(StateHasChanged);
}
-
+ bool AdditionalShow(IDirectoryEntryAdapter entry)
+ {
+ if(entry is IADOrganizationalUnit ou)
+ {
+ if (ou.CanCreateUser) return true;
+ if (ou.CanCreateUserInSubOUs) return true;
+ }
+ return false;
+ }
}
diff --git a/BLAZAM/Pages/Users/ViewUser.razor b/BLAZAM/Pages/Users/ViewUser.razor
index 73664ee0..073616c6 100644
--- a/BLAZAM/Pages/Users/ViewUser.razor
+++ b/BLAZAM/Pages/Users/ViewUser.razor
@@ -227,7 +227,7 @@
@bind-Value="@ConfirmPassword"
InputType="InputType.Password" />
}
-
+
+
}
@if (User.CanReadField(ActiveDirectoryFields.ScriptPath))
{
diff --git a/BLAZAM/Pages/_Layout.cshtml b/BLAZAM/Pages/_Layout.cshtml
index 6876c658..834867ca 100644
--- a/BLAZAM/Pages/_Layout.cshtml
+++ b/BLAZAM/Pages/_Layout.cshtml
@@ -48,7 +48,7 @@
🗙
- @if (!!ApplicationInfo.InDemoMode && !ApplicationInfo.InDebugMode && !Debugger.IsAttached)
+ @if (!!ApplicationInfo.InDemoMode && !ApplicationInfo.InDebugMode && !Debugger.IsAttached && DatabaseCache.ApplicationSettings?.SendDeveloperAnalytics == true)
{
diff --git a/BLAZAM/Program.cs b/BLAZAM/Program.cs
index 24204b67..310eb11d 100644
--- a/BLAZAM/Program.cs
+++ b/BLAZAM/Program.cs
@@ -81,10 +81,25 @@ public static void Main(string[] args)
builder.IntializeProperties();
+ //Create and discard a new instance of Encryption to inject the encryption seed string
_ = new Encryption(Configuration?.GetValue("EncryptionKey"));
+ //Assign installation ID
+ Loggers.InstallationId = ApplicationInfo.installationId.ToString();
+
//Setup host logging so it can catch the earliest logs possible
+ Loggers.SeqServerUri = "http://logs.blazam.org:5341";
+ if (Debugger.IsAttached)
+ {
+ Loggers.SeqAPIKey = "xE50e1ljqtgLzHcu8pYC";
+
+ }
+ else
+ {
+ Loggers.SeqAPIKey = "8TeLknA8XBk5ybamT5m9";
+ }
+
Loggers.SetupLoggers(WritablePath + @"logs\", ApplicationInfo.runningVersion.ToString());
builder.Host.UseSerilog(Log.Logger);
@@ -106,6 +121,23 @@ 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);
+ }
+ Loggers.SetupLoggers(WritablePath + @"logs\", ApplicationInfo.runningVersion.ToString());
+
+
+
// Configure the HTTP request pipeline.
diff --git a/BLAZAM/ProgramHelpers.cs b/BLAZAM/ProgramHelpers.cs
index 872936c1..93bab51e 100644
--- a/BLAZAM/ProgramHelpers.cs
+++ b/BLAZAM/ProgramHelpers.cs
@@ -29,6 +29,7 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Org.BouncyCastle.Ocsp;
+using System.Management;
namespace BLAZAM.Server
{
@@ -40,8 +41,18 @@ public static WebApplicationBuilder IntializeProperties(this WebApplicationBuild
ApplicationInfo ApplicationInfo = new(builder);
ApplicationInfo.inDebugMode = builder.Configuration.GetValue("DebugMode");
ApplicationInfo.inDemoMode = builder.Configuration.GetValue("DemoMode");
-
+ //Set the installation ID
+ try
+ {
+ ApplicationInfo.installationId = GetInstallationId();
+
+
+ }catch (Exception ex)
+ {
+ ApplicationInfo.installationId = Environment.MachineName.ToGuid();
+
+ }
//Set application directories
//Program.RootDirectory = new SystemDirectory(builder.Environment.ContentRootPath);
//Program.TempDirectory = new SystemDirectory(Path.GetTempPath() + "Blazam\\");
@@ -61,6 +72,35 @@ public static WebApplicationBuilder IntializeProperties(this WebApplicationBuild
return builder;
}
+ private static Guid GetInstallationId()
+ {
+ //Try and get os id
+ try
+ {
+ string ComputerName = "localhost";
+ ManagementScope Scope;
+ Scope = new ManagementScope(String.Format("\\\\{0}\\root\\CIMV2", ComputerName), null);
+ Scope.Connect();
+ ObjectQuery Query = new ObjectQuery("SELECT UUID FROM Win32_ComputerSystemProduct");
+ ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
+
+ foreach (ManagementObject WmiObject in Searcher.Get())
+ {
+ return Guid.Parse(WmiObject["UUID"].ToString());
+
+ }
+ throw new ApplicationException("Searched but could not find a CSProduct UUID");
+ }
+
+ catch (Exception ex)
+ {
+ Console.WriteLine("Failed to get client ID (GUID). Error: " + ex.Message);
+ throw ex;
+ }
+
+
+ }
+
public static WebApplicationBuilder InjectServices(this WebApplicationBuilder builder)
{
diff --git a/BLAZAM/_Imports.razor b/BLAZAM/_Imports.razor
index 3bf54606..17a2a059 100644
--- a/BLAZAM/_Imports.razor
+++ b/BLAZAM/_Imports.razor
@@ -58,6 +58,7 @@
@using BLAZAM.Gui.UI;
@using BLAZAM.Gui.UI.Dashboard.Widgets;
@using BLAZAM.Gui.UI.Inputs
+@using BLAZAM.Gui.UI.Inputs.TreeViews
@using BLAZAM.Gui.Layouts;
@using BLAZAM.Gui.UI.Settings;
@using BLAZAM.Gui.UI.Chat
diff --git a/BLAZAM/appsettings.example.json b/BLAZAM/appsettings.example.json
index 5569f34a..3d492b00 100644
--- a/BLAZAM/appsettings.example.json
+++ b/BLAZAM/appsettings.example.json
@@ -9,7 +9,6 @@
},
"EncryptionKey": "supersecretstring",
"DebugMode": "false",
- "InstallType": "IIS",
"ListeningAddress": "*",
"HTTPPort": "79",
"HTTPSPort": "442",
@@ -18,9 +17,6 @@
"ConnectionStrings": {
"DBConnectionString": ""
- //SQL Example "ConnectionString": "Data Source=localhost;Database=BLAZAM;Persist Security Info=True;Integrated Security=False;Connection Timeout=10;TrustServerCertificate=True;",
- //SQLite Example "ConnectionString": "Data Source=%temp%/Blazam/database.db;",
- //MySql Example "ConnectionString": "Server=localhost;User=blazam;Password=blazam;Database=blazam;"
}
}
diff --git a/BLAZAM/static/img/default_logo5.png b/BLAZAM/static/img/default_logo5.png
new file mode 100644
index 00000000..bbc66206
Binary files /dev/null and b/BLAZAM/static/img/default_logo5.png differ
diff --git a/BLAZAM/wwwroot/android-chrome-192x192.png b/BLAZAM/wwwroot/android-chrome-192x192.png
new file mode 100644
index 00000000..5d0a5f06
Binary files /dev/null and b/BLAZAM/wwwroot/android-chrome-192x192.png differ
diff --git a/BLAZAM/wwwroot/android-chrome-512x512.png b/BLAZAM/wwwroot/android-chrome-512x512.png
new file mode 100644
index 00000000..5b62a1c1
Binary files /dev/null and b/BLAZAM/wwwroot/android-chrome-512x512.png differ
diff --git a/BLAZAM/wwwroot/apple-touch-icon.png b/BLAZAM/wwwroot/apple-touch-icon.png
new file mode 100644
index 00000000..d00d3ae6
Binary files /dev/null and b/BLAZAM/wwwroot/apple-touch-icon.png differ
diff --git a/BLAZAM/wwwroot/css/site.css b/BLAZAM/wwwroot/css/site.css
index 856d97dc..24ac9b17 100644
--- a/BLAZAM/wwwroot/css/site.css
+++ b/BLAZAM/wwwroot/css/site.css
@@ -8,6 +8,9 @@ html, body {
h1:focus {
outline: none;
}
+.blur-background {
+ backdrop-filter: blur(10px);
+}
.app-icon{
margin-left:0.5rem;
max-height:2.5rem;
diff --git a/BLAZAM/wwwroot/favicon-16x16.png b/BLAZAM/wwwroot/favicon-16x16.png
new file mode 100644
index 00000000..c056d234
Binary files /dev/null and b/BLAZAM/wwwroot/favicon-16x16.png differ
diff --git a/BLAZAM/wwwroot/favicon-32x32.png b/BLAZAM/wwwroot/favicon-32x32.png
new file mode 100644
index 00000000..e4095c2b
Binary files /dev/null and b/BLAZAM/wwwroot/favicon-32x32.png differ
diff --git a/BLAZAM/wwwroot/favicon.ico b/BLAZAM/wwwroot/favicon.ico
index 63e859b4..39f5b507 100644
Binary files a/BLAZAM/wwwroot/favicon.ico and b/BLAZAM/wwwroot/favicon.ico differ
diff --git a/BLAZAM/wwwroot/icon-192.png b/BLAZAM/wwwroot/icon-192.png
new file mode 100644
index 00000000..166f56da
Binary files /dev/null and b/BLAZAM/wwwroot/icon-192.png differ
diff --git a/BLAZAM/wwwroot/logo.png b/BLAZAM/wwwroot/logo.png
new file mode 100644
index 00000000..f63d53b9
Binary files /dev/null and b/BLAZAM/wwwroot/logo.png differ
diff --git a/BLAZAM/wwwroot/mstile-150x150.png b/BLAZAM/wwwroot/mstile-150x150.png
new file mode 100644
index 00000000..3b9960b5
Binary files /dev/null and b/BLAZAM/wwwroot/mstile-150x150.png differ
diff --git a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs
index 6900ff7e..421dd220 100644
--- a/BLAZAMActiveDirectory/ActiveDirectoryContext.cs
+++ b/BLAZAMActiveDirectory/ActiveDirectoryContext.cs
@@ -290,7 +290,22 @@ private async void KeepAlive(object? state = null)
else if (Status == DirectoryConnectionStatus.OK)
{
//Throw away query used to keep connection alive
- _keepAliveUser = Users?.FindUsersByString(ConnectionSettings?.Username, false)?.FirstOrDefault();
+ try
+ {
+ _keepAliveUser = Users?.FindUsersByString(ConnectionSettings?.Username, false)?.FirstOrDefault();
+
+ }catch(DirectoryServicesCOMException ex)
+ {
+ //not usernam or password is incorrect
+ if (ex.HResult != -2147023570)
+ {
+ Loggers.ActiveDirectryLogger.Error("Unexpected error performing keep alive search.{@Error}", ex);
+
+ }
+ }
+ catch (Exception ex) {
+ Loggers.ActiveDirectryLogger.Error("Unexpected error performing keep alive search.{@Error}", ex);
+ }
}
await Task.Delay(30000);
}
diff --git a/BLAZAMActiveDirectory/Adapters/ADComputerSessions.cs b/BLAZAMActiveDirectory/Adapters/ADComputerSessions.cs
index e3152868..dbe03693 100644
--- a/BLAZAMActiveDirectory/Adapters/ADComputerSessions.cs
+++ b/BLAZAMActiveDirectory/Adapters/ADComputerSessions.cs
@@ -109,7 +109,7 @@ public void Dispose()
session.Dispose();
}
ConnectedSessions.Clear();
-
+
}
diff --git a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs
index 20d7fb2f..d6440eb1 100644
--- a/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs
+++ b/BLAZAMActiveDirectory/Adapters/ADOrganizationalUnit.cs
@@ -4,18 +4,17 @@
using BLAZAM.Logger;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
+using System.Data.SQLite;
using System.Diagnostics.Contracts;
using System.DirectoryServices;
using System.Reflection.PortableExecutable;
+using System.Web;
namespace BLAZAM.ActiveDirectory.Adapters
{
public class ADOrganizationalUnit : DirectoryEntryAdapter, IADOrganizationalUnit
{
private IEnumerable? childOUCache;
- //private IQueryable? childUserCache;
- //private IQueryable? childComputerCache;
- //private IQueryable? childGroupCache;
@@ -26,7 +25,7 @@ public async Task HasChildrenAsync()
return HasChildren;
});
}
- public async Task> GetChildrenAsync()
+ public async Task> GetChildrenAsync()
{
return await Task.Run(() =>
{
@@ -34,9 +33,9 @@ public async Task> GetChildrenAsync()
});
}
- public HashSet CachedTreeViewSubOUs { get; private set; } = new();
+ public HashSet CachedTreeViewSubOUs { get; private set; } = new();
- public HashSet TreeViewSubOUs
+ public HashSet TreeViewSubOUs
{
get
{
@@ -45,7 +44,7 @@ public HashSet TreeViewSubOUs
}
}
- public IEnumerable SubOUs
+ public IEnumerable SubOUs
{
get
{
@@ -59,7 +58,7 @@ public IEnumerable SubOUs
- public override string SearchUri => "/search/" + DN;
+ public override string SearchUri => "/search/" + HttpUtility.UrlEncode(DN);
public override string? CanonicalName
{
@@ -123,7 +122,7 @@ public IQueryable OffspringPermissionMappings
}
- public virtual bool CanReadInSubOus
+ public virtual bool CanReadUsersInSubOus
{
get
{
@@ -141,12 +140,126 @@ public virtual bool CanReadInSubOus
);
}
+ }
+ public virtual bool CanReadNonOUs
+ {
+ get
+ {
+ if (CanReadUsers) return true;
+ if (CanReadGroups) return true;
+ if (CanReadComputers) return true;
+ if (CanReadPrinters) return true;
+ return false;
+ }
+ }
+ public virtual bool CanReadPrinters
+ {
+ get
+ {
+ return HasPermission(p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.Printer &&
+ om.ObjectAccessLevel.Level > ObjectAccessLevels.Deny.Level
+ ))),
+ p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.Printer &&
+ om.ObjectAccessLevel.Level == ObjectAccessLevels.Deny.Level
+ )))
+ );
+ }
+
+ }
+ public virtual bool CanReadComputers
+ {
+ get
+ {
+ return HasPermission(p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.Computer &&
+ om.ObjectAccessLevel.Level > ObjectAccessLevels.Deny.Level
+ ))),
+ p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.Computer &&
+ om.ObjectAccessLevel.Level == ObjectAccessLevels.Deny.Level
+ )))
+ );
+ }
+
+ }
+ public virtual bool CanReadGroups
+ {
+ get
+ {
+ return HasPermission(p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.Group &&
+ om.ObjectAccessLevel.Level > ObjectAccessLevels.Deny.Level
+ ))),
+ p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.Group &&
+ om.ObjectAccessLevel.Level == ObjectAccessLevels.Deny.Level
+ )))
+ );
+ }
+
+ }
+ public virtual bool CanReadUsers
+ {
+ get
+ {
+ return HasPermission(p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.User &&
+ om.ObjectAccessLevel.Level > ObjectAccessLevels.Deny.Level
+ ))),
+ p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ObjectMap.Any(om =>
+ om.ObjectType == ActiveDirectoryObjectType.User &&
+ om.ObjectAccessLevel.Level == ObjectAccessLevels.Deny.Level
+ )))
+ );
+ }
+
}
public virtual bool CanCreateUser
{
get
{
- return HasActionPermission(ObjectActions.Create,ActiveDirectoryObjectType.User);
+ return HasActionPermission(ObjectActions.Create, ActiveDirectoryObjectType.User);
+ }
+
+ }
+ public virtual bool CanCreateUserInSubOUs
+ {
+ get
+ {
+
+ return HasPermission(p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ActionMap.Any(am=>
+ am.ObjectType==ActiveDirectoryObjectType.User &&
+ am.ObjectAction.Id==ObjectActions.Create.Id &&
+ am.AllowOrDeny==true))),
+ p => p.Where(pm =>
+ pm.AccessLevels.Any(al =>
+ al.ActionMap.Any(am =>
+ am.ObjectType == ActiveDirectoryObjectType.User &&
+ am.ObjectAction.Id == ObjectActions.Create.Id &&
+ am.AllowOrDeny == false))),
+ true
+ );
+
}
}
diff --git a/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs b/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs
index 2bbfa0c7..dbab5e79 100644
--- a/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs
+++ b/BLAZAMActiveDirectory/Adapters/AccountDirectoryAdapter.cs
@@ -27,6 +27,8 @@ public class AccountDirectoryAdapter : GroupableDirectoryAdapter, IAccountDirect
+ public virtual bool CanSetPassword { get => HasActionPermission(ObjectActions.SetPassword); }
+
public virtual bool CanEnable { get => HasActionPermission(ObjectActions.Enable); }
public virtual bool CanDisable { get => HasActionPermission(ObjectActions.Disable); }
@@ -46,7 +48,6 @@ public bool CanSearchDisabled
}
}
-
public virtual DateTime? LockoutTime
{
get
@@ -121,7 +122,7 @@ public virtual bool Disabled
}
}
}
- public virtual bool PasswordNotRequired
+ public virtual bool PasswordNotRequired
{
get
{
@@ -154,8 +155,8 @@ protected int UAC
{
get
{
- var uacRaw= Convert.ToInt32(GetProperty