@chevre/domain 22.11.0-alpha.11 → 22.11.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/example/src/chevre/roles/{assignRoles.ts → assignGlobalRoles.ts} +19 -18
- package/example/src/chevre/roles/findPermissions.ts +84 -0
- package/example/src/chevre/roles/findRoleNames.ts +117 -0
- package/lib/chevre/repo/member.d.ts +22 -5
- package/lib/chevre/repo/member.js +77 -28
- package/lib/chevre/repo/mongoose/schemas/member/global.d.ts +14 -0
- package/lib/chevre/repo/mongoose/schemas/member/global.js +82 -0
- package/lib/chevre/repo/role.d.ts +5 -4
- package/lib/chevre/repo/role.js +35 -32
- package/lib/chevre/service/iam.d.ts +17 -7
- package/lib/chevre/service/iam.js +26 -6
- package/package.json +1 -1
- package/example/src/chevre/searchPermissions.ts +0 -46
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import type { CognitoIdentityProvider as CognitoIdentityServiceProvider } from '@aws-sdk/client-cognito-identity-provider';
|
|
3
3
|
import * as mongoose from 'mongoose';
|
|
4
4
|
|
|
5
|
+
import { IGlobalMember } from '../../../../lib/chevre/repo/mongoose/schemas/member/global';
|
|
5
6
|
import { chevre } from '../../../../lib/index';
|
|
6
7
|
|
|
7
8
|
const { PROJECT_CREATOR_SUB } = process.env;
|
|
8
|
-
const project = { id: '*' };
|
|
9
9
|
|
|
10
10
|
let cognitoIdentityServiceProvider: CognitoIdentityServiceProvider | undefined;
|
|
11
11
|
|
|
@@ -23,7 +23,7 @@ async function main() {
|
|
|
23
23
|
throw new chevre.factory.errors.NotFound('setting.userPoolIdNew');
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
let
|
|
26
|
+
let globalMember: IGlobalMember;
|
|
27
27
|
|
|
28
28
|
if (cognitoIdentityServiceProvider === undefined) {
|
|
29
29
|
const { CognitoIdentityProvider } = await import('@aws-sdk/client-cognito-identity-provider');
|
|
@@ -43,25 +43,26 @@ async function main() {
|
|
|
43
43
|
? `${profile.givenName} ${profile.familyName}`
|
|
44
44
|
: profile.memberOf?.membershipNumber;
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
typeOf: chevre.factory.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
globalMember = {
|
|
47
|
+
typeOf: chevre.factory.role.RoleType.OrganizationRole,
|
|
48
|
+
member: {
|
|
49
|
+
typeOf: chevre.factory.personType.Person,
|
|
50
|
+
id: profile.id,
|
|
51
|
+
name: memberName,
|
|
52
|
+
username: profile.memberOf?.membershipNumber,
|
|
53
|
+
hasRole: [{
|
|
54
|
+
typeOf: chevre.factory.role.RoleType.OrganizationRole,
|
|
55
|
+
roleName: <any>'projectCreator'
|
|
56
|
+
}]
|
|
57
|
+
}
|
|
56
58
|
};
|
|
57
|
-
console.log(profile,
|
|
59
|
+
console.log(profile, globalMember);
|
|
60
|
+
|
|
61
|
+
const existingGlobalMemberRoles = await memberRepo.findGlobalRoleNamesByMember({ member: { id: { $eq: globalMember.member.id } } });
|
|
62
|
+
console.log('existingGlobalMemberRoles:', existingGlobalMemberRoles);
|
|
58
63
|
|
|
59
64
|
// 権限作成
|
|
60
|
-
await memberRepo.
|
|
61
|
-
project: { typeOf: chevre.factory.organizationType.Project, id: project.id },
|
|
62
|
-
typeOf: chevre.factory.role.RoleType.OrganizationRole,
|
|
63
|
-
member: member
|
|
64
|
-
}]);
|
|
65
|
+
await memberRepo.createGlobalMember([globalMember]);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
main()
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// tslint:disable:no-console
|
|
2
|
+
// import * as moment from 'moment';
|
|
3
|
+
import * as mongoose from 'mongoose';
|
|
4
|
+
|
|
5
|
+
import { chevre } from '../../../../lib/index';
|
|
6
|
+
|
|
7
|
+
const formatter = new Intl.NumberFormat('ja-JP');
|
|
8
|
+
|
|
9
|
+
const PROJECT_ID = String(process.env.PROJECT_ID);
|
|
10
|
+
const memberId = 'b3640a78-babd-4da4-81d3-7dcf4881a4a5';
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
await mongoose.connect(<string>process.env.MONGOLAB_URI);
|
|
14
|
+
|
|
15
|
+
const memberRepo = await chevre.repository.Member.createInstance(mongoose.connection);
|
|
16
|
+
const roleRepo = await chevre.repository.Role.createInstance(mongoose.connection);
|
|
17
|
+
|
|
18
|
+
let startTime: [number, number] = process.hrtime();
|
|
19
|
+
let diff: [number, number] = process.hrtime(startTime);
|
|
20
|
+
let result: any;
|
|
21
|
+
|
|
22
|
+
startTime = process.hrtime();
|
|
23
|
+
result = await (await chevre.service.iam.createService()).findProjectPermissionsByMember({
|
|
24
|
+
project: { id: PROJECT_ID },
|
|
25
|
+
member: {
|
|
26
|
+
id: memberId,
|
|
27
|
+
memberOf: {
|
|
28
|
+
id: PROJECT_ID,
|
|
29
|
+
typeOf: chevre.factory.organizationType.Project
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
})({
|
|
33
|
+
member: memberRepo,
|
|
34
|
+
role: roleRepo
|
|
35
|
+
});
|
|
36
|
+
diff = process.hrtime(startTime);
|
|
37
|
+
console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
38
|
+
console.log(result.roleNames.length, 'roleNames found');
|
|
39
|
+
console.log(result.permissions.length, 'permissions found');
|
|
40
|
+
|
|
41
|
+
startTime = process.hrtime();
|
|
42
|
+
result = await (await chevre.service.iam.createService()).findProjectPermissionsByMember({
|
|
43
|
+
project: { id: PROJECT_ID },
|
|
44
|
+
member: {
|
|
45
|
+
id: memberId,
|
|
46
|
+
memberOf: {
|
|
47
|
+
id: PROJECT_ID,
|
|
48
|
+
typeOf: chevre.factory.organizationType.Project
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
})({
|
|
52
|
+
member: memberRepo,
|
|
53
|
+
role: roleRepo
|
|
54
|
+
});
|
|
55
|
+
diff = process.hrtime(startTime);
|
|
56
|
+
console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
57
|
+
console.log(result.roleNames.length, 'roleNames found');
|
|
58
|
+
console.log(result.permissions.length, 'permissions found');
|
|
59
|
+
|
|
60
|
+
startTime = process.hrtime();
|
|
61
|
+
result = await (await chevre.service.iam.createService()).findProjectPermissionsByMember({
|
|
62
|
+
project: { id: PROJECT_ID },
|
|
63
|
+
member: {
|
|
64
|
+
id: memberId,
|
|
65
|
+
memberOf: {
|
|
66
|
+
id: PROJECT_ID,
|
|
67
|
+
typeOf: chevre.factory.organizationType.Project
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
})({
|
|
71
|
+
member: memberRepo,
|
|
72
|
+
role: roleRepo
|
|
73
|
+
});
|
|
74
|
+
diff = process.hrtime(startTime);
|
|
75
|
+
console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
76
|
+
console.log(result.roleNames.length, 'roleNames found');
|
|
77
|
+
console.log(result.permissions.length, 'permissions found');
|
|
78
|
+
|
|
79
|
+
console.log(result);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
main()
|
|
83
|
+
.then(console.log)
|
|
84
|
+
.catch(console.error);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// tslint:disable:no-console
|
|
2
|
+
// import * as moment from 'moment';
|
|
3
|
+
import * as mongoose from 'mongoose';
|
|
4
|
+
|
|
5
|
+
import { chevre } from '../../../../lib/index';
|
|
6
|
+
|
|
7
|
+
const formatter = new Intl.NumberFormat('ja-JP');
|
|
8
|
+
|
|
9
|
+
const PROJECT_ID = String(process.env.PROJECT_ID);
|
|
10
|
+
const memberId = 'xxx';
|
|
11
|
+
|
|
12
|
+
// tslint:disable-next-line:max-func-body-length
|
|
13
|
+
async function main() {
|
|
14
|
+
await mongoose.connect(<string>process.env.MONGOLAB_URI);
|
|
15
|
+
|
|
16
|
+
const memberRepo = await chevre.repository.Member.createInstance(mongoose.connection);
|
|
17
|
+
|
|
18
|
+
let startTime: [number, number] = process.hrtime();
|
|
19
|
+
let diff: [number, number] = process.hrtime(startTime);
|
|
20
|
+
let result: any;
|
|
21
|
+
|
|
22
|
+
// startTime = process.hrtime();
|
|
23
|
+
// result = await memberRepo.aggregateRoleNames({
|
|
24
|
+
// project: { id: { $eq: PROJECT_ID } },
|
|
25
|
+
// member: {
|
|
26
|
+
// id: { $eq: memberId },
|
|
27
|
+
// memberOf: {
|
|
28
|
+
// id: { $eq: PROJECT_ID },
|
|
29
|
+
// typeOf: { $eq: chevre.factory.organizationType.Project }
|
|
30
|
+
// }
|
|
31
|
+
// }
|
|
32
|
+
// });
|
|
33
|
+
// diff = process.hrtime(startTime);
|
|
34
|
+
// console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
35
|
+
// console.log(result.length, 'result found');
|
|
36
|
+
|
|
37
|
+
// startTime = process.hrtime();
|
|
38
|
+
// result = await memberRepo.aggregateRoleNames({
|
|
39
|
+
// project: { id: { $eq: PROJECT_ID } },
|
|
40
|
+
// member: {
|
|
41
|
+
// id: { $eq: memberId },
|
|
42
|
+
// memberOf: {
|
|
43
|
+
// id: { $eq: PROJECT_ID },
|
|
44
|
+
// typeOf: { $eq: chevre.factory.organizationType.Project }
|
|
45
|
+
// }
|
|
46
|
+
// }
|
|
47
|
+
// });
|
|
48
|
+
// diff = process.hrtime(startTime);
|
|
49
|
+
// console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
50
|
+
// console.log(result.length, 'result found');
|
|
51
|
+
|
|
52
|
+
// startTime = process.hrtime();
|
|
53
|
+
// result = await memberRepo.aggregateRoleNames({
|
|
54
|
+
// project: { id: { $eq: PROJECT_ID } },
|
|
55
|
+
// member: {
|
|
56
|
+
// id: { $eq: memberId },
|
|
57
|
+
// memberOf: {
|
|
58
|
+
// id: { $eq: PROJECT_ID },
|
|
59
|
+
// typeOf: { $eq: chevre.factory.organizationType.Project }
|
|
60
|
+
// }
|
|
61
|
+
// }
|
|
62
|
+
// });
|
|
63
|
+
// diff = process.hrtime(startTime);
|
|
64
|
+
// console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
65
|
+
// console.log(result.length, 'result found');
|
|
66
|
+
// console.log(result);
|
|
67
|
+
|
|
68
|
+
startTime = process.hrtime();
|
|
69
|
+
result = await memberRepo.findRoleNamesByMember({
|
|
70
|
+
project: { id: { $eq: PROJECT_ID } },
|
|
71
|
+
member: {
|
|
72
|
+
id: { $eq: memberId },
|
|
73
|
+
memberOf: {
|
|
74
|
+
id: { $eq: PROJECT_ID },
|
|
75
|
+
typeOf: { $eq: chevre.factory.organizationType.Project }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
diff = process.hrtime(startTime);
|
|
80
|
+
console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
81
|
+
console.log(result.length, 'result found');
|
|
82
|
+
|
|
83
|
+
startTime = process.hrtime();
|
|
84
|
+
result = await memberRepo.findRoleNamesByMember({
|
|
85
|
+
project: { id: { $eq: PROJECT_ID } },
|
|
86
|
+
member: {
|
|
87
|
+
id: { $eq: memberId },
|
|
88
|
+
memberOf: {
|
|
89
|
+
id: { $eq: PROJECT_ID },
|
|
90
|
+
typeOf: { $eq: chevre.factory.organizationType.Project }
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
diff = process.hrtime(startTime);
|
|
95
|
+
console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
96
|
+
console.log(result.length, 'result found');
|
|
97
|
+
|
|
98
|
+
startTime = process.hrtime();
|
|
99
|
+
result = await memberRepo.findRoleNamesByMember({
|
|
100
|
+
project: { id: { $eq: PROJECT_ID } },
|
|
101
|
+
member: {
|
|
102
|
+
id: { $eq: memberId },
|
|
103
|
+
memberOf: {
|
|
104
|
+
id: { $eq: PROJECT_ID },
|
|
105
|
+
typeOf: { $eq: chevre.factory.organizationType.Project }
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
diff = process.hrtime(startTime);
|
|
110
|
+
console.log('diff:', [diff[0], formatter.format(diff[1])]);
|
|
111
|
+
console.log(result.length, 'result found');
|
|
112
|
+
console.log(result);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
main()
|
|
116
|
+
.then(console.log)
|
|
117
|
+
.catch(console.error);
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { Connection, FilterQuery } from 'mongoose';
|
|
2
2
|
import * as factory from '../factory';
|
|
3
|
+
import { IGlobalMember } from './mongoose/schemas/member/global';
|
|
3
4
|
type IKeyOfProjection = keyof factory.iam.IMember;
|
|
4
5
|
export type ICustomerMember = Pick<factory.iam.IMemberOfRole, 'hasRole' | 'id' | 'name' | 'memberOf'>;
|
|
5
6
|
/**
|
|
6
7
|
* IAMメンバーリポジトリ
|
|
7
8
|
*/
|
|
8
9
|
export declare class MemberRepo {
|
|
10
|
+
private readonly globalMemberModel;
|
|
9
11
|
private readonly memberModel;
|
|
10
12
|
constructor(connection: Connection);
|
|
11
13
|
static CREATE_MONGO_CONDITIONS(params: factory.iam.ISearchConditions): FilterQuery<factory.iam.IMember>[];
|
|
@@ -37,7 +39,10 @@ export declare class MemberRepo {
|
|
|
37
39
|
}): Promise<{
|
|
38
40
|
member: ICustomerMember;
|
|
39
41
|
}[]>;
|
|
40
|
-
|
|
42
|
+
/**
|
|
43
|
+
* distinctコマンドを使用して、プロジェクトメンバーのロールを検索する
|
|
44
|
+
*/
|
|
45
|
+
findRoleNamesByMember(params: {
|
|
41
46
|
project: {
|
|
42
47
|
id: {
|
|
43
48
|
$eq: string;
|
|
@@ -56,9 +61,7 @@ export declare class MemberRepo {
|
|
|
56
61
|
};
|
|
57
62
|
};
|
|
58
63
|
};
|
|
59
|
-
}): Promise<
|
|
60
|
-
roleName: string;
|
|
61
|
-
}[]>;
|
|
64
|
+
}): Promise<string[]>;
|
|
62
65
|
deleteByProject(params: {
|
|
63
66
|
project: {
|
|
64
67
|
id: string;
|
|
@@ -125,7 +128,6 @@ export declare class MemberRepo {
|
|
|
125
128
|
}): Promise<import("mongodb").DeleteResult>;
|
|
126
129
|
/**
|
|
127
130
|
* メンバーの権限を持つプロジェクト検索
|
|
128
|
-
* ANY_PROJECT_IDは除外
|
|
129
131
|
*/
|
|
130
132
|
searchProjectIdsByMemberId(params: {
|
|
131
133
|
member: {
|
|
@@ -164,6 +166,21 @@ export declare class MemberRepo {
|
|
|
164
166
|
filter: any;
|
|
165
167
|
$unset: any;
|
|
166
168
|
}): Promise<import("mongoose").UpdateWriteOpResult>;
|
|
169
|
+
/**
|
|
170
|
+
* グローバルメンバー作成
|
|
171
|
+
* 2025-07-21~
|
|
172
|
+
*/
|
|
173
|
+
createGlobalMember(params: IGlobalMember[]): Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* distinctコマンドを使用して、グローバルメンバーのロールを検索する
|
|
176
|
+
*/
|
|
177
|
+
findGlobalRoleNamesByMember(params: {
|
|
178
|
+
member: {
|
|
179
|
+
id: {
|
|
180
|
+
$eq: string;
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
}): Promise<string[]>;
|
|
167
184
|
private projectFields;
|
|
168
185
|
}
|
|
169
186
|
export {};
|
|
@@ -13,6 +13,7 @@ exports.MemberRepo = void 0;
|
|
|
13
13
|
const factory = require("../factory");
|
|
14
14
|
const settings_1 = require("../settings");
|
|
15
15
|
const member_1 = require("./mongoose/schemas/member");
|
|
16
|
+
const global_1 = require("./mongoose/schemas/member/global");
|
|
16
17
|
const AVAILABLE_PROJECT_FIELDS = [
|
|
17
18
|
'project',
|
|
18
19
|
'typeOf',
|
|
@@ -24,6 +25,7 @@ const ANY_PROJECT_ID = '*';
|
|
|
24
25
|
*/
|
|
25
26
|
class MemberRepo {
|
|
26
27
|
constructor(connection) {
|
|
28
|
+
this.globalMemberModel = connection.model(global_1.modelName, (0, global_1.createSchema)());
|
|
27
29
|
this.memberModel = connection.model(member_1.modelName, (0, member_1.createSchema)());
|
|
28
30
|
}
|
|
29
31
|
// tslint:disable-next-line:cyclomatic-complexity max-func-body-length
|
|
@@ -164,32 +166,55 @@ class MemberRepo {
|
|
|
164
166
|
.exec();
|
|
165
167
|
});
|
|
166
168
|
}
|
|
167
|
-
|
|
169
|
+
// migrate to findRoleNamesByMember(2025-07-21~)
|
|
170
|
+
// public async aggregateRoleNames(params: {
|
|
171
|
+
// project: { id: { $eq: string } };
|
|
172
|
+
// member: {
|
|
173
|
+
// id: { $eq: string };
|
|
174
|
+
// memberOf: {
|
|
175
|
+
// id: { $eq: string };
|
|
176
|
+
// typeOf: { $eq: factory.organizationType.Corporation | factory.organizationType.Project };
|
|
177
|
+
// };
|
|
178
|
+
// };
|
|
179
|
+
// }): Promise<{ roleName: string }[]> {
|
|
180
|
+
// const matchStages: IMatchStage[] = [
|
|
181
|
+
// { $match: { 'project.id': { $eq: params.project.id.$eq } } },
|
|
182
|
+
// { $match: { 'member.id': { $eq: params.member.id.$eq } } },
|
|
183
|
+
// { $match: { 'member.memberOf.id': { $eq: params.member.memberOf.id.$eq } } },
|
|
184
|
+
// { $match: { 'member.memberOf.typeOf': { $eq: params.member.memberOf.typeOf.$eq } } }
|
|
185
|
+
// ];
|
|
186
|
+
// const aggregate = this.memberModel.aggregate([
|
|
187
|
+
// // ...(typeof params.sort?.productID === 'number')
|
|
188
|
+
// // ? [{ $sort: { productID: params.sort.productID } }]
|
|
189
|
+
// // : [],
|
|
190
|
+
// ...matchStages,
|
|
191
|
+
// {
|
|
192
|
+
// $unwind: {
|
|
193
|
+
// path: '$member.hasRole'
|
|
194
|
+
// }
|
|
195
|
+
// },
|
|
196
|
+
// {
|
|
197
|
+
// $project: {
|
|
198
|
+
// _id: 0,
|
|
199
|
+
// roleName: '$member.hasRole.roleName'
|
|
200
|
+
// }
|
|
201
|
+
// }
|
|
202
|
+
// ]);
|
|
203
|
+
// return aggregate.option({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
204
|
+
// .exec();
|
|
205
|
+
// }
|
|
206
|
+
/**
|
|
207
|
+
* distinctコマンドを使用して、プロジェクトメンバーのロールを検索する
|
|
208
|
+
*/
|
|
209
|
+
findRoleNamesByMember(params) {
|
|
168
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
// ...(typeof params.sort?.productID === 'number')
|
|
177
|
-
// ? [{ $sort: { productID: params.sort.productID } }]
|
|
178
|
-
// : [],
|
|
179
|
-
...matchStages,
|
|
180
|
-
{
|
|
181
|
-
$unwind: {
|
|
182
|
-
path: '$member.hasRole'
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
$project: {
|
|
187
|
-
_id: 0,
|
|
188
|
-
roleName: '$member.hasRole.roleName'
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
]);
|
|
192
|
-
return aggregate.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
211
|
+
return this.memberModel.distinct('member.hasRole.roleName', {
|
|
212
|
+
'project.id': { $eq: params.project.id.$eq },
|
|
213
|
+
'member.id': { $eq: params.member.id.$eq },
|
|
214
|
+
'member.memberOf.id': { $eq: params.member.memberOf.id.$eq },
|
|
215
|
+
'member.memberOf.typeOf': { $eq: params.member.memberOf.typeOf.$eq }
|
|
216
|
+
})
|
|
217
|
+
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
193
218
|
.exec();
|
|
194
219
|
});
|
|
195
220
|
}
|
|
@@ -284,7 +309,6 @@ class MemberRepo {
|
|
|
284
309
|
}
|
|
285
310
|
/**
|
|
286
311
|
* メンバーの権限を持つプロジェクト検索
|
|
287
|
-
* ANY_PROJECT_IDは除外
|
|
288
312
|
*/
|
|
289
313
|
searchProjectIdsByMemberId(params) {
|
|
290
314
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -296,8 +320,7 @@ class MemberRepo {
|
|
|
296
320
|
throw new factory.errors.ArgumentNull('page');
|
|
297
321
|
}
|
|
298
322
|
const matchStages = [
|
|
299
|
-
{ $match: { 'member.id': { $eq: params.member.id } } }
|
|
300
|
-
{ $match: { 'project.id': { $ne: ANY_PROJECT_ID } } }
|
|
323
|
+
{ $match: { 'member.id': { $eq: params.member.id } } }
|
|
301
324
|
];
|
|
302
325
|
if (typeof ((_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq) === 'string') {
|
|
303
326
|
matchStages.push({ $match: { 'project.id': { $eq: params.project.id.$eq } } });
|
|
@@ -348,6 +371,32 @@ class MemberRepo {
|
|
|
348
371
|
.exec();
|
|
349
372
|
});
|
|
350
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* グローバルメンバー作成
|
|
376
|
+
* 2025-07-21~
|
|
377
|
+
*/
|
|
378
|
+
createGlobalMember(params) {
|
|
379
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
380
|
+
if (params.length > 0) {
|
|
381
|
+
yield this.globalMemberModel.insertMany(params.map(({ typeOf, member }) => ({ typeOf, member })));
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
// no op
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* distinctコマンドを使用して、グローバルメンバーのロールを検索する
|
|
390
|
+
*/
|
|
391
|
+
findGlobalRoleNamesByMember(params) {
|
|
392
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
393
|
+
return this.globalMemberModel.distinct('member.hasRole.roleName', {
|
|
394
|
+
'member.id': { $eq: params.member.id.$eq }
|
|
395
|
+
})
|
|
396
|
+
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
397
|
+
.exec();
|
|
398
|
+
});
|
|
399
|
+
}
|
|
351
400
|
projectFields(params, inclusion) {
|
|
352
401
|
return __awaiter(this, void 0, void 0, function* () {
|
|
353
402
|
const conditions = MemberRepo.CREATE_MONGO_CONDITIONS(params);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IndexDefinition, IndexOptions, Model, Schema, SchemaDefinition } from 'mongoose';
|
|
2
|
+
import * as factory from '../../../../factory';
|
|
3
|
+
type IMemberOfRole = Pick<factory.iam.IMemberOfRole, 'hasRole' | 'id' | 'image' | 'name' | 'typeOf' | 'username'>;
|
|
4
|
+
type IGlobalMember = Pick<factory.iam.IMember, 'typeOf'> & {
|
|
5
|
+
member: IMemberOfRole;
|
|
6
|
+
};
|
|
7
|
+
type IDocType = IGlobalMember;
|
|
8
|
+
type IModel = Model<IDocType>;
|
|
9
|
+
type ISchemaDefinition = SchemaDefinition<IDocType>;
|
|
10
|
+
type ISchema = Schema<IDocType, IModel, {}, {}, {}, {}, ISchemaDefinition, IDocType>;
|
|
11
|
+
declare const modelName = "Member.Global";
|
|
12
|
+
declare const indexes: [d: IndexDefinition, o: IndexOptions][];
|
|
13
|
+
declare function createSchema(): ISchema;
|
|
14
|
+
export { createSchema, IGlobalMember, IModel, indexes, modelName };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modelName = exports.indexes = void 0;
|
|
4
|
+
exports.createSchema = createSchema;
|
|
5
|
+
const mongoose_1 = require("mongoose");
|
|
6
|
+
const writeConcern_1 = require("../../writeConcern");
|
|
7
|
+
const settings_1 = require("../../../../settings");
|
|
8
|
+
const modelName = 'Member.Global';
|
|
9
|
+
exports.modelName = modelName;
|
|
10
|
+
const schemaDefinition = {
|
|
11
|
+
// globalロール管理なのでprojectは不要
|
|
12
|
+
// project: {
|
|
13
|
+
// type: SchemaTypes.Mixed,
|
|
14
|
+
// required: true
|
|
15
|
+
// },
|
|
16
|
+
typeOf: {
|
|
17
|
+
type: String,
|
|
18
|
+
required: true
|
|
19
|
+
},
|
|
20
|
+
member: {
|
|
21
|
+
type: mongoose_1.SchemaTypes.Mixed,
|
|
22
|
+
required: true
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const schemaOptions = {
|
|
26
|
+
autoIndex: settings_1.MONGO_AUTO_INDEX,
|
|
27
|
+
autoCreate: false,
|
|
28
|
+
collection: 'members.global',
|
|
29
|
+
id: true,
|
|
30
|
+
read: settings_1.MONGO_READ_PREFERENCE,
|
|
31
|
+
writeConcern: writeConcern_1.writeConcern,
|
|
32
|
+
strict: true,
|
|
33
|
+
strictQuery: false,
|
|
34
|
+
timestamps: false,
|
|
35
|
+
versionKey: false,
|
|
36
|
+
toJSON: {
|
|
37
|
+
getters: false,
|
|
38
|
+
virtuals: false,
|
|
39
|
+
minimize: false,
|
|
40
|
+
versionKey: false
|
|
41
|
+
},
|
|
42
|
+
toObject: {
|
|
43
|
+
getters: false,
|
|
44
|
+
virtuals: true,
|
|
45
|
+
minimize: false,
|
|
46
|
+
versionKey: false
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const indexes = [
|
|
50
|
+
[
|
|
51
|
+
{ 'member.id': 1 },
|
|
52
|
+
{
|
|
53
|
+
name: 'uniqueIAMMember',
|
|
54
|
+
unique: true
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
[
|
|
58
|
+
{ 'member.hasRole.roleName': 1, 'member.id': 1 },
|
|
59
|
+
{
|
|
60
|
+
name: 'searchByMemberHasRoleRoleName',
|
|
61
|
+
partialFilterExpression: {
|
|
62
|
+
'member.hasRole.roleName': { $exists: true }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
];
|
|
67
|
+
exports.indexes = indexes;
|
|
68
|
+
/**
|
|
69
|
+
* グロバールIAMメンバースキーマ
|
|
70
|
+
*/
|
|
71
|
+
let schema;
|
|
72
|
+
function createSchema() {
|
|
73
|
+
if (schema === undefined) {
|
|
74
|
+
schema = new mongoose_1.Schema(schemaDefinition, schemaOptions);
|
|
75
|
+
if (settings_1.MONGO_AUTO_INDEX) {
|
|
76
|
+
indexes.forEach((indexParams) => {
|
|
77
|
+
schema === null || schema === void 0 ? void 0 : schema.index(...indexParams);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return schema;
|
|
82
|
+
}
|
|
@@ -11,13 +11,14 @@ export declare class RoleRepo {
|
|
|
11
11
|
constructor(connection: Connection);
|
|
12
12
|
static CREATE_MONGO_CONDITIONS(params: factory.role.organizationRole.ISearchConditions): FilterQuery<IDocType>[];
|
|
13
13
|
projectFields(params: factory.role.organizationRole.ISearchConditions, inclusion: IKeyOfProjection[]): Promise<IRole[]>;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* distinctコマンドを使用して、ロールから権限を検索する
|
|
16
|
+
*/
|
|
17
|
+
findUniquePermissionsByRoleName(params: {
|
|
15
18
|
roleName: {
|
|
16
19
|
$in: string[];
|
|
17
20
|
};
|
|
18
|
-
}): Promise<
|
|
19
|
-
_id: string;
|
|
20
|
-
}[]>;
|
|
21
|
+
}): Promise<string[]>;
|
|
21
22
|
addPermissionIfNotExists(params: {
|
|
22
23
|
roleName: {
|
|
23
24
|
$eq: factory.role.organizationRole.RoleName;
|
package/lib/chevre/repo/role.js
CHANGED
|
@@ -77,39 +77,42 @@ class RoleRepo {
|
|
|
77
77
|
.exec();
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
// migrate to findDistinctPermissionsByRoleName(2025-07-21~)
|
|
81
|
+
// public async aggregatePermissions(params: {
|
|
82
|
+
// roleName: { $in: string[] };
|
|
83
|
+
// }): Promise<{ _id: string }[]> {
|
|
84
|
+
// const matchStages: IMatchStage[] = [
|
|
85
|
+
// { $match: { roleName: { $in: params.roleName.$in } } }
|
|
86
|
+
// ];
|
|
87
|
+
// const aggregate = this.roleModel.aggregate([
|
|
88
|
+
// ...matchStages,
|
|
89
|
+
// {
|
|
90
|
+
// $unwind: {
|
|
91
|
+
// path: '$permissions'
|
|
92
|
+
// }
|
|
93
|
+
// },
|
|
94
|
+
// {
|
|
95
|
+
// $project: {
|
|
96
|
+
// _id: 0,
|
|
97
|
+
// permission: '$permissions'
|
|
98
|
+
// }
|
|
99
|
+
// },
|
|
100
|
+
// {
|
|
101
|
+
// $group: {
|
|
102
|
+
// _id: '$permission'
|
|
103
|
+
// }
|
|
104
|
+
// }
|
|
105
|
+
// ]);
|
|
106
|
+
// return aggregate.option({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
107
|
+
// .exec();
|
|
108
|
+
// }
|
|
109
|
+
/**
|
|
110
|
+
* distinctコマンドを使用して、ロールから権限を検索する
|
|
111
|
+
*/
|
|
112
|
+
findUniquePermissionsByRoleName(params) {
|
|
81
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
];
|
|
85
|
-
const aggregate = this.roleModel.aggregate([
|
|
86
|
-
// ...(typeof params.sort?.productID === 'number')
|
|
87
|
-
// ? [{ $sort: { productID: params.sort.productID } }]
|
|
88
|
-
// : [],
|
|
89
|
-
...matchStages,
|
|
90
|
-
{
|
|
91
|
-
$unwind: {
|
|
92
|
-
path: '$permissions'
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
$project: {
|
|
97
|
-
_id: 0,
|
|
98
|
-
permission: '$permissions'
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
$group: {
|
|
103
|
-
_id: '$permission'
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
]);
|
|
107
|
-
// if (typeof params.limit === 'number' && params.limit > 0) {
|
|
108
|
-
// const page: number = (typeof params.page === 'number' && params.page > 0) ? params.page : 1;
|
|
109
|
-
// aggregate.limit(params.limit * page)
|
|
110
|
-
// .skip(params.limit * (page - 1));
|
|
111
|
-
// }
|
|
112
|
-
return aggregate.option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
114
|
+
return this.roleModel.distinct('permissions', { roleName: { $in: params.roleName.$in } })
|
|
115
|
+
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
113
116
|
.exec();
|
|
114
117
|
});
|
|
115
118
|
}
|
|
@@ -8,7 +8,7 @@ export type IPermission = string;
|
|
|
8
8
|
/**
|
|
9
9
|
* プロジェクトメンバーの権限を検索する
|
|
10
10
|
*/
|
|
11
|
-
export declare function
|
|
11
|
+
export declare function findProjectPermissionsByMember(params: {
|
|
12
12
|
project: {
|
|
13
13
|
id: string;
|
|
14
14
|
};
|
|
@@ -23,10 +23,20 @@ export declare function searchPermissions(params: {
|
|
|
23
23
|
member: MemberRepo;
|
|
24
24
|
role: RoleRepo;
|
|
25
25
|
}) => Promise<{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
roleNames: string[];
|
|
27
|
+
permissions: string[];
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* グローバル権限を検索する
|
|
31
|
+
*/
|
|
32
|
+
export declare function findGloablPermissionsByMember(params: {
|
|
33
|
+
member: {
|
|
34
|
+
id: string;
|
|
35
|
+
};
|
|
36
|
+
}): (repos: {
|
|
37
|
+
member: MemberRepo;
|
|
38
|
+
role: RoleRepo;
|
|
39
|
+
}) => Promise<{
|
|
40
|
+
roleNames: string[];
|
|
41
|
+
permissions: string[];
|
|
32
42
|
}>;
|
|
@@ -9,14 +9,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.findProjectPermissionsByMember = findProjectPermissionsByMember;
|
|
13
|
+
exports.findGloablPermissionsByMember = findGloablPermissionsByMember;
|
|
13
14
|
/**
|
|
14
15
|
* プロジェクトメンバーの権限を検索する
|
|
15
16
|
*/
|
|
16
|
-
function
|
|
17
|
+
function findProjectPermissionsByMember(params) {
|
|
17
18
|
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
18
19
|
let permissions = [];
|
|
19
|
-
const hasRole =
|
|
20
|
+
// const hasRole = await repos.member.aggregateRoleNames({
|
|
21
|
+
const roleNames = yield repos.member.findRoleNamesByMember({
|
|
20
22
|
project: { id: { $eq: params.project.id } },
|
|
21
23
|
member: {
|
|
22
24
|
id: { $eq: params.member.id },
|
|
@@ -26,9 +28,27 @@ function searchPermissions(params) {
|
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
});
|
|
29
|
-
if (
|
|
30
|
-
permissions =
|
|
31
|
+
if (roleNames.length > 0) {
|
|
32
|
+
// permissions = await repos.role.aggregatePermissions({ roleName: { $in: hasRole.map((r) => r.roleName) } });
|
|
33
|
+
permissions = yield repos.role.findUniquePermissionsByRoleName({ roleName: { $in: roleNames } });
|
|
31
34
|
}
|
|
32
|
-
return {
|
|
35
|
+
return { roleNames, permissions };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* グローバル権限を検索する
|
|
40
|
+
*/
|
|
41
|
+
function findGloablPermissionsByMember(params) {
|
|
42
|
+
return (repos) => __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
let permissions = [];
|
|
44
|
+
const roleNames = yield repos.member.findGlobalRoleNamesByMember({
|
|
45
|
+
member: {
|
|
46
|
+
id: { $eq: params.member.id }
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
if (roleNames.length > 0) {
|
|
50
|
+
permissions = yield repos.role.findUniquePermissionsByRoleName({ roleName: { $in: roleNames } });
|
|
51
|
+
}
|
|
52
|
+
return { roleNames, permissions };
|
|
33
53
|
});
|
|
34
54
|
}
|
package/package.json
CHANGED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// tslint:disable:no-console
|
|
2
|
-
import * as moment from 'moment';
|
|
3
|
-
import * as mongoose from 'mongoose';
|
|
4
|
-
|
|
5
|
-
import { chevre } from '../../../lib/index';
|
|
6
|
-
|
|
7
|
-
const PROJECT_ID = String(process.env.PROJECT_ID);
|
|
8
|
-
const memberId = 'xxx';
|
|
9
|
-
|
|
10
|
-
async function main() {
|
|
11
|
-
await mongoose.connect(<string>process.env.MONGOLAB_URI);
|
|
12
|
-
|
|
13
|
-
const memberRepo = await chevre.repository.Member.createInstance(mongoose.connection);
|
|
14
|
-
const roleRepo = await chevre.repository.Role.createInstance(mongoose.connection);
|
|
15
|
-
|
|
16
|
-
let now: Date;
|
|
17
|
-
|
|
18
|
-
now = new Date();
|
|
19
|
-
const searchPermissionsResult = await (await chevre.service.iam.createService()).searchPermissions({
|
|
20
|
-
project: { id: PROJECT_ID },
|
|
21
|
-
member: {
|
|
22
|
-
id: memberId,
|
|
23
|
-
memberOf: {
|
|
24
|
-
id: PROJECT_ID,
|
|
25
|
-
typeOf: chevre.factory.organizationType.Project
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
})({
|
|
29
|
-
member: memberRepo,
|
|
30
|
-
role: roleRepo
|
|
31
|
-
});
|
|
32
|
-
console.log('time cost:', moment()
|
|
33
|
-
.diff(now));
|
|
34
|
-
|
|
35
|
-
console.log(searchPermissionsResult);
|
|
36
|
-
console.log(searchPermissionsResult.permissions.length);
|
|
37
|
-
|
|
38
|
-
// console.log(aggregateRoleNamesResult);
|
|
39
|
-
// console.log(aggregateRoleNamesResult.length);
|
|
40
|
-
// console.log(aggregatePermissionsResult);
|
|
41
|
-
// console.log(aggregatePermissionsResult.length);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
main()
|
|
45
|
-
.then(console.log)
|
|
46
|
-
.catch(console.error);
|