@xen-orchestra/rest-api 0.28.2 → 0.30.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 (55) hide show
  1. package/README.md +108 -1
  2. package/dist/abstract-classes/base-controller.mjs +28 -3
  3. package/dist/abstract-classes/listener.mjs +124 -15
  4. package/dist/acl-privileges/acl-privilege.controller.mjs +172 -0
  5. package/dist/acl-roles/acl-role.controller.mjs +384 -0
  6. package/dist/alarms/alarm.controller.mjs +25 -11
  7. package/dist/alarms/alarm.service.mjs +8 -0
  8. package/dist/backup-archives/backup-archive.controller.mjs +33 -23
  9. package/dist/backup-archives/backup-archive.service.mjs +21 -0
  10. package/dist/backup-jobs/backup-job.controller.mjs +74 -25
  11. package/dist/backup-jobs/backup-job.service.mjs +7 -0
  12. package/dist/backup-logs/backup-log.controller.mjs +28 -13
  13. package/dist/backup-logs/backup-log.service.mjs +19 -0
  14. package/dist/backup-repositories/backup-repositories.controller.mjs +24 -5
  15. package/dist/events/event.class.mjs +36 -18
  16. package/dist/events/event.controller.mjs +3 -0
  17. package/dist/events/event.service.mjs +4 -4
  18. package/dist/groups/group.controller.mjs +99 -12
  19. package/dist/helpers/markdown.helper.mjs +20 -0
  20. package/dist/helpers/object-wrapper.helper.mjs +3 -3
  21. package/dist/hosts/host.controller.mjs +90 -15
  22. package/dist/ioc/ioc.mjs +13 -4
  23. package/dist/messages/message.controller.mjs +32 -10
  24. package/dist/middlewares/acl.middleware.mjs +202 -0
  25. package/dist/middlewares/authentication.middleware.mjs +15 -6
  26. package/dist/middlewares/tsoa-to-xo-error.middleware.mjs +19 -1
  27. package/dist/networks/network.controller.mjs +72 -17
  28. package/dist/open-api/oa-examples/acl-privilege.oa-example.mjs +25 -0
  29. package/dist/open-api/oa-examples/acl-role.oa-example.mjs +22 -0
  30. package/dist/open-api/oa-examples/backup-archive.oa-example.mjs +6 -6
  31. package/dist/open-api/oa-examples/common.oa-example.mjs +3 -0
  32. package/dist/open-api/routes/routes.js +856 -172
  33. package/dist/pbds/pbd.controller.mjs +20 -5
  34. package/dist/pcis/pci.controller.mjs +19 -5
  35. package/dist/pgpus/pgpu.controller.mjs +19 -5
  36. package/dist/pifs/pif.controller.mjs +56 -16
  37. package/dist/pools/pool.controller.mjs +166 -17
  38. package/dist/proxies/proxy.controller.mjs +25 -6
  39. package/dist/restore-logs/restore-log.controller.mjs +42 -23
  40. package/dist/schedules/schedule.controller.mjs +36 -5
  41. package/dist/servers/server.controller.mjs +71 -9
  42. package/dist/sms/sm.controller.mjs +17 -4
  43. package/dist/srs/sr.controller.mjs +74 -18
  44. package/dist/tasks/task.controller.mjs +74 -13
  45. package/dist/users/user.controller.mjs +124 -22
  46. package/dist/vbds/vbd.controller.mjs +76 -38
  47. package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +48 -14
  48. package/dist/vdis/vdi.controller.mjs +81 -16
  49. package/dist/vifs/vif.controller.mjs +118 -16
  50. package/dist/vm-controller/vm-controller.controller.mjs +77 -19
  51. package/dist/vm-snapshots/vm-snapshot.controller.mjs +85 -18
  52. package/dist/vm-templates/vm-template.controller.mjs +86 -18
  53. package/dist/vms/vm.controller.mjs +182 -24
  54. package/open-api/spec/swagger.json +12112 -3537
  55. package/package.json +12 -11
