Skip to content
This repository was archived by the owner on Feb 21, 2023. It is now read-only.

Commit 814e7df

Browse files
committed
feat: 增加 group.updateGroupRolePermission 和 group.getGroupUserPermission
1 parent b156ddb commit 814e7df

5 files changed

Lines changed: 214 additions & 33 deletions

File tree

jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = {
66
],
77
globals: {
88
'ts-jest': {
9-
tsConfig: 'tsconfig.json',
9+
tsconfig: 'tsconfig.json',
1010
},
1111
},
1212
};

models/group/group.ts

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Severity,
99
} from '@typegoose/typegoose';
1010
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
11+
import _ from 'lodash';
1112
import { Types } from 'mongoose';
1213
import { BUILTIN_GROUP_PERM, NAME_REGEXP } from '../../lib/const';
1314
import { User } from '../user/user';
@@ -22,7 +23,7 @@ class GroupMember {
2223
@prop({
2324
type: () => String,
2425
})
25-
role?: string[]; // 角色
26+
roles?: string[]; // 角色
2627

2728
@prop({
2829
ref: () => User,
@@ -74,7 +75,7 @@ export class GroupRole implements Base {
7475
@prop({
7576
type: () => String,
7677
})
77-
permission: string[]; // 拥有的权限, 是一段字符串
78+
permissions: string[]; // 拥有的权限, 是一段字符串
7879
}
7980

8081
export class Group extends TimeStamps implements Base {
@@ -103,12 +104,7 @@ export class Group extends TimeStamps implements Base {
103104

104105
@prop({
105106
type: () => GroupRole,
106-
default: [
107-
{
108-
name: 'manager',
109-
permission: [...Object.keys(BUILTIN_GROUP_PERM)],
110-
},
111-
],
107+
default: [],
112108
})
113109
roles?: GroupRole[];
114110

@@ -153,7 +149,7 @@ export class Group extends TimeStamps implements Base {
153149
owner,
154150
members: [
155151
{
156-
role: ['manager'],
152+
roles: [],
157153
userId: owner,
158154
},
159155
],
@@ -174,6 +170,66 @@ export class Group extends TimeStamps implements Base {
174170
'members.userId': userId,
175171
});
176172
}
173+
174+
/**
175+
* 修改群组权限
176+
*/
177+
static async updateGroupRolePermission(
178+
this: ReturnModelType<typeof Group>,
179+
groupId: string,
180+
roleName: string,
181+
permissions: string[],
182+
operatorUserId: string
183+
): Promise<Group> {
184+
const group = await this.findById(groupId);
185+
if (!group) {
186+
throw new Error('Not Found Group');
187+
}
188+
189+
// 首先判断是否有修改权限的权限
190+
if (String(group.owner) !== operatorUserId) {
191+
throw new Error('No Permission');
192+
}
193+
194+
const modifyRole = group.roles.find((role) => role.name === roleName);
195+
if (!modifyRole) {
196+
throw new Error('Not Found Role');
197+
}
198+
199+
modifyRole.permissions = [...permissions];
200+
await group.save();
201+
202+
return group;
203+
}
204+
205+
/**
206+
* 获取用户所有权限
207+
*/
208+
static async getGroupUserPermission(
209+
this: ReturnModelType<typeof Group>,
210+
groupId: string,
211+
userId: string
212+
): Promise<string[]> {
213+
const group = await this.findById(groupId);
214+
if (!group) {
215+
throw new Error('Not Found Group');
216+
}
217+
218+
const member = group.members.find(
219+
(member) => String(member.userId) === userId
220+
);
221+
if (!member) {
222+
throw new Error('Not Found Member');
223+
}
224+
225+
const allRoles = member.roles;
226+
const allRolesPermission = allRoles.map((roleName) => {
227+
const p = group.roles.find((r) => r.name === roleName);
228+
229+
return p?.permissions ?? [];
230+
});
231+
return _.union(...allRolesPermission); // 权限取并集
232+
}
177233
}
178234

179235
export type GroupDocument = DocumentType<Group>;

services/base.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
ActionHandler,
33
ActionSchema,
4+
CallingOptions,
45
Context,
56
Service,
67
ServiceBroker,
@@ -192,6 +193,17 @@ export abstract class TcService extends Service {
192193
return `notify:${this.serviceName}.${eventName}`;
193194
}
194195

196+
/**
197+
* 本地调用操作,不经过外部转发
198+
*/
199+
protected localCall(
200+
actionName: string,
201+
params?: {},
202+
opts?: CallingOptions
203+
): Promise<any> {
204+
return this.actions[actionName](params, opts);
205+
}
206+
195207
/**
196208
* 单播推送socket事件
197209
*/

services/core/group/group.service.ts

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,25 @@ class GroupService extends TcService {
116116
roleName: 'string',
117117
},
118118
});
119+
this.registerAction(
120+
'updateGroupRolePermission',
121+
this.updateGroupRolePermission,
122+
{
123+
params: {
124+
groupId: 'string',
125+
roleName: 'string',
126+
permissions: {
127+
type: 'array',
128+
items: 'string',
129+
},
130+
},
131+
}
132+
);
133+
this.registerAction('getGroupUserPermission', this.getGroupUserPermission, {
134+
params: {
135+
groupId: 'string',
136+
},
137+
});
119138
}
120139

