diff options
| author | Jake Mannens <jake@asger.xyz> | 2023-10-06 19:00:57 +1100 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2023-10-06 19:00:57 +1100 |
| commit | 36757ad31901cce4bb55f4911a28bb63ee1dee7a (patch) | |
| tree | 0893771af5e973c45d05b6fb62f5bcde5280d75d /Pages | |
| parent | 2c6e3aa4456811a3d6412fc10019012a900eb6a0 (diff) | |
| parent | 2c30354c4af308bf9856a3651d9ba3a686eed936 (diff) | |
Merge branch 'security' of gitlab.com:plasmicplexus/HyperBooru-Server into security
Diffstat (limited to 'Pages')
| -rw-r--r-- | Pages/Component/AclDialog.razor | 127 | ||||
| -rw-r--r-- | Pages/Component/AclDialog.razor.css | 14 |
2 files changed, 114 insertions, 27 deletions
diff --git a/Pages/Component/AclDialog.razor b/Pages/Component/AclDialog.razor index 6df9320..0d24530 100644 --- a/Pages/Component/AclDialog.razor +++ b/Pages/Component/AclDialog.razor @@ -7,10 +7,19 @@ <div class="hcontainer"> <div> @if(obj?.Acl is not null) { - <label> - Owner - <input type="text" autocomplete="off"/> - </label> + <div class="principal-select"> + @if(editOwner is not null) { + <label>Owner</label> + <input type="text" autocomplete="off" @bind=editOwner/> + <button class="secondary" @onclick=@(() => editOwner = null)>Cancel</button> + <button @onclick=@(() => editOwner = null)>OK</button> + } else { + <label>Owner:</label> + <a href="javascript:;" @onclick=@(() => editOwner = obj.Owner.ToString())> + @obj.Owner.ToString() + </a> + } + </div> <table class="data-table"> <tr> <th>Action</th> @@ -21,42 +30,54 @@ <tr> <td><div><AclActionSwitch InitialValue=@(rule.Action == AclRuleAction.Allow)/></div></td> <td> - @(WellKnownSid.TranslateSid(rule.Principal) ?? rule.Principal.ToString()) + @rule.Principal.ToString() </td> <td>@GetActivePermissions(rule)</td> <td> - <a title="Edit" href="javascript:;">🖉</a> - <a title="Delete" href="javascript:;">✖</a> + <a title="Edit" href="javascript:;" @onclick=@(() => EditRule(rule))>🖉</a> + <a title="Delete" href="javascript:;" @onclick=@(() => RemoveRule(rule))>✖</a> </td> </tr> } </table> <br/> - <center><a href="javascript:;">Add new</a></center> + <center><a href="javascript:;" @onclick=AddRule>Add new</a></center> } else { <p><i>This item does not have any permissions set!</i></p> } </div> <div> - @if(obj?.Acl is not null) { + @if(ruleToEdit is not null && permissionCheckboxes is not null) { <div class="principal-select"> - <label> - Subject - <input type="text" autocomplete="off"/> - </label> - <button>Submit</button> + @if(editSubject is not null) { + <label>Subject</label> + <input type="text" autocomplete="off" @bind=editSubject/> + <button class="secondary" @onclick=@(() => editSubject = null)>Cancel</button> + <button @onclick=@(() => editSubject = null)>OK</button> + } else { + <label>Subject:</label> + <a href="javascript:;" @onclick=@(() => editSubject = ruleToEdit.Principal.ToString())> + @if(ruleToEdit.Principal == WellKnownSid.NullSid) { + <i>Select a user or group</i> + } else { + @ruleToEdit.Principal.ToString() + } + </a> + } </div> - var permissions = Acl.GetPermissionDescriptions(obj) + var permissions = Acl.GetPermissionDescriptions(obj!) .OrderByDescending(kv => BitOperations.PopCount(kv.Value)) .ThenBy(kv => kv.Value); - foreach(var kv in permissions) { + foreach(var perm in permissionCheckboxes) { <label> - <input type="checkbox"/> - @kv.Key + <input + type="checkbox" + @bind=perm.Value/> + @perm.Description </label> } } else { - <p><i>Click Edit next to an ACL to edit it's permissions</i></p> + <p><i>Click 'Edit' next to a rule to edit it's permissions</i></p> } </div> </div> @@ -79,7 +100,12 @@ } } - private HBObject? obj; + private HBObject? obj; + private AclRule? ruleToEdit; + private PermissionCheckbox[]? permissionCheckboxes; + + private string? editOwner; + private string? editSubject; private Dialog dialog; @@ -94,6 +120,9 @@ public HBObject? Object { get => obj; set { + editOwner = null; + CancelEditRule(); + if(value is null) { obj = null; return; @@ -110,7 +139,7 @@ } } - public string GetActivePermissions(AclRule rule) { + private string GetActivePermissions(AclRule rule) { var perms = Acl.GetPermissionDescriptions(obj!) .Where(kv => (rule.Permissions & kv.Value) == kv.Value) .ToList(); @@ -125,6 +154,7 @@ if(i != j) if((perms[i].Value & perms[j].Value) == perms[i].Value) toRemove.Add(i); + toRemove = toRemove.Order().Distinct().ToList(); for(int i = toRemove.Count() - 1; i >= 0; i--) perms.RemoveAt(toRemove[i]); @@ -133,4 +163,59 @@ .ThenBy(kv => kv.Value) .Select(kv => kv.Key)); } + + private void AddRule() { + var rule = new AclRule() { + Principal = WellKnownSid.NullSid, + Action = AclRuleAction.Allow, + Permissions = 0 + }; + + obj!.Acl!.Rules.Add(rule); + EditRule(rule); + } + + private void RemoveRule(AclRule rule) { + if(rule == ruleToEdit) + CancelEditRule(); + obj!.Acl!.Rules.Remove(rule); + } + + private void EditRule(AclRule rule) { + ruleToEdit = rule; + editSubject = null; + permissionCheckboxes = Acl.GetPermissionDescriptions(obj!) + .OrderByDescending(kv => BitOperations.PopCount(kv.Value)) + .ThenBy(kv => kv.Value) + .Select(kv => new PermissionCheckbox(rule, kv)) + .ToArray(); + } + + private void CancelEditRule() { + ruleToEdit = null; + permissionCheckboxes = null; + } + + private class PermissionCheckbox { + public string Description { get; private init; } + + private AclRule rule; + private ulong mask; + + public PermissionCheckbox(AclRule rule, KeyValuePair<string, ulong> kv) { + this.rule = rule; + this.mask = kv.Value; + Description = kv.Key; + } + + public bool Value { + get => (rule.Permissions & mask) == mask; + set { + if(value) + rule.Permissions |= mask; + else + rule.Permissions &= ~mask; + } + } + } }
\ No newline at end of file diff --git a/Pages/Component/AclDialog.razor.css b/Pages/Component/AclDialog.razor.css index 74e405f..c9ac518 100644 --- a/Pages/Component/AclDialog.razor.css +++ b/Pages/Component/AclDialog.razor.css @@ -34,6 +34,7 @@ div.principal-select { align-items: center; display: flex; flex-direction: row; + margin-bottom: 16px; } div.principal-select * { @@ -61,16 +62,11 @@ table tr { } table td { - white-space: nowrap; text-overflow: ellipsis; font-size: 8pt; font-family: 'Lucida Console'; } -table td:last-child { - font-size: 12pt; -} - table td:nth-last-child(2) { border-right: none !important; } @@ -79,9 +75,15 @@ table tr:nth-child(2n+1) td:not(:first-child) { background: rgba(255, 255, 255, 0.1); } -table td:nth-child(2n) { +table td:first-child { + width: 1px; +} + +table td:last-child { width: 1px; white-space: nowrap; + text-align: right; + font-size: 12pt; } table td > div { |
