From 0efc238fdbda8c7bcb9bba30af395498ca7e42b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Fri, 30 Apr 2021 13:25:24 +0200 Subject: [PATCH] fix: define root role by setting the name of the role (#823) --- src/lib/services/access-service.ts | 21 +++++++++++++++---- src/lib/services/user-service.ts | 11 ++++------ .../e2e/services/user-service.e2e.test.ts | 13 ++++++++++++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/lib/services/access-service.ts b/src/lib/services/access-service.ts index a950955d00..cb4be95744 100644 --- a/src/lib/services/access-service.ts +++ b/src/lib/services/access-service.ts @@ -159,9 +159,11 @@ export class AccessService { return this.store.addUserToRole(userId, roleId); } - async setUserRootRole(userId: number, roleId: number): Promise { - const roles = await this.getRootRoles(); - const newRootRole = roles.find(r => r.id === roleId); + async setUserRootRole( + userId: number, + role: number | RoleName, + ): Promise { + const newRootRole = await this.resolveRootRole(role); if (newRootRole) { try { @@ -176,7 +178,7 @@ export class AccessService { ); } } else { - throw new Error(`Could not find rootRole with id=${roleId}`); + throw new Error(`Could not find rootRole=${role}`); } } @@ -316,6 +318,17 @@ export class AccessService { return this.store.getRootRoles(); } + private async resolveRootRole(rootRole: number | RoleName): Promise { + const rootRoles = await this.getRootRoles(); + let role: IRole; + if (typeof rootRole === 'number') { + role = rootRoles.find(r => r.id === rootRole); + } else { + role = rootRoles.find(r => r.name === rootRole); + } + return role; + } + async getRootRole(roleName: RoleName): Promise { const roles = await this.store.getRootRoles(); return roles.find(r => r.name === roleName); diff --git a/src/lib/services/user-service.ts b/src/lib/services/user-service.ts index 6ed9916de4..e0caf8e8b6 100644 --- a/src/lib/services/user-service.ts +++ b/src/lib/services/user-service.ts @@ -21,6 +21,7 @@ import { IUnleashStores } from '../types/stores'; import PasswordUndefinedError from '../error/password-undefined'; import EventStore from '../db/event-store'; import { USER_UPDATED, USER_CREATED, USER_DELETED } from '../types/events'; +import { IRole } from '../db/access-store'; const systemUser = new User({ id: -1, username: 'system' }); @@ -29,14 +30,14 @@ export interface ICreateUser { email?: string; username?: string; password?: string; - rootRole: number; + rootRole: number | RoleName; } export interface IUpdateUser { id: number; name?: string; email?: string; - rootRole?: number; + rootRole?: number | RoleName; } interface IUserWithRole extends IUser { @@ -128,11 +129,7 @@ class UserService { const passwordHash = await bcrypt.hash(pwd, saltRounds); await this.store.setPasswordHash(user.id, passwordHash); - const rootRoles = await this.accessService.getRootRoles(); - const adminRole = rootRoles.find( - r => r.name === RoleName.ADMIN, - ); - await this.accessService.setUserRootRole(user.id, adminRole.id); + await this.accessService.setUserRootRole(user.id, RoleName.ADMIN); } catch (e) { this.logger.error('Unable to create default user "admin"'); } diff --git a/src/test/e2e/services/user-service.e2e.test.ts b/src/test/e2e/services/user-service.e2e.test.ts index c62c1d0dc7..797f4632c4 100644 --- a/src/test/e2e/services/user-service.e2e.test.ts +++ b/src/test/e2e/services/user-service.e2e.test.ts @@ -97,6 +97,19 @@ test.serial('should get user with root role', async t => { t.is(user.rootRole, adminRole.id); }); +test.serial('should get user with root role by name', async t => { + const email = 'some2@test.com'; + const u = await userService.createUser({ + email, + password: 'A very strange P4ssw0rd_', + rootRole: RoleName.ADMIN, + }); + const user = await userService.getUser(u.id); + t.is(user.email, email); + t.is(user.id, u.id); + t.is(user.rootRole, adminRole.id); +}); + test.serial(`deleting a user should delete the user's sessions`, async t => { const email = 'some@test.com'; const user = await userService.createUser({