121140
/**
@@ -593,11 +612,10 @@ class GroupService extends TcService {
593612
.exec();
594613

595614
const json = await this.transformDocuments(ctx, {}, group);
596-
597615
this.roomcastNotify(ctx, groupId, 'updateInfo', json);
598-
599616
return json;
600617
}
618+
601619
/**
602620
* 删除群组角色
603621
*/
@@ -625,11 +643,53 @@ class GroupService extends TcService {
625643
.exec();
626644

627645
const json = await this.transformDocuments(ctx, {}, group);
628-
629646
this.roomcastNotify(ctx, groupId, 'updateInfo', json);
647+
return json;
648+
}
649+
650+
/**
651+
* 更新群组角色权限
652+
*/
653+
async updateGroupRolePermission(
654+
ctx: TcContext<{
655+
groupId: string;
656+
roleName: string;
657+
permissions: string[];
658+
}>
659+
) {
660+
const { groupId, roleName, permissions } = ctx.params;
661+
const userId = ctx.meta.userId;
630662

663+
const group = await this.adapter.model.updateGroupRolePermission(
664+
groupId,
665+
roleName,
666+
permissions,
667+
userId
668+
);
669+
670+
const json = await this.transformDocuments(ctx, {}, group);
671+
this.roomcastNotify(ctx, groupId, 'updateInfo', json);
631672
return json;
632673
}
674+
675+
/**
676+
* 获取群组成员权限
677+
*/
678+
async getGroupUserPermission(
679+
ctx: TcContext<{
680+
groupId: string;
681+
}>
682+
) {
683+
const { groupId } = ctx.params;
684+
const userId = ctx.meta.userId;
685+
686+
const permissions = await this.adapter.model.getGroupUserPermission(
687+
groupId,
688+
userId
689+
);
690+
691+
return permissions;
692+
}
633693
}
634694

635695
export default GroupService;

test/integration/group/group.spec.ts

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,7 @@ describe('Test "group" service', () => {
8383
const panels = res.panels;
8484
expect(panels[0].id).toHaveLength(24);
8585
expect(panels[1].id).toBe(panels[2].parentId);
86-
87-
// 将会创建默认权限组
88-
expect(res.roles).toMatchObject([
89-
{
90-
permission: [
91-
'displayChannel',
92-
'manageChannel',
93-
'manageRole',
94-
'manageGroup',
95-
'sendMessage',
96-
'sendImage',
97-
],
98-
name: 'manager',
99-
},
100-
]);
86+
expect(res.roles).toEqual([]);
10187
} finally {
10288
await service.adapter.model.findByIdAndRemove(res._id);
10389
}
@@ -129,7 +115,7 @@ describe('Test "group" service', () => {
129115
[...testGroup.members].map((v) => service.adapter.entityToObject(v))
130116
).toEqual([
131117
{
132-
role: ['manager'],
118+
roles: [],
133119
userId,
134120
},
135121
]);
@@ -151,11 +137,11 @@ describe('Test "group" service', () => {
151137
const newMembers = [...res.members];
152138
expect(newMembers).toEqual([
153139
{
154-
role: ['manager'],
140+
roles: [],
155141
userId,
156142
},
157143
{
158-
role: [],
144+
roles: [],
159145
userId: newMemberUserId,
160146
},
161147
]);
@@ -301,7 +287,7 @@ describe('Test "group" service', () => {
301287
},
302288
{
303289
meta: {
304-
userId,
290+
userId: String(userId),
305291
},
306292
}
307293
);
@@ -335,13 +321,80 @@ describe('Test "group" service', () => {
335321
},
336322
{
337323
meta: {
338-
userId,
324+
userId: String(userId),
339325
},
340326
}
341327
);
342328

343329
expect(res.roles.length).toBe(0);
344330
expect(res.roles).toEqual([]);
345331
});
332+
333+
test('Test "group.updateGroupRolePermission"', async () => {
334+
const userId = new Types.ObjectId();
335+
const role = createTestRole('TestRole', ['permission1', 'permission2']);
336+
const role2 = createTestRole('TestRole2', ['permission1', 'permission2']);
337+
const testGroup = await insertTestData(
338+
createTestGroup(userId, {
339+
roles: [role, role2],
340+
})
341+
);
342+
343+
const res: Group = await broker.call(
344+
'group.updateGroupRolePermission',
345+
{
346+
groupId: String(testGroup.id),
347+
roleName: 'TestRole',
348+
permissions: ['foo'],
349+
},
350+
{
351+
meta: {
352+
userId: String(userId),
353+
},
354+
}
355+
);
356+
357+
expect(res.roles.length).toBe(2);
358+
expect(res.roles).toMatchObject([
359+
{
360+
name: 'TestRole',
361+
permissions: ['foo'],
362+
},
363+
{
364+
name: 'TestRole2',
365+
permissions: ['permission1', 'permission2'],
366+
},
367+
]);
368+
});
369+
370+
test('Test "group.getGroupUserPermission"', async () => {
371+
const userId = new Types.ObjectId();
372+
const role1 = createTestRole('TestRole1', ['permission1', 'permission2']);
373+
const role2 = createTestRole('TestRole2', ['permission2', 'permission3']);
374+
const testGroup = await insertTestData(
375+
createTestGroup(userId, {
376+
members: [
377+
{
378+
userId,
379+
roles: ['TestRole1', 'TestRole2'],
380+
},
381+
],
382+
roles: [role1, role2],
383+
})
384+
);
385+
386+
const res: string[] = await broker.call(
387+
'group.getGroupUserPermission',
388+
{
389+
groupId: String(testGroup.id),
390+
},
391+
{
392+
meta: {
393+
userId: String(userId),
394+
},
395+
}
396+
);
397+
expect(res).toEqual(['permission1', 'permission2', 'permission3']);
398+
});
346399
});
347400
});

0 commit comments

Comments
 (0)