mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
fix: Make permissions actually work with new environments
This commit is contained in:
parent
ba40099b41
commit
0634758784
@ -20,6 +20,7 @@ const T = {
|
|||||||
ROLES: 'roles',
|
ROLES: 'roles',
|
||||||
ROLE_PERMISSION: 'role_permission',
|
ROLE_PERMISSION: 'role_permission',
|
||||||
PERMISSIONS: 'permissions',
|
PERMISSIONS: 'permissions',
|
||||||
|
PERMISSION_TYPES: 'permission_types',
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IPermissionRow {
|
interface IPermissionRow {
|
||||||
@ -60,6 +61,10 @@ export class AccessStore implements IAccessStore {
|
|||||||
await this.db.batchInsert(T.PERMISSIONS, rows);
|
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> {
|
async delete(key: number): Promise<void> {
|
||||||
await this.db(T.ROLES).where({ id: key }).del();
|
await this.db(T.ROLES).where({ id: key }).del();
|
||||||
}
|
}
|
||||||
@ -93,8 +98,20 @@ export class AccessStore implements IAccessStore {
|
|||||||
|
|
||||||
async getAvailablePermissions(): Promise<IAvailablePermissions> {
|
async getAvailablePermissions(): Promise<IAvailablePermissions> {
|
||||||
const rows = await this.db
|
const rows = await this.db
|
||||||
.select(['id', 'permission', 'environment', 'display_name'])
|
.select([
|
||||||
.from(T.PERMISSIONS);
|
'p.id',
|
||||||
|
'p.permission',
|
||||||
|
'p.environment',
|
||||||
|
'pt.display_name',
|
||||||
|
])
|
||||||
|
.join(
|
||||||
|
`${T.PERMISSION_TYPES} AS pt`,
|
||||||
|
'pt.permission',
|
||||||
|
'p.permission',
|
||||||
|
)
|
||||||
|
.where('pt.type', 'project')
|
||||||
|
.orWhere('pt.type', 'environment')
|
||||||
|
.from(`${T.PERMISSIONS} as p`);
|
||||||
|
|
||||||
let projectPermissions: IPermission[] = [];
|
let projectPermissions: IPermission[] = [];
|
||||||
let rawEnvironments = new Map<string, IPermissionRow[]>();
|
let rawEnvironments = new Map<string, IPermissionRow[]>();
|
||||||
@ -174,15 +191,24 @@ export class AccessStore implements IAccessStore {
|
|||||||
return this.db
|
return this.db
|
||||||
.select(['id', 'name', 'type', 'description'])
|
.select(['id', 'name', 'type', 'description'])
|
||||||
.from<IRole>(T.ROLES)
|
.from<IRole>(T.ROLES)
|
||||||
.andWhere('type', 'project');
|
.where('type', 'custom')
|
||||||
|
.orWhere('type', 'project');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRolesForProject(projectId: string): Promise<IRole[]> {
|
async getRolesForProject(projectId: string): Promise<IRole[]> {
|
||||||
return this.db
|
return this.db
|
||||||
.select(['id', 'name', 'type', 'project', 'description'])
|
.select(['r.id', 'r.name', 'r.type', 'ru.project', 'r.description'])
|
||||||
.from<IRole>(T.ROLES)
|
.from<IRole>(`${T.ROLE_USER} as ru`)
|
||||||
.where('project', projectId)
|
.innerJoin(`${T.ROLES} as r`, 'ru.role_id', 'r.id')
|
||||||
.andWhere('type', 'project');
|
.where('project', projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async unlinkUserRoles(userId: number): Promise<void> {
|
||||||
|
return this.db(T.ROLE_USER)
|
||||||
|
.where({
|
||||||
|
user_id: userId,
|
||||||
|
})
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRootRoles(): Promise<IRole[]> {
|
async getRootRoles(): Promise<IRole[]> {
|
||||||
@ -208,15 +234,25 @@ export class AccessStore implements IAccessStore {
|
|||||||
.where('ru.user_id', '=', userId);
|
.where('ru.user_id', '=', userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserIdsForRole(
|
async getUserIdsForRole(roleId: number): Promise<number[]> {
|
||||||
roleId: number,
|
|
||||||
projectId?: string,
|
|
||||||
): Promise<number[]> {
|
|
||||||
const rows = await this.db
|
const rows = await this.db
|
||||||
.select(['user_id'])
|
.select(['user_id'])
|
||||||
.from<IRole>(T.ROLE_USER)
|
.from<IRole>(T.ROLE_USER)
|
||||||
.where('role_id', roleId)
|
.where('role_id', roleId);
|
||||||
.andWhere('project', projectId);
|
return rows.map((r) => r.user_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProjectUserIdsForRole(
|
||||||
|
roleId: number,
|
||||||
|
projectId?: string,
|
||||||
|
): Promise<number[]> {
|
||||||
|
console.log('Checking for', roleId, projectId);
|
||||||
|
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);
|
return rows.map((r) => r.user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,11 +268,16 @@ export class AccessStore implements IAccessStore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeUserFromRole(userId: number, roleId: number): Promise<void> {
|
async removeUserFromRole(
|
||||||
|
userId: number,
|
||||||
|
roleId: number,
|
||||||
|
projectId: string,
|
||||||
|
): Promise<void> {
|
||||||
return this.db(T.ROLE_USER)
|
return this.db(T.ROLE_USER)
|
||||||
.where({
|
.where({
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
role_id: roleId,
|
role_id: roleId,
|
||||||
|
project: projectId,
|
||||||
})
|
})
|
||||||
.delete();
|
.delete();
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,7 @@ export class AccessService {
|
|||||||
permission: p,
|
permission: p,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
console.log('Checking perms for user id', user.id);
|
||||||
return this.store.getPermissionsForUser(user.id);
|
return this.store.getPermissionsForUser(user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,8 +172,12 @@ export class AccessService {
|
|||||||
return userRoles.filter((r) => r.type === RoleType.ROOT);
|
return userRoles.filter((r) => r.type === RoleType.ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeUserFromRole(userId: number, roleId: number): Promise<void> {
|
async removeUserFromRole(
|
||||||
return this.store.removeUserFromRole(userId, roleId);
|
userId: number,
|
||||||
|
roleId: number,
|
||||||
|
projectId: string,
|
||||||
|
): Promise<void> {
|
||||||
|
return this.store.removeUserFromRole(userId, roleId, projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addPermissionToRole(
|
async addPermissionToRole(
|
||||||
@ -230,11 +235,23 @@ export class AccessService {
|
|||||||
return this.store.getRolesForUserId(userId);
|
return this.store.getRolesForUserId(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUsersForRole(
|
async unlinkUserRoles(userId: number): Promise<void> {
|
||||||
|
return this.store.unlinkUserRoles(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUsersForRole(roleId: number): Promise<IUser[]> {
|
||||||
|
const userIdList = await this.store.getUserIdsForRole(roleId);
|
||||||
|
if (userIdList.length > 0) {
|
||||||
|
return this.userStore.getAllWithId(userIdList);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProjectUsersForRole(
|
||||||
roleId: number,
|
roleId: number,
|
||||||
projectId?: string,
|
projectId?: string,
|
||||||
): Promise<IUser[]> {
|
): Promise<IUser[]> {
|
||||||
const userIdList = await this.store.getUserIdsForRole(
|
const userIdList = await this.store.getProjectUserIdsForRole(
|
||||||
roleId,
|
roleId,
|
||||||
projectId,
|
projectId,
|
||||||
);
|
);
|
||||||
@ -250,9 +267,13 @@ export class AccessService {
|
|||||||
): Promise<[IRole[], IUserWithRole[]]> {
|
): Promise<[IRole[], IUserWithRole[]]> {
|
||||||
const roles = await this.store.getProjectRoles();
|
const roles = await this.store.getProjectRoles();
|
||||||
|
|
||||||
|
console.log('GOt the following roles bacl', roles);
|
||||||
const users = await Promise.all(
|
const users = await Promise.all(
|
||||||
roles.map(async (role) => {
|
roles.map(async (role) => {
|
||||||
const usrs = await this.getUsersForRole(role.id, projectId);
|
const usrs = await this.getProjectUsersForRole(
|
||||||
|
role.id,
|
||||||
|
projectId,
|
||||||
|
);
|
||||||
return usrs.map((u) => ({ ...u, roleId: role.id }));
|
return usrs.map((u) => ({ ...u, roleId: role.id }));
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -267,11 +288,8 @@ export class AccessService {
|
|||||||
throw new Error('ProjectId cannot be empty');
|
throw new Error('ProjectId cannot be empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
const ownerRole = await this.store.createRole(
|
const ownerRole = await this.store.getRoleByName(RoleName.OWNER);
|
||||||
RoleName.OWNER,
|
|
||||||
RoleType.PROJECT,
|
|
||||||
PROJECT_DESCRIPTION.OWNER,
|
|
||||||
);
|
|
||||||
await this.store.addPermissionsToRole(
|
await this.store.addPermissionsToRole(
|
||||||
ownerRole.id,
|
ownerRole.id,
|
||||||
PROJECT_ADMIN,
|
PROJECT_ADMIN,
|
||||||
@ -285,12 +303,9 @@ export class AccessService {
|
|||||||
);
|
);
|
||||||
await this.store.addUserToRole(owner.id, ownerRole.id, projectId);
|
await this.store.addUserToRole(owner.id, ownerRole.id, projectId);
|
||||||
}
|
}
|
||||||
const memberRole = await this.store.createRole(
|
|
||||||
RoleName.MEMBER,
|
const memberRole = await this.store.getRoleByName(RoleName.MEMBER);
|
||||||
RoleType.PROJECT,
|
|
||||||
projectId,
|
|
||||||
PROJECT_DESCRIPTION.MEMBER,
|
|
||||||
);
|
|
||||||
await this.store.addPermissionsToRole(
|
await this.store.addPermissionsToRole(
|
||||||
memberRole.id,
|
memberRole.id,
|
||||||
PROJECT_REGULAR,
|
PROJECT_REGULAR,
|
||||||
|
@ -25,7 +25,7 @@ import { IFeatureTypeStore } from '../types/stores/feature-type-store';
|
|||||||
import { IFeatureToggleStore } from '../types/stores/feature-toggle-store';
|
import { IFeatureToggleStore } from '../types/stores/feature-toggle-store';
|
||||||
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
||||||
import { IProjectQuery, IProjectStore } from '../types/stores/project-store';
|
import { IProjectQuery, IProjectStore } from '../types/stores/project-store';
|
||||||
import { IRole } from '../types/stores/access-store';
|
import { IRoleDescriptor } from '../types/stores/access-store';
|
||||||
import { IEventStore } from '../types/stores/event-store';
|
import { IEventStore } from '../types/stores/event-store';
|
||||||
import FeatureToggleService from './feature-toggle-service';
|
import FeatureToggleService from './feature-toggle-service';
|
||||||
import { CREATE_FEATURE, UPDATE_FEATURE } from '../types/permissions';
|
import { CREATE_FEATURE, UPDATE_FEATURE } from '../types/permissions';
|
||||||
@ -38,7 +38,7 @@ const DEFAULT_PROJECT = 'default';
|
|||||||
|
|
||||||
export interface UsersWithRoles {
|
export interface UsersWithRoles {
|
||||||
users: IUserWithRole[];
|
users: IUserWithRole[];
|
||||||
roles: IRole[];
|
roles: IRoleDescriptor[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class ProjectService {
|
export default class ProjectService {
|
||||||
@ -271,6 +271,7 @@ export default class ProjectService {
|
|||||||
const [roles, users] = await this.accessService.getProjectRoleUsers(
|
const [roles, users] = await this.accessService.getProjectRoleUsers(
|
||||||
projectId,
|
projectId,
|
||||||
);
|
);
|
||||||
|
console.log('Got the following response', roles, users);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
roles,
|
roles,
|
||||||
@ -324,7 +325,7 @@ export default class ProjectService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.accessService.removeUserFromRole(userId, role.id);
|
await this.accessService.removeUserFromRole(userId, role.id, projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMembers(projectId: string): Promise<number> {
|
async getMembers(projectId: string): Promise<number> {
|
||||||
|
@ -262,12 +262,7 @@ class UserService {
|
|||||||
|
|
||||||
async deleteUser(userId: number, updatedBy?: User): Promise<void> {
|
async deleteUser(userId: number, updatedBy?: User): Promise<void> {
|
||||||
const user = await this.store.get(userId);
|
const user = await this.store.get(userId);
|
||||||
const roles = await this.accessService.getRolesForUser(userId);
|
await this.accessService.unlinkUserRoles(userId);
|
||||||
await Promise.all(
|
|
||||||
roles.map((role) =>
|
|
||||||
this.accessService.removeUserFromRole(userId, role.id),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await this.sessionService.deleteSessionsForUser(userId);
|
await this.sessionService.deleteSessionsForUser(userId);
|
||||||
|
|
||||||
await this.store.delete(userId);
|
await this.store.delete(userId);
|
||||||
|
@ -14,20 +14,29 @@ export interface IRole {
|
|||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IRoleDescriptor {
|
||||||
|
name: string;
|
||||||
|
description?: string;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IUserRole {
|
export interface IUserRole {
|
||||||
roleId: number;
|
roleId: number;
|
||||||
userId: number;
|
userId: number;
|
||||||
}
|
}
|
||||||
export interface IAccessStore extends Store<IRole, number> {
|
export interface IAccessStore extends Store<IRole, number> {
|
||||||
|
getRoleByName(name: string): Promise<IRole>;
|
||||||
getAvailablePermissions(): Promise<IAvailablePermissions>;
|
getAvailablePermissions(): Promise<IAvailablePermissions>;
|
||||||
getPermissionsForUser(userId: number): Promise<IUserPermission[]>;
|
getPermissionsForUser(userId: number): Promise<IUserPermission[]>;
|
||||||
getPermissionsForRole(roleId: number): Promise<IUserPermission[]>;
|
getPermissionsForRole(roleId: number): Promise<IUserPermission[]>;
|
||||||
getRoles(): Promise<IRole[]>;
|
getRoles(): Promise<IRole[]>;
|
||||||
getRolesForProject(projectId: string): Promise<IRole[]>;
|
getRolesForProject(projectId: string): Promise<IRole[]>;
|
||||||
|
unlinkUserRoles(userId: number): Promise<void>;
|
||||||
getProjectRoles(): Promise<IRole[]>;
|
getProjectRoles(): Promise<IRole[]>;
|
||||||
getRootRoles(): Promise<IRole[]>;
|
getRootRoles(): Promise<IRole[]>;
|
||||||
removeRolesForProject(projectId: string): Promise<void>;
|
removeRolesForProject(projectId: string): Promise<void>;
|
||||||
getRolesForUserId(userId: number): Promise<IRole[]>;
|
getRolesForUserId(userId: number): Promise<IRole[]>;
|
||||||
|
getProjectUserIdsForRole(roleId: number, projectId?: string);
|
||||||
getUserIdsForRole(roleId: number, projectId?: string): Promise<number[]>;
|
getUserIdsForRole(roleId: number, projectId?: string): Promise<number[]>;
|
||||||
addEnvironmentPermissionsToRole(
|
addEnvironmentPermissionsToRole(
|
||||||
role_id: number,
|
role_id: number,
|
||||||
@ -42,7 +51,11 @@ export interface IAccessStore extends Store<IRole, number> {
|
|||||||
roleId: number,
|
roleId: number,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
): Promise<void>;
|
): Promise<void>;
|
||||||
removeUserFromRole(userId: number, roleId: number): Promise<void>;
|
removeUserFromRole(
|
||||||
|
userId: number,
|
||||||
|
roleId: number,
|
||||||
|
projectId: string,
|
||||||
|
): Promise<void>;
|
||||||
removeRolesOfTypeForUser(userId: number, roleType: string): Promise<void>;
|
removeRolesOfTypeForUser(userId: number, roleType: string): Promise<void>;
|
||||||
createRole(
|
createRole(
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -5,11 +5,16 @@ exports.up = function (db, cb) {
|
|||||||
( id SERIAL PRIMARY KEY,
|
( id SERIAL PRIMARY KEY,
|
||||||
permission VARCHAR(255) NOT NULL,
|
permission VARCHAR(255) NOT NULL,
|
||||||
environment VARCHAR(255),
|
environment VARCHAR(255),
|
||||||
display_name TEXT,
|
|
||||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT now()
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO permissions (permission, environment, display_name) (SELECT DISTINCT permission, environment, '' from role_permission);
|
CREATE TABLE IF NOT EXISTS permission_types (
|
||||||
|
permission VARCHAR(255),
|
||||||
|
display_name TEXT,
|
||||||
|
type VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO permissions (permission, environment) (select distinct permission,environment from role_permission);
|
||||||
|
|
||||||
ALTER TABLE role_user ADD COLUMN
|
ALTER TABLE role_user ADD COLUMN
|
||||||
project VARCHAR(255);
|
project VARCHAR(255);
|
||||||
@ -19,6 +24,9 @@ exports.up = function (db, cb) {
|
|||||||
FROM roles
|
FROM roles
|
||||||
WHERE role_user.role_id = roles.id;
|
WHERE role_user.role_id = roles.id;
|
||||||
|
|
||||||
|
ALTER TABLE role_user DROP CONSTRAINT role_user_pkey;
|
||||||
|
ALTER TABLE role_user ADD PRIMARY KEY (role_id, user_id, project);
|
||||||
|
|
||||||
ALTER TABLE roles DROP COLUMN project;
|
ALTER TABLE roles DROP COLUMN project;
|
||||||
|
|
||||||
ALTER TABLE roles
|
ALTER TABLE roles
|
||||||
@ -29,7 +37,7 @@ exports.up = function (db, cb) {
|
|||||||
ADD COLUMN
|
ADD COLUMN
|
||||||
permission_id INTEGER;
|
permission_id INTEGER;
|
||||||
|
|
||||||
UPDATE role_permission
|
UPDATE role_permission
|
||||||
SET permission_id = permissions.id
|
SET permission_id = permissions.id
|
||||||
FROM permissions
|
FROM permissions
|
||||||
WHERE
|
WHERE
|
||||||
@ -43,29 +51,30 @@ exports.up = function (db, cb) {
|
|||||||
DROP COLUMN permission,
|
DROP COLUMN permission,
|
||||||
DROP COLUMN environment;
|
DROP COLUMN environment;
|
||||||
|
|
||||||
UPDATE permissions SET display_name = 'Admin' where permission = 'ADMIN';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('ADMIN', 'Admin', 'root');
|
||||||
UPDATE permissions SET display_name = 'Create Strategies' where permission = 'CREATE_STRATEGY';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CLIENT', 'Client', 'root');
|
||||||
UPDATE permissions SET display_name = 'Create Addons' where permission = 'CREATE_ADDON';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CREATE_STRATEGY','Create Strategies', 'root');
|
||||||
UPDATE permissions SET display_name = 'Delete Addons' where permission = 'DELETE_ADDON';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CREATE_ADDON', 'Create Addons', 'root');
|
||||||
UPDATE permissions SET display_name = 'Update Addons' where permission = 'UPDATE_ADDON';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_ADDON', 'Delete Addons', 'root');
|
||||||
UPDATE permissions SET display_name = 'Create Feature Toggles' where permission = 'CREATE_FEATURE';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_ADDON', 'Update Addons', 'root');
|
||||||
UPDATE permissions SET display_name = 'Update Feature Toggles' where permission = 'UPDATE_FEATURE';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CREATE_FEATURE', 'Create Feature Toggles', 'project');
|
||||||
UPDATE permissions SET display_name = 'Delete Feature Toggles' where permission = 'DELETE_FEATURE';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_FEATURE', 'Update Feature Toggles', 'project');
|
||||||
UPDATE permissions SET display_name = 'Update Applications' where permission = 'UPDATE_APPLICATION';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_FEATURE', 'Delete Feature Toggles', 'project');
|
||||||
UPDATE permissions SET display_name = 'Update Tag Types' where permission = 'UPDATE_TAG_TYPE';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_APPLICATION', 'Update Applications', 'root');
|
||||||
UPDATE permissions SET display_name = 'Delete Tag Types' where permission = 'DELETE_TAG_TYPE';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_TAG_TYPE', 'Update Tag Types', 'root');
|
||||||
UPDATE permissions SET display_name = 'Create Projects' where permission = 'CREATE_PROJECT';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_TAG_TYPE', 'Delete Tag Types', 'root');
|
||||||
UPDATE permissions SET display_name = 'Update Projects' where permission = 'UPDATE_PROJECT';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CREATE_PROJECT', 'Create Projects', 'root');
|
||||||
UPDATE permissions SET display_name = 'Delete Projects' where permission = 'DELETE_PROJECT';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_PROJECT', 'Update Projects', 'project');
|
||||||
UPDATE permissions SET display_name = 'Update Strategies on Toggles' where permission = 'UPDATE_FEATURE_STRATEGY';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_PROJECT', 'Delete Projects', 'project');
|
||||||
UPDATE permissions SET display_name = 'Add Strategies to Toggles' where permission = 'CREATE_FEATURE_STRATEGY';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_FEATURE_STRATEGY', 'Update Strategies on Toggles', 'environment');
|
||||||
UPDATE permissions SET display_name = 'Remove Strategies from Toggles' where permission = 'DELETE_FEATURE_STRATEGY';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CREATE_FEATURE_STRATEGY', 'Add Strategies to Toggles', 'environment');
|
||||||
UPDATE permissions SET display_name = 'Update Strategies' where permission = 'UPDATE_STRATEGY';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_FEATURE_STRATEGY', 'Remove Strategies from Toggles', 'environment');
|
||||||
UPDATE permissions SET display_name = 'Delete Strategies' where permission = 'DELETE_STRATEGY';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_STRATEGY', 'Update Strategies', 'root');
|
||||||
UPDATE permissions SET display_name = 'Enable/Disable Toggles for Environments' where permission = 'UPDATE_FEATURE_ENVIRONMENT';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_STRATEGY', 'Delete Strategies', 'root');
|
||||||
UPDATE permissions SET display_name = 'Update Context Fields' where permission = 'UPDATE_CONTEXT_FIELD';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_FEATURE_ENVIRONMENT', 'Enable/Disable Toggles for Environments', 'environment');
|
||||||
UPDATE permissions SET display_name = 'Create Context Fields' where permission = 'CREATE_CONTEXT_FIELD';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('UPDATE_CONTEXT_FIELD', 'Update Context Fields', 'root');
|
||||||
UPDATE permissions SET display_name = 'Delete Context Fields' where permission = 'DELETE_CONTEXT_FIELD';
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('CREATE_CONTEXT_FIELD', 'Create Context Fields', 'root');
|
||||||
|
INSERT INTO permission_types (permission, display_name, type) VALUES ('DELETE_CONTEXT_FIELD', 'Delete Context Fields', 'root');
|
||||||
`,
|
`,
|
||||||
cb,
|
cb,
|
||||||
);
|
);
|
||||||
|
@ -53,7 +53,12 @@ afterEach(async () => {
|
|||||||
.map(async (env) => {
|
.map(async (env) => {
|
||||||
await stores.environmentStore.delete(env.name);
|
await stores.environmentStore.delete(env.name);
|
||||||
});
|
});
|
||||||
|
const users = await stores.userStore.getAll();
|
||||||
|
const wipeUserPermissions = users.map(async (u) => {
|
||||||
|
await stores.accessStore.unlinkUserRoles(u.id);
|
||||||
|
});
|
||||||
await Promise.allSettled(deleteEnvs);
|
await Promise.allSettled(deleteEnvs);
|
||||||
|
await Promise.allSettled(wipeUserPermissions);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should have default project', async () => {
|
test('should have default project', async () => {
|
||||||
@ -240,13 +245,10 @@ test('should get list of users with access to project', async () => {
|
|||||||
description: 'Blah',
|
description: 'Blah',
|
||||||
};
|
};
|
||||||
await projectService.createProject(project, user);
|
await projectService.createProject(project, user);
|
||||||
const { roles, users } = await projectService.getUsersWithAccess(
|
const { users } = await projectService.getUsersWithAccess(project.id, user);
|
||||||
project.id,
|
|
||||||
user,
|
|
||||||
);
|
|
||||||
|
|
||||||
const owner = roles.find((role) => role.name === RoleName.OWNER);
|
const member = await stores.accessStore.getRoleByName(RoleName.MEMBER);
|
||||||
const member = roles.find((role) => role.name === RoleName.MEMBER);
|
const owner = await stores.accessStore.getRoleByName(RoleName.OWNER);
|
||||||
|
|
||||||
expect(users).toHaveLength(1);
|
expect(users).toHaveLength(1);
|
||||||
expect(users[0].id).toBe(user.id);
|
expect(users[0].id).toBe(user.id);
|
||||||
@ -272,8 +274,7 @@ test('should add a member user to the project', async () => {
|
|||||||
email: 'member2@getunleash.io',
|
email: 'member2@getunleash.io',
|
||||||
});
|
});
|
||||||
|
|
||||||
const roles = await stores.accessStore.getRolesForProject(project.id);
|
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
|
||||||
const memberRole = roles.find((r) => r.name === RoleName.MEMBER);
|
|
||||||
|
|
||||||
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
|
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
|
||||||
await projectService.addUser(project.id, memberRole.id, projectMember2.id);
|
await projectService.addUser(project.id, memberRole.id, projectMember2.id);
|
||||||
@ -305,10 +306,7 @@ test('should add admin users to the project', async () => {
|
|||||||
email: 'admin2@getunleash.io',
|
email: 'admin2@getunleash.io',
|
||||||
});
|
});
|
||||||
|
|
||||||
const projectRoles = await stores.accessStore.getRolesForProject(
|
const ownerRole = await stores.accessStore.getRoleByName(RoleName.OWNER);
|
||||||
project.id,
|
|
||||||
);
|
|
||||||
const ownerRole = projectRoles.find((r) => r.name === RoleName.OWNER);
|
|
||||||
|
|
||||||
await projectService.addUser(project.id, ownerRole.id, projectAdmin1.id);
|
await projectService.addUser(project.id, ownerRole.id, projectAdmin1.id);
|
||||||
await projectService.addUser(project.id, ownerRole.id, projectAdmin2.id);
|
await projectService.addUser(project.id, ownerRole.id, projectAdmin2.id);
|
||||||
@ -325,8 +323,7 @@ test('should add admin users to the project', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('add user only accept to add users to project roles', async () => {
|
test('add user only accept to add users to project roles', async () => {
|
||||||
const roles = await accessService.getRoles();
|
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
|
||||||
const memberRole = roles.find((r) => r.name === RoleName.MEMBER);
|
|
||||||
|
|
||||||
await expect(async () => {
|
await expect(async () => {
|
||||||
await projectService.addUser('some-id', memberRole.id, user.id);
|
await projectService.addUser('some-id', memberRole.id, user.id);
|
||||||
@ -346,8 +343,7 @@ test('add user should fail if user already have access', async () => {
|
|||||||
email: 'member42@getunleash.io',
|
email: 'member42@getunleash.io',
|
||||||
});
|
});
|
||||||
|
|
||||||
const roles = await stores.accessStore.getRolesForProject(project.id);
|
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
|
||||||
const memberRole = roles.find((r) => r.name === RoleName.MEMBER);
|
|
||||||
|
|
||||||
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
|
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
|
||||||
|
|
||||||
@ -371,8 +367,7 @@ test('should remove user from the project', async () => {
|
|||||||
email: 'member99@getunleash.io',
|
email: 'member99@getunleash.io',
|
||||||
});
|
});
|
||||||
|
|
||||||
const roles = await stores.accessStore.getRolesForProject(project.id);
|
const memberRole = await stores.accessStore.getRoleByName(RoleName.MEMBER);
|
||||||
const memberRole = roles.find((r) => r.name === RoleName.MEMBER);
|
|
||||||
|
|
||||||
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
|
await projectService.addUser(project.id, memberRole.id, projectMember1.id);
|
||||||
await projectService.removeUser(
|
await projectService.removeUser(
|
||||||
|
15
src/test/fixtures/fake-access-store.ts
vendored
15
src/test/fixtures/fake-access-store.ts
vendored
@ -9,6 +9,21 @@ import {
|
|||||||
import { IAvailablePermissions, IPermission } from 'lib/types/model';
|
import { IAvailablePermissions, IPermission } from 'lib/types/model';
|
||||||
|
|
||||||
class AccessStoreMock implements IAccessStore {
|
class AccessStoreMock implements IAccessStore {
|
||||||
|
unlinkUserRoles(userId: number): Promise<void> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
getRoleByName(name: string): Promise<IRole> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
|
getProjectUserIdsForRole(
|
||||||
|
roleId: number,
|
||||||
|
projectId?: string,
|
||||||
|
): Promise<number[]> {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
|
||||||
getProjectRoles(): Promise<IRole[]> {
|
getProjectRoles(): Promise<IRole[]> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user