mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
feat: Return permissions on get role endpoint
This commit is contained in:
parent
8babe8cadf
commit
f8550790c5
@ -163,14 +163,27 @@ export class AccessStore implements IAccessStore {
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPermissionsForRole(roleId: number): Promise<IUserPermission[]> {
|
async getPermissionsForRole(roleId: number): Promise<IPermission[]> {
|
||||||
const stopTimer = this.timer('getPermissionsForRole');
|
const stopTimer = this.timer('getPermissionsForRole');
|
||||||
const rows = await this.db
|
const rows = await this.db
|
||||||
.select('project', 'permission', 'environment')
|
.select('p.id', 'p.permission', 'p.environment', 'pt.display_name')
|
||||||
.from<IUserPermission>(`${T.ROLE_PERMISSION}`)
|
.from<IPermission>(`${T.ROLE_PERMISSION} as rp`)
|
||||||
.where('role_id', '=', roleId);
|
.join(`${T.PERMISSIONS} as p`, 'p.id', 'rp.permission_id')
|
||||||
|
.join(
|
||||||
|
`${T.PERMISSION_TYPES} as pt`,
|
||||||
|
'pt.permission',
|
||||||
|
'p.permission',
|
||||||
|
)
|
||||||
|
.where('rp.role_id', '=', roleId);
|
||||||
stopTimer();
|
stopTimer();
|
||||||
return rows;
|
return rows.map((permission) => {
|
||||||
|
return {
|
||||||
|
id: permission.id,
|
||||||
|
name: permission.permission,
|
||||||
|
environment: permission.environment,
|
||||||
|
displayName: permission.display_name,
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRoles(): Promise<IRole[]> {
|
async getRoles(): Promise<IRole[]> {
|
||||||
@ -338,6 +351,13 @@ export class AccessStore implements IAccessStore {
|
|||||||
`SELECT id FROM ${T.PERMISSIONS} where environment = ? and permission = ANY(?)`,
|
`SELECT id FROM ${T.PERMISSIONS} where environment = ? and permission = ANY(?)`,
|
||||||
[environment, permissions],
|
[environment, permissions],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'Adding permissions to table',
|
||||||
|
role_id,
|
||||||
|
permissions,
|
||||||
|
environment,
|
||||||
|
);
|
||||||
const ids = result.rows.map((x) => x.id);
|
const ids = result.rows.map((x) => x.id);
|
||||||
|
|
||||||
const rows = ids.map((permission_id) => ({
|
const rows = ids.map((permission_id) => ({
|
||||||
@ -345,19 +365,29 @@ export class AccessStore implements IAccessStore {
|
|||||||
permission_id,
|
permission_id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
console.log('Final inssert', rows);
|
||||||
return this.db.batchInsert(T.ROLE_PERMISSION, rows);
|
return this.db.batchInsert(T.ROLE_PERMISSION, rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
async removePermissionFromRole(
|
async removePermissionFromRole(
|
||||||
roleId: number,
|
role_id: number,
|
||||||
permission: string,
|
permission: string,
|
||||||
projectId?: string,
|
environment?: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
const result = await this.db.raw(
|
||||||
|
`SELECT id FROM ${T.PERMISSIONS} where environment = ? and permission = ?`,
|
||||||
|
[environment, permission],
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('Gett results for ', environment, permission);
|
||||||
|
console.log('My result is', result);
|
||||||
|
|
||||||
|
const permissionId = result.first();
|
||||||
|
|
||||||
return this.db(T.ROLE_PERMISSION)
|
return this.db(T.ROLE_PERMISSION)
|
||||||
.where({
|
.where({
|
||||||
role_id: roleId,
|
role_id,
|
||||||
permission,
|
permissionId,
|
||||||
project: projectId,
|
|
||||||
})
|
})
|
||||||
.delete();
|
.delete();
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@ import { ICustomRole } from 'lib/types/model';
|
|||||||
import { ICustomRoleInsert } from 'lib/types/stores/role-store';
|
import { ICustomRoleInsert } from 'lib/types/stores/role-store';
|
||||||
|
|
||||||
const TABLE = 'roles';
|
const TABLE = 'roles';
|
||||||
const COLUMNS = ['id', 'name', 'description', 'created_at'];
|
const COLUMNS = ['id', 'name', 'description', 'type'];
|
||||||
|
|
||||||
interface IRoleRow {
|
interface IRoleRow {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
created_at: Date;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class RoleStore {
|
export default class RoleStore {
|
||||||
@ -79,7 +79,7 @@ export default class RoleStore {
|
|||||||
id: row.id,
|
id: row.id,
|
||||||
name: row.name,
|
name: row.name,
|
||||||
description: row.description,
|
description: row.description,
|
||||||
createdAt: row.created_at,
|
type: row.type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,14 +198,18 @@ export class AccessService {
|
|||||||
async addPermissionToRole(
|
async addPermissionToRole(
|
||||||
roleId: number,
|
roleId: number,
|
||||||
permission: string,
|
permission: string,
|
||||||
projectId?: string,
|
environment?: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (isProjectPermission(permission) && !projectId) {
|
if (isProjectPermission(permission) && !environment) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`ProjectId cannot be empty for permission=${permission}`,
|
`ProjectId cannot be empty for permission=${permission}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return this.store.addPermissionsToRole(roleId, [permission], projectId);
|
return this.store.addPermissionsToRole(
|
||||||
|
roleId,
|
||||||
|
[permission],
|
||||||
|
environment,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async removePermissionFromRole(
|
async removePermissionFromRole(
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
import { IUnleashConfig } from 'lib/server-impl';
|
import { IUnleashConfig } from 'lib/server-impl';
|
||||||
import { IUnleashStores } from 'lib/types';
|
import { IUnleashStores } from 'lib/types';
|
||||||
import { ICustomRole, IPermission } from 'lib/types/model';
|
import { ICustomRole, IPermission } from 'lib/types/model';
|
||||||
import { IAccessStore } from 'lib/types/stores/access-store';
|
import {
|
||||||
|
IAccessStore,
|
||||||
|
IRoleWithPermissions,
|
||||||
|
} from 'lib/types/stores/access-store';
|
||||||
import { IRoleStore } from 'lib/types/stores/role-store';
|
import { IRoleStore } from 'lib/types/stores/role-store';
|
||||||
import { Logger } from '../logger';
|
import { Logger } from '../logger';
|
||||||
|
|
||||||
@ -34,8 +37,15 @@ export default class RoleService {
|
|||||||
return this.store.getAll();
|
return this.store.getAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(id: number): Promise<ICustomRole> {
|
async get(id: number): Promise<IRoleWithPermissions> {
|
||||||
return this.store.get(id);
|
const role = await this.store.get(id);
|
||||||
|
const permissions = await this.accessStore.getPermissionsForRole(
|
||||||
|
role.id,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...role,
|
||||||
|
permissions,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(role: IRoleCreation): Promise<ICustomRole> {
|
async create(role: IRoleCreation): Promise<ICustomRole> {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ITagType } from './stores/tag-type-store';
|
import { ITagType } from './stores/tag-type-store';
|
||||||
import { LogProvider } from '../logger';
|
import { LogProvider } from '../logger';
|
||||||
import { IRole, IUserPermission } from './stores/access-store';
|
import { IRole } from './stores/access-store';
|
||||||
import { IUser } from './user';
|
import { IUser } from './user';
|
||||||
|
|
||||||
export interface IConstraint {
|
export interface IConstraint {
|
||||||
@ -212,7 +212,7 @@ export interface IUserWithRole {
|
|||||||
export interface IRoleData {
|
export interface IRoleData {
|
||||||
role: IRole;
|
role: IRole;
|
||||||
users: IUser[];
|
users: IUser[];
|
||||||
permissions: IUserPermission[];
|
permissions: IPermission[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAvailablePermissions {
|
export interface IAvailablePermissions {
|
||||||
@ -224,6 +224,7 @@ export interface IPermission {
|
|||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
|
environment?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IEnvironmentPermission {
|
export interface IEnvironmentPermission {
|
||||||
@ -328,7 +329,7 @@ export interface ICustomRole {
|
|||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
createdAt: Date;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectWithCount extends IProject {
|
export interface IProjectWithCount extends IProject {
|
||||||
|
@ -14,6 +14,10 @@ export interface IRole {
|
|||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IRoleWithPermissions extends IRole {
|
||||||
|
permissions: IPermission[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface IRoleDescriptor {
|
export interface IRoleDescriptor {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
@ -28,7 +32,7 @@ export interface IAccessStore extends Store<IRole, number> {
|
|||||||
getRoleByName(name: string): Promise<IRole>;
|
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<IPermission[]>;
|
||||||
getRoles(): Promise<IRole[]>;
|
getRoles(): Promise<IRole[]>;
|
||||||
getRolesForProject(projectId: string): Promise<IRole[]>;
|
getRolesForProject(projectId: string): Promise<IRole[]>;
|
||||||
unlinkUserRoles(userId: number): Promise<void>;
|
unlinkUserRoles(userId: number): Promise<void>;
|
||||||
|
@ -4,6 +4,7 @@ import getLogger from '../../fixtures/no-logger';
|
|||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import {
|
import {
|
||||||
AccessService,
|
AccessService,
|
||||||
|
ALL_ENVS,
|
||||||
ALL_PROJECTS,
|
ALL_PROJECTS,
|
||||||
} from '../../../lib/services/access-service';
|
} from '../../../lib/services/access-service';
|
||||||
|
|
||||||
@ -177,13 +178,13 @@ test('should remove CREATE_FEATURE on all projects', async () => {
|
|||||||
await accessService.addPermissionToRole(
|
await accessService.addPermissionToRole(
|
||||||
editorRole.id,
|
editorRole.id,
|
||||||
permissions.CREATE_FEATURE,
|
permissions.CREATE_FEATURE,
|
||||||
ALL_PROJECTS,
|
ALL_ENVS,
|
||||||
);
|
);
|
||||||
|
|
||||||
await accessService.removePermissionFromRole(
|
await accessService.removePermissionFromRole(
|
||||||
editorRole.id,
|
editorRole.id,
|
||||||
permissions.CREATE_FEATURE,
|
permissions.CREATE_FEATURE,
|
||||||
ALL_PROJECTS,
|
ALL_ENVS,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
|
2
src/test/fixtures/fake-access-store.ts
vendored
2
src/test/fixtures/fake-access-store.ts
vendored
@ -54,7 +54,7 @@ class AccessStoreMock implements IAccessStore {
|
|||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPermissionsForRole(roleId: number): Promise<IUserPermission[]> {
|
getPermissionsForRole(roleId: number): Promise<IPermission[]> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
src/test/fixtures/fake-role-store.ts
vendored
6
src/test/fixtures/fake-role-store.ts
vendored
@ -12,7 +12,7 @@ export default class FakeRoleStore implements IRoleStore {
|
|||||||
id: 1,
|
id: 1,
|
||||||
name: 'Role',
|
name: 'Role',
|
||||||
description: 'Hello',
|
description: 'Hello',
|
||||||
createdAt: new Date(),
|
type: 'custom',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ export default class FakeRoleStore implements IRoleStore {
|
|||||||
id: 1,
|
id: 1,
|
||||||
name: 'Role',
|
name: 'Role',
|
||||||
description: 'Hello',
|
description: 'Hello',
|
||||||
createdAt: new Date(),
|
type: 'custom',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ export default class FakeRoleStore implements IRoleStore {
|
|||||||
id: 1,
|
id: 1,
|
||||||
name: 'Role',
|
name: 'Role',
|
||||||
description: 'Hello',
|
description: 'Hello',
|
||||||
createdAt: new Date(),
|
type: 'custom',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user