Skip to content

Commit f7450c9

Browse files
authored
Merge pull request #285 from weaviate/fix/false-on-conflict
fix: revert breaking change and add deprecation notices - Bring back roles.assignedUserIds -- I'd got a false impression that this method was removed in the Python client and replaced it with userAssignments rather than deprecating it. - Return false on HTTP 409 Conflict from /activate and /deactivate endpoints. - Add deprecation notices to users.assignRoles, users.revokeRoles, and roles.assignedUserIds
2 parents 064882b + 7d9310a commit f7450c9

File tree

5 files changed

+42
-10
lines changed

5 files changed

+42
-10
lines changed

.github/workflows/main.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ env:
1313
WEAVIATE_127: 1.27.15
1414
WEAVIATE_128: 1.28.11
1515
WEAVIATE_129: 1.29.1
16-
WEAVIATE_130: 1.30.0-rc.0-6b9a01c
16+
WEAVIATE_130: 1.30.0
1717

1818
concurrency:
1919
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}

src/roles/index.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,25 @@ export interface Roles {
3434
* @returns {Promise<Role | null>} The role if it exists, or null if it does not.
3535
*/
3636
byName: (roleName: string) => Promise<Role | null>;
37+
38+
/**
39+
* Retrieve the user IDs assigned to a role.
40+
*
41+
* @param {string} roleName The name of the role to retrieve the assigned user IDs for.
42+
* @returns {Promise<string[]>} The user IDs assigned to the role.
43+
*
44+
* @deprecated: Use `userAssignments` instead.
45+
*/
46+
assignedUserIds: (roleName: string) => Promise<string[]>;
3747
/**
3848
* Retrieve the user IDs assigned to a role. Each user has a qualifying user type,
3949
* e.g. `'db_user' | 'db_env_user' | 'oidc'`.
4050
*
51+
* Note, unlike `assignedUserIds`, this method may return multiple entries for the same username,
52+
* if OIDC authentication is enabled: once with 'db_*' and once with 'oidc' user type.
53+
*
4154
* @param {string} roleName The name of the role to retrieve the assigned user IDs for.
42-
* @returns {Promise<string[]>} The user IDs assigned to the role.
55+
* @returns {Promise<UserAssignment[]>} User IDs and user types assigned to the role.
4356
*/
4457
userAssignments: (roleName: string) => Promise<UserAssignment[]>;
4558
/**
@@ -95,6 +108,7 @@ const roles = (connection: ConnectionREST): Roles => {
95108
listAll: () => connection.get<WeaviateRole[]>('/authz/roles').then(Map.roles),
96109
byName: (roleName: string) =>
97110
connection.get<WeaviateRole>(`/authz/roles/${roleName}`).then(Map.roleFromWeaviate),
111+
assignedUserIds: (roleName: string) => connection.get<string[]>(`/authz/roles/${roleName}/users`),
98112
userAssignments: (roleName: string) =>
99113
connection
100114
.get<WeaviateAssignedUser[]>(`/authz/roles/${roleName}/user-assignments`, true)

src/roles/integration.test.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ requireAtLeast(
322322
30,
323323
0
324324
)('namespaced users', () => {
325-
it('retrieves assigned users with namespace', async () => {
325+
it('retrieves assigned users with/without namespace', async () => {
326326
await client.roles.create('landlord', {
327327
collection: 'Buildings',
328328
tenant: 'john-doe',
@@ -342,6 +342,10 @@ requireAtLeast(
342342
])
343343
);
344344

345+
// Legacy
346+
const assignedUsers = await client.roles.assignedUserIds('landlord');
347+
expect(assignedUsers).toEqual(['Innkeeper', 'custom-user']);
348+
345349
await client.users.db.delete('Innkeeper');
346350
await client.roles.delete('landlord');
347351
});

src/users/index.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ interface UsersBase {
3434
}
3535

3636
export interface Users extends UsersBase {
37+
/** @deprecated: Use `users.db.assignRoles` or `users.oidc.assignRoles` instead. */
38+
assignRoles: (roleNames: string | string[], userId: string) => Promise<void>;
39+
/** @deprecated: Use `users.db.revokeRoles` or `users.oidc.revokeRoles` instead. */
40+
revokeRoles: (roleNames: string | string[], userId: string) => Promise<void>;
41+
3742
/**
3843
* Retrieve the information relevant to the currently authenticated user.
3944
*
@@ -45,6 +50,8 @@ export interface Users extends UsersBase {
4550
*
4651
* @param {string} userId The ID of the user to retrieve the assigned roles for.
4752
* @returns {Promise<Record<string, Role>>} A map of role names to their respective roles.
53+
*
54+
* @deprecated: Use `users.db.getAssignedRoles` or `users.oidc.getAssignedRoles` instead.
4855
*/
4956
getAssignedRoles: (userId: string) => Promise<Record<string, Role>>;
5057

@@ -147,11 +154,12 @@ const users = (connection: ConnectionREST): Users => {
147154
const db = (connection: ConnectionREST): DBUsers => {
148155
const ns = namespacedUsers(connection);
149156

150-
/** expectCode returns true if the error contained an expected status code. */
157+
/** expectCode returns false if the contained WeaviateUnexpectedStatusCodeError
158+
* has an known error code and rethrows the error otherwise. */
151159
const expectCode = (code: number): ((_: any) => boolean) => {
152160
return (error) => {
153-
if (error instanceof WeaviateUnexpectedStatusCodeError) {
154-
return error.code === code;
161+
if (error instanceof WeaviateUnexpectedStatusCodeError && error.code === code) {
162+
return false;
155163
}
156164
throw error;
157165
};

src/users/integration.test.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,22 @@ requireAtLeast(
7979
await expectDave().toHaveProperty('active', true);
8080

8181
// Second activation is a no-op
82-
await expect(client.users.db.activate('dynamic-dave')).resolves.toEqual(true);
82+
await expect(client.users.db.activate('dynamic-dave')).resolves.toEqual(false);
8383

84-
await client.users.db.deactivate('dynamic-dave');
84+
await expect(client.users.db.deactivate('dynamic-dave')).resolves.toEqual(true);
8585
await expectDave().toHaveProperty('active', false);
8686

8787
// Second deactivation is a no-op
88-
await expect(client.users.db.deactivate('dynamic-dave', { revokeKey: true })).resolves.toEqual(true);
88+
await expect(client.users.db.deactivate('dynamic-dave', { revokeKey: true })).resolves.toEqual(false);
89+
90+
// Re-activate
91+
await expect(client.users.db.activate('dynamic-dave')).resolves.toEqual(true);
8992

90-
await client.users.db.delete('dynamic-dave');
93+
await expect(client.users.db.delete('dynamic-dave')).resolves.toEqual(true);
9194
await expectDave(false).toHaveProperty('code', 404);
95+
96+
// Second deletion is a no-op
97+
await expect(client.users.db.delete('dynamic-dave')).resolves.toEqual(false);
9298
});
9399

94100
it('should be able to obtain and rotate api keys', async () => {

0 commit comments

Comments
 (0)