1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-12 01:17:04 +02:00

chore: sync user groups is a system action (#7214)

## About the changes
After an internal conversation, we concluded that syncExternalGroups is
an action that Unleash performs as a system, not something triggered by
the user. We keep the method and just write the event log that the
action was performed by the system user.
This commit is contained in:
Gastón Fournier 2024-05-30 11:47:30 +02:00 committed by GitHub
parent 1ac447141a
commit 07ef4a114f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 88 deletions

View File

@ -10,6 +10,7 @@ import type {
import {
GroupDeletedEvent,
GroupUpdatedEvent,
SYSTEM_USER_AUDIT,
type IAuditUser,
type IUnleashConfig,
type IUnleashStores,
@ -19,8 +20,6 @@ import type { Logger } from '../logger';
import BadDataError from '../error/bad-data-error';
import {
GROUP_CREATED,
GROUP_USER_ADDED,
GROUP_USER_REMOVED,
GroupUserAdded,
GroupUserRemoved,
type IBaseEvent,
@ -238,62 +237,11 @@ export class GroupService {
return this.groupStore.getProjectGroupRoles(projectId);
}
/** @deprecated use syncExternalGroupsWithAudit */
async syncExternalGroups(
userId: number,
externalGroups: string[],
createdBy?: string,
createdByUserId?: number,
): Promise<void> {
if (Array.isArray(externalGroups)) {
const newGroups = await this.groupStore.getNewGroupsForExternalUser(
userId,
externalGroups,
);
await this.groupStore.addUserToGroups(
userId,
newGroups.map((g) => g.id),
createdBy,
);
const oldGroups = await this.groupStore.getOldGroupsForExternalUser(
userId,
externalGroups,
);
await this.groupStore.deleteUsersFromGroup(oldGroups);
const events: IBaseEvent[] = [];
for (const group of newGroups) {
events.push({
type: GROUP_USER_ADDED,
createdBy: createdBy ?? 'unknown',
createdByUserId: createdByUserId ?? -9999,
data: {
groupId: group.id,
userId,
},
});
}
for (const group of oldGroups) {
events.push({
type: GROUP_USER_REMOVED,
createdBy: createdBy ?? 'unknown',
createdByUserId: createdByUserId ?? -9999,
preData: {
groupId: group.groupId,
userId,
},
});
}
await this.eventService.storeEvents(events);
}
}
async syncExternalGroupsWithAudit(
userId: number,
externalGroups: string[],
auditUser: IAuditUser,
createdBy?: string, // deprecated
createdByUserId?: number, // deprecated
): Promise<void> {
if (Array.isArray(externalGroups)) {
const newGroups = await this.groupStore.getNewGroupsForExternalUser(
@ -317,7 +265,7 @@ export class GroupService {
new GroupUserAdded({
userId,
groupId: group.id,
auditUser,
auditUser: SYSTEM_USER_AUDIT,
}),
);
}
@ -327,7 +275,7 @@ export class GroupService {
new GroupUserRemoved({
userId,
groupId: group.groupId,
auditUser,
auditUser: SYSTEM_USER_AUDIT,
}),
);
}

View File

@ -8,7 +8,6 @@ import {
type IUnleashStores,
type IUser,
TEST_AUDIT_USER,
SYSTEM_USER_AUDIT,
} from '../../../lib/types';
let stores: IUnleashStores;
@ -70,11 +69,7 @@ test('should have three group', async () => {
});
test('should add person to 2 groups', async () => {
await groupService.syncExternalGroupsWithAudit(
user.id,
['dev', 'maintainer'],
SYSTEM_USER_AUDIT,
);
await groupService.syncExternalGroups(user.id, ['dev', 'maintainer']);
const groups = await groupService.getGroupsForUser(user.id);
expect(groups.length).toBe(2);
const events = await getTestEvents();
@ -99,11 +94,7 @@ test('should remove person from one group', async () => {
const removedGroups = (await groupService.getGroupsForUser(user.id)).filter(
(g) => !g.mappingsSSO?.includes('maintainer'),
);
await groupService.syncExternalGroupsWithAudit(
user.id,
['maintainer'],
SYSTEM_USER_AUDIT,
);
await groupService.syncExternalGroups(user.id, ['maintainer']);
const groups = await groupService.getGroupsForUser(user.id);
expect(groups.length).toBe(1);
expect(groups[0].name).toEqual('maintainer_group');
@ -124,11 +115,7 @@ test('should add person to completely new group with new name', async () => {
const removedGroups = (await groupService.getGroupsForUser(user.id)).filter(
(g) => !g.mappingsSSO?.includes('dev'),
);
await groupService.syncExternalGroupsWithAudit(
user.id,
['dev'],
SYSTEM_USER_AUDIT,
);
await groupService.syncExternalGroups(user.id, ['dev']);
const groups = await groupService.getGroupsForUser(user.id);
expect(groups.length).toBe(1);
expect(groups[0].name).toEqual('dev_group');
@ -153,11 +140,7 @@ test('should add person to completely new group with new name', async () => {
test('should not update groups when not string array ', async () => {
const beforeEvents = await getTestEvents();
await groupService.syncExternalGroupsWithAudit(
user.id,
'Everyone' as any,
SYSTEM_USER_AUDIT,
);
await groupService.syncExternalGroups(user.id, 'Everyone' as any);
const groups = await groupService.getGroupsForUser(user.id);
expect(groups.length).toBe(1);
expect(groups[0].name).toEqual('dev_group');
@ -168,11 +151,7 @@ test('should not update groups when not string array ', async () => {
// this test depends on the other tests being executed
test('should clear groups when empty array ', async () => {
const removedGroups = await groupService.getGroupsForUser(user.id);
await groupService.syncExternalGroupsWithAudit(
user.id,
[],
SYSTEM_USER_AUDIT,
);
await groupService.syncExternalGroups(user.id, []);
const groups = await groupService.getGroupsForUser(user.id);
expect(groups.length).toBe(0);
expect(removedGroups).toHaveLength(1);
@ -193,11 +172,7 @@ test('should not remove user from no SSO definition group', async () => {
description: 'no_mapping_group',
});
await groupStore.addUserToGroups(user.id, [group.id]);
await groupService.syncExternalGroupsWithAudit(
user.id,
[],
SYSTEM_USER_AUDIT,
);
await groupService.syncExternalGroups(user.id, []);
const groups = await groupService.getGroupsForUser(user.id);
expect(groups.length).toBe(1);
expect(groups[0].name).toEqual('no_mapping_group');