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

Implement group access edit for project (#1854)

This commit is contained in:
sjaanus 2022-07-25 10:11:16 +00:00 committed by GitHub
parent cc341e7913
commit 33ed72716f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 4 deletions

View File

@ -17,10 +17,10 @@ const T = {
GROUP_ROLE: 'group_role', GROUP_ROLE: 'group_role',
USERS: 'users', USERS: 'users',
PROJECTS: 'projects', PROJECTS: 'projects',
ROLES: 'roles',
}; };
const GROUP_COLUMNS = ['id', 'name', 'description', 'created_at', 'created_by']; const GROUP_COLUMNS = ['id', 'name', 'description', 'created_at', 'created_by'];
const GROUP_ROLE_COLUMNS = ['group_id', 'role_id', 'created_at'];
const rowToGroup = (row) => { const rowToGroup = (row) => {
if (!row) { if (!row) {
@ -81,14 +81,17 @@ export default class GroupStore implements IGroupStore {
async getProjectGroupRoles(projectId: string): Promise<IGroupRole[]> { async getProjectGroupRoles(projectId: string): Promise<IGroupRole[]> {
const rows = await this.db const rows = await this.db
.select(GROUP_ROLE_COLUMNS) .select('gr.group_id', 'gr.role_id', 'gr.created_at', 'r.name')
.from(`${T.GROUP_ROLE}`) .from(`${T.GROUP_ROLE} as gr`)
.innerJoin(`${T.ROLES} as r`, 'gr.role_id', 'r.id')
.where('project', projectId); .where('project', projectId);
return rows.map((r) => { return rows.map((r) => {
return { return {
groupId: r.group_id, groupId: r.group_id,
roleId: r.role_id, roleId: r.role_id,
createdAt: r.created_at, createdAt: r.created_at,
name: r.name,
}; };
}); });
} }

View File

@ -3,6 +3,7 @@ import {
IGroupModel, IGroupModel,
IGroupModelWithProjectRole, IGroupModelWithProjectRole,
IGroupProject, IGroupProject,
IGroupRole,
IGroupUser, IGroupUser,
} from '../types/group'; } from '../types/group';
import { IUnleashConfig, IUnleashStores } from '../types'; import { IUnleashConfig, IUnleashStores } from '../types';
@ -193,6 +194,10 @@ export class GroupService {
} }
} }
async getRolesForProject(projectId: string): Promise<IGroupRole[]> {
return this.groupStore.getProjectGroupRoles(projectId);
}
private mapGroupWithUsers( private mapGroupWithUsers(
group: IGroup, group: IGroup,
allGroupUsers: IGroupUser[], allGroupUsers: IGroupUser[],

View File

@ -14,6 +14,7 @@ import {
ProjectUserUpdateRoleEvent, ProjectUserUpdateRoleEvent,
ProjectGroupAddedEvent, ProjectGroupAddedEvent,
ProjectGroupRemovedEvent, ProjectGroupRemovedEvent,
ProjectGroupUpdateRoleEvent,
} from '../types/events'; } from '../types/events';
import { IUnleashStores } from '../types'; import { IUnleashStores } from '../types';
import { IUnleashConfig } from '../types/option'; import { IUnleashConfig } from '../types/option';
@ -45,7 +46,7 @@ import ProjectWithoutOwnerError from '../error/project-without-owner-error';
import { IUserStore } from 'lib/types/stores/user-store'; import { IUserStore } from 'lib/types/stores/user-store';
import { arraysHaveSameItems } from '../util/arraysHaveSameItems'; import { arraysHaveSameItems } from '../util/arraysHaveSameItems';
import { GroupService } from './group-service'; import { GroupService } from './group-service';
import { IGroupModelWithProjectRole } from 'lib/types/group'; import { IGroupModelWithProjectRole, IGroupRole } from 'lib/types/group';
const getCreatedBy = (user: User) => user.email || user.username; const getCreatedBy = (user: User) => user.email || user.username;
@ -436,6 +437,20 @@ export default class ProjectService {
); );
} }
async findProjectGroupRole(
projectId: string,
roleId: number,
): Promise<IGroupRole> {
const roles = await this.groupService.getRolesForProject(projectId);
const role = roles.find((r) => r.roleId === roleId);
if (!role) {
throw new NotFoundError(
`Couldn't find roleId=${roleId} on project=${projectId}`,
);
}
return role;
}
async findProjectRole( async findProjectRole(
projectId: string, projectId: string,
roleId: number, roleId: number,
@ -513,6 +528,50 @@ export default class ProjectService {
); );
} }
async changeGroupRole(
projectId: string,
roleId: number,
userId: number,
createdBy: string,
): Promise<void> {
const usersWithRoles = await this.getAccessToProject(projectId);
const user = usersWithRoles.groups.find((u) => u.id === userId);
const currentRole = usersWithRoles.roles.find(
(r) => r.id === user.roleId,
);
if (currentRole.id === roleId) {
// Nothing to do....
return;
}
await this.validateAtLeastOneOwner(projectId, currentRole);
await this.accessService.updateGroupProjectRole(
userId,
roleId,
projectId,
);
const role = await this.findProjectGroupRole(projectId, roleId);
await this.eventStore.store(
new ProjectGroupUpdateRoleEvent({
project: projectId,
createdBy,
preData: {
userId,
roleId: currentRole.id,
roleName: currentRole.name,
},
data: {
userId,
roleId,
roleName: role.name,
},
}),
);
}
async getMembers(projectId: string): Promise<number> { async getMembers(projectId: string): Promise<number> {
return this.store.getMembers(projectId); return this.store.getMembers(projectId);
} }

View File

@ -17,6 +17,7 @@ export interface IGroupUser {
} }
export interface IGroupRole { export interface IGroupRole {
name: string;
groupId: number; groupId: number;
roleId: number; roleId: number;
createdAt: Date; createdAt: Date;