@xen-orchestra/acl 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/actions/acl-privilege.d.mts +12 -0
  2. package/dist/actions/acl-privilege.mjs +11 -0
  3. package/dist/actions/acl-role.d.mts +12 -0
  4. package/dist/actions/acl-role.mjs +11 -0
  5. package/dist/actions/alarm.d.mts +4 -0
  6. package/dist/actions/alarm.mjs +3 -0
  7. package/dist/actions/backup-archive.d.mts +4 -0
  8. package/dist/actions/backup-archive.mjs +3 -0
  9. package/dist/actions/backup-job.d.mts +4 -0
  10. package/dist/actions/backup-job.mjs +3 -0
  11. package/dist/actions/backup-log.d.mts +4 -0
  12. package/dist/actions/backup-log.mjs +3 -0
  13. package/dist/actions/backup-repository.d.mts +4 -0
  14. package/dist/actions/backup-repository.mjs +3 -0
  15. package/dist/actions/gpuGroup.d.mts +4 -0
  16. package/dist/actions/gpuGroup.mjs +3 -0
  17. package/dist/actions/group.d.mts +10 -0
  18. package/dist/actions/group.mjs +9 -0
  19. package/dist/actions/host.d.mts +11 -0
  20. package/dist/actions/host.mjs +10 -0
  21. package/dist/actions/index.d.mts +225 -0
  22. package/dist/actions/index.mjs +79 -0
  23. package/dist/actions/message.d.mts +4 -0
  24. package/dist/actions/message.mjs +3 -0
  25. package/dist/actions/network.d.mts +9 -0
  26. package/dist/actions/network.mjs +8 -0
  27. package/dist/actions/pbd.d.mts +4 -0
  28. package/dist/actions/pbd.mjs +3 -0
  29. package/dist/actions/pci.d.mts +4 -0
  30. package/dist/actions/pci.mjs +3 -0
  31. package/dist/actions/pgpu.d.mts +4 -0
  32. package/dist/actions/pgpu.mjs +3 -0
  33. package/dist/actions/pif.d.mts +4 -0
  34. package/dist/actions/pif.mjs +3 -0
  35. package/dist/actions/pool.d.mts +14 -0
  36. package/dist/actions/pool.mjs +13 -0
  37. package/dist/actions/proxy.d.mts +4 -0
  38. package/dist/actions/proxy.mjs +3 -0
  39. package/dist/actions/restore-log.d.mts +4 -0
  40. package/dist/actions/restore-log.mjs +3 -0
  41. package/dist/actions/schedule.d.mts +5 -0
  42. package/dist/actions/schedule.mjs +4 -0
  43. package/dist/actions/server.d.mts +8 -0
  44. package/dist/actions/server.mjs +7 -0
  45. package/dist/actions/sm.d.mts +4 -0
  46. package/dist/actions/sm.mjs +3 -0
  47. package/dist/actions/sr.d.mts +11 -0
  48. package/dist/actions/sr.mjs +10 -0
  49. package/dist/actions/task.d.mts +6 -0
  50. package/dist/actions/task.mjs +5 -0
  51. package/dist/actions/user.d.mts +12 -0
  52. package/dist/actions/user.mjs +11 -0
  53. package/dist/actions/vbd.d.mts +4 -0
  54. package/dist/actions/vbd.mjs +3 -0
  55. package/dist/actions/vdi-snapshot.d.mts +4 -0
  56. package/dist/actions/vdi-snapshot.mjs +3 -0
  57. package/dist/actions/vdi-unmanaged.d.mts +4 -0
  58. package/dist/actions/vdi-unmanaged.mjs +3 -0
  59. package/dist/actions/vdi.d.mts +12 -0
  60. package/dist/actions/vdi.mjs +11 -0
  61. package/dist/actions/vgpu.d.mts +4 -0
  62. package/dist/actions/vgpu.mjs +3 -0
  63. package/dist/actions/vgpuType.d.mts +4 -0
  64. package/dist/actions/vgpuType.mjs +3 -0
  65. package/dist/actions/vif.d.mts +5 -0
  66. package/dist/actions/vif.mjs +4 -0
  67. package/dist/actions/vm-controller.d.mts +7 -0
  68. package/dist/actions/vm-controller.mjs +6 -0
  69. package/dist/actions/vm-snapshot.d.mts +9 -0
  70. package/dist/actions/vm-snapshot.mjs +8 -0
  71. package/dist/actions/vm-template.d.mts +10 -0
  72. package/dist/actions/vm-template.mjs +9 -0
  73. package/dist/actions/vm.d.mts +24 -0
  74. package/dist/actions/vm.mjs +23 -0
  75. package/dist/actions/vtpm.d.mts +4 -0
  76. package/dist/actions/vtpm.mjs +3 -0
  77. package/dist/class/privilege.d.mts +25 -0
  78. package/dist/class/privilege.mjs +76 -0
  79. package/dist/generated/privilege-types.d.mts +378 -0
  80. package/dist/generated/privilege-types.mjs +5 -0
  81. package/dist/index.d.mts +40 -0
  82. package/dist/index.mjs +97 -0
  83. package/dist/tests/acl.test.d.mts +1 -0
  84. package/package.json +47 -0
  85. package/scripts/generate-types.mjs +55 -0
  86. package/tsconfig.json +19 -0
