Skip to content

Commit 7938b03

Browse files
committed
feat(breaking): include user types in user assignments
1 parent 0299405 commit 7938b03

File tree

7 files changed

+80
-24
lines changed

7 files changed

+80
-24
lines changed

src/openapi/types.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { definitions } from './schema.js';
1+
import { definitions, operations } from './schema.js';
22

33
type Override<T1, T2> = Omit<T1, keyof T2> & T2;
44
type DefaultProperties = { [key: string]: unknown };
@@ -54,11 +54,6 @@ export type WeaviateMultiTenancyConfig = WeaviateClass['multiTenancyConfig'];
5454
export type WeaviateReplicationConfig = WeaviateClass['replicationConfig'];
5555
export type WeaviateShardingConfig = WeaviateClass['shardingConfig'];
5656
export type WeaviateShardStatus = definitions['ShardStatusGetResponse'];
57-
export type WeaviateUser = definitions['UserOwnInfo'];
58-
export type WeaviateDBUser = definitions['DBUserInfo'];
59-
export type WeaviateUserType = definitions['UserTypeOutput'];
60-
export type WeaviateUserTypeInternal = definitions['UserTypeInput'];
61-
export type WeaviateUserTypeDB = definitions['DBUserInfo']['dbUserType'];
6257
export type WeaviateVectorIndexConfig = WeaviateClass['vectorIndexConfig'];
6358
export type WeaviateVectorsConfig = WeaviateClass['vectorConfig'];
6459
export type WeaviateVectorConfig = definitions['VectorConfig'];
@@ -73,3 +68,9 @@ export type Meta = definitions['Meta'];
7368
export type Role = definitions['Role'];
7469
export type Permission = definitions['Permission'];
7570
export type Action = definitions['Permission']['action'];
71+
export type WeaviateUser = definitions['UserOwnInfo'];
72+
export type WeaviateDBUser = definitions['DBUserInfo'];
73+
export type WeaviateUserType = definitions['UserTypeOutput'];
74+
export type WeaviateUserTypeInternal = definitions['UserTypeInput'];
75+
export type WeaviateUserTypeDB = definitions['DBUserInfo']['dbUserType'];
76+
export type WeaviateAssignedUser = operations['getUsersForRole']['responses']['200']['schema'][0];

