From 6a5805158f66846c1cf72b153b63e263fc13526f Mon Sep 17 00:00:00 2001 From: Aviad Lichtenstadt Date: Sun, 11 Feb 2024 16:07:51 +0200 Subject: [PATCH] Tenant level roles (#335) + tests + readme related to https://github.com/descope/etc/issues/2563 --- README.md | 8 +++++--- lib/management/role.test.ts | 18 +++++++++++++----- lib/management/role.ts | 10 ++++++---- lib/management/types.ts | 1 + 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5ab80654..ebf3bf0b 100644 --- a/README.md +++ b/README.md @@ -906,19 +906,21 @@ You can create, update, delete or load roles: ```typescript // You can optionally set a description and associated permission for a roles. +// The optional `tenantId` will scope this role for a specific tenant. If left empty, the role will be available to all tenants. const name = 'My Role'; +const tenantId = ''; let description = 'Optional description to briefly explain what this role allows.'; const permissionNames = ['My Updated Permission']; -descopeClient.management.role.create(name, description, permissionNames); +descopeClient.management.role.create(name, description, permissionNames, tenantId); // Update will override all fields as is. Use carefully. const newName = 'My Updated Role'; description = 'A revised description'; permissionNames.push('Another Permission'); -descopeClient.management.role.update(name, newName, description, permissionNames); +descopeClient.management.role.update(name, newName, description, permissionNames, tenantId); // Role deletion cannot be undone. Use carefully. -descopeClient.management.role.delete(newName); +descopeClient.management.role.delete(newName, tenantId); // Load all roles const rolesRes = await descopeClient.management.role.loadAll(); diff --git a/lib/management/role.test.ts b/lib/management/role.test.ts index 0b3cbab7..f27f2676 100644 --- a/lib/management/role.test.ts +++ b/lib/management/role.test.ts @@ -24,6 +24,7 @@ const mockRoles = [ description: 'description3', permissionNames: [], createdTime: new Date().getTime(), + tenantId: 't1', }, ]; @@ -48,11 +49,11 @@ describe('Management Role', () => { }; mockHttpClient.post.mockResolvedValue(httpResponse); - const resp = await management.role.create('name', 'description', ['p1', 'p2']); + const resp = await management.role.create('name', 'description', ['p1', 'p2'], 't1'); expect(mockHttpClient.post).toHaveBeenCalledWith( apiPaths.role.create, - { name: 'name', description: 'description', permissionNames: ['p1', 'p2'] }, + { name: 'name', description: 'description', permissionNames: ['p1', 'p2'], tenantId: 't1' }, { token: 'key' }, ); @@ -75,12 +76,19 @@ describe('Management Role', () => { }; mockHttpClient.post.mockResolvedValue(httpResponse); - const resp = await management.role.update('name', 'newName', 'description', ['p1', 'p2']); + const resp = await management.role.update( + 'name', + 'newName', + 'description', + ['p1', 'p2'], + 't1', + ); expect(mockHttpClient.post).toHaveBeenCalledWith( apiPaths.role.update, { name: 'name', + tenantId: 't1', newName: 'newName', description: 'description', permissionNames: ['p1', 'p2'], @@ -107,11 +115,11 @@ describe('Management Role', () => { }; mockHttpClient.post.mockResolvedValue(httpResponse); - const resp = await management.role.delete('name'); + const resp = await management.role.delete('name', 't1'); expect(mockHttpClient.post).toHaveBeenCalledWith( apiPaths.role.delete, - { name: 'name' }, + { name: 'name', tenantId: 't1' }, { token: 'key' }, ); diff --git a/lib/management/role.ts b/lib/management/role.ts index 99eb6453..a041bae1 100644 --- a/lib/management/role.ts +++ b/lib/management/role.ts @@ -12,11 +12,12 @@ const withRole = (sdk: CoreSdk, managementKey?: string) => ({ name: string, description?: string, permissionNames?: string[], + tenantId?: string, ): Promise> => transformResponse( sdk.httpClient.post( apiPaths.role.create, - { name, description, permissionNames }, + { name, description, permissionNames, tenantId }, { token: managementKey }, ), ), @@ -25,17 +26,18 @@ const withRole = (sdk: CoreSdk, managementKey?: string) => ({ newName: string, description?: string, permissionNames?: string[], + tenantId?: string, ): Promise> => transformResponse( sdk.httpClient.post( apiPaths.role.update, - { name, newName, description, permissionNames }, + { name, newName, description, permissionNames, tenantId }, { token: managementKey }, ), ), - delete: (name: string): Promise> => + delete: (name: string, tenantId?: string): Promise> => transformResponse( - sdk.httpClient.post(apiPaths.role.delete, { name }, { token: managementKey }), + sdk.httpClient.post(apiPaths.role.delete, { name, tenantId }, { token: managementKey }), ), loadAll: (): Promise> => transformResponse( diff --git a/lib/management/types.ts b/lib/management/types.ts index e0ece9dd..d8dc7fff 100644 --- a/lib/management/types.ts +++ b/lib/management/types.ts @@ -233,6 +233,7 @@ export type Role = { description?: string; permissionNames: string[]; createdTime: number; + tenantId?: string; }; /** Represents a group in a project. It has an id and display name and a list of group members. */