mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-17 01:17:29 +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:
parent
1ac447141a
commit
07ef4a114f
@ -10,6 +10,7 @@ import type {
|
|||||||
import {
|
import {
|
||||||
GroupDeletedEvent,
|
GroupDeletedEvent,
|
||||||
GroupUpdatedEvent,
|
GroupUpdatedEvent,
|
||||||
|
SYSTEM_USER_AUDIT,
|
||||||
type IAuditUser,
|
type IAuditUser,
|
||||||
type IUnleashConfig,
|
type IUnleashConfig,
|
||||||
type IUnleashStores,
|
type IUnleashStores,
|
||||||
@ -19,8 +20,6 @@ import type { Logger } from '../logger';
|
|||||||
import BadDataError from '../error/bad-data-error';
|
import BadDataError from '../error/bad-data-error';
|
||||||
import {
|
import {
|
||||||
GROUP_CREATED,
|
GROUP_CREATED,
|
||||||
GROUP_USER_ADDED,
|
|
||||||
GROUP_USER_REMOVED,
|
|
||||||
GroupUserAdded,
|
GroupUserAdded,
|
||||||
GroupUserRemoved,
|
GroupUserRemoved,
|
||||||
type IBaseEvent,
|
type IBaseEvent,
|
||||||
@ -238,62 +237,11 @@ export class GroupService {
|
|||||||
return this.groupStore.getProjectGroupRoles(projectId);
|
return this.groupStore.getProjectGroupRoles(projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @deprecated use syncExternalGroupsWithAudit */
|
|
||||||
async syncExternalGroups(
|
async syncExternalGroups(
|
||||||
userId: number,
|
userId: number,
|
||||||
externalGroups: string[],
|
externalGroups: string[],
|
||||||
createdBy?: string,
|
createdBy?: string, // deprecated
|
||||||
createdByUserId?: number,
|
createdByUserId?: number, // deprecated
|
||||||
): 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,
|
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (Array.isArray(externalGroups)) {
|
if (Array.isArray(externalGroups)) {
|
||||||
const newGroups = await this.groupStore.getNewGroupsForExternalUser(
|
const newGroups = await this.groupStore.getNewGroupsForExternalUser(
|
||||||
@ -317,7 +265,7 @@ export class GroupService {
|
|||||||
new GroupUserAdded({
|
new GroupUserAdded({
|
||||||
userId,
|
userId,
|
||||||
groupId: group.id,
|
groupId: group.id,
|
||||||
auditUser,
|
auditUser: SYSTEM_USER_AUDIT,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -327,7 +275,7 @@ export class GroupService {
|
|||||||
new GroupUserRemoved({
|
new GroupUserRemoved({
|
||||||
userId,
|
userId,
|
||||||
groupId: group.groupId,
|
groupId: group.groupId,
|
||||||
auditUser,
|
auditUser: SYSTEM_USER_AUDIT,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
type IUnleashStores,
|
type IUnleashStores,
|
||||||
type IUser,
|
type IUser,
|
||||||
TEST_AUDIT_USER,
|
TEST_AUDIT_USER,
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
} from '../../../lib/types';
|
} from '../../../lib/types';
|
||||||
|
|
||||||
let stores: IUnleashStores;
|
let stores: IUnleashStores;
|
||||||
@ -70,11 +69,7 @@ test('should have three group', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should add person to 2 groups', async () => {
|
test('should add person to 2 groups', async () => {
|
||||||
await groupService.syncExternalGroupsWithAudit(
|
await groupService.syncExternalGroups(user.id, ['dev', 'maintainer']);
|
||||||
user.id,
|
|
||||||
['dev', 'maintainer'],
|
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
);
|
|
||||||
const groups = await groupService.getGroupsForUser(user.id);
|
const groups = await groupService.getGroupsForUser(user.id);
|
||||||
expect(groups.length).toBe(2);
|
expect(groups.length).toBe(2);
|
||||||
const events = await getTestEvents();
|
const events = await getTestEvents();
|
||||||
@ -99,11 +94,7 @@ test('should remove person from one group', async () => {
|
|||||||
const removedGroups = (await groupService.getGroupsForUser(user.id)).filter(
|
const removedGroups = (await groupService.getGroupsForUser(user.id)).filter(
|
||||||
(g) => !g.mappingsSSO?.includes('maintainer'),
|
(g) => !g.mappingsSSO?.includes('maintainer'),
|
||||||
);
|
);
|
||||||
await groupService.syncExternalGroupsWithAudit(
|
await groupService.syncExternalGroups(user.id, ['maintainer']);
|
||||||
user.id,
|
|
||||||
['maintainer'],
|
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
);
|
|
||||||
const groups = await groupService.getGroupsForUser(user.id);
|
const groups = await groupService.getGroupsForUser(user.id);
|
||||||
expect(groups.length).toBe(1);
|
expect(groups.length).toBe(1);
|
||||||
expect(groups[0].name).toEqual('maintainer_group');
|
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(
|
const removedGroups = (await groupService.getGroupsForUser(user.id)).filter(
|
||||||
(g) => !g.mappingsSSO?.includes('dev'),
|
(g) => !g.mappingsSSO?.includes('dev'),
|
||||||
);
|
);
|
||||||
await groupService.syncExternalGroupsWithAudit(
|
await groupService.syncExternalGroups(user.id, ['dev']);
|
||||||
user.id,
|
|
||||||
['dev'],
|
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
);
|
|
||||||
const groups = await groupService.getGroupsForUser(user.id);
|
const groups = await groupService.getGroupsForUser(user.id);
|
||||||
expect(groups.length).toBe(1);
|
expect(groups.length).toBe(1);
|
||||||
expect(groups[0].name).toEqual('dev_group');
|
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 () => {
|
test('should not update groups when not string array ', async () => {
|
||||||
const beforeEvents = await getTestEvents();
|
const beforeEvents = await getTestEvents();
|
||||||
await groupService.syncExternalGroupsWithAudit(
|
await groupService.syncExternalGroups(user.id, 'Everyone' as any);
|
||||||
user.id,
|
|
||||||
'Everyone' as any,
|
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
);
|
|
||||||
const groups = await groupService.getGroupsForUser(user.id);
|
const groups = await groupService.getGroupsForUser(user.id);
|
||||||
expect(groups.length).toBe(1);
|
expect(groups.length).toBe(1);
|
||||||
expect(groups[0].name).toEqual('dev_group');
|
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
|
// this test depends on the other tests being executed
|
||||||
test('should clear groups when empty array ', async () => {
|
test('should clear groups when empty array ', async () => {
|
||||||
const removedGroups = await groupService.getGroupsForUser(user.id);
|
const removedGroups = await groupService.getGroupsForUser(user.id);
|
||||||
await groupService.syncExternalGroupsWithAudit(
|
await groupService.syncExternalGroups(user.id, []);
|
||||||
user.id,
|
|
||||||
[],
|
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
);
|
|
||||||
const groups = await groupService.getGroupsForUser(user.id);
|
const groups = await groupService.getGroupsForUser(user.id);
|
||||||
expect(groups.length).toBe(0);
|
expect(groups.length).toBe(0);
|
||||||
expect(removedGroups).toHaveLength(1);
|
expect(removedGroups).toHaveLength(1);
|
||||||
@ -193,11 +172,7 @@ test('should not remove user from no SSO definition group', async () => {
|
|||||||
description: 'no_mapping_group',
|
description: 'no_mapping_group',
|
||||||
});
|
});
|
||||||
await groupStore.addUserToGroups(user.id, [group.id]);
|
await groupStore.addUserToGroups(user.id, [group.id]);
|
||||||
await groupService.syncExternalGroupsWithAudit(
|
await groupService.syncExternalGroups(user.id, []);
|
||||||
user.id,
|
|
||||||
[],
|
|
||||||
SYSTEM_USER_AUDIT,
|
|
||||||
);
|
|
||||||
const groups = await groupService.getGroupsForUser(user.id);
|
const groups = await groupService.getGroupsForUser(user.id);
|
||||||
expect(groups.length).toBe(1);
|
expect(groups.length).toBe(1);
|
||||||
expect(groups[0].name).toEqual('no_mapping_group');
|
expect(groups[0].name).toEqual('no_mapping_group');
|
||||||
|
Loading…
Reference in New Issue
Block a user