summaryrefslogtreecommitdiff
path: root/Pages/Component/AclDialog.razor
blob: 6df93204f2cc82c64dac747e104a18aaf5bb0916 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
@using System.Numerics;
@inject IDbContextFactory<HBContext> dbFactory;
@implements IDialog

<Dialog HeightPixels=500 WidthPixels=900 Title="Edit permissions" @ref=dialog>
    <div class="vcontainer">
        <div class="hcontainer">
            <div>
                @if(obj?.Acl is not null) {
                    <label>
                        Owner
                        <input type="text" autocomplete="off"/>
                    </label>
                    <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>
                                    @(WellKnownSid.TranslateSid(rule.Principal) ?? rule.Principal.ToString())
                                </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 {
                    <p><i>This item does not have any permissions set!</i></p>
                }
            </div>
            <div>
                @if(obj?.Acl is not null) {
                    <div class="principal-select">
                        <label>
                            Subject
                            <input type="text" autocomplete="off"/>
                        </label>
                        <button>Submit</button>
                    </div>
                    var permissions = Acl.GetPermissionDescriptions(obj)
                        .OrderByDescending(kv => BitOperations.PopCount(kv.Value))
                        .ThenBy(kv => kv.Value);
                    foreach(var kv in permissions) {
                        <label>
                            <input type="checkbox"/>
                            @kv.Key
                        </label>
                    }
                } else {
                    <p><i>Click Edit next to an ACL to edit it's permissions</i></p>
                }
            </div>
        </div>
        <ButtonContainer>
            <button class="secondary" @onclick=Hide>Cancel</button>
            @if(obj?.Acl is not null) {
                <button data-keyboard-shortcut="a" @onclick=Hide><u>A</u>pply</button>
            }
        </ButtonContainer>
    </div>
</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))
            .ThenBy(kv => kv.Value)
            .Select(kv => kv.Key));
    }
}