@@ -8,8 +8,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
8
8
  return function (target, key) { decorator(target, key, paramIndex); }
9
9
  };
10
10
  import { XoController } from '../abstract-classes/xo-controller.mjs';
11
- import { Get, Path, Query, Request, Route, Security, Tags, Response, Example, Delete, Post, SuccessResponse, } from 'tsoa';
12
- import { asynchronousActionResp, badRequestResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
11
+ import { Get, Path, Query, Request, Route, Security, Tags, Response, Example, Delete, Post, SuccessResponse, Middlewares, } from 'tsoa';
12
+ import { acl } from '../middlewares/acl.middleware.mjs';
13
+ import { asynchronousActionResp, badRequestResp, forbiddenOperationResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
13
14
  import { inject } from 'inversify';
14
15
  import { provide } from 'inversify-binding-decorators';
15
16
  import { partialTasks, task, taskIds, taskLocation } from '../open-api/oa-examples/task.oa-example.mjs';
@@ -19,6 +20,7 @@ import { Transform } from 'node:stream';
19
20
  import { makeObjectMapper } from '../helpers/object-wrapper.helper.mjs';
20
21
  import { safeParseComplexMatcher } from '../helpers/utils.helper.mjs';
21
22
  import { RestApi } from '../rest-api/rest-api.mjs';
23
+ import { hasPrivilegeOn } from '@xen-orchestra/acl';
22
24
  let TaskController = class TaskController extends XoController {
23
25
  constructor(restApi) {
24
26
  super('task', restApi);
@@ -34,6 +36,8 @@ let TaskController = class TaskController extends XoController {
34
36
  return this.restApi.tasks.get(id);
35
37
  }
36
38
  /**
39
+ * Returns all tasks that match the following privilege:
40
+ * - resource: task, action: read
37
41
  *
38
42
  * If watch is true, ndjson must also be true
39
43
  *
@@ -41,7 +45,7 @@ let TaskController = class TaskController extends XoController {
41
45
  * @example filter "status:failure"
42
46
  * @example limit 42
43
47
  */
44
- async getTasks(req, fields, ndjson, watch, filter, limit) {
48
+ async getTasks(req, fields, ndjson, markdown, watch, filter, limit) {
45
49
  if (watch) {
46
50
  if (!ndjson) {
47
51
  throw new ApiError('watch=true requires ndjson=true', 400);
@@ -63,21 +67,36 @@ let TaskController = class TaskController extends XoController {
63
67
  process.on('SIGTERM', () => {
64
68
  req.destroy();
65
69
  });
66
- function update(task) {
67
- if (userFilter === undefined || userFilter(task)) {
70
+ const userId = this.restApi.getCurrentUser().id;
71
+ const update = async (task) => {
72
+ const user = await this.restApi.xoApp.getUser(userId);
73
+ const userPrivileges = (await this.restApi.xoApp.getAclV2UserPrivileges(user.id));
74
+ if (hasPrivilegeOn({ user, userPrivileges, action: 'read', resource: 'task', objects: task }) &&
75
+ (userFilter === undefined || userFilter(task))) {
68
76
  stream.write(['update', task]);
69
77
  }
70
- }
71
- function remove(task) {
72
- stream.write(['remove', { id: task.id }]);
73
- }
78
+ };
79
+ const remove = async (task) => {
80
+ const user = await this.restApi.xoApp.getUser(userId);
81
+ const userPrivileges = (await this.restApi.xoApp.getAclV2UserPrivileges(user.id));
82
+ if (hasPrivilegeOn({ user, userPrivileges, action: 'read', resource: 'task', objects: task }) &&
83
+ (userFilter === undefined || userFilter(task))) {
84
+ stream.write(['remove', { id: task.id }]);
85
+ }
86
+ };
74
87
  this.restApi.tasks.on('update', update).on('remove', remove);
75
88
  return stream;
76
89
  }
77
- const tasks = Object.values(await this.getObjects({ filter, limit }));
78
- return this.sendObjects(tasks, req);
90
+ const tasks = Object.values(await this.getObjects({ filter }));
91
+ return this.sendObjects(tasks, req, {
92
+ limit,
93
+ privilege: { action: 'read', resource: 'task' },
94
+ });
79
95
  }
80
96
  /**
97
+ * Required privilege:
98
+ * - resource: task, action: read
99
+ *
81
100
  * @example id "0mdd1basu"
82
101
  */
83
102
  async getTask(req, id, wait) {
@@ -95,10 +114,25 @@ let TaskController = class TaskController extends XoController {
95
114
  }
96
115
  return this.getObject(taskId);
97
116
  }
117
+ /**
118
+ * Deletes all tasks the current user has the following privilege on:
119
+ * - resource: task, action: delete
120
+ */
98
121
  async deleteTasks() {
99
- await this.restApi.tasks.clearLogs();
122
+ const user = this.restApi.getCurrentUser();
123
+ const userPrivileges = (await this.restApi.xoApp.getAclV2UserPrivileges(user.id));
124
+ const deletePromises = [];
125
+ for await (const task of this.restApi.tasks.list()) {
126
+ if (hasPrivilegeOn({ user, userPrivileges, resource: 'task', action: 'delete', objects: task })) {
127
+ deletePromises.push(this.restApi.tasks.deleteLog(task.id));
128
+ }
129
+ }
130
+ await Promise.all(deletePromises);
100
131
  }
101
132
  /**
133
+ * Required privilege:
134
+ * - resource: task, action: delete
135
+ *
102
136
  * @example id "0mdd1basu"
103
137
  */
104
138
  async deleteTask(id) {
@@ -106,6 +140,9 @@ let TaskController = class TaskController extends XoController {
106
140
  await this.restApi.tasks.deleteLog(task.id);
107
141
  }
108
142
  /**
143
+ * Required privilege:
144
+ * - resource: task, action: abort
145
+ *
109
146
  * @example id "0mdd1basu"
110
147
  */
111
148
  async abortTask(id, sync) {
@@ -127,17 +164,26 @@ __decorate([
127
164
  Example(taskIds),
128
165
  Example(partialTasks),
129
166
  Get(''),
167
+ Security('*', ['acl']),
130
168
  Response(badRequestResp.status, badRequestResp.description),
131
169
  __param(0, Request()),
132
170
  __param(1, Query()),
133
171
  __param(2, Query()),
134
172
  __param(3, Query()),
135
173
  __param(4, Query()),
136
- __param(5, Query())
174
+ __param(5, Query()),
175
+ __param(6, Query())
137
176
  ], TaskController.prototype, "getTasks", null);
138
177
  __decorate([
139
178
  Example(task),
140
179
  Get('{id}'),
180
+ Middlewares(acl({
181
+ resource: 'task',
182
+ action: 'read',
183
+ objectId: 'params.id',
184
+ getObject: ({ restApi }) => restApi.xoApp.tasks.get.bind(restApi.xoApp.tasks),
185
+ })),
186
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
141
187
  Response(notFoundResp.status, notFoundResp.description),
142
188
  __param(0, Request()),
143
189
  __param(1, Path()),
@@ -145,19 +191,34 @@ __decorate([
145
191
  ], TaskController.prototype, "getTask", null);
146
192
  __decorate([
147
193
  Delete(''),
194
+ Security('*', ['acl']),
148
195
  SuccessResponse(noContentResp.status, noContentResp.description)
149
196
  ], TaskController.prototype, "deleteTasks", null);
150
197
  __decorate([
151
198
  Delete('{id}'),
199
+ Middlewares(acl({
200
+ resource: 'task',
201
+ action: 'delete',
202
+ objectId: 'params.id',
203
+ getObject: ({ restApi }) => restApi.xoApp.tasks.get.bind(restApi.xoApp.tasks),
204
+ })),
152
205
  SuccessResponse(noContentResp.status, noContentResp.description),
206
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
153
207
  Response(notFoundResp.status, notFoundResp.description),
154
208
  __param(0, Path())
155
209
  ], TaskController.prototype, "deleteTask", null);
156
210
  __decorate([
157
211
  Example(taskLocation),
158
212
  Post('{id}/actions/abort'),
213
+ Middlewares(acl({
214
+ resource: 'task',
215
+ action: 'abort',
216
+ objectId: 'params.id',
217
+ getObject: ({ restApi }) => restApi.xoApp.tasks.get.bind(restApi.xoApp.tasks),
218
+ })),
159
219
  SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description),
160
220
  Response(noContentResp.status, noContentResp.description),
221
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
161
222
  Response(notFoundResp.status, notFoundResp.description),
162
223
  __param(0, Path()),
163
224
  __param(1, Query())
@@ -9,11 +9,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
9
9
  };
10
10
  import { Body, Delete, Deprecated, Example, Get, Middlewares, Patch, Path, Post, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
11
11
  import { createLogger } from '@xen-orchestra/log';
12
+ import { forbiddenOperation } from 'xo-common/api-errors.js';
12
13
  import { inject } from 'inversify';
13
14
  import { json } from 'express';
14
15
  import { provide } from 'inversify-binding-decorators';
16
+ import { acl, actionIfNotSelfUser, actionsFromBody } from '../middlewares/acl.middleware.mjs';
15
17
  import { badRequestResp, createdResp, forbiddenOperationResp, internalServerErrorResp, invalidParameters, noContentResp, notFoundResp, resourceAlreadyExists, unauthorizedResp, } from '../open-api/common/response.common.mjs';
16
- import { forbiddenOperation } from 'xo-common/api-errors.js';
17
18
  import { partialUsers, user, authenticationTokens, userId, userIds, authenticationToken, } from '../open-api/oa-examples/user.oa-example.mjs';
18
19
  import { RestApi } from '../rest-api/rest-api.mjs';
19
20
  import { limitAndFilterArray } from '../helpers/utils.helper.mjs';
@@ -22,6 +23,7 @@ import { XoController } from '../abstract-classes/xo-controller.mjs';
22
23
  import { groupIds, partialGroups } from '../open-api/oa-examples/group.oa-example.mjs';
23
24
  import { partialTasks, taskIds } from '../open-api/oa-examples/task.oa-example.mjs';
24
25
  import { redirectMeAlias } from './user.middleware.mjs';
26
+ import { aclPrivilegeIds, partialAclPrivileges } from '../open-api/oa-examples/acl-privilege.oa-example.mjs';
25
27
  const log = createLogger('xo:rest-api:user-controller');
26
28
  let UserController = class UserController extends XoController {
27
29
  #userService;
@@ -37,21 +39,39 @@ let UserController = class UserController extends XoController {
37
39
  return this.#userService.getUser(id);
38
40
  }
39
41
  /**
42
+ * Returns all users that match the following privilege:
43
+ * - resource: user, action: read
44
+ *
40
45
  * @example fields "permission,name,id"
41
46
  * @example filter "permission:none"
42
47
  * @example limit 42
43
48
  */
44
- async getUsers(req, fields, ndjson, filter, limit) {
45
- const users = Object.values(await this.getObjects({ filter, limit }));
46
- return this.sendObjects(users, req);
49
+ async getUsers(req, fields, ndjson, markdown, filter, limit) {
50
+ const users = Object.values(await this.getObjects({ filter }));
51
+ return this.sendObjects(users, req, {
52
+ limit,
53
+ privilege: { action: 'read', resource: 'user' },
54
+ });
47
55
  }
48
56
  /**
57
+ * Required privilege:
58
+ * - resource: user, action: read (if not self)
59
+ *
49
60
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
50
61
  */
51
62
  getUser(id) {
52
63
  return this.getObject(id);
53
64
  }
54
65
  /**
66
+ * You cannot change your own `permission` (even with the right privilege)
67
+ *
68
+ * Required privileges:
69
+ * - resource: user, action: update (grants all fields)
70
+ * - resource: user, action: update:name (if name is passed)
71
+ * - resource: user, action: update:password (if password is passed)
72
+ * - resource: user, action: update:permission (if permission is passed)
73
+ * - resource: user, action: update:preferences (if preferences is passed)
74
+ *
55
75
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
56
76
  * @example body {
57
77
  * "name": "updated user name",
@@ -62,14 +82,8 @@ let UserController = class UserController extends XoController {
62
82
  */
63
83
  async updateUser(id, body) {
64
84
  const currentUser = this.restApi.getCurrentUser();
65
- const isAdmin = currentUser.permission === 'admin';
66
- if (isAdmin) {
67
- if (body.permission !== undefined && currentUser.id === id) {
68
- throw forbiddenOperation('update user', 'cannot change own permission');
69
- }
70
- }
71
- else if (body.name !== undefined || body.password !== undefined || body.permission !== undefined) {
72
- throw forbiddenOperation('update user', 'cannot change these fields without admin rights');
85
+ if (body.permission !== undefined && currentUser.id === id) {
86
+ throw forbiddenOperation('update user', 'cannot change own permission');
73
87
  }
74
88
  const user = await this.getObject(id);
75
89
  if (user.authProviders !== undefined &&
@@ -80,6 +94,9 @@ let UserController = class UserController extends XoController {
80
94
  await this.restApi.xoApp.updateUser(user.id, body);
81
95
  }
82
96
  /**
97
+ * Required privilege:
98
+ * - resource: user, action: create
99
+ *
83
100
  * @example body { "name": "new user", "password": "password", "permission": "none" }
84
101
  */
85
102
  async createUser(body) {
@@ -87,23 +104,35 @@ let UserController = class UserController extends XoController {
87
104
  return { id: user.id };
88
105
  }
89
106
  /**
107
+ * Required privilege:
108
+ * - resource: user, action: delete
109
+ *
90
110
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
91
111
  */
92
112
  async deleteUser(id) {
93
113
  await this.restApi.xoApp.deleteUser(id);
94
114
  }
95
115
  /**
116
+ * Returns all groups that match the following privilege:
117
+ * - resource: group, action: read
118
+ *
96
119
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
97
120
  * @example fields "name,id,users"
98
121
  * @example filter "users:length:>0"
99
122
  * @example limit 42
100
123
  */
101
- async getUserGroups(req, id, fields, ndjson, filter, limit) {
124
+ async getUserGroups(req, id, fields, ndjson, markdown, filter, limit) {
102
125
  const user = await this.getObject(id);
103
126
  const groups = await Promise.all(user.groups.map(group => this.restApi.xoApp.getGroup(group)));
104
- return this.sendObjects(limitAndFilterArray(groups, { filter, limit }), req, 'groups');
127
+ return this.sendObjects(limitAndFilterArray(groups, { filter }), req, {
128
+ path: 'groups',
129
+ limit,
130
+ privilege: { action: 'read', resource: 'group' },
131
+ });
105
132
  }
106
133
  /**
134
+ * You can only see your own authentication tokens
135
+ *
107
136
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
108
137
  * @example filter "expiration:>1757371582496"
109
138
  * @example limit 42
@@ -118,14 +147,21 @@ let UserController = class UserController extends XoController {
118
147
  return limitAndFilterArray(tokens, { filter, limit });
119
148
  }
120
149
  /**
150
+ * Returns all tasks that match the following privilege:
151
+ * - resource: task, action: read
152
+ *
121
153
  * @example id "722d17b9-699b-49d2-8193-be1ac573d3de"
122
154
  * @example fields "id,status,properties"
123
155
  * @example filter "status:failure"
124
156
  * @example limit 42
125
157
  */
126
- async getUserTasks(req, id, fields, ndjson, filter, limit) {
127
- const tasks = await this.getTasksForObject(id, { filter, limit });
128
- return this.sendObjects(Object.values(tasks), req, 'tasks');
158
+ async getUserTasks(req, id, fields, ndjson, markdown, filter, limit) {
159
+ const tasks = await this.getTasksForObject(id, { filter });
160
+ return this.sendObjects(Object.values(tasks), req, {
161
+ path: 'tasks',
162
+ limit,
163
+ privilege: { action: 'read', resource: 'task' },
164
+ });
129
165
  }
130
166
  // ----------- DEPRECATED TO BE REMOVED IN ONE YEAR (10-13-2026)--------------------
131
167
  /**
@@ -142,6 +178,8 @@ let UserController = class UserController extends XoController {
142
178
  }
143
179
  // ----------- DEPRECATED TO BE REMOVED IN ONE YEAR (10-13-2026)--------------------
144
180
  /**
181
+ * You can only create authentication token for yourself
182
+ *
145
183
  * @example id "me"
146
184
  * @example body {"client": {"id": "my-fav-client"}, "description": "token for CLI usage", "expiresIn": "1 hour"}
147
185
  */
@@ -156,26 +194,62 @@ let UserController = class UserController extends XoController {
156
194
  });
157
195
  return { token };
158
196
  }
197
+ /**
198
+ * Returns all ACL privileges that match the following privilege:
199
+ * - resource: acl-privilege, action: read (if not self)
200
+ *
201
+ * @example id "me"
202
+ * @example fields "id,action,resource"
203
+ * @example filter "action:create"
204
+ * @example limit 42
205
+ */
206
+ async getUserPrivileges(req, id, fields, ndjson, filter, limit) {
207
+ const user = await this.getObject(id);
208
+ const currentUser = this.restApi.getCurrentUser();
209
+ const userPrivileges = (await this.restApi.xoApp.getAclV2UserPrivileges(user.id));
210
+ return this.sendObjects(limitAndFilterArray(userPrivileges, { filter }), req, {
211
+ path: 'acl-privileges',
212
+ limit,
213
+ privilege: currentUser.id === user.id ? undefined : { action: 'read', resource: 'acl-privilege' },
214
+ });
215
+ }
159
216
  };
160
217
  __decorate([
161
218
  Example(userIds),
162
219
  Example(partialUsers),
163
220
  Get(''),
221
+ Security('*', ['acl']),
164
222
  __param(0, Request()),
165
223
  __param(1, Query()),
166
224
  __param(2, Query()),
167
225
  __param(3, Query()),
168
- __param(4, Query())
226
+ __param(4, Query()),
227
+ __param(5, Query())
169
228
  ], UserController.prototype, "getUsers", null);
170
229
  __decorate([
171
230
  Example(user),
172
231
  Get('{id}'),
232
+ Middlewares(acl({
233
+ resource: 'user',
234
+ action: actionIfNotSelfUser('read'),
235
+ objectId: 'params.id',
236
+ getObject: ({ restApi }) => restApi.xoApp.getUser,
237
+ })),
238
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
173
239
  Response(notFoundResp.status, notFoundResp.description),
174
240
  __param(0, Path())
175
241
  ], UserController.prototype, "getUser", null);
176
242
  __decorate([
177
243
  Patch('{id}'),
178
- Middlewares(json()),
244
+ Middlewares([
245
+ json(),
246
+ acl({
247
+ resource: 'user',
248
+ actions: actionsFromBody(['update:name', 'update:password', 'update:permission', 'update:preferences']),
249
+ objectId: 'params.id',
250
+ getObject: ({ restApi }) => restApi.xoApp.getUser,
251
+ }),
252
+ ]),
179
253
  SuccessResponse(noContentResp.status, noContentResp.description),
180
254
  Response(notFoundResp.status, notFoundResp.description),
181
255
  Response(resourceAlreadyExists.status, resourceAlreadyExists.description),
@@ -186,15 +260,23 @@ __decorate([
186
260
  __decorate([
187
261
  Example(userId),
188
262
  Post(''),
189
- Middlewares(json()),
263
+ Middlewares([json(), acl({ resource: 'user', action: 'create', object: ({ req }) => req.body })]),
190
264
  SuccessResponse(createdResp.status, createdResp.description),
191
265
  Response(unauthorizedResp.status, unauthorizedResp.description),
266
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
192
267
  Response(invalidParameters.status, invalidParameters.description),
193
268
  __param(0, Body())
194
269
  ], UserController.prototype, "createUser", null);
195
270
  __decorate([
196
271
  Delete('{id}'),
272
+ Middlewares(acl({
273
+ resource: 'user',
274
+ action: 'delete',
275
+ objectId: 'params.id',
276
+ getObject: ({ restApi }) => restApi.xoApp.getUser,
277
+ })),
197
278
  SuccessResponse(noContentResp.status, noContentResp.description),
279
+ Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
198
280
  Response(notFoundResp.status, notFoundResp.description),
199
281
  __param(0, Path())
200
282
  ], UserController.prototype, "deleteUser", null);
@@ -202,6 +284,7 @@ __decorate([
202
284
  Example(groupIds),
203
285
  Example(partialGroups),
204
286
  Get('{id}/groups'),
287
+ Security('*', ['acl']),
205
288
  Tags('groups'),
206
289
  Response(notFoundResp.status, notFoundResp.description),
207
290
  __param(0, Request()),
@@ -209,11 +292,13 @@ __decorate([
209
292
  __param(2, Query()),
210
293
  __param(3, Query()),
211
294
  __param(4, Query()),
212
- __param(5, Query())
295
+ __param(5, Query()),
296
+ __param(6, Query())
213
297
  ], UserController.prototype, "getUserGroups", null);
214
298
  __decorate([
215
299
  Example(authenticationTokens),
216
300
  Get('{id}/authentication_tokens'),
301
+ Security('*', ['acl']),
217
302
  Response(notFoundResp.status, notFoundResp.description),
218
303
  Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
219
304
  __param(0, Request()),
@@ -225,6 +310,7 @@ __decorate([
225
310
  Example(taskIds),
226
311
  Example(partialTasks),
227
312
  Get('{id}/tasks'),
313
+ Security('*', ['acl']),
228
314
  Tags('tasks'),
229
315
  Response(notFoundResp.status, notFoundResp.description),
230
316
  __param(0, Request()),
@@ -232,7 +318,8 @@ __decorate([
232
318
  __param(2, Query()),
233
319
  __param(3, Query()),
234
320
  __param(4, Query()),
235
- __param(5, Query())
321
+ __param(5, Query()),
322
+ __param(6, Query())
236
323
  ], UserController.prototype, "getUserTasks", null);
237
324
  __decorate([
238
325
  Example(authenticationToken),
@@ -247,12 +334,27 @@ __decorate([
247
334
  Example(authenticationToken),
248
335
  Post('{id}/authentication_tokens'),
249
336
  Middlewares(json()),
337
+ Security('*', ['acl']),
250
338
  SuccessResponse(createdResp.status, createdResp.description),
251
339
  Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
252
340
  Response(internalServerErrorResp.status, internalServerErrorResp.description),
253
341
  __param(0, Body()),
254
342
  __param(1, Path())
255
343
  ], UserController.prototype, "postAuthenticationTokens", null);
344
+ __decorate([
345
+ Example(aclPrivilegeIds),
346
+ Example(partialAclPrivileges),
347
+ Get('{id}/acl-privileges'),
348
+ Security('*', ['acl']),
349
+ Tags('acls'),
350
+ Response(notFoundResp.status, notFoundResp.description),
351
+ __param(0, Request()),
352
+ __param(1, Path()),
353
+ __param(2, Query()),
354
+ __param(3, Query()),
355
+ __param(4, Query()),
356
+ __param(5, Query())
357
+ ], UserController.prototype, "getUserPrivileges", null);
256
358
  UserController = __decorate([
257
359
  Route('users'),
258
360
  Security('*'),