@@ -0,0 +1,378 @@
1
+ // -----------------------------------------------------------------------
2
+ // AUTO-GENERATED — do not edit manually.
3
+ // Regenerated on every `npm run build`.
4
+ // -----------------------------------------------------------------------
5
+ import type { XoAclBasePrivilege } from '@vates/types'
6
+
7
+
8
+ export type AclPrivilegePrivilege = {
9
+ id: XoAclBasePrivilege['id']
10
+ resource: 'acl-privilege'
11
+ action: '*' | 'create' | 'delete' | 'read' | 'update' | '*' | 'update:action' | 'update:effect' | 'update:resource' | 'update:selector'
12
+ selector?: XoAclBasePrivilege['selector']
13
+ effect: XoAclBasePrivilege['effect']
14
+ roleId: XoAclBasePrivilege['roleId']
15
+ }
16
+
17
+ export type AclRolePrivilege = {
18
+ id: XoAclBasePrivilege['id']
19
+ resource: 'acl-role'
20
+ action: '*' | 'create' | 'delete' | 'read' | 'update' | '*' | 'update:description' | 'update:groups' | 'update:name' | 'update:users'
21
+ selector?: XoAclBasePrivilege['selector']
22
+ effect: XoAclBasePrivilege['effect']
23
+ roleId: XoAclBasePrivilege['roleId']
24
+ }
25
+
26
+ export type AlarmPrivilege = {
27
+ id: XoAclBasePrivilege['id']
28
+ resource: 'alarm'
29
+ action: '*' | 'read'
30
+ selector?: XoAclBasePrivilege['selector']
31
+ effect: XoAclBasePrivilege['effect']
32
+ roleId: XoAclBasePrivilege['roleId']
33
+ }
34
+
35
+ export type BackupArchivePrivilege = {
36
+ id: XoAclBasePrivilege['id']
37
+ resource: 'backup-archive'
38
+ action: '*' | 'read'
39
+ selector?: XoAclBasePrivilege['selector']
40
+ effect: XoAclBasePrivilege['effect']
41
+ roleId: XoAclBasePrivilege['roleId']
42
+ }
43
+
44
+ export type BackupJobPrivilege = {
45
+ id: XoAclBasePrivilege['id']
46
+ resource: 'backup-job'
47
+ action: '*' | 'read'
48
+ selector?: XoAclBasePrivilege['selector']
49
+ effect: XoAclBasePrivilege['effect']
50
+ roleId: XoAclBasePrivilege['roleId']
51
+ }
52
+
53
+ export type BackupLogPrivilege = {
54
+ id: XoAclBasePrivilege['id']
55
+ resource: 'backup-log'
56
+ action: '*' | 'read'
57
+ selector?: XoAclBasePrivilege['selector']
58
+ effect: XoAclBasePrivilege['effect']
59
+ roleId: XoAclBasePrivilege['roleId']
60
+ }
61
+
62
+ export type BackupRepositoryPrivilege = {
63
+ id: XoAclBasePrivilege['id']
64
+ resource: 'backup-repository'
65
+ action: '*' | 'read'
66
+ selector?: XoAclBasePrivilege['selector']
67
+ effect: XoAclBasePrivilege['effect']
68
+ roleId: XoAclBasePrivilege['roleId']
69
+ }
70
+
71
+ export type GroupPrivilege = {
72
+ id: XoAclBasePrivilege['id']
73
+ resource: 'group'
74
+ action: '*' | 'create' | 'delete' | 'read' | 'update' | '*' | 'update:name' | 'update:users'
75
+ selector?: XoAclBasePrivilege['selector']
76
+ effect: XoAclBasePrivilege['effect']
77
+ roleId: XoAclBasePrivilege['roleId']
78
+ }
79
+
80
+ export type GpuGroupPrivilege = {
81
+ id: XoAclBasePrivilege['id']
82
+ resource: 'gpuGroup'
83
+ action: '*' | 'read'
84
+ selector?: XoAclBasePrivilege['selector']
85
+ effect: XoAclBasePrivilege['effect']
86
+ roleId: XoAclBasePrivilege['roleId']
87
+ }
88
+
89
+ export type HostPrivilege = {
90
+ id: XoAclBasePrivilege['id']
91
+ resource: 'host'
92
+ action: '*' | 'allow-vm' | 'export' | '*' | 'export:logs' | 'read' | 'update' | '*' | 'update:tags'
93
+ selector?: XoAclBasePrivilege['selector']
94
+ effect: XoAclBasePrivilege['effect']
95
+ roleId: XoAclBasePrivilege['roleId']
96
+ }
97
+
98
+ export type MessagePrivilege = {
99
+ id: XoAclBasePrivilege['id']
100
+ resource: 'message'
101
+ action: '*' | 'read'
102
+ selector?: XoAclBasePrivilege['selector']
103
+ effect: XoAclBasePrivilege['effect']
104
+ roleId: XoAclBasePrivilege['roleId']
105
+ }
106
+
107
+ export type NetworkPrivilege = {
108
+ id: XoAclBasePrivilege['id']
109
+ resource: 'network'
110
+ action: '*' | 'create' | 'delete' | 'read' | 'update' | '*' | 'update:tags'
111
+ selector?: XoAclBasePrivilege['selector']
112
+ effect: XoAclBasePrivilege['effect']
113
+ roleId: XoAclBasePrivilege['roleId']
114
+ }
115
+
116
+ export type PbdPrivilege = {
117
+ id: XoAclBasePrivilege['id']
118
+ resource: 'pbd'
119
+ action: '*' | 'read'
120
+ selector?: XoAclBasePrivilege['selector']
121
+ effect: XoAclBasePrivilege['effect']
122
+ roleId: XoAclBasePrivilege['roleId']
123
+ }
124
+
125
+ export type PciPrivilege = {
126
+ id: XoAclBasePrivilege['id']
127
+ resource: 'pci'
128
+ action: '*' | 'read'
129
+ selector?: XoAclBasePrivilege['selector']
130
+ effect: XoAclBasePrivilege['effect']
131
+ roleId: XoAclBasePrivilege['roleId']
132
+ }
133
+
134
+ export type PgpuPrivilege = {
135
+ id: XoAclBasePrivilege['id']
136
+ resource: 'pgpu'
137
+ action: '*' | 'read'
138
+ selector?: XoAclBasePrivilege['selector']
139
+ effect: XoAclBasePrivilege['effect']
140
+ roleId: XoAclBasePrivilege['roleId']
141
+ }
142
+
143
+ export type PifPrivilege = {
144
+ id: XoAclBasePrivilege['id']
145
+ resource: 'pif'
146
+ action: '*' | 'read'
147
+ selector?: XoAclBasePrivilege['selector']
148
+ effect: XoAclBasePrivilege['effect']
149
+ roleId: XoAclBasePrivilege['roleId']
150
+ }
151
+
152
+ export type PoolPrivilege = {
153
+ id: XoAclBasePrivilege['id']
154
+ resource: 'pool'
155
+ action: '*' | 'create' | '*' | 'create:network' | 'create:vm' | 'emergency-shutdown' | 'read' | 'rolling-reboot' | 'rolling-update' | 'update' | '*' | 'update:tags'
156
+ selector?: XoAclBasePrivilege['selector']
157
+ effect: XoAclBasePrivilege['effect']
158
+ roleId: XoAclBasePrivilege['roleId']
159
+ }
160
+
161
+ export type ProxyPrivilege = {
162
+ id: XoAclBasePrivilege['id']
163
+ resource: 'proxy'
164
+ action: '*' | 'read'
165
+ selector?: XoAclBasePrivilege['selector']
166
+ effect: XoAclBasePrivilege['effect']
167
+ roleId: XoAclBasePrivilege['roleId']
168
+ }
169
+
170
+ export type RestoreLogPrivilege = {
171
+ id: XoAclBasePrivilege['id']
172
+ resource: 'restore-log'
173
+ action: '*' | 'read'
174
+ selector?: XoAclBasePrivilege['selector']
175
+ effect: XoAclBasePrivilege['effect']
176
+ roleId: XoAclBasePrivilege['roleId']
177
+ }
178
+
179
+ export type SchedulePrivilege = {
180
+ id: XoAclBasePrivilege['id']
181
+ resource: 'schedule'
182
+ action: '*' | 'read' | 'run'
183
+ selector?: XoAclBasePrivilege['selector']
184
+ effect: XoAclBasePrivilege['effect']
185
+ roleId: XoAclBasePrivilege['roleId']
186
+ }
187
+
188
+ export type ServerPrivilege = {
189
+ id: XoAclBasePrivilege['id']
190
+ resource: 'server'
191
+ action: '*' | 'connect' | 'create' | 'delete' | 'disconnect' | 'read'
192
+ selector?: XoAclBasePrivilege['selector']
193
+ effect: XoAclBasePrivilege['effect']
194
+ roleId: XoAclBasePrivilege['roleId']
195
+ }
196
+
197
+ export type SmPrivilege = {
198
+ id: XoAclBasePrivilege['id']
199
+ resource: 'sm'
200
+ action: '*' | 'read'
201
+ selector?: XoAclBasePrivilege['selector']
202
+ effect: XoAclBasePrivilege['effect']
203
+ roleId: XoAclBasePrivilege['roleId']
204
+ }
205
+
206
+ export type SrPrivilege = {
207
+ id: XoAclBasePrivilege['id']
208
+ resource: 'sr'
209
+ action: '*' | 'import' | '*' | 'import:vdi' | 'import:vm' | 'read' | 'update' | '*' | 'update:tags'
210
+ selector?: XoAclBasePrivilege['selector']
211
+ effect: XoAclBasePrivilege['effect']
212
+ roleId: XoAclBasePrivilege['roleId']
213
+ }
214
+
215
+ export type TaskPrivilege = {
216
+ id: XoAclBasePrivilege['id']
217
+ resource: 'task'
218
+ action: '*' | 'abort' | 'delete' | 'read'
219
+ selector?: XoAclBasePrivilege['selector']
220
+ effect: XoAclBasePrivilege['effect']
221
+ roleId: XoAclBasePrivilege['roleId']
222
+ }
223
+
224
+ export type UserPrivilege = {
225
+ id: XoAclBasePrivilege['id']
226
+ resource: 'user'
227
+ action: '*' | 'create' | 'delete' | 'read' | 'update' | '*' | 'update:name' | 'update:password' | 'update:permission' | 'update:preferences'
228
+ selector?: XoAclBasePrivilege['selector']
229
+ effect: XoAclBasePrivilege['effect']
230
+ roleId: XoAclBasePrivilege['roleId']
231
+ }
232
+
233
+ export type VbdPrivilege = {
234
+ id: XoAclBasePrivilege['id']
235
+ resource: 'vbd'
236
+ action: '*' | 'read'
237
+ selector?: XoAclBasePrivilege['selector']
238
+ effect: XoAclBasePrivilege['effect']
239
+ roleId: XoAclBasePrivilege['roleId']
240
+ }
241
+
242
+ export type VdiSnapshotPrivilege = {
243
+ id: XoAclBasePrivilege['id']
244
+ resource: 'vdi-snapshot'
245
+ action: '*' | 'read'
246
+ selector?: XoAclBasePrivilege['selector']
247
+ effect: XoAclBasePrivilege['effect']
248
+ roleId: XoAclBasePrivilege['roleId']
249
+ }
250
+
251
+ export type VdiUnmanagedPrivilege = {
252
+ id: XoAclBasePrivilege['id']
253
+ resource: 'vdi-unmanaged'
254
+ action: '*' | 'read'
255
+ selector?: XoAclBasePrivilege['selector']
256
+ effect: XoAclBasePrivilege['effect']
257
+ roleId: XoAclBasePrivilege['roleId']
258
+ }
259
+
260
+ export type VdiPrivilege = {
261
+ id: XoAclBasePrivilege['id']
262
+ resource: 'vdi'
263
+ action: '*' | 'boot' | 'create' | 'delete' | 'export-content' | 'import-content' | 'read' | 'update' | '*' | 'update:tags'
264
+ selector?: XoAclBasePrivilege['selector']
265
+ effect: XoAclBasePrivilege['effect']
266
+ roleId: XoAclBasePrivilege['roleId']
267
+ }
268
+
269
+ export type VgpuPrivilege = {
270
+ id: XoAclBasePrivilege['id']
271
+ resource: 'vgpu'
272
+ action: '*' | 'read'
273
+ selector?: XoAclBasePrivilege['selector']
274
+ effect: XoAclBasePrivilege['effect']
275
+ roleId: XoAclBasePrivilege['roleId']
276
+ }
277
+
278
+ export type VgpuTypePrivilege = {
279
+ id: XoAclBasePrivilege['id']
280
+ resource: 'vgpuType'
281
+ action: '*' | 'read'
282
+ selector?: XoAclBasePrivilege['selector']
283
+ effect: XoAclBasePrivilege['effect']
284
+ roleId: XoAclBasePrivilege['roleId']
285
+ }
286
+
287
+ export type VifPrivilege = {
288
+ id: XoAclBasePrivilege['id']
289
+ resource: 'vif'
290
+ action: '*' | 'read' | 'create'
291
+ selector?: XoAclBasePrivilege['selector']
292
+ effect: XoAclBasePrivilege['effect']
293
+ roleId: XoAclBasePrivilege['roleId']
294
+ }
295
+
296
+ export type VmControllerPrivilege = {
297
+ id: XoAclBasePrivilege['id']
298
+ resource: 'vm-controller'
299
+ action: '*' | 'read' | 'update' | '*' | 'update:tags'
300
+ selector?: XoAclBasePrivilege['selector']
301
+ effect: XoAclBasePrivilege['effect']
302
+ roleId: XoAclBasePrivilege['roleId']
303
+ }
304
+
305
+ export type VmSnapshotPrivilege = {
306
+ id: XoAclBasePrivilege['id']
307
+ resource: 'vm-snapshot'
308
+ action: '*' | 'delete' | 'export' | 'read' | 'update' | '*' | 'update:tags'
309
+ selector?: XoAclBasePrivilege['selector']
310
+ effect: XoAclBasePrivilege['effect']
311
+ roleId: XoAclBasePrivilege['roleId']
312
+ }
313
+
314
+ export type VmTemplatePrivilege = {
315
+ id: XoAclBasePrivilege['id']
316
+ resource: 'vm-template'
317
+ action: '*' | 'delete' | 'export' | 'instantiate' | 'read' | 'update' | '*' | 'update:tags'
318
+ selector?: XoAclBasePrivilege['selector']
319
+ effect: XoAclBasePrivilege['effect']
320
+ roleId: XoAclBasePrivilege['roleId']
321
+ }
322
+
323
+ export type VmPrivilege = {
324
+ id: XoAclBasePrivilege['id']
325
+ resource: 'vm'
326
+ action: '*' | 'delete' | 'export' | 'pause' | 'read' | 'reboot' | '*' | 'reboot:clean' | 'reboot:hard' | 'resume' | 'shutdown' | '*' | 'shutdown:clean' | 'shutdown:hard' | 'snapshot' | 'start' | 'suspend' | 'unpause' | 'update' | '*' | 'update:datasources' | 'update:tags'
327
+ selector?: XoAclBasePrivilege['selector']
328
+ effect: XoAclBasePrivilege['effect']
329
+ roleId: XoAclBasePrivilege['roleId']
330
+ }
331
+
332
+ export type VtpmPrivilege = {
333
+ id: XoAclBasePrivilege['id']
334
+ resource: 'vtpm'
335
+ action: '*' | 'read'
336
+ selector?: XoAclBasePrivilege['selector']
337
+ effect: XoAclBasePrivilege['effect']
338
+ roleId: XoAclBasePrivilege['roleId']
339
+ }
340
+
341
+ export type AnyPrivilege =
342
+ | AclPrivilegePrivilege
343
+ | AclRolePrivilege
344
+ | AlarmPrivilege
345
+ | BackupArchivePrivilege
346
+ | BackupJobPrivilege
347
+ | BackupLogPrivilege
348
+ | BackupRepositoryPrivilege
349
+ | GroupPrivilege
350
+ | GpuGroupPrivilege
351
+ | HostPrivilege
352
+ | MessagePrivilege
353
+ | NetworkPrivilege
354
+ | PbdPrivilege
355
+ | PciPrivilege
356
+ | PgpuPrivilege
357
+ | PifPrivilege
358
+ | PoolPrivilege
359
+ | ProxyPrivilege
360
+ | RestoreLogPrivilege
361
+ | SchedulePrivilege
362
+ | ServerPrivilege
363
+ | SmPrivilege
364
+ | SrPrivilege
365
+ | TaskPrivilege
366
+ | UserPrivilege
367
+ | VbdPrivilege
368
+ | VdiSnapshotPrivilege
369
+ | VdiUnmanagedPrivilege
370
+ | VdiPrivilege
371
+ | VgpuPrivilege
372
+ | VgpuTypePrivilege
373
+ | VifPrivilege
374
+ | VmControllerPrivilege
375
+ | VmSnapshotPrivilege
376
+ | VmTemplatePrivilege
377
+ | VmPrivilege
378
+ | VtpmPrivilege
@@ -0,0 +1,5 @@
1
+ // DO NOT EDIT
2
+ // Overwritten by scripts/generate-types.mjs after running npm run build
3
+ // scripts/generate-types.mjs will replace this file to automatically generate and export all privileged types.
4
+ // This makes external use easier because it's not necessary to resolve the type every time.
5
+ export {};
@@ -0,0 +1,40 @@
1
+ import type { XoUser } from '@vates/types/xo';
2
+ import { SUPPORTED_ACTIONS_BY_RESOURCE } from './actions/index.mjs';
3
+ import { TPrivilege as Privilege, SupportedActions, SupportedActionsByResource, SupportedResource } from './class/privilege.mjs';
4
+ export type { Privilege, SupportedActions, SupportedActionsByResource, SupportedResource };
5
+ export { SUPPORTED_ACTIONS_BY_RESOURCE };
6
+ export type * from './generated/privilege-types.mjs';
7
+ import { AnyPrivilege } from './generated/privilege-types.mjs';
8
+ export type AnyPrivilegeOnParam = {
9
+ [Resource in SupportedResource]: {
10
+ user: XoUser;
11
+ resource: Resource;
12
+ action: SupportedActions<Resource>;
13
+ objects: object | object[];
14
+ };
15
+ }[SupportedResource];
16
+ export declare function hasPrivilegeOn<T extends SupportedResource>({ user, action, resource, objects, userPrivileges, }: {
17
+ user: XoUser;
18
+ resource: T;
19
+ action: SupportedActions<T>;
20
+ objects: object | object[];
21
+ userPrivileges: AnyPrivilege[];
22
+ }): boolean;
23
+ export declare function getMissingPrivileges(params: AnyPrivilegeOnParam[], userPrivileges: AnyPrivilege[]): {
24
+ objectId: unknown;
25
+ objectIds: unknown[] | undefined;
26
+ action: "create" | "delete" | "read" | "update" | "allow-vm" | "export" | "emergency-shutdown" | "rolling-reboot" | "rolling-update" | "run" | "connect" | "disconnect" | "import" | "abort" | "boot" | "export-content" | "import-content" | "instantiate" | "pause" | "reboot" | "resume" | "shutdown" | "snapshot" | "start" | "suspend" | "unpause" | "*" | "update:action" | "update:resource" | "update:effect" | "update:selector" | "update:description" | "update:groups" | "update:name" | "update:users" | "update:tags" | "export:logs" | "create:network" | "create:vm" | "import:vdi" | "import:vm" | "update:password" | "update:permission" | "update:preferences" | "update:datasources" | "reboot:clean" | "reboot:hard" | "shutdown:clean" | "shutdown:hard";
27
+ resource: "acl-privilege" | "acl-role" | "alarm" | "backup-archive" | "backup-job" | "backup-log" | "backup-repository" | "group" | "gpuGroup" | "host" | "message" | "network" | "pbd" | "pci" | "pgpu" | "pif" | "pool" | "proxy" | "restore-log" | "schedule" | "server" | "sm" | "sr" | "task" | "user" | "vbd" | "vdi-snapshot" | "vdi-unmanaged" | "vdi" | "vgpu" | "vgpuType" | "vif" | "vm-controller" | "vm-snapshot" | "vm-template" | "vm" | "vtpm";
28
+ }[];
29
+ export declare function hasPrivileges(params: AnyPrivilegeOnParam[], userPrivileges: AnyPrivilege[]): boolean;
30
+ export declare function filterObjectsWithPrivilege<Resource extends SupportedResource, Object extends object>(param: {
31
+ user: XoUser;
32
+ resource: Resource;
33
+ action: SupportedActions<Resource>;
34
+ objects: Object[];
35
+ userPrivileges: AnyPrivilege[];
36
+ }): Object[];
37
+ /**
38
+ * Mirror GetKeysRecursively from @vates/types
39
+ */
40
+ export declare function getActionStrings<Resource extends SupportedResource, Actions = SupportedActions<Resource>>(resource: Resource): Actions[];
package/dist/index.mjs ADDED
@@ -0,0 +1,97 @@
1
+ import assert from 'node:assert';
2
+ import { SUPPORTED_ACTIONS_BY_RESOURCE } from './actions/index.mjs';
3
+ import { Privilege as CPrivilege, } from './class/privilege.mjs';
4
+ export { SUPPORTED_ACTIONS_BY_RESOURCE };
5
+ export function hasPrivilegeOn({ user, action, resource, objects, userPrivileges, }) {
6
+ // Function that will be called outside of the module
7
+ // We cannot be sure types are respected
8
+ assert.strictEqual(typeof user?.permission, 'string');
9
+ assert.strictEqual(typeof action, 'string');
10
+ assert.strictEqual(typeof resource, 'string');
11
+ assert.strictEqual(objects === undefined, false);
12
+ CPrivilege.checkActionIsValid(resource, action);
13
+ if (user.permission === 'admin') {
14
+ return true;
15
+ }
16
+ const effectsByObject = new Map();
17
+ if (Array.isArray(objects)) {
18
+ objects.forEach(obj => effectsByObject.set(obj, []));
19
+ }
20
+ else {
21
+ effectsByObject.set(objects, []);
22
+ }
23
+ for (const userPrivilege of userPrivileges) {
24
+ const privilege = new CPrivilege(userPrivilege);
25
+ for (const [object, effects] of effectsByObject.entries()) {
26
+ if (!privilege.match({ action, resource, object })) {
27
+ continue;
28
+ }
29
+ effects.push(privilege.effect);
30
+ }
31
+ }
32
+ if (Array.from(effectsByObject.values()).some(effects => effects.length === 0 || effects.some(effect => effect === 'deny'))) {
33
+ return false;
34
+ }
35
+ return true;
36
+ }
37
+ export function getMissingPrivileges(params, userPrivileges) {
38
+ return params
39
+ .filter(param => !hasPrivilegeOn({
40
+ user: param.user,
41
+ resource: param.resource,
42
+ action: param.action,
43
+ objects: param.objects,
44
+ userPrivileges,
45
+ }))
46
+ .map(({ action, objects, resource }) => {
47
+ let objectIds;
48
+ let objectId;
49
+ if (Array.isArray(objects)) {
50
+ if (objects.length > 1) {
51
+ objectIds = [];
52
+ objects.forEach(obj => {
53
+ if ('id' in obj) {
54
+ objectIds.push(obj.id);
55
+ }
56
+ });
57
+ }
58
+ else {
59
+ objects = objects?.[0] ?? {};
60
+ }
61
+ }
62
+ if (!Array.isArray(objects)) {
63
+ objectId = 'id' in objects ? objects.id : undefined;
64
+ }
65
+ return {
66
+ objectId,
67
+ objectIds,
68
+ action,
69
+ resource,
70
+ };
71
+ });
72
+ }
73
+ export function hasPrivileges(params, userPrivileges) {
74
+ return getMissingPrivileges(params, userPrivileges).length === 0;
75
+ }
76
+ export function filterObjectsWithPrivilege(param) {
77
+ return param.objects.filter(obj => hasPrivilegeOn({ ...param, objects: obj }));
78
+ }
79
+ // Utils
80
+ /**
81
+ * Mirror GetKeysRecursively from @vates/types
82
+ */
83
+ export function getActionStrings(resource) {
84
+ function collectActions(obj, prefix) {
85
+ const actions = ['*'];
86
+ for (const [key, value] of Object.entries(obj)) {
87
+ const action = (prefix !== undefined ? `${prefix}:${key}` : key);
88
+ actions.push(action);
89
+ if (typeof value === 'boolean') {
90
+ continue;
91
+ }
92
+ actions.push(...collectActions(value, action));
93
+ }
94
+ return actions;
95
+ }
96
+ return collectActions(SUPPORTED_ACTIONS_BY_RESOURCE[resource]);
97
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "author": {
3
+ "name": "Vates SAS",
4
+ "url": "https://vates.fr"
5
+ },
6
+ "main": "dist/index.mjs",
7
+ "name": "@xen-orchestra/acl",
8
+ "homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/acl",
9
+ "version": "1.0.0",
10
+ "license": "AGPL-3.0-or-later",
11
+ "private": false,
12
+ "type": "module",
13
+ "engines": {
14
+ "node": ">= 20.18"
15
+ },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.mts",
19
+ "default": "./dist/index.mjs"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "build": "tsc && node scripts/generate-types.mjs",
24
+ "clean": "rimraf dist/",
25
+ "dev": "tsc --watch",
26
+ "postversion": "npm publish --access public",
27
+ "test": "npm run build && node --test ./dist/**/*.test.mjs",
28
+ "prebuild": "npm run clean",
29
+ "prepublishOnly": "npm run build"
30
+ },
31
+ "devDependencies": {
32
+ "@eslint/js": "^9.19.0",
33
+ "@vates/types": "^1.24.0",
34
+ "rimraf": "^6.0.1",
35
+ "typescript": "~5.6",
36
+ "typescript-eslint": "^8.23.0"
37
+ },
38
+ "bugs": "https://github.com/vatesfr/xen-orchestra/issues",
39
+ "repository": {
40
+ "directory": "@xen-orchestra/acl",
41
+ "type": "git",
42
+ "url": "https://github.com/vatesfr/xen-orchestra.git"
43
+ },
44
+ "dependencies": {
45
+ "complex-matcher": "^1.0.0"
46
+ }
47
+ }
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ // AUTO-GENERATES dist/generated/privilege-types.d.mts
3
+ // Run via `npm run build` (after tsc).
4
+
5
+ import { mkdirSync, writeFileSync } from 'node:fs'
6
+ import { dirname, join } from 'node:path'
7
+ import { fileURLToPath } from 'node:url'
8
+
9
+ import { SUPPORTED_ACTIONS_BY_RESOURCE } from '../dist/actions/index.mjs'
10
+ import { getActionStrings } from '../dist/index.mjs'
11
+
12
+ function toPascalCase(str) {
13
+ return str
14
+ .split(/[-_]/)
15
+ .map(s => s.charAt(0).toUpperCase() + s.slice(1))
16
+ .join('')
17
+ }
18
+
19
+ const resources = Object.keys(SUPPORTED_ACTIONS_BY_RESOURCE)
20
+
21
+ const typeBlocks = resources.map(resource => {
22
+ const actionUnion = getActionStrings(resource)
23
+ .map(action => `'${action}'`)
24
+ .join(' | ')
25
+ return `export type ${toPascalCase(resource)}Privilege = {
26
+ id: XoAclBasePrivilege['id']
27
+ resource: '${resource}'
28
+ action: ${actionUnion}
29
+ selector?: XoAclBasePrivilege['selector']
30
+ effect: XoAclBasePrivilege['effect']
31
+ roleId: XoAclBasePrivilege['roleId']
32
+ }`
33
+ })
34
+
35
+ const anyUnion = resources.map(resource => ` | ${toPascalCase(resource)}Privilege`).join('\n')
36
+
37
+ const types = `\
38
+ // -----------------------------------------------------------------------
39
+ // AUTO-GENERATED — do not edit manually.
40
+ // Regenerated on every \`npm run build\`.
41
+ // -----------------------------------------------------------------------
42
+ import type { XoAclBasePrivilege } from '@vates/types'
43
+
44
+
45
+ ${typeBlocks.join('\n\n')}
46
+
47
+ export type AnyPrivilege =
48
+ ${anyUnion}
49
+ `
50
+
51
+ const root = join(dirname(fileURLToPath(import.meta.url)), '..')
52
+ const outDir = join(root, 'dist/generated')
53
+
54
+ mkdirSync(outDir, { recursive: true })
55
+ writeFileSync(join(outDir, 'privilege-types.d.mts'), types, 'utf-8')
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./dist",
4
+ "rootDir": "./src",
5
+
6
+ "strict": true,
7
+ "module": "nodenext",
8
+ "lib": ["ESNext"],
9
+ "moduleResolution": "nodenext",
10
+ "target": "ES2022",
11
+ "skipLibCheck": true,
12
+ "types": ["node"], // Only use types from Node.js and packages that are explicitly imported
13
+ "noImplicitAny": false, // otherwise it will throw an error when importing packages without type definition
14
+ "noUncheckedIndexedAccess": true,
15
+ "declaration": true
16
+ },
17
+ "include": ["./src/**/*"],
18
+ "exclude": ["./node_modules", "./dist"]
19
+ }