@nocobase/plugin-acl 2.1.0-alpha.2 → 2.1.0-alpha.20

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 (37) hide show
  1. package/LICENSE +201 -661
  2. package/README.md +79 -10
  3. package/client-v2.d.ts +2 -0
  4. package/client-v2.js +1 -0
  5. package/dist/client/949.7ad4ad3b554e5452.js +10 -0
  6. package/dist/client/971.50ecf7b6ac572080.js +10 -0
  7. package/dist/client/index.js +1 -1
  8. package/dist/client-v2/139.929bc11d582ef7d4.js +10 -0
  9. package/dist/client-v2/193.3245b23f17b4c9f8.js +10 -0
  10. package/dist/client-v2/366.069b6cf12cfb9a67.js +10 -0
  11. package/dist/client-v2/627.ce101823deb86dd6.js +10 -0
  12. package/dist/client-v2/index.d.ts +9 -0
  13. package/dist/client-v2/index.js +10 -0
  14. package/dist/client-v2/plugin.d.ts +5 -0
  15. package/dist/client-v2/routes/AppInfoDemoRoute.d.ts +10 -0
  16. package/dist/client-v2/routes/DemoHomepageRoute.d.ts +10 -0
  17. package/dist/client-v2/routes/FlowSettingsComponentLoaderDemoRoute.d.ts +2 -0
  18. package/dist/client-v2/settings/DemoFlowSettingsLazyField.d.ts +10 -0
  19. package/dist/externalVersion.js +11 -9
  20. package/dist/server/index.d.ts +1 -0
  21. package/dist/server/index.js +2 -0
  22. package/dist/server/middlewares/check-association-operate.js +14 -5
  23. package/dist/server/middlewares/check-change-with-association.d.ts +21 -0
  24. package/dist/server/middlewares/check-change-with-association.js +327 -246
  25. package/dist/server/middlewares/check-query-permission.d.ts +10 -0
  26. package/dist/server/middlewares/check-query-permission.js +64 -0
  27. package/dist/server/middlewares/with-acl-meta.js +7 -2
  28. package/dist/server/migrations/20251119225252-update-member-default-permission.js +1 -1
  29. package/dist/server/query/apply-query-permission.d.ts +27 -0
  30. package/dist/server/query/apply-query-permission.js +242 -0
  31. package/dist/server/server.d.ts +6 -1
  32. package/dist/server/server.js +8 -1
  33. package/dist/swagger/index.d.ts +962 -143
  34. package/dist/swagger/index.js +854 -183
  35. package/package.json +5 -3
  36. package/dist/client/0655d5ded9f45bb1.js +0 -10
  37. package/dist/client/50204a14518b3a0d.js +0 -10
