summaryrefslogtreecommitdiff
path: root/Pages/Component/AclDialog.razor
blob: 87fbd6ef702b19494042799c88d71e3d62ab6a2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@using System.Numerics;
@inject IDbContextFactory<HBContext> dbFactory;
@implements IDialog

<Dialog WidthPixels=900 Title="Edit permissions" @ref=dialog>
    <div class="container">
        <div>
            @if(obj?.Acl is not null) {
                <table class="data-table">
                    <tr>
                        <th>Action</th>
                        <th>Subject</th>
                        <th colspan="2">Permissions</th>
                    </tr>
                    @foreach(var rule in obj.Acl.Rules.OrderByDescending(r => r.Action)) {
                        <tr>
                            <td><div><AclActionSwitch InitialValue=@(rule.Action == AclRuleAction.Allow)/></div></td>
                            <td>
                                <a class="nondecorated" href="javascript:;">@(WellKnownSid.TranslateSid(rule.Principal) ?? rule.Principal.ToString())</a>
                            </td>
                            <td>@GetActivePermissions(rule)</td>
                            <td>
                                <a title="Edit" href="javascript:;">&#x1F589</a>
                                <a title="Delete" href="javascript:;">&#x2716</a>
                            </td>
                        </tr>
                    }
                </table>
                <br/>
                <center><a href="javascript:;">Add new</a></center>
            } else {
                <center><i>This item does not have any permissions set!</i></center>
            }
        </div>
        <div>
            <p><i>Click Edit next to an ACL to edit it's permissions</i></p>
        </div>
    </div>
    @if(obj?.Acl is not null) {
        <ButtonContainer>
            <button class="secondary" @onclick=Hide>Cancel</button>
            <button data-keyboard-shortcut="a" @onclick=Hide><u>A</u>pply</button>
        </ButtonContainer>
    } else {
        <ButtonContainer>
            <button class="secondary" @onclick=Hide>Cancel</button>
        </ButtonContainer>
    }
</Dialog>

@code {
    public bool Visible {
        get => dialog.Visible;
        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<int> 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));
    }
}