From 33438ac951430fa370965b42a3d98a54e704ab01 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Tue, 3 Oct 2023 16:41:58 +1100 Subject: AclDialog --- Pages/Component/AclDialog.razor | 95 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 5 deletions(-) (limited to 'Pages/Component/AclDialog.razor') diff --git a/Pages/Component/AclDialog.razor b/Pages/Component/AclDialog.razor index 33d1f03..8116f04 100644 --- a/Pages/Component/AclDialog.razor +++ b/Pages/Component/AclDialog.razor @@ -1,19 +1,104 @@ -@implements IDialog +@using System.Numerics; +@inject IDbContextFactory dbFactory; +@implements IDialog + @if(obj?.Acl is not null) { + + + + + + + + @foreach(var rule in obj.Acl.Rules.OrderByDescending(r => r.Action)) { + + + + + + + } +
ActionSubjectPermissions
@rule.Principal.ToString()@GetActivePermissions(rule) + 🖉 + +
+
+
Add new
+ + + + + } else { +
This item does not have any permissions set!
+ + + + }
@code { - [Parameter] - public HBObject Object { get; set; } - public bool Visible { get => dialog.Visible; - set => dialog.Visible = value; + set { + dialog.Visible = value; + if(value) + StateHasChanged(); + } } + private HBObject? obj; + private Dialog dialog; public void Show() => Visible = true; public void Hide() => Visible = false; + + public void Show(HBObject obj) { + Object = obj; + Show(); + } + + public HBObject? Object { + get => obj; + set { + if(value is null) { + obj = null; + return; + } + + using var db = dbFactory.CreateDbContext(); + + obj = db.Objects + .Include(o => o.Acl) + .First(o => o.ObjectId == value.ObjectId); + + if(obj.Acl is not null) + db.Entry(obj.Acl).Collection(a => a.Rules).Load(); + } + } + + public string GetActivePermissions(AclRule rule) { + var perms = Acl.GetPermissionDescriptions(obj!) + .Where(kv => (rule.Permissions & kv.Value) == kv.Value) + .ToList(); + + // Filter the list of matching permissions to include the + // most relevant encapsulation permissions only. E.g. if + // 'Full access' includes 'Read' and 'Write', then only + // show 'Full access'. + List toRemove = new(); + for(int i = 0; i < perms.Count(); i++) + for(int j = 0; j < perms.Count(); j++) + if(i != j) + if((perms[i].Value & perms[j].Value) == perms[i].Value) + toRemove.Add(i); + for(int i = toRemove.Count() - 1; i >= 0; i--) + perms.RemoveAt(toRemove[i]); + + return string.Join(", ", perms + .OrderByDescending(kv => BitOperations.PopCount(kv.Value)) + .ThenByDescending(kv => kv.Value) + .Select(kv => kv.Key)); + } } \ No newline at end of file -- cgit v1.3 From aa0b68f7648bd5a7c14b64737a4f8d3e402bfce5 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Wed, 4 Oct 2023 15:59:52 +1100 Subject: Fix SID equality and WellKnownSid mappings --- HBContext.cs | 2 +- HBObject.cs | 2 +- Pages/Component/AclDialog.razor | 57 ++++++++++++-------- Pages/Component/AclDialog.razor.css | 30 ++++++++++- Pages/Component/Dialog.razor | 14 +++-- Pages/Component/Switch.razor.css | 8 +-- PrincipalProviders/LocalPrincipalProvider.cs | 8 +++ SecurityIdentifier.cs | 79 ++++++++++++++++++++++------ Services/PrincipalProvider.cs | 17 ++++++ 9 files changed, 168 insertions(+), 49 deletions(-) (limited to 'Pages/Component/AclDialog.razor') diff --git a/HBContext.cs b/HBContext.cs index 2e78b5a..dee100d 100644 --- a/HBContext.cs +++ b/HBContext.cs @@ -57,7 +57,7 @@ public class HBContext : DbContext { modelBuilder.Entity() .Property(o => o.Owner) - .HasDefaultValue(new SecurityIdentifier(WellKnownSidType.WorldSid)); + .HasDefaultValue(WellKnownSid.WorldSid); // Seed internal tag definitions // These should NEVER change diff --git a/HBObject.cs b/HBObject.cs index df60ed0..eecb3f5 100644 --- a/HBObject.cs +++ b/HBObject.cs @@ -15,5 +15,5 @@ public class HBObject { [ForeignKey("AclId")] public Acl? Acl { get; set; } public SecurityIdentifier Owner { get; set; } = - new SecurityIdentifier(WellKnownSidType.WorldSid); + WellKnownSid.WorldSid; } \ No newline at end of file diff --git a/Pages/Component/AclDialog.razor b/Pages/Component/AclDialog.razor index 8116f04..87fbd6e 100644 --- a/Pages/Component/AclDialog.razor +++ b/Pages/Component/AclDialog.razor @@ -2,35 +2,46 @@ @inject IDbContextFactory dbFactory; @implements IDialog - - @if(obj?.Acl is not null) { - - - - - - - - @foreach(var rule in obj.Acl.Rules.OrderByDescending(r => r.Action)) { - - - - - - + +
+
+ @if(obj?.Acl is not null) { +
ActionSubjectPermissions
@rule.Principal.ToString()@GetActivePermissions(rule) - 🖉 - -
+ + + + + + @foreach(var rule in obj.Acl.Rules.OrderByDescending(r => r.Action)) { + + + + + + + } +
ActionSubjectPermissions
+ @(WellKnownSid.TranslateSid(rule.Principal) ?? rule.Principal.ToString()) + @GetActivePermissions(rule) + 🖉 + +
+
+
Add new
+ } else { +
This item does not have any permissions set!
} - -
-
Add new
+ +
+

Click Edit next to an ACL to edit it's permissions

+
+ + @if(obj?.Acl is not null) { } else { -
This item does not have any permissions set!
diff --git a/Pages/Component/AclDialog.razor.css b/Pages/Component/AclDialog.razor.css index f1b7931..b98cc6d 100644 --- a/Pages/Component/AclDialog.razor.css +++ b/Pages/Component/AclDialog.razor.css @@ -1,4 +1,28 @@ -table p { +div.container { + display: flex; + flex-direction: row; +} + +div.container > div { + width: 50%; +} + +div.container > div:first-child { + border-right: 1px solid white; + padding-right: 15px; +} + +div.container > div:last-child { + padding-left: 15px; + height: stretch; +} + +div.container > div:last-child p { + vertical-align: middle; + text-align: center; +} + +table p { margin: 8px 0 8px 0; } @@ -17,6 +41,10 @@ table td:last-child { font-size: 12pt; } +table td:nth-last-child(2) { + border-right: none !important; +} + table tr:nth-child(2n+1) td:not(:first-child) { background: rgba(255, 255, 255, 0.1); } diff --git a/Pages/Component/Dialog.razor b/Pages/Component/Dialog.razor index 673ec2f..8e8ddca 100644 --- a/Pages/Component/Dialog.razor +++ b/Pages/Component/Dialog.razor @@ -4,7 +4,7 @@
@code { @@ -109,7 +130,7 @@ return string.Join(", ", perms .OrderByDescending(kv => BitOperations.PopCount(kv.Value)) - .ThenByDescending(kv => kv.Value) + .ThenBy(kv => kv.Value) .Select(kv => kv.Key)); } } \ No newline at end of file diff --git a/Pages/Component/AclDialog.razor.css b/Pages/Component/AclDialog.razor.css index b98cc6d..74e405f 100644 --- a/Pages/Component/AclDialog.razor.css +++ b/Pages/Component/AclDialog.razor.css @@ -1,27 +1,57 @@ -div.container { +div.vcontainer{ + display: flex; + flex-direction: column; + height: 100%; +} + +div.hcontainer { display: flex; flex-direction: row; + flex-grow: 1; } -div.container > div { - width: 50%; +div.hcontainer > div { + width: 50%; + flex-direction: column; + display: flex; } -div.container > div:first-child { +div.hcontainer > div:first-child { border-right: 1px solid white; padding-right: 15px; } -div.container > div:last-child { +div.hcontainer > div:last-child { padding-left: 15px; - height: stretch; } -div.container > div:last-child p { - vertical-align: middle; +div.hcontainer > div > p { + margin: auto 0 auto 0; text-align: center; } +div.principal-select { + align-items: center; + display: flex; + flex-direction: row; +} + +div.principal-select * { + margin: 0; +} + +div.principal-select :not(:last-child) { + margin-right: 5px; +} + +div.principal-select input[type="text"] { + flex-grow: 1; +} + +div.hcontainer > div:last-child > label { + font-family: 'Lucida Console'; +} + table p { margin: 8px 0 8px 0; } @@ -31,10 +61,10 @@ table tr { } table td { - font-family: 'Lucida Console'; - font-size: 8pt; - text-overflow: ellipsis; white-space: nowrap; + text-overflow: ellipsis; + font-size: 8pt; + font-family: 'Lucida Console'; } table td:last-child { @@ -50,11 +80,11 @@ table tr:nth-child(2n+1) td:not(:first-child) { } table td:nth-child(2n) { - white-space: nowrap; width: 1px; + white-space: nowrap; } table td > div { - margin: auto; width: min-content; + margin: auto; } \ No newline at end of file diff --git a/Pages/Component/Dialog.razor b/Pages/Component/Dialog.razor index 8e8ddca..ac05515 100644 --- a/Pages/Component/Dialog.razor +++ b/Pages/Component/Dialog.razor @@ -30,6 +30,14 @@ public int HeightPixels { set => height = $"{value}px"; } [Parameter] public int HeightPercent { set => height = $"{value}%"; } + [Parameter] + public int MinHeightPixels { set => minHeight = $"{value}px"; } + [Parameter] + public int MinHeightPercent { set => minHeight = $"{value}%"; } + [Parameter] + public int MaxHeightPixels { set => maxHeight = $"{value}px"; } + [Parameter] + public int MaxHeightPercent { set => maxHeight = $"{value}%"; } public bool Visible { get => visible; @@ -45,6 +53,8 @@ private string? width; private string? height; + private string? minHeight; + private string? maxHeight; private ElementReference dialogDiv; @@ -68,11 +78,19 @@ } } - private string sizeStyle => widthStyle + heightStyle; + private string sizeStyle => string.Join("", new[] { + widthStyle, heightStyle, minHeightStyle, maxHeightStyle + }); private string widthStyle => $"{(width is null ? "" : $"width:{width};")}"; private string heightStyle => - $"{(height is null ? "" : $"max-height:{height};")}"; + $"{(height is null ? "" : $"height:{height};")}"; + + private string minHeightStyle => + $"{(minHeight is null ? "" : $"min-height:{minHeight};")}"; + + private string maxHeightStyle => + $"{(maxHeight is null ? "" : $"max-height:{maxHeight};")}"; } diff --git a/Pages/Component/Dialog.razor.css b/Pages/Component/Dialog.razor.css index 1447407..5e983a2 100644 --- a/Pages/Component/Dialog.razor.css +++ b/Pages/Component/Dialog.razor.css @@ -31,5 +31,6 @@ div.titlebar p.title { div.content { display: flex; flex-direction: column; + flex-grow: 1; padding: 20px; } diff --git a/wwwroot/styles/global.css b/wwwroot/styles/global.css index ec77442..5e46d37 100644 --- a/wwwroot/styles/global.css +++ b/wwwroot/styles/global.css @@ -89,6 +89,11 @@ button, input[type=submit] { user-select: none; } +input[type="checkbox"] { + accent-color: var(--col-accent-pri); + background: #222; +} + button:disabled { color: var(--col-button-disabled) !important; background: var(--col-button-disabled-bg) !important; @@ -143,7 +148,7 @@ input, textarea { margin-bottom: 10px; } -input { +input:not(input[type="checkbox"]) { height: 25px !important; } -- cgit v1.3