@@ -32,23 +32,23 @@ module.exports = __toCommonJS(swagger_exports);
32
32
  var swagger_default = {
33
33
  openapi: "3.0.2",
34
34
  info: {
35
- title: "NocoBase API - ACL plugin"
35
+ title: "NocoBase API - ACL plugin",
36
+ version: "1.0.0"
36
37
  },
37
38
  paths: {
38
39
  "/roles:list": {
39
40
  get: {
40
41
  tags: ["roles"],
41
- description: "",
42
- parameters: [],
42
+ summary: "List roles",
43
43
  responses: {
44
44
  200: {
45
- description: "ok",
45
+ description: "OK",
46
46
  content: {
47
47
  "application/json": {
48
48
  schema: {
49
49
  type: "array",
50
50
  items: {
51
- $ref: "#/components/schemas/role"
51
+ $ref: "#/components/schemas/Role"
52
52
  }
53
53
  }
54
54
  }
@@ -60,25 +60,15 @@ var swagger_default = {
60
60
  "/roles:get": {
61
61
  get: {
62
62
  tags: ["roles"],
63
- description: "",
64
- parameters: [
65
- {
66
- name: "filterByTk",
67
- in: "query",
68
- description: "role name",
69
- required: true,
70
- schema: {
71
- type: "string"
72
- }
73
- }
74
- ],
63
+ summary: "Get a role",
64
+ parameters: [{ $ref: "#/components/parameters/RoleNameQuery" }],
75
65
  responses: {
76
66
  200: {
77
- description: "ok",
67
+ description: "OK",
78
68
  content: {
79
69
  "application/json": {
80
70
  schema: {
81
- $ref: "#/components/schemas/role"
71
+ $ref: "#/components/schemas/Role"
82
72
  }
83
73
  }
84
74
  }
@@ -89,23 +79,25 @@ var swagger_default = {
89
79
  "/roles:create": {
90
80
  post: {
91
81
  tags: ["roles"],
92
- description: "",
82
+ summary: "Create a role",
83
+ description: "Create a role. Request body uses direct role values.",
93
84
  requestBody: {
85
+ required: true,
94
86
  content: {
95
87
  "application/json": {
96
88
  schema: {
97
- $ref: "#/components/schemas/role"
89
+ $ref: "#/components/schemas/RoleWrite"
98
90
  }
99
91
  }
100
92
  }
101
93
  },
102
94
  responses: {
103
- "200": {
95
+ 200: {
104
96
  description: "OK",
105
97
  content: {
106
98
  "application/json": {
107
99
  schema: {
108
- $ref: "#/components/schemas/role"
100
+ $ref: "#/components/schemas/Role"
109
101
  }
110
102
  }
111
103
  }
@@ -116,34 +108,26 @@ var swagger_default = {
116
108
  "/roles:update": {
117
109
  post: {
118
110
  tags: ["roles"],
119
- description: "",
120
- parameters: [
121
- {
122
- name: "filterByTk",
123
- in: "query",
124
- description: "role name",
125
- required: true,
126
- schema: {
127
- type: "string"
128
- }
129
- }
130
- ],
111
+ summary: "Update a role",
112
+ description: "Update a role by role name (`filterByTk`). Commonly used for role metadata and system permission snippets.",
113
+ parameters: [{ $ref: "#/components/parameters/RoleNameQuery" }],
131
114
  requestBody: {
115
+ required: true,
132
116
  content: {
133
117
  "application/json": {
134
118
  schema: {
135
- $ref: "#/components/schemas/role"
119
+ $ref: "#/components/schemas/RoleWrite"
136
120
  }
137
121
  }
138
122
  }
139
123
  },
140
124
  responses: {
141
125
  200: {
142
- description: "ok",
126
+ description: "OK",
143
127
  content: {
144
128
  "application/json": {
145
129
  schema: {
146
- $ref: "#/components/schemas/role"
130
+ $ref: "#/components/schemas/Role"
147
131
  }
148
132
  }
149
133
  }
@@ -154,20 +138,10 @@ var swagger_default = {
154
138
  "/roles:destroy": {
155
139
  post: {
156
140
  tags: ["roles"],
157
- description: "",
158
- parameters: [
159
- {
160
- name: "filterByTk",
161
- in: "query",
162
- description: "role name",
163
- required: true,
164
- schema: {
165
- type: "string"
166
- }
167
- }
168
- ],
141
+ summary: "Destroy a role",
142
+ parameters: [{ $ref: "#/components/parameters/RoleNameQuery" }],
169
143
  responses: {
170
- "200": {
144
+ 200: {
171
145
  description: "OK"
172
146
  }
173
147
  }
@@ -176,14 +150,15 @@ var swagger_default = {
176
150
  "/roles:check": {
177
151
  get: {
178
152
  tags: ["roles"],
179
- description: "return current user role",
153
+ summary: "Check current role context",
154
+ description: "Return the current effective role context, including role mode and resolved ACL action map for the current user.",
180
155
  responses: {
181
156
  200: {
182
- description: "ok",
157
+ description: "OK",
183
158
  content: {
184
159
  "application/json": {
185
160
  schema: {
186
- $ref: "#/components/schemas/role"
161
+ $ref: "#/components/schemas/RoleCheck"
187
162
  }
188
163
  }
189
164
  }
@@ -194,82 +169,438 @@ var swagger_default = {
194
169
  "/roles:setDefaultRole": {
195
170
  post: {
196
171
  tags: ["roles"],
197
- description: "set default role for new user",
172
+ summary: "Set default role for new users",
198
173
  requestBody: {
174
+ required: true,
199
175
  content: {
200
176
  "application/json": {
201
177
  schema: {
202
178
  type: "object",
203
179
  properties: {
204
- roleName: {
205
- type: "string"
180
+ roleName: { type: "string" }
181
+ },
182
+ required: ["roleName"]
183
+ }
184
+ }
185
+ }
186
+ },
187
+ responses: {
188
+ 200: {
189
+ description: "OK"
190
+ }
191
+ }
192
+ }
193
+ },
194
+ "/roles:setSystemRoleMode": {
195
+ post: {
196
+ tags: ["roles"],
197
+ summary: "Set system role mode",
198
+ description: "Set the system role mode. Valid values are `default`, `allow-use-union`, and `only-use-union`.",
199
+ requestBody: {
200
+ required: true,
201
+ content: {
202
+ "application/json": {
203
+ schema: {
204
+ $ref: "#/components/schemas/RoleModeWrite"
205
+ }
206
+ }
207
+ }
208
+ },
209
+ responses: {
210
+ 200: {
211
+ description: "OK"
212
+ }
213
+ }
214
+ }
215
+ },
216
+ "/roles/{roleName}/users:list": {
217
+ get: {
218
+ tags: ["roles.users"],
219
+ summary: "List users bound to a role",
220
+ parameters: [
221
+ { $ref: "#/components/parameters/RoleNamePath" },
222
+ { $ref: "#/components/parameters/PageQuery" },
223
+ { $ref: "#/components/parameters/PageSizeQuery" },
224
+ { $ref: "#/components/parameters/SortQuery" },
225
+ { $ref: "#/components/parameters/AppendsQuery" },
226
+ { $ref: "#/components/parameters/FilterQuery" }
227
+ ],
228
+ responses: {
229
+ 200: {
230
+ description: "OK",
231
+ content: {
232
+ "application/json": {
233
+ schema: {
234
+ type: "object",
235
+ additionalProperties: true,
236
+ properties: {
237
+ data: {
238
+ type: "array",
239
+ items: {
240
+ type: "object",
241
+ additionalProperties: true
242
+ }
243
+ },
244
+ meta: {
245
+ type: "object",
246
+ additionalProperties: true
247
+ }
206
248
  }
207
249
  }
208
250
  }
209
251
  }
210
252
  }
211
- },
253
+ }
254
+ }
255
+ },
256
+ "/roles/{roleName}/users:add": {
257
+ post: {
258
+ tags: ["roles.users"],
259
+ summary: "Bind one or more users to a role",
260
+ parameters: [
261
+ { $ref: "#/components/parameters/RoleNamePath" },
262
+ { $ref: "#/components/parameters/MembershipUserFilterByTkQuery" }
263
+ ],
212
264
  responses: {
213
- "200": {
265
+ 200: {
214
266
  description: "OK"
215
267
  }
216
268
  }
217
269
  }
218
270
  },
219
- "/roles/{roleName}/collections:list": {
271
+ "/roles/{roleName}/users:remove": {
272
+ post: {
273
+ tags: ["roles.users"],
274
+ summary: "Unbind one or more users from a role",
275
+ parameters: [
276
+ { $ref: "#/components/parameters/RoleNamePath" },
277
+ { $ref: "#/components/parameters/MembershipUserFilterByTkQuery" }
278
+ ],
279
+ responses: {
280
+ 200: {
281
+ description: "OK"
282
+ }
283
+ }
284
+ }
285
+ },
286
+ "/users/{userId}/roles:list": {
220
287
  get: {
221
- tags: ["roles.collections"],
222
- description: "list permissions of collections for role by roleName",
288
+ tags: ["users.roles"],
289
+ summary: "List roles bound to a user",
223
290
  parameters: [
224
- {
225
- name: "filterByTk",
226
- in: "query",
227
- description: "role name",
228
- required: true,
229
- schema: {
230
- type: "string"
291
+ { $ref: "#/components/parameters/UserIdPath" },
292
+ { $ref: "#/components/parameters/PageQuery" },
293
+ { $ref: "#/components/parameters/PageSizeQuery" },
294
+ { $ref: "#/components/parameters/SortQuery" },
295
+ { $ref: "#/components/parameters/AppendsQuery" },
296
+ { $ref: "#/components/parameters/FilterQuery" }
297
+ ],
298
+ responses: {
299
+ 200: {
300
+ description: "OK",
301
+ content: {
302
+ "application/json": {
303
+ schema: {
304
+ type: "object",
305
+ additionalProperties: true,
306
+ properties: {
307
+ data: {
308
+ type: "array",
309
+ items: {
310
+ type: "object",
311
+ additionalProperties: true
312
+ }
313
+ },
314
+ meta: {
315
+ type: "object",
316
+ additionalProperties: true
317
+ }
318
+ }
319
+ }
320
+ }
231
321
  }
232
322
  }
323
+ }
324
+ }
325
+ },
326
+ "/users/{userId}/roles:add": {
327
+ post: {
328
+ tags: ["users.roles"],
329
+ summary: "Bind one or more roles to a user",
330
+ parameters: [
331
+ { $ref: "#/components/parameters/UserIdPath" },
332
+ { $ref: "#/components/parameters/MembershipRoleFilterByTkQuery" }
333
+ ],
334
+ responses: {
335
+ 200: {
336
+ description: "OK"
337
+ }
338
+ }
339
+ }
340
+ },
341
+ "/users/{userId}/roles:remove": {
342
+ post: {
343
+ tags: ["users.roles"],
344
+ summary: "Unbind one or more roles from a user",
345
+ parameters: [
346
+ { $ref: "#/components/parameters/UserIdPath" },
347
+ { $ref: "#/components/parameters/MembershipRoleFilterByTkQuery" }
233
348
  ],
234
349
  responses: {
235
- "200": {
350
+ 200: {
351
+ description: "OK"
352
+ }
353
+ }
354
+ }
355
+ },
356
+ "/dataSources/{dataSourceKey}/roles:update": {
357
+ post: {
358
+ tags: ["dataSources.roles"],
359
+ summary: "Update global ACL strategy for a role in a data source",
360
+ description: "Configure global table permissions for a role inside a data source. Request body typically includes `roleName`, `dataSourceKey`, and `strategy.actions`.",
361
+ parameters: [
362
+ { $ref: "#/components/parameters/DataSourceKeyPath" },
363
+ { $ref: "#/components/parameters/RoleNameQuery" }
364
+ ],
365
+ requestBody: {
366
+ required: true,
367
+ content: {
368
+ "application/json": {
369
+ schema: {
370
+ $ref: "#/components/schemas/DataSourceRole"
371
+ }
372
+ }
373
+ }
374
+ },
375
+ responses: {
376
+ 200: {
377
+ description: "OK",
378
+ content: {
379
+ "application/json": {
380
+ schema: {
381
+ $ref: "#/components/schemas/DataSourceRole"
382
+ }
383
+ }
384
+ }
385
+ }
386
+ }
387
+ }
388
+ },
389
+ "/dataSources/{dataSourceKey}/roles:get": {
390
+ get: {
391
+ tags: ["dataSources.roles"],
392
+ summary: "Get global ACL strategy for a role in a data source",
393
+ parameters: [
394
+ { $ref: "#/components/parameters/DataSourceKeyPath" },
395
+ { $ref: "#/components/parameters/RoleNameQuery" }
396
+ ],
397
+ responses: {
398
+ 200: {
399
+ description: "OK",
400
+ content: {
401
+ "application/json": {
402
+ schema: {
403
+ $ref: "#/components/schemas/DataSourceRole"
404
+ }
405
+ }
406
+ }
407
+ }
408
+ }
409
+ }
410
+ },
411
+ "/roles/{roleName}/dataSourcesCollections:list": {
412
+ get: {
413
+ tags: ["roles.dataSourcesCollections"],
414
+ summary: "List data-source collections in role permission configuration",
415
+ description: "List collections in the target data source for the given role and indicate whether they use global permissions or collection-level independent permissions.",
416
+ parameters: [
417
+ { $ref: "#/components/parameters/RoleNamePath" },
418
+ { $ref: "#/components/parameters/PageQuery" },
419
+ { $ref: "#/components/parameters/PageSizeQuery" },
420
+ { $ref: "#/components/parameters/SortQuery" },
421
+ { $ref: "#/components/parameters/AppendsQuery" },
422
+ { $ref: "#/components/parameters/FilterQuery" }
423
+ ],
424
+ responses: {
425
+ 200: {
426
+ description: "OK",
427
+ content: {
428
+ "application/json": {
429
+ schema: {
430
+ type: "object",
431
+ properties: {
432
+ count: { type: "integer" },
433
+ rows: {
434
+ type: "array",
435
+ items: { $ref: "#/components/schemas/RoleCollectionPermissionRow" }
436
+ },
437
+ page: { type: "integer" },
438
+ pageSize: { type: "integer" },
439
+ totalPage: { type: "integer" }
440
+ }
441
+ }
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+ },
448
+ "/roles/{roleName}/dataSourceResources:create": {
449
+ post: {
450
+ tags: ["roles.dataSourceResources"],
451
+ summary: "Create collection-level independent ACL permissions for a role",
452
+ description: [
453
+ "Create collection-level independent permission config for a role in a data source.",
454
+ "Request body usually includes `name`, `dataSourceKey`, `usingActionsConfig`, and `actions`.",
455
+ "The server uses the role path parameter plus request-body `name` and `dataSourceKey` to create the record."
456
+ ].join("\n"),
457
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }, { $ref: "#/components/parameters/FilterQuery" }],
458
+ requestBody: {
459
+ required: true,
460
+ content: {
461
+ "application/json": {
462
+ schema: {
463
+ $ref: "#/components/schemas/RoleDataSourceResourceWrite"
464
+ }
465
+ }
466
+ }
467
+ },
468
+ responses: {
469
+ 200: {
470
+ description: "OK",
471
+ content: {
472
+ "application/json": {
473
+ schema: {
474
+ $ref: "#/components/schemas/RoleDataSourceResource"
475
+ }
476
+ }
477
+ }
478
+ }
479
+ }
480
+ }
481
+ },
482
+ "/roles/{roleName}/dataSourceResources:get": {
483
+ get: {
484
+ tags: ["roles.dataSourceResources"],
485
+ summary: "Get one collection-level independent ACL permission for a role",
486
+ description: "Get one collection-level independent permission config. Target it with a `filter` such as `{ name, dataSourceKey }`. Do not rely on `filterByTk` for this endpoint.",
487
+ parameters: [
488
+ { $ref: "#/components/parameters/RoleNamePath" },
489
+ { $ref: "#/components/parameters/FilterQuery" },
490
+ { $ref: "#/components/parameters/AppendsQuery" }
491
+ ],
492
+ responses: {
493
+ 200: {
494
+ description: "OK",
495
+ content: {
496
+ "application/json": {
497
+ schema: {
498
+ $ref: "#/components/schemas/RoleDataSourceResource"
499
+ }
500
+ }
501
+ }
502
+ }
503
+ }
504
+ }
505
+ },
506
+ "/roles/{roleName}/dataSourceResources:update": {
507
+ post: {
508
+ tags: ["roles.dataSourceResources"],
509
+ summary: "Update collection-level independent ACL permissions for a role",
510
+ description: "Update one collection-level independent permission config. Target it with a `filter` such as `{ name, dataSourceKey }`. Do not rely on `filterByTk` for this endpoint.",
511
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }, { $ref: "#/components/parameters/FilterQuery" }],
512
+ requestBody: {
513
+ required: true,
514
+ content: {
515
+ "application/json": {
516
+ schema: {
517
+ $ref: "#/components/schemas/RoleDataSourceResourceWrite"
518
+ }
519
+ }
520
+ }
521
+ },
522
+ responses: {
523
+ 200: {
524
+ description: "OK",
525
+ content: {
526
+ "application/json": {
527
+ schema: {
528
+ $ref: "#/components/schemas/RoleDataSourceResource"
529
+ }
530
+ }
531
+ }
532
+ }
533
+ }
534
+ }
535
+ },
536
+ "/rolesResourcesScopes:list": {
537
+ get: {
538
+ tags: ["rolesResourcesScopes"],
539
+ summary: "List reusable ACL scopes",
540
+ parameters: [
541
+ { $ref: "#/components/parameters/PageQuery" },
542
+ { $ref: "#/components/parameters/PageSizeQuery" },
543
+ { $ref: "#/components/parameters/FilterQuery" }
544
+ ],
545
+ responses: {
546
+ 200: {
236
547
  description: "OK",
237
548
  content: {
238
549
  "application/json": {
239
550
  schema: {
240
551
  type: "array",
241
- items: {
242
- type: "object",
243
- properties: {
244
- type: {
245
- type: "string",
246
- description: "collection"
247
- },
248
- name: {
249
- type: "string",
250
- description: "collection name"
251
- },
252
- collectionName: {
253
- type: "string",
254
- description: "collection name"
255
- },
256
- title: {
257
- type: "string",
258
- description: "collection title"
259
- },
260
- roleName: {
261
- type: "string",
262
- description: "role name"
263
- },
264
- usingConfig: {
265
- type: "string",
266
- enum: ["resourceAction", "strategy"],
267
- description: "resourceAction: \u5355\u72EC\u914D\u7F6E, strategy: \u5168\u5C40\u7B56\u7565"
268
- },
269
- exists: {
270
- type: "boolean",
271
- description: "\u662F\u5426\u5B58\u5728\u5355\u72EC\u914D\u7F6E\u7684\u6743\u9650"
272
- }
552
+ items: { $ref: "#/components/schemas/RoleResourceScope" }
553
+ }
554
+ }
555
+ }
556
+ }
557
+ }
558
+ }
559
+ },
560
+ "/rolesResourcesScopes:get": {
561
+ get: {
562
+ tags: ["rolesResourcesScopes"],
563
+ summary: "Get a reusable ACL scope",
564
+ parameters: [{ $ref: "#/components/parameters/ScopePkQuery" }, { $ref: "#/components/parameters/FilterQuery" }],
565
+ responses: {
566
+ 200: {
567
+ description: "OK",
568
+ content: {
569
+ "application/json": {
570
+ schema: {
571
+ $ref: "#/components/schemas/RoleResourceScope"
572
+ }
573
+ }
574
+ }
575
+ }
576
+ }
577
+ }
578
+ },
579
+ "/dataSources/{dataSourceKey}/rolesResourcesScopes:list": {
580
+ get: {
581
+ tags: ["dataSources.rolesResourcesScopes"],
582
+ summary: "List reusable ACL scopes in a data source",
583
+ parameters: [
584
+ { $ref: "#/components/parameters/DataSourceKeyPath" },
585
+ { $ref: "#/components/parameters/PageQuery" },
586
+ { $ref: "#/components/parameters/PageSizeQuery" },
587
+ { $ref: "#/components/parameters/FilterQuery" }
588
+ ],
589
+ responses: {
590
+ 200: {
591
+ description: "OK",
592
+ content: {
593
+ "application/json": {
594
+ schema: {
595
+ type: "object",
596
+ properties: {
597
+ data: {
598
+ type: "array",
599
+ items: { $ref: "#/components/schemas/RoleResourceScope" }
600
+ },
601
+ meta: {
602
+ type: "object",
603
+ additionalProperties: true
273
604
  }
274
605
  }
275
606
  }
@@ -279,50 +610,121 @@ var swagger_default = {
279
610
  }
280
611
  }
281
612
  },
613
+ "/dataSources/{dataSourceKey}/rolesResourcesScopes:get": {
614
+ get: {
615
+ tags: ["dataSources.rolesResourcesScopes"],
616
+ summary: "Get a reusable ACL scope in a data source",
617
+ parameters: [
618
+ { $ref: "#/components/parameters/DataSourceKeyPath" },
619
+ { $ref: "#/components/parameters/ScopePkQuery" },
620
+ { $ref: "#/components/parameters/FilterQuery" }
621
+ ],
622
+ responses: {
623
+ 200: {
624
+ description: "OK",
625
+ content: {
626
+ "application/json": {
627
+ schema: {
628
+ $ref: "#/components/schemas/RoleResourceScope"
629
+ }
630
+ }
631
+ }
632
+ }
633
+ }
634
+ }
635
+ },
636
+ "/dataSources/{dataSourceKey}/rolesResourcesScopes:create": {
637
+ post: {
638
+ tags: ["dataSources.rolesResourcesScopes"],
639
+ summary: "Create a reusable ACL scope in a data source",
640
+ description: "Create a reusable scope definition under the target data source.",
641
+ parameters: [{ $ref: "#/components/parameters/DataSourceKeyPath" }],
642
+ requestBody: {
643
+ required: true,
644
+ content: {
645
+ "application/json": {
646
+ schema: {
647
+ $ref: "#/components/schemas/RoleResourceScopeWrite"
648
+ }
649
+ }
650
+ }
651
+ },
652
+ responses: {
653
+ 200: {
654
+ description: "OK",
655
+ content: {
656
+ "application/json": {
657
+ schema: {
658
+ $ref: "#/components/schemas/RoleResourceScope"
659
+ }
660
+ }
661
+ }
662
+ }
663
+ }
664
+ }
665
+ },
666
+ "/dataSources/{dataSourceKey}/rolesResourcesScopes:update": {
667
+ post: {
668
+ tags: ["dataSources.rolesResourcesScopes"],
669
+ summary: "Update a reusable ACL scope in a data source",
670
+ parameters: [
671
+ { $ref: "#/components/parameters/DataSourceKeyPath" },
672
+ { $ref: "#/components/parameters/ScopePkQuery" },
673
+ { $ref: "#/components/parameters/FilterQuery" }
674
+ ],
675
+ requestBody: {
676
+ required: true,
677
+ content: {
678
+ "application/json": {
679
+ schema: {
680
+ $ref: "#/components/schemas/RoleResourceScopeWrite"
681
+ }
682
+ }
683
+ }
684
+ },
685
+ responses: {
686
+ 200: {
687
+ description: "OK",
688
+ content: {
689
+ "application/json": {
690
+ schema: {
691
+ $ref: "#/components/schemas/RoleResourceScope"
692
+ }
693
+ }
694
+ }
695
+ }
696
+ }
697
+ }
698
+ },
699
+ "/dataSources/{dataSourceKey}/rolesResourcesScopes:destroy": {
700
+ post: {
701
+ tags: ["dataSources.rolesResourcesScopes"],
702
+ summary: "Destroy a reusable ACL scope in a data source",
703
+ parameters: [
704
+ { $ref: "#/components/parameters/DataSourceKeyPath" },
705
+ { $ref: "#/components/parameters/ScopePkQuery" },
706
+ { $ref: "#/components/parameters/FilterQuery" }
707
+ ],
708
+ responses: {
709
+ 200: {
710
+ description: "OK"
711
+ }
712
+ }
713
+ }
714
+ },
282
715
  "/availableActions:list": {
283
716
  get: {
284
717
  tags: ["availableActions"],
285
- description: "available actions of resource in current system",
286
- parameters: [],
718
+ summary: "List configurable ACL actions",
719
+ description: "List ACL actions available in the current system. Use this before configuring resource-level action or field permissions.",
287
720
  responses: {
288
- "200": {
721
+ 200: {
289
722
  description: "OK",
290
723
  content: {
291
724
  "application/json": {
292
725
  schema: {
293
726
  type: "array",
294
- items: {
295
- type: "object",
296
- properties: {
297
- name: {
298
- type: "string",
299
- description: "Action\u540D\u79F0"
300
- },
301
- displayName: {
302
- type: "string",
303
- description: "Action\u663E\u793A\u540D\u79F0"
304
- },
305
- allowConfigureFields: {
306
- type: "boolean",
307
- description: "\u662F\u5426\u5141\u8BB8\u914D\u7F6E\u5B57\u6BB5"
308
- },
309
- onNewRecord: {
310
- type: "string",
311
- description: "\u662F\u5426\u662F\u65B0\u8BB0\u5F55\u7684Action"
312
- },
313
- type: {
314
- type: "string",
315
- description: "new-data \u6216\u8005 old-data"
316
- },
317
- aliases: {
318
- type: "array",
319
- items: {
320
- type: "string"
321
- },
322
- description: "\u522B\u540D"
323
- }
324
- }
325
- }
727
+ items: { $ref: "#/components/schemas/AvailableAction" }
326
728
  }
327
729
  }
328
730
  }
@@ -332,72 +734,341 @@ var swagger_default = {
332
734
  }
333
735
  },
334
736
  components: {
737
+ parameters: {
738
+ RoleNameQuery: {
739
+ name: "filterByTk",
740
+ in: "query",
741
+ description: "Role name.",
742
+ required: true,
743
+ schema: { type: "string" }
744
+ },
745
+ RoleNamePath: {
746
+ name: "roleName",
747
+ in: "path",
748
+ description: "Role name.",
749
+ required: true,
750
+ schema: { type: "string" }
751
+ },
752
+ UserIdPath: {
753
+ name: "userId",
754
+ in: "path",
755
+ description: "User primary key.",
756
+ required: true,
757
+ schema: {
758
+ anyOf: [{ type: "string" }, { type: "integer" }]
759
+ }
760
+ },
761
+ DataSourceKeyPath: {
762
+ name: "dataSourceKey",
763
+ in: "path",
764
+ description: "Data source key, for example `main`.",
765
+ required: true,
766
+ schema: { type: "string" }
767
+ },
768
+ MembershipUserFilterByTkQuery: {
769
+ name: "filterByTk",
770
+ in: "query",
771
+ description: "User primary key, or a list of user primary keys.",
772
+ required: true,
773
+ schema: {
774
+ anyOf: [
775
+ { type: "string" },
776
+ { type: "integer" },
777
+ {
778
+ type: "array",
779
+ items: {
780
+ anyOf: [{ type: "string" }, { type: "integer" }]
781
+ }
782
+ }
783
+ ]
784
+ }
785
+ },
786
+ MembershipRoleFilterByTkQuery: {
787
+ name: "filterByTk",
788
+ in: "query",
789
+ description: "Role name, or a list of role names.",
790
+ required: true,
791
+ schema: {
792
+ anyOf: [
793
+ { type: "string" },
794
+ {
795
+ type: "array",
796
+ items: {
797
+ type: "string"
798
+ }
799
+ }
800
+ ]
801
+ }
802
+ },
803
+ ResourceNameQuery: {
804
+ name: "filterByTk",
805
+ in: "query",
806
+ description: "Resource name, typically the collection name.",
807
+ required: true,
808
+ schema: { type: "string" }
809
+ },
810
+ ScopePkQuery: {
811
+ name: "filterByTk",
812
+ in: "query",
813
+ description: "Scope primary key.",
814
+ schema: { type: "integer" }
815
+ },
816
+ ResourcePermissionTkQuery: {
817
+ name: "filterByTk",
818
+ in: "query",
819
+ description: "Resource permission record primary key.",
820
+ schema: { type: "integer" }
821
+ },
822
+ PageQuery: {
823
+ name: "page",
824
+ in: "query",
825
+ schema: { type: "integer" }
826
+ },
827
+ PageSizeQuery: {
828
+ name: "pageSize",
829
+ in: "query",
830
+ schema: { type: "integer" }
831
+ },
832
+ FilterQuery: {
833
+ name: "filter",
834
+ in: "query",
835
+ schema: {
836
+ type: "object",
837
+ additionalProperties: true
838
+ }
839
+ },
840
+ AppendsQuery: {
841
+ name: "appends",
842
+ in: "query",
843
+ schema: {
844
+ type: "array",
845
+ items: { type: "string" }
846
+ }
847
+ }
848
+ },
335
849
  schemas: {
336
- role: {
850
+ RoleStrategy: {
851
+ type: "object",
852
+ description: "Global action strategy for a role.",
853
+ properties: {
854
+ actions: {
855
+ type: "array",
856
+ items: { type: "string" },
857
+ description: "Action names such as `create`, `view`, `update`, `destroy`, or scoped variants like `view:own`."
858
+ }
859
+ },
860
+ additionalProperties: true
861
+ },
862
+ RoleWrite: {
863
+ type: "object",
864
+ properties: {
865
+ title: { type: "string", description: "Role title." },
866
+ name: { type: "string", description: "Role identifier." },
867
+ description: { type: "string", description: "Role description." },
868
+ hidden: { type: "boolean", description: "Whether the role is hidden." },
869
+ default: { type: "boolean", description: "Whether the role is default for new users." },
870
+ allowConfigure: { type: "boolean", description: "Whether the role can be configured." },
871
+ allowNewMenu: { type: "boolean", description: "Whether the role can create menus." },
872
+ snippets: {
873
+ type: "array",
874
+ items: { type: "string" },
875
+ description: "System permission snippets, for example `ui.*`, `!pm`, or `!app`."
876
+ },
877
+ strategy: {
878
+ allOf: [{ $ref: "#/components/schemas/RoleStrategy" }],
879
+ description: "Role-level ACL strategy."
880
+ }
881
+ },
882
+ additionalProperties: true
883
+ },
884
+ Role: {
885
+ allOf: [{ $ref: "#/components/schemas/RoleWrite" }],
886
+ properties: {
887
+ createdAt: { type: "string", format: "date-time" },
888
+ updatedAt: { type: "string", format: "date-time" }
889
+ }
890
+ },
891
+ RoleCheck: {
337
892
  type: "object",
338
893
  properties: {
339
- title: {
894
+ role: { type: "string", description: "Current effective role name." },
895
+ roleMode: {
340
896
  type: "string",
341
- description: "\u89D2\u8272\u540D\u79F0"
897
+ enum: ["default", "allow-use-union", "only-use-union"],
898
+ description: "System role mode."
342
899
  },
343
- name: {
900
+ availableActions: {
901
+ type: "array",
902
+ items: { type: "string" }
903
+ },
904
+ actions: {
905
+ type: "object",
906
+ additionalProperties: true,
907
+ description: "Resolved ACL action map for the current role context."
908
+ }
909
+ },
910
+ additionalProperties: true
911
+ },
912
+ RoleModeWrite: {
913
+ type: "object",
914
+ properties: {
915
+ roleMode: {
344
916
  type: "string",
345
- description: "\u89D2\u8272\u6807\u8BC6"
917
+ enum: ["default", "allow-use-union", "only-use-union"]
918
+ }
919
+ },
920
+ required: ["roleMode"]
921
+ },
922
+ DataSourceRole: {
923
+ type: "object",
924
+ properties: {
925
+ id: { type: "string", description: "Optional existing role-data-source permission record id." },
926
+ roleName: { type: "string", description: "Role name." },
927
+ dataSourceKey: { type: "string", description: "Data source key, usually `main`." },
928
+ strategy: {
929
+ allOf: [{ $ref: "#/components/schemas/RoleStrategy" }],
930
+ description: "Global table actions for this role in the data source."
931
+ }
932
+ },
933
+ additionalProperties: true
934
+ },
935
+ RoleCollectionPermissionRow: {
936
+ type: "object",
937
+ properties: {
938
+ type: { type: "string", description: "Resource type, usually `collection`." },
939
+ name: { type: "string", description: "Collection name." },
940
+ collectionName: { type: "string", description: "Collection name." },
941
+ title: { type: "string", description: "Collection title." },
942
+ roleName: { type: "string", description: "Role name." },
943
+ usingConfig: {
944
+ type: "string",
945
+ enum: ["resourceAction", "strategy"],
946
+ description: "`strategy` means the collection uses global permissions. `resourceAction` means it has collection-level independent permissions."
346
947
  },
347
- description: {
948
+ exists: { type: "boolean", description: "Whether a dedicated resource config exists." }
949
+ }
950
+ },
951
+ RoleResourceScope: {
952
+ type: "object",
953
+ properties: {
954
+ id: { type: "integer", description: "Scope primary key." },
955
+ key: { type: "string", description: "Scope key such as `all` or `own`." },
956
+ dataSourceKey: {
348
957
  type: "string",
349
- description: "\u89D2\u8272\u63CF\u8FF0"
958
+ nullable: true,
959
+ description: "Optional data source key, for example `main`."
350
960
  },
351
- hidden: {
352
- type: "boolean",
353
- description: "\u662F\u5426\u9690\u85CF"
961
+ name: { type: "string", description: "Scope display name." },
962
+ resourceName: { type: "string", nullable: true, description: "Optional resource binding." },
963
+ scope: {
964
+ type: "object",
965
+ additionalProperties: true,
966
+ description: "JSON filter object used as the ACL scope condition."
967
+ }
968
+ },
969
+ additionalProperties: true
970
+ },
971
+ RoleResourceScopeWrite: {
972
+ type: "object",
973
+ properties: {
974
+ id: { type: "integer", description: "Optional scope primary key, commonly present in update payloads." },
975
+ dataSourceKey: { type: "string", nullable: true, description: "Optional data source key." },
976
+ resourceName: { type: "string", nullable: true, description: "Optional bound resource name." },
977
+ name: { type: "string", description: "Scope display name." },
978
+ scope: {
979
+ type: "object",
980
+ additionalProperties: true,
981
+ description: "Row filter JSON."
982
+ }
983
+ },
984
+ required: ["name", "scope"],
985
+ additionalProperties: true
986
+ },
987
+ RoleResourceAction: {
988
+ type: "object",
989
+ properties: {
990
+ id: {
991
+ type: "integer",
992
+ description: "Optional action record id, commonly present in update payloads."
354
993
  },
355
- default: {
356
- type: "boolean",
357
- description: "\u662F\u5426\u9ED8\u8BA4"
994
+ name: {
995
+ type: "string",
996
+ description: "ACL action name, for example `view`, `create`, `update`, `destroy`, or a scoped variant."
358
997
  },
359
- allowConfigure: {
360
- type: "boolean",
361
- description: "\u662F\u5426\u5141\u8BB8\u914D\u7F6E"
998
+ fields: {
999
+ type: "array",
1000
+ items: { type: "string" },
1001
+ description: "Allowed field names for this action when field-level configuration is supported."
362
1002
  },
363
- allowNewMenu: {
1003
+ scopeId: {
1004
+ type: "integer",
1005
+ nullable: true,
1006
+ description: "Optional bound scope id. Use `null` to clear the scope."
1007
+ },
1008
+ scope: {
1009
+ allOf: [{ $ref: "#/components/schemas/RoleResourceScope" }],
1010
+ nullable: true,
1011
+ description: "Optional row-permission scope for this action."
1012
+ }
1013
+ },
1014
+ required: ["name"],
1015
+ additionalProperties: true
1016
+ },
1017
+ RoleDataSourceResourceWrite: {
1018
+ type: "object",
1019
+ description: "Collection-level independent permission config inside a data source.",
1020
+ properties: {
1021
+ id: {
1022
+ type: "integer",
1023
+ description: "Optional resource permission record id, commonly present in update payloads."
1024
+ },
1025
+ name: { type: "string", description: "Resource name, typically the collection name." },
1026
+ dataSourceKey: { type: "string", description: "Data source key, usually `main`." },
1027
+ roleName: { type: "string", description: "Optional role name echoed by the client in update payloads." },
1028
+ usingActionsConfig: {
364
1029
  type: "boolean",
365
- description: "\u662F\u5426\u5141\u8BB8\u65B0\u5EFA\u83DC\u5355"
1030
+ description: "Whether this collection uses independent actions instead of only the global strategy."
366
1031
  },
367
- snippets: {
1032
+ actions: {
368
1033
  type: "array",
369
- items: {
370
- type: "string"
371
- },
372
- description: "\u63A5\u53E3\u6743\u9650"
1034
+ items: { $ref: "#/components/schemas/RoleResourceAction" },
1035
+ description: "Independent action configs for this collection."
1036
+ }
1037
+ },
1038
+ required: ["name", "dataSourceKey"],
1039
+ additionalProperties: true
1040
+ },
1041
+ RoleDataSourceResource: {
1042
+ allOf: [{ $ref: "#/components/schemas/RoleDataSourceResourceWrite" }],
1043
+ properties: {
1044
+ id: { type: "integer" },
1045
+ roleName: { type: "string" }
1046
+ }
1047
+ },
1048
+ AvailableAction: {
1049
+ type: "object",
1050
+ properties: {
1051
+ name: { type: "string", description: "Action name." },
1052
+ displayName: { type: "string", description: "Localized display name." },
1053
+ allowConfigureFields: {
1054
+ type: "boolean",
1055
+ description: "Whether field-level permission config is supported for this action."
373
1056
  },
374
- strategy: {
375
- type: "array",
376
- description: "\u6570\u636E\u8868\u6743\u9650\u7B56\u7565",
377
- items: {
378
- type: "object",
379
- properties: {
380
- actions: {
381
- type: "array",
382
- items: {
383
- type: "string"
384
- },
385
- description: "\u64CD\u4F5C"
386
- }
387
- }
388
- }
1057
+ onNewRecord: {
1058
+ type: "boolean",
1059
+ description: "Whether the action applies to new records instead of existing records."
389
1060
  },
390
- createdAt: {
1061
+ type: {
391
1062
  type: "string",
392
- format: "date-time",
393
- description: "\u521B\u5EFA\u65F6\u95F4"
1063
+ description: "Action category such as `new-data` or `old-data`."
394
1064
  },
395
- updatedAt: {
396
- type: "string",
397
- format: "date-time",
398
- description: "\u66F4\u65B0\u65F6\u95F4"
1065
+ aliases: {
1066
+ type: "array",
1067
+ items: { type: "string" },
1068
+ description: "Action aliases resolved by ACL."
399
1069
  }
400
- }
1070
+ },
1071
+ additionalProperties: true
401
1072
  }
402
1073
  }
403
1074
  }