src/roles/index.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { ConnectionREST } from '../index.js';
2-
import { Permission as WeaviatePermission, Role as WeaviateRole } from '../openapi/types.js';
2+
import {
3+
WeaviateAssignedUser,
4+
Permission as WeaviatePermission,
5+
Role as WeaviateRole,
6+
} from '../openapi/types.js';
37
import {
48
BackupsPermission,
59
ClusterPermission,
@@ -11,6 +15,7 @@ import {
1115
Role,
1216
RolesPermission,
1317
TenantsPermission,
18+
UserAssignment,
1419
UsersPermission,
1520
} from './types.js';
1621
import { Map } from './util.js';
@@ -35,7 +40,7 @@ export interface Roles {
3540
* @param {string} roleName The name of the role to retrieve the assigned user IDs for.
3641
* @returns {Promise<string[]>} The user IDs assigned to the role.
3742
*/
38-
assignedUserIds: (roleName: string) => Promise<string[]>;
43+
userAssignments: (roleName: string) => Promise<UserAssignment[]>;
3944
/**
4045
* Delete a role by its name.
4146
*
@@ -89,7 +94,10 @@ const roles = (connection: ConnectionREST): Roles => {
8994
listAll: () => connection.get<WeaviateRole[]>('/authz/roles').then(Map.roles),
9095
byName: (roleName: string) =>
9196
connection.get<WeaviateRole>(`/authz/roles/${roleName}`).then(Map.roleFromWeaviate),
92-
assignedUserIds: (roleName: string) => connection.get<string[]>(`/authz/roles/${roleName}/users`),
97+
userAssignments: (roleName: string) =>
98+
connection
99+
.get<WeaviateAssignedUser[]>(`/authz/roles/${roleName}/user-assignments`, true)
100+
.then(Map.assignedUsers),
93101
create: (roleName: string, permissions: PermissionsInput) => {
94102
const perms = Map.flattenPermissions(permissions).flatMap(Map.permissionToWeaviate);
95103
return connection

src/roles/integration.test.ts

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import weaviate, { ApiKey, Permission, Role, WeaviateClient } from '..';
1+
import weaviate, { ApiKey, Permission, Role, UserAssignment, WeaviateClient } from '..';
2+
import { requireAtLeast } from '../../test/version';
23
import { WeaviateStartUpError, WeaviateUnexpectedStatusCodeError } from '../errors';
3-
import { DbVersion } from '../utils/dbVersion';
44

5-
const only = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`).isAtLeast(1, 29, 0)
6-
? describe
7-
: describe.skip;
8-
9-
only('Integration testing of the roles namespace', () => {
5+
requireAtLeast(
6+
1,
7+
29,
8+
0
9+
)('Integration testing of the roles namespace', () => {
1010
let client: WeaviateClient;
1111

1212
beforeAll(async () => {
@@ -40,6 +40,35 @@ only('Integration testing of the roles namespace', () => {
4040
expect(exists).toBeFalsy();
4141
});
4242

43+
requireAtLeast(
44+
1,
45+
30,
46+
0
47+
)('namespaced users', () => {
48+
it('retrieves assigned users with namespace', async () => {
49+
await client.roles.create('landlord', {
50+
collection: 'Buildings',
51+
actions: ['create_tenants', 'delete_tenants'],
52+
});
53+
54+
await client.users.db.create('Innkeeper').catch((res) => expect(res.code).toEqual(409));
55+
56+
await client.users.db.assignRoles('landlord', 'custom-user');
57+
await client.users.db.assignRoles('landlord', 'Innkeeper');
58+
59+
const assignments = await client.roles.userAssignments('landlord');
60+
61+
expect(assignments).toEqual(
62+
expect.arrayContaining([
63+
expect.objectContaining<UserAssignment>({ id: 'custom-user', userType: 'db_env_user' }),
64+
expect.objectContaining<UserAssignment>({ id: 'Innkeeper', userType: 'db_user' }),
65+
])
66+
);
67+
68+
await client.users.db.delete('Innkeeper');
69+
});
70+
});
71+
4372
describe('should be able to create roles using the permissions factory', () => {
4473
type TestCase = {
4574
roleName: string;
@@ -262,6 +291,7 @@ only('Integration testing of the roles namespace', () => {
262291
'roles',
263292
'tenants',
264293
'users',
294+
'landlord',
265295
].map((n) => client.roles.delete(n))
266296
)
267297
);

src/roles/types.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Action } from '../openapi/types.js';
1+
import { Action, WeaviateUserType } from '../openapi/types.js';
22

33
export type BackupsAction = Extract<Action, 'manage_backups'>;
44
export type ClusterAction = Extract<Action, 'read_cluster'>;
@@ -22,6 +22,11 @@ export type TenantsAction = Extract<
2222
>;
2323
export type UsersAction = Extract<Action, 'read_users' | 'assign_and_revoke_users'>;
2424

25+
export type UserAssignment = {
26+
id: string;
27+
userType: WeaviateUserType;
28+
};
29+
2530
export type BackupsPermission = {
2631
collection: string;
2732
actions: BackupsAction[];

src/roles/util.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
WeaviateAssignedUser,
23
WeaviateDBUser,
34
Permission as WeaviatePermission,
45
Role as WeaviateRole,
@@ -22,6 +23,7 @@ import {
2223
RolesPermission,
2324
TenantsAction,
2425
TenantsPermission,
26+
UserAssignment,
2527
UsersAction,
2628
UsersPermission,
2729
} from './types.js';
@@ -148,6 +150,15 @@ export class Map {
148150
acc.push(Map.dbUser(user));
149151
return acc;
150152
}, [] as UserDB[]);
153+
154+
static assignedUsers = (users: WeaviateAssignedUser[]): UserAssignment[] =>
155+
users.reduce((acc, user) => {
156+
acc.push({
157+
id: user.userId || '',
158+
userType: user.userType,
159+
});
160+
return acc;
161+
}, [] as UserAssignment[]);
151162
}
152163

153164
class PermissionsMapping {

src/users/integration.test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
import weaviate, { ApiKey } from '..';
2-
import { DbVersion } from '../utils/dbVersion';
2+
import { requireAtLeast } from '../../test/version.js';
33
import { WeaviateUserTypeDB } from '../v2';
44
import { UserDB } from './types.js';
55

6-
const version = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`);
7-
8-
/** Run the suite / test only for Weaviate version above this. */
9-
const requireAtLeast = (...semver: [...Parameters<DbVersion['isAtLeast']>]) =>
10-
version.isAtLeast(...semver) ? describe : describe.skip;
11-
126
requireAtLeast(
137
1,
148
29,

test/version.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { DbVersion } from '../src/utils/dbVersion';
2+
3+
const version = DbVersion.fromString(`v${process.env.WEAVIATE_VERSION!}`);
4+
5+
/** Run the suite / test only for Weaviate version above this. */
6+
export const requireAtLeast = (...semver: [...Parameters<DbVersion['isAtLeast']>]) =>
7+
version.isAtLeast(...semver) ? describe : describe.skip;

0 commit comments

Comments
 (0)