Skip to content

Commit 54225ec

Browse files
authored
Merge pull request #274 from weaviate/1.30/rbac-tenant-filtering
Add ability to define tenant-level perms for `data` and `tenants` perms
2 parents 4d16a06 + 87501e0 commit 54225ec

File tree

4 files changed

+406
-231
lines changed

4 files changed

+406
-231
lines changed

src/roles/index.ts

Lines changed: 108 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ const roles = (connection: ConnectionREST): Roles => {
121121
};
122122

123123
export const permissions = {
124+
/**
125+
* Create a set of permissions specific to Weaviate's backup functionality.
126+
*
127+
* For all collections, provide the `collection` argument as `'*'`.
128+
*
129+
* @param {string | string[]} args.collection The collection or collections to create permissions for.
130+
* @param {boolean} [args.manage] Whether to allow managing backups. Defaults to `false`.
131+
* @returns {BackupsPermission[]} The permissions for the specified collections.
132+
*/
124133
backup: (args: { collection: string | string[]; manage?: boolean }): BackupsPermission[] => {
125134
const collections = Array.isArray(args.collection) ? args.collection : [args.collection];
126135
return collections.flatMap((collection) => {
@@ -129,11 +138,27 @@ export const permissions = {
129138
return out;
130139
});
131140
},
141+
/**
142+
* Create a set of permissions specific to Weaviate's cluster endpoints.
143+
*
144+
* @param {boolean} [args.read] Whether to allow reading cluster information. Defaults to `false`.
145+
*/
132146
cluster: (args: { read?: boolean }): ClusterPermission[] => {
133147
const out: ClusterPermission = { actions: [] };
134148
if (args.read) out.actions.push('read_cluster');
135149
return [out];
136150
},
151+
/**
152+
* Create a set of permissions specific to any operations involving collections.
153+
*
154+
* For all collections, provide the `collection` argument as `'*'`.
155+
*
156+
* @param {string | string[]} args.collection The collection or collections to create permissions for.
157+
* @param {boolean} [args.create_collection] Whether to allow creating collections. Defaults to `false`.
158+
* @param {boolean} [args.read_config] Whether to allow reading collection configurations. Defaults to `false`.
159+
* @param {boolean} [args.update_config] Whether to allow updating collection configurations. Defaults to `false`.
160+
* @param {boolean} [args.delete_collection] Whether to allow deleting collections. Defaults to `false`.
161+
*/
137162
collections: (args: {
138163
collection: string | string[];
139164
create_collection?: boolean;
@@ -151,24 +176,54 @@ export const permissions = {
151176
return out;
152177
});
153178
},
179+
/**
180+
* Create a set of permissions specific to any operations involving objects within collections and tenants.
181+
*
182+
* For all collections, provide the `collection` argument as `'*'`.
183+
* For all tenants, provide the `tenant` argument as `'*'`.
184+
*
185+
* Providing arrays of collections and tenants will create permissions for each combination of collection and tenant.
186+
* E.g., `data({ collection: ['A', 'B'], tenant: ['X', 'Y'] })` will create permissions for tenants `X` and `Y` in both collections `A` and `B`.
187+
*
188+
* @param {string | string[]} args.collection The collection or collections to create permissions for.
189+
* @param {string | string[]} [args.tenant] The tenant or tenants to create permissions for. Defaults to `'*'`.
190+
* @param {boolean} [args.create] Whether to allow creating objects. Defaults to `false`.
191+
* @param {boolean} [args.read] Whether to allow reading objects. Defaults to `false`.
192+
* @param {boolean} [args.update] Whether to allow updating objects. Defaults to `false`.
193+
* @param {boolean} [args.delete] Whether to allow deleting objects. Defaults to `false`.
194+
*/
154195
data: (args: {
155196
collection: string | string[];
197+
tenant?: string | string[];
156198
create?: boolean;
157199
read?: boolean;
158200
update?: boolean;
159201
delete?: boolean;
160202
}): DataPermission[] => {
161203
const collections = Array.isArray(args.collection) ? args.collection : [args.collection];
162-
return collections.flatMap((collection) => {
163-
const out: DataPermission = { collection, actions: [] };
204+
const tenants = Array.isArray(args.tenant) ? args.tenant : [args.tenant ?? '*'];
205+
const combinations = collections.flatMap((collection) =>
206+
tenants.map((tenant) => ({ collection, tenant }))
207+
);
208+
return combinations.flatMap(({ collection, tenant }) => {
209+
const out: DataPermission = { collection, tenant, actions: [] };
164210
if (args.create) out.actions.push('create_data');
165211
if (args.read) out.actions.push('read_data');
166212
if (args.update) out.actions.push('update_data');
167213
if (args.delete) out.actions.push('delete_data');
168214
return out;
169215
});
170216
},
217+
/**
218+
* This namespace contains methods to create permissions specific to nodes.
219+
*/
171220
nodes: {
221+
/**
222+
* Create a set of permissions specific to reading nodes with verbosity set to `minimal`.
223+
*
224+
* @param {boolean} [args.read] Whether to allow reading nodes. Defaults to `false`.
225+
* @returns {NodesPermission[]} The permissions for reading nodes.
226+
*/
172227
minimal: (args: { read?: boolean }): NodesPermission[] => {
173228
const out: NodesPermission = {
174229
collection: '*',
@@ -178,6 +233,13 @@ export const permissions = {
178233
if (args.read) out.actions.push('read_nodes');
179234
return [out];
180235
},
236+
/**
237+
* Create a set of permissions specific to reading nodes with verbosity set to `verbose`.
238+
*
239+
* @param {string | string[]} args.collection The collection or collections to create permissions for.
240+
* @param {boolean} [args.read] Whether to allow reading nodes. Defaults to `false`.
241+
* @returns {NodesPermission[]} The permissions for reading nodes.
242+
*/
181243
verbose: (args: { collection: string | string[]; read?: boolean }): NodesPermission[] => {
182244
const collections = Array.isArray(args.collection) ? args.collection : [args.collection];
183245
return collections.flatMap((collection) => {
@@ -191,6 +253,16 @@ export const permissions = {
191253
});
192254
},
193255
},
256+
/**
257+
* Create a set of permissions specific to any operations involving roles.
258+
*
259+
* @param {string | string[]} args.role The role or roles to create permissions for.
260+
* @param {boolean} [args.create] Whether to allow creating roles. Defaults to `false`.
261+
* @param {boolean} [args.read] Whether to allow reading roles. Defaults to `false`.
262+
* @param {boolean} [args.update] Whether to allow updating roles. Defaults to `false`.
263+
* @param {boolean} [args.delete] Whether to allow deleting roles. Defaults to `false`.
264+
* @returns {RolesPermission[]} The permissions for the specified roles.
265+
*/
194266
roles: (args: {
195267
role: string | string[];
196268
create?: boolean;
@@ -208,32 +280,62 @@ export const permissions = {
208280
return out;
209281
});
210282
},
283+
/**
284+
* Create a set of permissions specific to any operations involving tenants.
285+
*
286+
* For all collections, provide the `collection` argument as `'*'`.
287+
* For all tenants, provide the `tenant` argument as `'*'`.
288+
*
289+
* Providing arrays of collections and tenants will create permissions for each combination of collection and tenant.
290+
* E.g., `tenants({ collection: ['A', 'B'], tenant: ['X', 'Y'] })` will create permissions for tenants `X` and `Y` in both collections `A` and `B`.
291+
*
292+
* @param {string | string[] | Record<string, string | string[]>} args.collection The collection or collections to create permissions for.
293+
* @param {string | string[]} [args.tenant] The tenant or tenants to create permissions for. Defaults to `'*'`.
294+
* @param {boolean} [args.create] Whether to allow creating tenants. Defaults to `false`.
295+
* @param {boolean} [args.read] Whether to allow reading tenants. Defaults to `false`.
296+
* @param {boolean} [args.update] Whether to allow updating tenants. Defaults to `false`.
297+
* @param {boolean} [args.delete] Whether to allow deleting tenants. Defaults to `false`.
298+
* @returns {TenantsPermission[]} The permissions for the specified tenants.
299+
*/
211300
tenants: (args: {
212301
collection: string | string[];
302+
tenant?: string | string[];
213303
create?: boolean;
214304
read?: boolean;
215305
update?: boolean;
216306
delete?: boolean;
217307
}): TenantsPermission[] => {
218308
const collections = Array.isArray(args.collection) ? args.collection : [args.collection];
219-
return collections.flatMap((collection) => {
220-
const out: TenantsPermission = { collection, actions: [] };
309+
const tenants = Array.isArray(args.tenant) ? args.tenant : [args.tenant ?? '*'];
310+
const combinations = collections.flatMap((collection) =>
311+
tenants.map((tenant) => ({ collection, tenant }))
312+
);
313+
return combinations.flatMap(({ collection, tenant }) => {
314+
const out: TenantsPermission = { collection, tenant, actions: [] };
221315
if (args.create) out.actions.push('create_tenants');
222316
if (args.read) out.actions.push('read_tenants');
223317
if (args.update) out.actions.push('update_tenants');
224318
if (args.delete) out.actions.push('delete_tenants');
225319
return out;
226320
});
227321
},
322+
/**
323+
* Create a set of permissions specific to any operations involving users.
324+
*
325+
* @param {string | string[]} args.user The user or users to create permissions for.
326+
* @param {boolean} [args.assignAndRevoke] Whether to allow assigning and revoking users. Defaults to `false`.
327+
* @param {boolean} [args.read] Whether to allow reading users. Defaults to `false`.
328+
* @returns {UsersPermission[]} The permissions for the specified users.
329+
*/
228330
users: (args: {
229331
user: string | string[];
230-
assign_and_revoke?: boolean;
332+
assignAndRevoke?: boolean;
231333
read?: boolean;
232334
}): UsersPermission[] => {
233335
const users = Array.isArray(args.user) ? args.user : [args.user];
234336
return users.flatMap((user) => {
235337
const out: UsersPermission = { users: user, actions: [] };
236-
if (args.assign_and_revoke) out.actions.push('assign_and_revoke_users');
338+
if (args.assignAndRevoke) out.actions.push('assign_and_revoke_users');
237339
if (args.read) out.actions.push('read_users');
238340
return out;
239341
});

0 commit comments

Comments
 (0)