1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-07 01:16:28 +02:00

chore: Refactor role/access stores into more logical domains

This commit is contained in:
sighphyre 2021-12-20 16:17:59 +02:00 committed by Ivar Conradi Østhus
parent f97f8b03bc
commit 30de5f4b39
No known key found for this signature in database
GPG Key ID: 31AC596886B0BD09
15 changed files with 268 additions and 331 deletions

View File

@ -7,7 +7,6 @@ import {
IAccessStore,
IRole,
IUserPermission,
IUserRole,
} from '../types/stores/access-store';
import {
IAvailablePermissions,
@ -61,10 +60,6 @@ export class AccessStore implements IAccessStore {
await this.db.batchInsert(T.PERMISSIONS, rows);
}
async getRoleByName(name: string): Promise<IRole> {
return this.db(T.ROLES).where({ name }).first();
}
async delete(key: number): Promise<void> {
await this.db(T.ROLES).where({ id: key }).del();
}
@ -186,34 +181,17 @@ export class AccessStore implements IAccessStore {
});
}
async getRoles(): Promise<IRole[]> {
return this.db
.select(['id', 'name', 'type', 'description'])
.from<IRole>(T.ROLES);
}
async getRoleWithId(id: number): Promise<IRole> {
return this.db
.select(['id', 'name', 'type', 'description'])
.where('id', id)
.first()
.from<IRole>(T.ROLES);
}
async getProjectRoles(): Promise<IRole[]> {
return this.db
.select(['id', 'name', 'type', 'description'])
.from<IRole>(T.ROLES)
.where('type', 'custom')
.orWhere('type', 'project');
}
async getRolesForProject(projectId: string): Promise<IRole[]> {
return this.db
.select(['r.id', 'r.name', 'r.type', 'ru.project', 'r.description'])
.from<IRole>(`${T.ROLE_USER} as ru`)
.innerJoin(`${T.ROLES} as r`, 'ru.role_id', 'r.id')
.where('project', projectId);
async addEnvironmentPermissionsToRole(
role_id: number,
permissions: IPermission[],
): Promise<void> {
const rows = permissions.map((x) => {
return {
role_id,
permission_id: x.id,
};
});
this.db.batchInsert(T.ROLE_PERMISSION, rows);
}
async unlinkUserRoles(userId: number): Promise<void> {
@ -224,19 +202,17 @@ export class AccessStore implements IAccessStore {
.delete();
}
async getRootRoles(): Promise<IRole[]> {
return this.db
.select(['id', 'name', 'type', 'description'])
.from<IRole>(T.ROLES)
.andWhere('type', 'root');
}
async removeRolesForProject(projectId: string): Promise<void> {
return this.db(T.ROLE_USER)
.where({
project: projectId,
})
.delete();
async getProjectUserIdsForRole(
roleId: number,
projectId?: string,
): Promise<number[]> {
const rows = await this.db
.select(['user_id'])
.from<IRole>(`${T.ROLE_USER} AS ru`)
.join(`${T.ROLES} as r`, 'ru.role_id', 'id')
.where('r.id', roleId)
.andWhere('ru.project', projectId);
return rows.map((r) => r.user_id);
}
async getRolesForUserId(userId: number): Promise<IRole[]> {
@ -255,19 +231,6 @@ export class AccessStore implements IAccessStore {
return rows.map((r) => r.user_id);
}
async getProjectUserIdsForRole(
roleId: number,
projectId?: string,
): Promise<number[]> {
const rows = await this.db
.select(['user_id'])
.from<IRole>(`${T.ROLE_USER} AS ru`)
.join(`${T.ROLES} as r`, 'ru.role_id', 'id')
.where('r.id', roleId)
.andWhere('ru.project', projectId);
return rows.map((r) => r.user_id);
}
async addUserToRole(
userId: number,
roleId: number,
@ -308,39 +271,6 @@ export class AccessStore implements IAccessStore {
.delete();
}
async createRole(
name: string,
type: string,
description?: string,
): Promise<IRole> {
const [id] = await this.db(T.ROLES)
.insert({
name,
description,
type,
})
.returning('id');
return {
id,
name,
description,
type,
};
}
async addEnvironmentPermissionsToRole(
role_id: number,
permissions: IPermission[],
): Promise<void> {
const rows = permissions.map((x) => {
return {
role_id,
permission_id: x.id,
};
});
this.db.batchInsert(T.ROLE_PERMISSION, rows);
}
async addPermissionsToRole(
role_id: number,
permissions: string[],
@ -388,18 +318,4 @@ export class AccessStore implements IAccessStore {
})
.delete();
}
async getRootRoleForAllUsers(): Promise<IUserRole[]> {
const rows = await this.db
.select('id', 'user_id')
.distinctOn('user_id')
.from(`${T.ROLES} AS r`)
.leftJoin(`${T.ROLE_USER} AS ru`, 'r.id', 'ru.role_id')
.where('r.type', '=', 'root');
return rows.map((row) => ({
roleId: +row.id,
userId: +row.user_id,
}));
}
}

View File

@ -7,8 +7,13 @@ import {
ICustomRoleInsert,
ICustomRoleUpdate,
} from 'lib/types/stores/role-store';
import { IRole, IUserRole } from 'lib/types/stores/access-store';
const T = {
ROLE_USER: 'role_user',
ROLES: 'roles',
};
const TABLE = 'roles';
const COLUMNS = ['id', 'name', 'description', 'type'];
interface IRoleRow {
@ -34,14 +39,14 @@ export default class RoleStore {
async getAll(): Promise<ICustomRole[]> {
const rows = await this.db
.select(COLUMNS)
.from(TABLE)
.from(T.ROLES)
.orderBy('name', 'asc');
return rows.map(this.mapRow);
}
async create(role: ICustomRoleInsert): Promise<ICustomRole> {
const row = await this.db(TABLE)
const row = await this.db(T.ROLES)
.insert({
name: role.name,
description: role.description,
@ -52,16 +57,16 @@ export default class RoleStore {
}
async delete(id: number): Promise<void> {
return this.db(TABLE).where({ id }).del();
return this.db(T.ROLES).where({ id }).del();
}
async get(id: number): Promise<ICustomRole> {
const rows = await this.db.select(COLUMNS).from(TABLE).where({ id });
const rows = await this.db.select(COLUMNS).from(T.ROLES).where({ id });
return this.mapRow(rows[0]);
}
async update(role: ICustomRoleUpdate): Promise<ICustomRole> {
const rows = await this.db(TABLE)
const rows = await this.db(T.ROLES)
.where({
id: role.id,
})
@ -76,7 +81,7 @@ export default class RoleStore {
async exists(id: number): Promise<boolean> {
const result = await this.db.raw(
`SELECT EXISTS (SELECT 1 FROM ${TABLE} WHERE id = ?) AS present`,
`SELECT EXISTS (SELECT 1 FROM ${T.ROLES} WHERE id = ?) AS present`,
[id],
);
const { present } = result.rows[0];
@ -84,7 +89,7 @@ export default class RoleStore {
}
async deleteAll(): Promise<void> {
return this.db(TABLE).del();
return this.db(T.ROLES).del();
}
mapRow(row: IRoleRow): ICustomRole {
@ -100,6 +105,69 @@ export default class RoleStore {
};
}
async getRoles(): Promise<IRole[]> {
return this.db
.select(['id', 'name', 'type', 'description'])
.from<IRole>(T.ROLES);
}
async getRoleWithId(id: number): Promise<IRole> {
return this.db
.select(['id', 'name', 'type', 'description'])
.where('id', id)
.first()
.from<IRole>(T.ROLES);
}
async getProjectRoles(): Promise<IRole[]> {
return this.db
.select(['id', 'name', 'type', 'description'])
.from<IRole>(T.ROLES)
.where('type', 'custom')
.orWhere('type', 'project');
}
async getRolesForProject(projectId: string): Promise<IRole[]> {
return this.db
.select(['r.id', 'r.name', 'r.type', 'ru.project', 'r.description'])
.from<IRole>(`${T.ROLE_USER} as ru`)
.innerJoin(`${T.ROLES} as r`, 'ru.role_id', 'r.id')
.where('project', projectId);
}
async getRootRoles(): Promise<IRole[]> {
return this.db
.select(['id', 'name', 'type', 'description'])
.from<IRole>(T.ROLES)
.where('type', 'root');
}
async removeRolesForProject(projectId: string): Promise<void> {
return this.db(T.ROLE_USER)
.where({
project: projectId,
})
.delete();
}
async getRootRoleForAllUsers(): Promise<IUserRole[]> {
const rows = await this.db
.select('id', 'user_id')
.distinctOn('user_id')
.from(`${T.ROLES} AS r`)
.leftJoin(`${T.ROLE_USER} AS ru`, 'r.id', 'ru.role_id')
.where('r.type', '=', 'root');
return rows.map((row) => ({
roleId: +row.id,
userId: +row.user_id,
}));
}
async getRoleByName(name: string): Promise<IRole> {
return this.db(T.ROLES).where({ name }).first();
}
destroy(): void {}
}

View File

@ -3,6 +3,7 @@ import User, { IUser } from '../types/user';
import {
IAccessStore,
IRole,
IRoleWithPermissions,
IUserPermission,
IUserRole,
} from '../types/stores/access-store';
@ -11,12 +12,14 @@ import { Logger } from '../logger';
import { IUnleashStores } from '../types/stores';
import {
IAvailablePermissions,
ICustomRole,
IPermission,
IRoleData,
IUserWithRole,
RoleName,
RoleType,
} from '../types/model';
import { IRoleStore } from 'lib/types/stores/role-store';
export const ALL_PROJECTS = '*';
export const ALL_ENVS = '*';
@ -37,6 +40,19 @@ const PROJECT_REGULAR = [
permissions.DELETE_FEATURE,
];
interface IRoleCreation {
name: string;
description: string;
permissions?: IPermission[];
}
interface IRoleUpdate {
id: number;
name: string;
description: string;
permissions?: IPermission[];
}
const isProjectPermission = (permission) => PROJECT_ADMIN.includes(permission);
export class AccessService {
@ -44,26 +60,22 @@ export class AccessService {
private userStore: IUserStore;
private logger: Logger;
private roleStore: IRoleStore;
private permissions: IPermission[];
private logger: Logger;
constructor(
{
accessStore,
userStore,
}: Pick<IUnleashStores, 'accessStore' | 'userStore'>,
roleStore,
}: Pick<IUnleashStores, 'accessStore' | 'userStore' | 'roleStore'>,
{ getLogger }: { getLogger: Function },
) {
this.store = accessStore;
this.userStore = userStore;
this.roleStore = roleStore;
this.logger = getLogger('/services/access-service.ts');
// this.permissions = Object.values(permissions).map((p) => ({
// name: p,
// type: isProjectPermission(p)
// ? PermissionType.project
// : PermissionType.root,
// }));
}
/**
@ -133,7 +145,7 @@ export class AccessService {
}
async getRoleByName(roleName: string): Promise<IRole> {
return this.store.getRoleByName(roleName);
return this.roleStore.getRoleByName(roleName);
}
async setUserRootRole(
@ -148,11 +160,11 @@ export class AccessService {
RoleType.ROOT,
);
const editorRole = await this.store.getRoleByName(
const editorRole = await this.roleStore.getRoleByName(
RoleName.EDITOR,
);
if (newRootRole.id === editorRole.id) {
const viewerRole = await this.store.getRoleByName(
const viewerRole = await this.roleStore.getRoleByName(
RoleName.VIEWER,
);
await this.store.addUserToRole(
@ -230,10 +242,19 @@ export class AccessService {
}
async getRoles(): Promise<IRole[]> {
return this.store.getRoles();
return this.roleStore.getRoles();
}
async getRole(roleId: number): Promise<IRoleData> {
async getRole(id: number): Promise<IRoleWithPermissions> {
const role = await this.store.get(id);
const rolePermissions = await this.store.getPermissionsForRole(role.id);
return {
...role,
permissions: rolePermissions,
};
}
async getRoleData(roleId: number): Promise<IRoleData> {
const [role, rolePerms, users] = await Promise.all([
this.store.get(roleId),
this.store.getPermissionsForRole(roleId),
@ -243,11 +264,11 @@ export class AccessService {
}
async getProjectRoles(): Promise<IRole[]> {
return this.store.getProjectRoles();
return this.roleStore.getProjectRoles();
}
async getRolesForProject(projectId: string): Promise<IRole[]> {
return this.store.getRolesForProject(projectId);
return this.roleStore.getRolesForProject(projectId);
}
async getRolesForUser(userId: number): Promise<IRole[]> {
@ -284,7 +305,7 @@ export class AccessService {
async getProjectRoleUsers(
projectId: string,
): Promise<[IRole[], IUserWithRole[]]> {
const roles = await this.store.getProjectRoles();
const roles = await this.roleStore.getProjectRoles();
const users = await Promise.all(
roles.map(async (role) => {
@ -306,7 +327,7 @@ export class AccessService {
throw new Error('ProjectId cannot be empty');
}
const ownerRole = await this.store.getRoleByName(RoleName.OWNER);
const ownerRole = await this.roleStore.getRoleByName(RoleName.OWNER);
await this.store.addPermissionsToRole(
ownerRole.id,
@ -322,7 +343,7 @@ export class AccessService {
await this.store.addUserToRole(owner.id, ownerRole.id, projectId);
}
const memberRole = await this.store.getRoleByName(RoleName.MEMBER);
const memberRole = await this.roleStore.getRoleByName(RoleName.MEMBER);
await this.store.addPermissionsToRole(
memberRole.id,
@ -336,15 +357,15 @@ export class AccessService {
projectId: string,
): Promise<void> {
this.logger.info(`Removing project roles for ${projectId}`);
return this.store.removeRolesForProject(projectId);
return this.roleStore.removeRolesForProject(projectId);
}
async getRootRoleForAllUsers(): Promise<IUserRole[]> {
return this.store.getRootRoleForAllUsers();
return this.roleStore.getRootRoleForAllUsers();
}
async getRootRoles(): Promise<IRole[]> {
return this.store.getRootRoles();
return this.roleStore.getRootRoles();
}
public async resolveRootRole(rootRole: number | RoleName): Promise<IRole> {
@ -359,7 +380,51 @@ export class AccessService {
}
async getRootRole(roleName: RoleName): Promise<IRole> {
const roles = await this.store.getRootRoles();
const roles = await this.roleStore.getRootRoles();
return roles.find((r) => r.name === roleName);
}
async getAllRoles(): Promise<ICustomRole[]> {
return this.roleStore.getAll();
}
async createRole(role: IRoleCreation): Promise<ICustomRole> {
const baseRole = {
name: role.name,
description: role.description,
roleType: 'custom',
};
const rolePermissions = role.permissions;
const newRole = await this.roleStore.create(baseRole);
if (rolePermissions) {
this.store.addEnvironmentPermissionsToRole(
newRole.id,
rolePermissions,
);
}
return newRole;
}
async updateRole(role: IRoleUpdate): Promise<ICustomRole> {
const baseRole = {
id: role.id,
name: role.name,
description: role.description,
roleType: 'custom',
};
const rolePermissions = role.permissions;
const newRole = await this.roleStore.update(baseRole);
if (rolePermissions) {
this.store.wipePermissionsFromRole(newRole.id);
this.store.addEnvironmentPermissionsToRole(
newRole.id,
rolePermissions,
);
}
return newRole;
}
async deleteRole(id: number): Promise<void> {
return this.roleStore.delete(id);
}
}

View File

@ -28,7 +28,6 @@ import EnvironmentService from './environment-service';
import FeatureTagService from './feature-tag-service';
import ProjectHealthService from './project-health-service';
import UserSplashService from './user-splash-service';
import RoleService from './role-service';
export const createServices = (
stores: IUnleashStores,
@ -76,8 +75,6 @@ export const createServices = (
);
const userSplashService = new UserSplashService(stores, config);
const roleService = new RoleService(stores, config);
return {
accessService,
addonService,
@ -106,7 +103,6 @@ export const createServices = (
featureTagService,
projectHealthService,
userSplashService,
roleService,
};
};

View File

@ -1,96 +0,0 @@
import { IUnleashConfig } from 'lib/server-impl';
import { IUnleashStores } from 'lib/types';
import { ICustomRole, IPermission } from 'lib/types/model';
import {
IAccessStore,
IRoleWithPermissions,
} from 'lib/types/stores/access-store';
import { IRoleStore } from 'lib/types/stores/role-store';
import { Logger } from '../logger';
interface IRoleCreation {
name: string;
description: string;
permissions?: IPermission[];
}
interface IRoleUpdate {
id: number;
name: string;
description: string;
permissions?: IPermission[];
}
export default class RoleService {
private logger: Logger;
private store: IRoleStore;
private accessStore: IAccessStore;
constructor(
{
roleStore,
accessStore,
}: Pick<IUnleashStores, 'roleStore' | 'accessStore'>,
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
) {
this.logger = getLogger('lib/services/session-service.ts');
this.store = roleStore;
this.accessStore = accessStore;
}
async getAll(): Promise<ICustomRole[]> {
return this.store.getAll();
}
async get(id: number): Promise<IRoleWithPermissions> {
const role = await this.store.get(id);
const permissions = await this.accessStore.getPermissionsForRole(
role.id,
);
return {
...role,
permissions,
};
}
async create(role: IRoleCreation): Promise<ICustomRole> {
const baseRole = {
name: role.name,
description: role.description,
roleType: 'custom',
};
const permissions = role.permissions;
const newRole = await this.store.create(baseRole);
if (permissions) {
this.accessStore.addEnvironmentPermissionsToRole(
newRole.id,
permissions,
);
}
return newRole;
}
async update(role: IRoleUpdate): Promise<ICustomRole> {
const baseRole = {
id: role.id,
name: role.name,
description: role.description,
roleType: 'custom',
};
const permissions = role.permissions;
const newRole = await this.store.update(baseRole);
if (permissions) {
this.accessStore.wipePermissionsFromRole(newRole.id);
this.accessStore.addEnvironmentPermissionsToRole(
newRole.id,
permissions,
);
}
return newRole;
}
async delete(id: number): Promise<void> {
return this.store.delete(id);
}
}

View File

@ -349,7 +349,7 @@ class UserService {
token,
);
const user = await this.getUser(userId);
const role = await this.accessService.getRole(user.rootRole);
const role = await this.accessService.getRoleData(user.rootRole);
return {
token,
createdBy,

View File

@ -24,7 +24,6 @@ import FeatureTagService from '../services/feature-tag-service';
import ProjectHealthService from '../services/project-health-service';
import ClientMetricsServiceV2 from '../services/client-metrics/metrics-service-v2';
import UserSplashService from '../services/user-splash-service';
import RoleService from 'lib/services/role-service';
export interface IUnleashServices {
accessService: AccessService;
@ -54,5 +53,4 @@ export interface IUnleashServices {
userService: UserService;
versionService: VersionService;
userSplashService: UserSplashService;
roleService: RoleService;
}

View File

@ -29,16 +29,10 @@ export interface IUserRole {
userId: number;
}
export interface IAccessStore extends Store<IRole, number> {
getRoleByName(name: string): Promise<IRole>;
getAvailablePermissions(): Promise<IAvailablePermissions>;
getPermissionsForUser(userId: number): Promise<IUserPermission[]>;
getPermissionsForRole(roleId: number): Promise<IPermission[]>;
getRoles(): Promise<IRole[]>;
getRolesForProject(projectId: string): Promise<IRole[]>;
unlinkUserRoles(userId: number): Promise<void>;
getProjectRoles(): Promise<IRole[]>;
getRootRoles(): Promise<IRole[]>;
removeRolesForProject(projectId: string): Promise<void>;
getRolesForUserId(userId: number): Promise<IRole[]>;
getProjectUserIdsForRole(roleId: number, projectId?: string);
getUserIdsForRole(roleId: number, projectId?: string): Promise<number[]>;
@ -62,12 +56,6 @@ export interface IAccessStore extends Store<IRole, number> {
projectId: string,
): Promise<void>;
removeRolesOfTypeForUser(userId: number, roleType: string): Promise<void>;
createRole(
name: string,
type: string,
project?: string,
description?: string,
): Promise<IRole>;
addPermissionsToRole(
role_id: number,
permissions: string[],
@ -78,5 +66,4 @@ export interface IAccessStore extends Store<IRole, number> {
permission: string,
projectId?: string,
): Promise<void>;
getRootRoleForAllUsers(): Promise<IUserRole[]>;
}

View File

@ -1,4 +1,5 @@
import { ICustomRole } from '../model';
import { IRole, IUserRole } from './access-store';
import { Store } from './store';
export interface ICustomRoleInsert {
@ -19,4 +20,11 @@ export interface IRoleStore extends Store<ICustomRole, number> {
create(role: ICustomRoleInsert): Promise<ICustomRole>;
update(role: ICustomRoleUpdate): Promise<ICustomRole>;
delete(id: number): Promise<void>;
getRoles(): Promise<IRole[]>;
getRoleByName(name: string): Promise<IRole>;
getRolesForProject(projectId: string): Promise<IRole[]>;
removeRolesForProject(projectId: string): Promise<void>;
getProjectRoles(): Promise<IRole[]>;
getRootRoles(): Promise<IRole[]>;
getRootRoleForAllUsers(): Promise<IUserRole[]>;
}

View File

@ -6,10 +6,11 @@ import {
USER_DELETED,
USER_UPDATED,
} from '../../../../lib/types/events';
import { IAccessStore, IRole } from '../../../../lib/types/stores/access-store';
import { IRole } from '../../../../lib/types/stores/access-store';
import { IEventStore } from '../../../../lib/types/stores/event-store';
import { IUserStore } from '../../../../lib/types/stores/user-store';
import { RoleName } from '../../../../lib/types/model';
import { IRoleStore } from 'lib/types/stores/role-store';
let stores;
let db;
@ -17,7 +18,7 @@ let app;
let userStore: IUserStore;
let eventStore: IEventStore;
let accessStore: IAccessStore;
let roleStore: IRoleStore;
let editorRole: IRole;
let adminRole: IRole;
@ -27,9 +28,9 @@ beforeAll(async () => {
app = await setupApp(stores);
userStore = stores.userStore;
accessStore = stores.accessStore;
eventStore = stores.eventStore;
const roles = await accessStore.getRootRoles();
roleStore = stores.roleStore;
const roles = await roleStore.getRootRoles();
editorRole = roles.find((r) => r.name === RoleName.EDITOR);
adminRole = roles.find((r) => r.name === RoleName.ADMIN);
});

View File

@ -366,7 +366,7 @@ test('should return role with permissions and users', async () => {
await accessService.addUserToRole(user.id, editorRole.id, 'default');
const roleWithPermission = await accessService.getRole(editorRole.id);
const roleWithPermission = await accessService.getRoleData(editorRole.id);
expect(roleWithPermission.role.name).toBe(RoleName.EDITOR);
expect(roleWithPermission.permissions.length > 2).toBe(true);
@ -436,7 +436,7 @@ test('should not crash if user does not have permission', async () => {
});
test('should support permission with "ALL" environment requirement', async () => {
const { userStore, accessStore } = stores;
const { userStore, roleStore, accessStore } = stores;
const user = await userStore.insert({
name: 'Some User',
@ -445,11 +445,11 @@ test('should support permission with "ALL" environment requirement', async () =>
await accessService.setUserRootRole(user.id, readRole.id);
const customRole = await accessStore.createRole(
'Power user',
'custom',
'Grants access to modify all environments',
);
const customRole = await roleStore.create({
name: 'Power user',
roleType: 'custom',
description: 'Grants access to modify all environments',
});
const { CREATE_FEATURE_STRATEGY } = permissions;
await accessStore.addPermissionsToRole(

View File

@ -3,12 +3,7 @@ import getLogger from '../../fixtures/no-logger';
import FeatureToggleService from '../../../lib/services/feature-toggle-service';
import ProjectService from '../../../lib/services/project-service';
import { AccessService } from '../../../lib/services/access-service';
import {
CREATE_FEATURE,
UPDATE_FEATURE,
UPDATE_PROJECT,
} from '../../../lib/types/permissions';
import NotFoundError from '../../../lib/error/notfound-error';
import { CREATE_FEATURE, UPDATE_FEATURE } from '../../../lib/types/permissions';
import { createTestConfig } from '../../config/test-config';
import { RoleName } from '../../../lib/types/model';
@ -216,8 +211,8 @@ test('should get list of users with access to project', async () => {
await projectService.createProject(project, user);
const { users } = await projectService.getUsersWithAccess(project.id, user);
const member = await stores.accessStore.getRoleByName(RoleName.MEMBER);
const owner = await stores.accessStore.getRoleByName(RoleName.OWNER);
const member = await stores.roleStore.getRoleByName(RoleName.MEMBER);
const owner = await stores.roleStore.getRoleByName(RoleName.OWNER);
expect(users).toHaveLength(1);
expect(users[0].id).toBe(user.id);
@ -243,7 +238,7 @@ test('should add a member user to the project', async () => {
email: 'member2@getunleash.io',
});
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
const memberRole = await stores.roleStore.getRoleByName(RoleName.MEMBER);
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
await projectService.addUser(project.id, memberRole.id, projectMember2.id);
@ -275,7 +270,7 @@ test('should add admin users to the project', async () => {
email: 'admin2@getunleash.io',
});
const ownerRole = await stores.accessStore.getRoleByName(RoleName.OWNER);
const ownerRole = await stores.roleStore.getRoleByName(RoleName.OWNER);
await projectService.addUser(project.id, ownerRole.id, projectAdmin1.id);
await projectService.addUser(project.id, ownerRole.id, projectAdmin2.id);
@ -304,7 +299,7 @@ test('add user should fail if user already have access', async () => {
email: 'member42@getunleash.io',
});
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
const memberRole = await stores.roleStore.getRoleByName(RoleName.MEMBER);
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
@ -328,7 +323,7 @@ test('should remove user from the project', async () => {
email: 'member99@getunleash.io',
});
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
const memberRole = await stores.roleStore.getRoleByName(RoleName.MEMBER);
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
await projectService.removeUser(
@ -351,7 +346,7 @@ test('should not remove user from the project', async () => {
};
await projectService.createProject(project, user);
const roles = await stores.accessStore.getRolesForProject(project.id);
const roles = await stores.roleStore.getRolesForProject(project.id);
const ownerRole = roles.find((r) => r.name === RoleName.OWNER);
await expect(async () => {

View File

@ -13,7 +13,11 @@ import {
class AccessServiceMock extends AccessService {
constructor() {
super(
{ accessStore: undefined, userStore: undefined },
{
accessStore: undefined,
userStore: undefined,
roleStore: undefined,
},
{ getLogger: noLoggerProvider },
);
}
@ -62,10 +66,6 @@ class AccessServiceMock extends AccessService {
throw new Error('Method not implemented.');
}
getRole(roleId: number): Promise<IRoleData> {
throw new Error('Method not implemented.');
}
getRolesForProject(projectId: string): Promise<IRole[]> {
throw new Error('Method not implemented.');
}

View File

@ -94,15 +94,6 @@ class AccessStoreMock implements IAccessStore {
throw new Error('Method not implemented.');
}
createRole(
name: string,
type: string,
project?: string,
description?: string,
): Promise<IRole> {
throw new Error('Method not implemented.');
}
addPermissionsToRole(
role_id: number,
permissions: string[],

View File

@ -1,62 +1,70 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { ICustomRole } from 'lib/types/model';
import { IRole, IUserRole } from 'lib/types/stores/access-store';
import {
ICustomRoleInsert,
ICustomRoleUpdate,
IRoleStore,
} from 'lib/types/stores/role-store';
import {
IUserFeedback,
IUserFeedbackKey,
IUserFeedbackStore,
} from '../../lib/types/stores/user-feedback-store';
export default class FakeRoleStore implements IRoleStore {
async update(role: ICustomRoleUpdate): Promise<ICustomRole> {
getAll(): Promise<ICustomRole[]> {
throw new Error('Method not implemented.');
}
async get(key: number): Promise<ICustomRole> {
return Promise.resolve({
id: 1,
name: 'Role',
description: 'Hello',
type: 'custom',
});
}
async getAll(): Promise<ICustomRole[]> {
return Promise.resolve([
{
id: 1,
name: 'Role',
description: 'Hello',
type: 'custom',
},
]);
}
async exists(): Promise<boolean> {
return Promise.resolve(true);
}
create(role: ICustomRoleInsert): Promise<ICustomRole> {
return Promise.resolve({
id: 1,
name: 'Role',
description: 'Hello',
type: 'custom',
});
throw new Error('Method not implemented.');
}
update(role: ICustomRoleUpdate): Promise<ICustomRole> {
throw new Error('Method not implemented.');
}
delete(id: number): Promise<void> {
return Promise.resolve();
throw new Error('Method not implemented.');
}
destroy(): Promise<void> {
return Promise.resolve();
getRoles(): Promise<IRole[]> {
throw new Error('Method not implemented.');
}
getRoleByName(name: string): Promise<IRole> {
throw new Error('Method not implemented.');
}
getRolesForProject(projectId: string): Promise<IRole[]> {
throw new Error('Method not implemented.');
}
removeRolesForProject(projectId: string): Promise<void> {
throw new Error('Method not implemented.');
}
getProjectRoles(): Promise<IRole[]> {
throw new Error('Method not implemented.');
}
getRootRoles(): Promise<IRole[]> {
throw new Error('Method not implemented.');
}
getRootRoleForAllUsers(): Promise<IUserRole[]> {
throw new Error('Method not implemented.');
}
get(key: number): Promise<ICustomRole> {
throw new Error('Method not implemented.');
}
exists(key: number): Promise<boolean> {
throw new Error('Method not implemented.');
}
deleteAll(): Promise<void> {
return Promise.resolve();
throw new Error('Method not implemented.');
}
destroy(): void {
throw new Error('Method not implemented.');
}
}