Skip to content

Commit 4e0bb71

Browse files
committed
feat: enable dynamic user management, add db/oidc namespaces
1 parent 8e99a85 commit 4e0bb71

File tree

7 files changed

+252
-121
lines changed

7 files changed

+252
-121
lines changed

src/classifications/scheduler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export default class ClassificationsScheduler extends CommandBase {
101101
reject(
102102
new Error(
103103
"classification didn't finish within configured timeout, " +
104-
'set larger timeout with .withWaitTimeout(timeout)'
104+
'set larger timeout with .withWaitTimeout(timeout)'
105105
)
106106
);
107107
}, this.waitTimeout);

src/connection/http.ts

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,14 @@ export default class ConnectionREST {
116116
postReturn = <B, T>(path: string, payload: B): Promise<T> => {
117117
if (this.authEnabled) {
118118
return this.login().then((token) =>
119-
this.http.post<B, T>(path, payload, true, token).then((res) => res as T)
119+
this.http.post<B, T>(path, payload, true, token) as T
120120
);
121121
}
122-
return this.http.post<B, T>(path, payload, true, '').then((res) => res as T);
122+
return this.http.post<B, T>(path, payload, true, '') as Promise<T>;
123+
};
124+
125+
postNoBody = <T>(path: string): Promise<T> => {
126+
return this.postReturn<null, T>(path, null);
123127
};
124128

125129
postEmpty = <B>(path: string, payload: B): Promise<void> => {
@@ -372,46 +376,46 @@ const makeUrl = (basePath: string) => (path: string) => basePath + path;
372376

373377
const checkStatus =
374378
<T>(expectResponseBody: boolean) =>
375-
(res: Response) => {
376-
if (res.status >= 400) {
377-
return res.text().then((errText: string) => {
378-
let err: string;
379-
try {
380-
// in case of invalid json response (like empty string)
381-
err = JSON.stringify(JSON.parse(errText));
382-
} catch (e) {
383-
err = errText;
384-
}
385-
if (res.status === 401) {
386-
return Promise.reject(new WeaviateUnauthenticatedError(err));
387-
} else if (res.status === 403) {
388-
return Promise.reject(new WeaviateInsufficientPermissionsError(403, err));
389-
} else {
390-
return Promise.reject(new WeaviateUnexpectedStatusCodeError(res.status, err));
391-
}
392-
});
393-
}
394-
if (expectResponseBody) {
395-
return res.json() as Promise<T>;
396-
}
397-
return Promise.resolve(undefined);
398-
};
379+
(res: Response) => {
380+
if (res.status >= 400) {
381+
return res.text().then((errText: string) => {
382+
let err: string;
383+
try {
384+
// in case of invalid json response (like empty string)
385+
err = JSON.stringify(JSON.parse(errText));
386+
} catch (e) {
387+
err = errText;
388+
}
389+
if (res.status === 401) {
390+
return Promise.reject(new WeaviateUnauthenticatedError(err));
391+
} else if (res.status === 403) {
392+
return Promise.reject(new WeaviateInsufficientPermissionsError(403, err));
393+
} else {
394+
return Promise.reject(new WeaviateUnexpectedStatusCodeError(res.status, err));
395+
}
396+
});
397+
}
398+
if (expectResponseBody) {
399+
return res.json() as Promise<T>;
400+
}
401+
return Promise.resolve(undefined);
402+
};
399403

400404
const handleHeadResponse =
401405
<T>(expectResponseBody: boolean) =>
402-
(res: Response) => {
403-
if (res.status == 200 || res.status == 204 || res.status == 404) {
404-
return Promise.resolve(res.status == 200 || res.status == 204);
405-
}
406-
return checkStatus<T>(expectResponseBody)(res);
407-
};
406+
(res: Response) => {
407+
if (res.status == 200 || res.status == 204 || res.status == 404) {
408+
return Promise.resolve(res.status == 200 || res.status == 204);
409+
}
410+
return checkStatus<T>(expectResponseBody)(res);
411+
};
408412

409413
const getAuthHeaders = (config: InternalConnectionParams, bearerToken: string) =>
410414
bearerToken
411415
? {
412-
Authorization: `Bearer ${bearerToken}`,
413-
'X-Weaviate-Cluster-Url': config.host,
414-
// keeping for backwards compatibility for older clusters for now. On newer clusters, Embedding Service reuses Authorization header.
415-
'X-Weaviate-Api-Key': bearerToken,
416-
}
416+
Authorization: `Bearer ${bearerToken}`,
417+
'X-Weaviate-Cluster-Url': config.host,
418+
// keeping for backwards compatibility for older clusters for now. On newer clusters, Embedding Service reuses Authorization header.
419+
'X-Weaviate-Api-Key': bearerToken,
420+
}
417421
: undefined;

src/openapi/schema.ts

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -386,30 +386,30 @@ export interface definitions {
386386
* @enum {string}
387387
*/
388388
action:
389-
| 'manage_backups'
390-
| 'read_cluster'
391-
| 'create_data'
392-
| 'read_data'
393-
| 'update_data'
394-
| 'delete_data'
395-
| 'read_nodes'
396-
| 'create_roles'
397-
| 'read_roles'
398-
| 'update_roles'
399-
| 'delete_roles'
400-
| 'create_collections'
401-
| 'read_collections'
402-
| 'update_collections'
403-
| 'delete_collections'
404-
| 'assign_and_revoke_users'
405-
| 'create_users'
406-
| 'read_users'
407-
| 'update_users'
408-
| 'delete_users'
409-
| 'create_tenants'
410-
| 'read_tenants'
411-
| 'update_tenants'
412-
| 'delete_tenants';
389+
| 'manage_backups'
390+
| 'read_cluster'
391+
| 'create_data'
392+
| 'read_data'
393+
| 'update_data'
394+
| 'delete_data'
395+
| 'read_nodes'
396+
| 'create_roles'
397+
| 'read_roles'
398+
| 'update_roles'
399+
| 'delete_roles'
400+
| 'create_collections'
401+
| 'read_collections'
402+
| 'update_collections'
403+
| 'delete_collections'
404+
| 'assign_and_revoke_users'
405+
| 'create_users'
406+
| 'read_users'
407+
| 'update_users'
408+
| 'delete_users'
409+
| 'create_tenants'
410+
| 'read_tenants'
411+
| 'update_tenants'
412+
| 'delete_tenants';
413413
};
414414
/** @description list of roles */
415415
RolesListResponse: definitions['Role'][];
@@ -787,15 +787,15 @@ export interface definitions {
787787
* @enum {string}
788788
*/
789789
tokenization?:
790-
| 'word'
791-
| 'lowercase'
792-
| 'whitespace'
793-
| 'field'
794-
| 'trigram'
795-
| 'gse'
796-
| 'kagome_kr'
797-
| 'kagome_ja'
798-
| 'gse_ch';
790+
| 'word'
791+
| 'lowercase'
792+
| 'whitespace'
793+
| 'field'
794+
| 'trigram'
795+
| 'gse'
796+
| 'kagome_kr'
797+
| 'kagome_ja'
798+
| 'gse_ch';
799799
/** @description The properties of the nested object(s). Applies to object and object[] data types. */
800800
nestedProperties?: definitions['NestedProperty'][];
801801
};
@@ -816,15 +816,15 @@ export interface definitions {
816816
indexRangeFilters?: boolean;
817817
/** @enum {string} */
818818
tokenization?:
819-
| 'word'
820-
| 'lowercase'
821-
| 'whitespace'
822-
| 'field'
823-
| 'trigram'
824-
| 'gse'
825-
| 'kagome_kr'
826-
| 'kagome_ja'
827-
| 'gse_ch';
819+
| 'word'
820+
| 'lowercase'
821+
| 'whitespace'
822+
| 'field'
823+
| 'trigram'
824+
| 'gse'
825+
| 'kagome_kr'
826+
| 'kagome_ja'
827+
| 'gse_ch';
828828
/** @description The properties of the nested object(s). Applies to object and object[] data types. */
829829
nestedProperties?: definitions['NestedProperty'][];
830830
};
@@ -1505,19 +1505,19 @@ export interface definitions {
15051505
* @enum {string}
15061506
*/
15071507
operator?:
1508-
| 'And'
1509-
| 'Or'
1510-
| 'Equal'
1511-
| 'Like'
1512-
| 'NotEqual'
1513-
| 'GreaterThan'
1514-
| 'GreaterThanEqual'
1515-
| 'LessThan'
1516-
| 'LessThanEqual'
1517-
| 'WithinGeoRange'
1518-
| 'IsNull'
1519-
| 'ContainsAny'
1520-
| 'ContainsAll';
1508+
| 'And'
1509+
| 'Or'
1510+
| 'Equal'
1511+
| 'Like'
1512+
| 'NotEqual'
1513+
| 'GreaterThan'
1514+
| 'GreaterThanEqual'
1515+
| 'LessThan'
1516+
| 'LessThanEqual'
1517+
| 'WithinGeoRange'
1518+
| 'IsNull'
1519+
| 'ContainsAny'
1520+
| 'ContainsAll';
15211521
/**
15221522
* @description path to the property currently being filtered
15231523
* @example [
@@ -1618,16 +1618,16 @@ export interface definitions {
16181618
* @enum {string}
16191619
*/
16201620
activityStatus?:
1621-
| 'ACTIVE'
1622-
| 'INACTIVE'
1623-
| 'OFFLOADED'
1624-
| 'OFFLOADING'
1625-
| 'ONLOADING'
1626-
| 'HOT'
1627-
| 'COLD'
1628-
| 'FROZEN'
1629-
| 'FREEZING'
1630-
| 'UNFREEZING';
1621+
| 'ACTIVE'
1622+
| 'INACTIVE'
1623+
| 'OFFLOADED'
1624+
| 'OFFLOADING'
1625+
| 'ONLOADING'
1626+
| 'HOT'
1627+
| 'COLD'
1628+
| 'FROZEN'
1629+
| 'FREEZING'
1630+
| 'UNFREEZING';
16311631
};
16321632
/** @description attributes representing a single tenant response within weaviate */
16331633
TenantResponse: definitions['Tenant'] & {
@@ -4187,4 +4187,4 @@ export interface operations {
41874187
};
41884188
}
41894189

4190-
export interface external {}
4190+
export interface external { }

src/openapi/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ export type WeaviateReplicationConfig = WeaviateClass['replicationConfig'];
5555
export type WeaviateShardingConfig = WeaviateClass['shardingConfig'];
5656
export type WeaviateShardStatus = definitions['ShardStatusGetResponse'];
5757
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'];
5862
export type WeaviateVectorIndexConfig = WeaviateClass['vectorIndexConfig'];
5963
export type WeaviateVectorsConfig = WeaviateClass['vectorConfig'];
6064
export type WeaviateVectorConfig = definitions['VectorConfig'];

src/roles/util.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Permission as WeaviatePermission, Role as WeaviateRole, WeaviateUser } from '../openapi/types.js';
2-
import { User } from '../users/types.js';
1+
import { WeaviateDBUser, Permission as WeaviatePermission, Role as WeaviateRole, WeaviateUser } from '../openapi/types.js';
2+
import { User, UserDB } from '../users/types.js';
33
import {
44
BackupsAction,
55
BackupsPermission,
@@ -136,7 +136,19 @@ export class Map {
136136
static user = (user: WeaviateUser): User => ({
137137
id: user.username,
138138
roles: user.roles?.map(Map.roleFromWeaviate),
139-
});
139+
})
140+
static dbUser = (user: WeaviateDBUser): UserDB => ({
141+
userType: user.dbUserType,
142+
id: user.userId,
143+
roleNames: user.roles,
144+
active: user.active,
145+
})
146+
static dbUsers = (users: WeaviateDBUser[]): UserDB[] =>
147+
users.reduce((acc, user) => {
148+
acc.push(Map.dbUser(user));
149+
return acc;
150+
}, [] as UserDB[])
151+
;
140152
}
141153

142154
class PermissionsMapping {

0 commit comments

Comments
 (0)