oak-domain 3.0.2 → 3.0.4
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/lib/actions/action.d.ts +8 -8
- package/lib/actions/action.js +2 -2
- package/lib/actions/relation.d.ts +1 -1
- package/lib/actions/relation.js +9 -22
- package/lib/base-app-domain/ActionAuth/Schema.d.ts +68 -42
- package/lib/base-app-domain/ActionAuth/Storage.js +12 -15
- package/lib/base-app-domain/ActionDefDict.d.ts +2 -3
- package/lib/base-app-domain/ActionDefDict.js +3 -5
- package/lib/base-app-domain/EntityDict.d.ts +5 -1
- package/lib/base-app-domain/I18n/Schema.d.ts +24 -24
- package/lib/base-app-domain/I18n/Storage.js +5 -5
- package/lib/base-app-domain/Modi/Action.d.ts +4 -4
- package/lib/base-app-domain/Modi/Action.js +3 -3
- package/lib/base-app-domain/Modi/Schema.d.ts +24 -24
- package/lib/base-app-domain/Modi/Storage.js +3 -3
- package/lib/base-app-domain/ModiEntity/Schema.d.ts +128 -55
- package/lib/base-app-domain/ModiEntity/Storage.js +2 -2
- package/lib/base-app-domain/Oper/Schema.d.ts +30 -29
- package/lib/base-app-domain/Oper/Storage.js +1 -1
- package/lib/base-app-domain/OperEntity/Schema.d.ts +126 -53
- package/lib/base-app-domain/OperEntity/Storage.js +2 -2
- package/lib/base-app-domain/Path/Schema.d.ts +149 -0
- package/lib/base-app-domain/Path/Schema.js +2 -0
- package/lib/base-app-domain/Path/Storage.d.ts +3 -0
- package/lib/base-app-domain/Path/Storage.js +54 -0
- package/lib/base-app-domain/Relation/Schema.d.ts +34 -34
- package/lib/base-app-domain/Relation/Storage.js +6 -6
- package/lib/base-app-domain/Relation.d.ts +0 -8
- package/lib/base-app-domain/Relation.js +1 -7
- package/lib/base-app-domain/RelationAuth/Schema.d.ts +74 -40
- package/lib/base-app-domain/RelationAuth/Storage.js +9 -11
- package/lib/base-app-domain/Storage.js +20 -16
- package/lib/base-app-domain/User/Action.d.ts +4 -4
- package/lib/base-app-domain/User/Action.js +3 -3
- package/lib/base-app-domain/User/Schema.d.ts +40 -27
- package/lib/base-app-domain/User/Storage.js +1 -1
- package/lib/base-app-domain/UserEntityClaim/Schema.d.ts +264 -0
- package/lib/base-app-domain/UserEntityClaim/Schema.js +2 -0
- package/lib/base-app-domain/UserEntityClaim/Storage.d.ts +3 -0
- package/lib/base-app-domain/UserEntityClaim/Storage.js +37 -0
- package/lib/base-app-domain/UserEntityGrant/Action.d.ts +2 -2
- package/lib/base-app-domain/UserEntityGrant/Schema.d.ts +55 -81
- package/lib/base-app-domain/UserEntityGrant/Storage.js +7 -11
- package/lib/base-app-domain/UserRelation/Schema.d.ts +50 -36
- package/lib/base-app-domain/UserRelation/Storage.js +7 -7
- package/lib/base-app-domain/_SubQuery.d.ts +45 -15
- package/lib/base-app-domain/index.js +1 -1
- package/lib/checkers/index.js +6 -7
- package/lib/compiler/env.js +16 -18
- package/lib/compiler/localeBuilder.js +83 -79
- package/lib/compiler/schemalBuilder.d.ts +16 -0
- package/lib/compiler/schemalBuilder.js +1160 -1378
- package/lib/entities/ActionAuth.d.ts +3 -5
- package/lib/entities/ActionAuth.js +9 -7
- package/lib/entities/I18n.js +1 -1
- package/lib/entities/Modi.js +2 -2
- package/lib/entities/ModiEntity.js +1 -1
- package/lib/entities/Oper.js +1 -1
- package/lib/entities/OperEntity.js +1 -1
- package/lib/entities/Path.d.ts +8 -0
- package/lib/entities/Path.js +35 -0
- package/lib/entities/Relation.js +1 -1
- package/lib/entities/RelationAuth.d.ts +2 -2
- package/lib/entities/RelationAuth.js +1 -1
- package/lib/entities/User.js +2 -2
- package/lib/entities/UserEntityClaim.d.ts +13 -0
- package/lib/entities/UserEntityClaim.js +17 -0
- package/lib/entities/UserEntityGrant.d.ts +5 -4
- package/lib/entities/UserEntityGrant.js +4 -7
- package/lib/entities/UserRelation.js +1 -1
- package/lib/index.d.ts +23 -0
- package/lib/index.js +37 -0
- package/lib/store/AsyncRowStore.d.ts +2 -1
- package/lib/store/AsyncRowStore.js +75 -149
- package/lib/store/CascadeStore.js +968 -1341
- package/lib/store/RelationAuth.d.ts +9 -16
- package/lib/store/RelationAuth.js +752 -910
- package/lib/store/SyncRowStore.d.ts +1 -1
- package/lib/store/SyncRowStore.js +27 -26
- package/lib/store/TriggerExecutor.d.ts +17 -10
- package/lib/store/TriggerExecutor.js +350 -423
- package/lib/store/actionAuth.js +13 -28
- package/lib/store/actionDef.js +142 -215
- package/lib/store/checker.js +225 -361
- package/lib/store/filter.d.ts +2 -3
- package/lib/store/filter.js +451 -589
- package/lib/store/modi.js +116 -177
- package/lib/store/relation.js +17 -17
- package/lib/timers/oper.d.ts +1 -1
- package/lib/timers/oper.js +44 -47
- package/lib/timers/vaccum.d.ts +2 -2
- package/lib/timers/vaccum.js +100 -165
- package/lib/triggers/index.js +1 -1
- package/lib/types/Action.d.ts +7 -7
- package/lib/types/AppLoader.d.ts +8 -2
- package/lib/types/AppLoader.js +4 -4
- package/lib/types/Auth.d.ts +15 -19
- package/lib/types/Connector.d.ts +19 -14
- package/lib/types/Connector.js +0 -7
- package/lib/types/DataType.d.ts +19 -18
- package/lib/types/DataType.js +1 -1
- package/lib/types/Demand.d.ts +25 -25
- package/lib/types/Endpoint.d.ts +1 -1
- package/lib/types/Entity.d.ts +62 -53
- package/lib/types/Entity.js +4 -3
- package/lib/types/EntityDesc.d.ts +2 -1
- package/lib/types/Environment.d.ts +4 -4
- package/lib/types/Exception.d.ts +34 -2
- package/lib/types/Exception.js +214 -197
- package/lib/types/Expression.d.ts +14 -14
- package/lib/types/Expression.js +54 -87
- package/lib/types/Geo.d.ts +6 -6
- package/lib/types/Locale.d.ts +5 -5
- package/lib/types/Polyfill.d.ts +9 -9
- package/lib/types/Port.d.ts +4 -4
- package/lib/types/RowStore.d.ts +3 -3
- package/lib/types/RowStore.js +18 -19
- package/lib/types/Storage.d.ts +5 -4
- package/lib/types/Style.d.ts +2 -2
- package/lib/types/Timer.d.ts +3 -3
- package/lib/types/Trigger.d.ts +30 -14
- package/lib/types/Trigger.js +6 -2
- package/lib/types/Watcher.d.ts +2 -2
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +2 -1
- package/lib/types/schema/DataTypes.d.ts +7 -7
- package/lib/utils/SimpleConnector.d.ts +26 -10
- package/lib/utils/SimpleConnector.js +167 -141
- package/lib/utils/assert.js +2 -2
- package/lib/utils/concurrent.d.ts +1 -1
- package/lib/utils/concurrent.js +31 -57
- package/lib/utils/date.js +2 -2
- package/lib/utils/geo.js +8 -8
- package/lib/utils/lodash.d.ts +3 -1
- package/lib/utils/lodash.js +21 -34
- package/lib/utils/mask.js +12 -13
- package/lib/utils/money.d.ts +1 -1
- package/lib/utils/money.js +22 -11
- package/lib/utils/projection.d.ts +4 -0
- package/lib/utils/projection.js +15 -0
- package/lib/utils/random/random.js +11 -16
- package/lib/utils/random/random.mp.js +7 -18
- package/lib/utils/random/random.web.js +6 -12
- package/lib/utils/string.d.ts +4 -4
- package/lib/utils/string.js +19 -32
- package/lib/utils/url.js +5 -4
- package/lib/utils/uuid.d.ts +1 -1
- package/lib/utils/uuid.js +46 -85
- package/lib/utils/validator.d.ts +4 -3
- package/lib/utils/validator.js +35 -32
- package/lib/utils/version.js +6 -6
- package/package.json +7 -7
- package/src/entities/ActionAuth.ts +10 -10
- package/src/entities/Path.ts +43 -0
- package/src/entities/RelationAuth.ts +2 -1
- package/src/entities/UserEntityClaim.ts +30 -0
- package/src/entities/UserEntityGrant.ts +9 -12
|
@@ -1,139 +1,145 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getUserRelationsByActions = exports.RelationAuth = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
const AsyncRowStore_1 = require("./AsyncRowStore");
|
|
8
|
+
const filter_1 = require("./filter");
|
|
9
|
+
const relation_1 = require("./relation");
|
|
10
|
+
const action_1 = require("../actions/action");
|
|
11
|
+
const lodash_1 = require("../utils/lodash");
|
|
12
|
+
const env_1 = require("../compiler/env");
|
|
13
|
+
class RelationAuth {
|
|
14
|
+
authDeduceRelationMap;
|
|
15
|
+
schema;
|
|
16
|
+
static SPECIAL_ENTITIES = env_1.SYSTEM_RESERVE_ENTITIES;
|
|
17
|
+
selectFreeEntities;
|
|
18
|
+
updateFreeDict;
|
|
19
|
+
constructor(schema, authDeduceRelationMap, selectFreeEntities, updateFreeDict) {
|
|
17
20
|
this.schema = schema;
|
|
18
21
|
this.selectFreeEntities = selectFreeEntities || [];
|
|
19
|
-
this.
|
|
20
|
-
this.updateFreeEntities = updateFreeEntities || [];
|
|
22
|
+
this.updateFreeDict = updateFreeDict || {};
|
|
21
23
|
this.authDeduceRelationMap = Object.assign({}, authDeduceRelationMap, {
|
|
22
24
|
modi: 'entity',
|
|
23
25
|
});
|
|
24
26
|
}
|
|
25
27
|
// 前台检查filter是否满足relation约束
|
|
26
|
-
|
|
28
|
+
checkRelationSync(entity, operation, context) {
|
|
27
29
|
if (context.isRoot()) {
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
32
|
this.checkActions2(entity, operation, context);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
}
|
|
34
|
+
// 后台检查filter是否满足relation约束
|
|
35
|
+
async checkRelationAsync(entity, operation, context) {
|
|
36
|
+
if (context.isRoot()) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
await this.checkActions2(entity, operation, context);
|
|
40
|
+
}
|
|
41
|
+
checkUserRelation(context, action, filter) {
|
|
42
|
+
const userId = context.getCurrentUserId();
|
|
43
|
+
let filter2 = {
|
|
44
|
+
destRelation: {
|
|
45
|
+
userRelation$relation: filter,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
if (action === 'create') {
|
|
49
|
+
const { entity, entityId, relationId } = filter;
|
|
50
|
+
if (relationId) {
|
|
51
|
+
// 如果指定relation,则测试该relation上是否可行
|
|
52
|
+
filter2 = {
|
|
53
|
+
destRelationId: relationId,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// 否则为测试“能否”有权限管理的资格,此时只要有一个就可以
|
|
58
|
+
(0, assert_1.default)(entity);
|
|
59
|
+
filter2 = {
|
|
60
|
+
destRelation: {
|
|
61
|
+
entity,
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
(0, assert_1.default)(action === 'remove');
|
|
68
|
+
// 如果一次删除多个userRelation,接下来的流程判断是只有一个relationAuth满足就会通过,这样可能会有错判 by Xc 20231019
|
|
69
|
+
(0, assert_1.default)(typeof filter.id === 'string', '当前只支持指定id的用户关系删除');
|
|
70
|
+
}
|
|
71
|
+
const relationAuths = context.select('relationAuth', {
|
|
41
72
|
data: {
|
|
42
73
|
id: 1,
|
|
74
|
+
path: {
|
|
75
|
+
id: 1,
|
|
76
|
+
sourceEntity: 1,
|
|
77
|
+
destEntity: 1,
|
|
78
|
+
value: 1,
|
|
79
|
+
recursive: 1,
|
|
80
|
+
},
|
|
81
|
+
sourceRelationId: 1,
|
|
82
|
+
sourceRelation: {
|
|
83
|
+
id: 1,
|
|
84
|
+
entity: 1,
|
|
85
|
+
entityId: 1,
|
|
86
|
+
},
|
|
43
87
|
destRelationId: 1,
|
|
44
88
|
destRelation: {
|
|
45
89
|
id: 1,
|
|
46
|
-
name: 1,
|
|
47
90
|
entity: 1,
|
|
48
91
|
entityId: 1,
|
|
49
|
-
display: 1,
|
|
50
92
|
},
|
|
51
93
|
},
|
|
52
|
-
filter:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
$or: [
|
|
61
|
-
{
|
|
62
|
-
entityId: entityId,
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
entityId: {
|
|
66
|
-
$exists: false,
|
|
67
|
-
},
|
|
68
|
-
}
|
|
69
|
-
],
|
|
94
|
+
filter: filter2,
|
|
95
|
+
}, { dontCollect: true });
|
|
96
|
+
const checkRelationAuth = (relationAuth) => {
|
|
97
|
+
const { destRelation, sourceRelationId, path } = relationAuth;
|
|
98
|
+
let destEntityFilter = this.makePathFilter(destRelation.entity, path, this.schema, {
|
|
99
|
+
userRelation$entity: {
|
|
100
|
+
userId,
|
|
101
|
+
relationId: sourceRelationId,
|
|
70
102
|
},
|
|
71
|
-
},
|
|
72
|
-
}, {});
|
|
73
|
-
if (result instanceof Promise) {
|
|
74
|
-
return result.then(function (r2) { return r2.map(function (ele) { return ele.destRelation; }); });
|
|
75
|
-
}
|
|
76
|
-
return result.map(function (ele) { return ele.destRelation; });
|
|
77
|
-
};
|
|
78
|
-
// 后台检查filter是否满足relation约束
|
|
79
|
-
RelationAuth.prototype.checkRelationAsync = function (entity, operation, context) {
|
|
80
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
81
|
-
return tslib_1.__generator(this, function (_a) {
|
|
82
|
-
switch (_a.label) {
|
|
83
|
-
case 0:
|
|
84
|
-
if (context.isRoot()) {
|
|
85
|
-
return [2 /*return*/];
|
|
86
|
-
}
|
|
87
|
-
return [4 /*yield*/, this.checkActions2(entity, operation, context)];
|
|
88
|
-
case 1:
|
|
89
|
-
_a.sent();
|
|
90
|
-
return [2 /*return*/];
|
|
91
|
-
}
|
|
92
103
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (action === 'create') {
|
|
101
|
-
(0, assert_1.default)(!(filter instanceof Array));
|
|
102
|
-
var _a = filter, entity = _a.entity, entityId = _a.entityId, relationId_1 = _a.relationId;
|
|
103
|
-
// 创建userRelation如果是领取动作,先暂使用root身份通过
|
|
104
|
-
var destRelations = this.getGrantedRelationIds(entity, entityId, context);
|
|
105
|
-
if (destRelations instanceof Promise) {
|
|
106
|
-
return destRelations.then(function (r2) {
|
|
107
|
-
if (relationId_1 && !r2.find(function (ele) { return ele.id === relationId_1; }) || r2.length === 0) {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
return true;
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
// 若指定了要create的relation,则必须有该relationId存在,否则只要有任意可授权的relation即可
|
|
114
|
-
if (relationId_1 && !destRelations.find(function (ele) { return ele.id === relationId_1; }) || destRelations.length === 0) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
return true;
|
|
104
|
+
if (action === 'create') {
|
|
105
|
+
const { entity, entityId } = filter;
|
|
106
|
+
(0, assert_1.default)(entity && typeof entity === 'string');
|
|
107
|
+
if (entityId) {
|
|
108
|
+
Object.assign(destEntityFilter, {
|
|
109
|
+
id: entityId,
|
|
110
|
+
});
|
|
118
111
|
}
|
|
119
112
|
else {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
(0, assert_1.default)(
|
|
123
|
-
|
|
124
|
-
relation: {
|
|
125
|
-
relationAuth$destRelation: {
|
|
126
|
-
sourceRelation: {
|
|
127
|
-
userRelation$relation: {
|
|
128
|
-
userId: userId,
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
return (0, filter_1.checkFilterContains)(entity2, context, contained, filter, true);
|
|
113
|
+
// userEntityGrant会有这种情况,限定某个对象的范围进行授权
|
|
114
|
+
const { [entity]: entityFilter } = filter;
|
|
115
|
+
(0, assert_1.default)(entityFilter);
|
|
116
|
+
destEntityFilter = (0, filter_1.combineFilters)(entity, this.schema, [destEntityFilter, entityFilter]);
|
|
135
117
|
}
|
|
136
118
|
}
|
|
119
|
+
else {
|
|
120
|
+
destEntityFilter = (0, filter_1.combineFilters)(destRelation.entity, this.schema, [destEntityFilter, {
|
|
121
|
+
userRelation$entity: filter,
|
|
122
|
+
}]);
|
|
123
|
+
}
|
|
124
|
+
return context.count(destRelation.entity, {
|
|
125
|
+
filter: destEntityFilter,
|
|
126
|
+
}, { ignoreAttrMiss: true });
|
|
127
|
+
};
|
|
128
|
+
if (relationAuths instanceof Promise) {
|
|
129
|
+
return relationAuths.then((ras) => Promise.all(ras.map(ra => checkRelationAuth(ra)))).then((result) => !!result.find(ele => {
|
|
130
|
+
(0, assert_1.default)(typeof ele === 'number');
|
|
131
|
+
return ele > 0;
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
const result = relationAuths.map(ra => checkRelationAuth(ra));
|
|
135
|
+
return !!result.find(ele => ele > 0);
|
|
136
|
+
}
|
|
137
|
+
checkOperateSpecialEntities2(entity2, action, filter, context) {
|
|
138
|
+
switch (entity2) {
|
|
139
|
+
case 'userRelation': {
|
|
140
|
+
(0, assert_1.default)(!(filter instanceof Array));
|
|
141
|
+
return this.checkUserRelation(context, action, filter);
|
|
142
|
+
}
|
|
137
143
|
case 'user': {
|
|
138
144
|
// 对用户的操作由应用自己去管理权限,这里只检查grant/revoke
|
|
139
145
|
if (['grant', 'revoke'].includes(action)) {
|
|
@@ -147,8 +153,19 @@ var RelationAuth = /** @class */ (function () {
|
|
|
147
153
|
}
|
|
148
154
|
}
|
|
149
155
|
case 'modi': {
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
/** 正常情况下对modi的生成是在触发器下openRootMode,不会走到这里
|
|
157
|
+
* 但是有些例外,如extraFile如果在modi中创建,上传成功之后需要显式生成一条modi,这时对modi的
|
|
158
|
+
* 检查可以转化为对其父entity的update权限检查
|
|
159
|
+
*/
|
|
160
|
+
(0, assert_1.default)(action === 'create');
|
|
161
|
+
const { entity, entityId } = filter;
|
|
162
|
+
return this.checkOperation(entity, {
|
|
163
|
+
action: 'update',
|
|
164
|
+
data: {},
|
|
165
|
+
filter: {
|
|
166
|
+
id: entityId,
|
|
167
|
+
},
|
|
168
|
+
}, context);
|
|
152
169
|
}
|
|
153
170
|
case 'relation': {
|
|
154
171
|
// 创建relation目前不支持,以后再说
|
|
@@ -158,7 +175,14 @@ var RelationAuth = /** @class */ (function () {
|
|
|
158
175
|
// userEntityGrant的创建相当于授权,领取相当于赋权
|
|
159
176
|
if (['create', 'update', 'remove'].includes(action)) {
|
|
160
177
|
if (action === 'create') {
|
|
161
|
-
|
|
178
|
+
const { relationEntity, relationEntityFilter, relationIds } = filter;
|
|
179
|
+
return this.checkOperateSpecialEntities2('userRelation', 'create', {
|
|
180
|
+
entity: relationEntity,
|
|
181
|
+
[relationEntity]: relationEntityFilter,
|
|
182
|
+
relationId: {
|
|
183
|
+
$in: relationIds,
|
|
184
|
+
},
|
|
185
|
+
}, context);
|
|
162
186
|
}
|
|
163
187
|
return this.checkOperateSpecialEntities2('userRelation', 'action', {
|
|
164
188
|
relation: {
|
|
@@ -166,71 +190,58 @@ var RelationAuth = /** @class */ (function () {
|
|
|
166
190
|
},
|
|
167
191
|
}, context);
|
|
168
192
|
}
|
|
169
|
-
// 领取和读取动作公开
|
|
170
193
|
return true;
|
|
171
194
|
}
|
|
172
195
|
default: {
|
|
173
|
-
(0, assert_1.default)(false,
|
|
196
|
+
(0, assert_1.default)(false, `对象${entity2}的权限控制没有加以控制`);
|
|
174
197
|
}
|
|
175
198
|
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
var _this = this;
|
|
180
|
-
var entityFilters = [
|
|
199
|
+
}
|
|
200
|
+
getDeducedEntityFilters(entity, filter, actions, context) {
|
|
201
|
+
const entityFilters = [
|
|
181
202
|
{
|
|
182
|
-
entity
|
|
183
|
-
filter
|
|
184
|
-
actions
|
|
203
|
+
entity,
|
|
204
|
+
filter,
|
|
205
|
+
actions,
|
|
185
206
|
}
|
|
186
207
|
];
|
|
187
208
|
if (this.authDeduceRelationMap[entity]) {
|
|
188
209
|
(0, assert_1.default)(this.authDeduceRelationMap[entity] === 'entity');
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (deduceEntity &&
|
|
192
|
-
deduceFilter = { id:
|
|
210
|
+
let { entity: deduceEntity, entityId: deduceEntityId } = filter;
|
|
211
|
+
let deduceFilter = {};
|
|
212
|
+
if (deduceEntity && deduceEntityId) {
|
|
213
|
+
deduceFilter = { id: deduceEntityId };
|
|
193
214
|
}
|
|
194
215
|
else {
|
|
195
216
|
// 也可能是用cascade方式进行查找,这里有时候filter上会带有两个不同的entity目标,尚未处理(todo!)
|
|
196
|
-
|
|
217
|
+
const { ref } = this.schema[entity].attributes.entity;
|
|
197
218
|
(0, assert_1.default)(ref instanceof Array);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
deduceFilter = filter[refEntity];
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
209
|
-
finally {
|
|
210
|
-
try {
|
|
211
|
-
if (ref_1_1 && !ref_1_1.done && (_a = ref_1.return)) _a.call(ref_1);
|
|
219
|
+
for (const refEntity of ref) {
|
|
220
|
+
if (filter[refEntity]) {
|
|
221
|
+
deduceEntity = refEntity;
|
|
222
|
+
deduceFilter = filter[refEntity];
|
|
223
|
+
break;
|
|
212
224
|
}
|
|
213
|
-
finally { if (e_1) throw e_1.error; }
|
|
214
225
|
}
|
|
215
226
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
227
|
+
const getRecursiveDeducedFilters = (deduceEntity, deduceFilter) => {
|
|
228
|
+
const excludeActions = action_1.readOnlyActions.concat([ /* 'create', 'remove' */]);
|
|
229
|
+
const updateActions = this.schema[deduceEntity].actions.filter((a) => !excludeActions.includes(a));
|
|
219
230
|
/* if (!RelationAuth.SPECIAL_ENTITIES.includes(deduceEntity as string)) {
|
|
220
231
|
return this.getDeducedEntityFilters(deduceEntity, deduceFilter, actions[0] === 'select' ? actions : updateActions, context);
|
|
221
232
|
}
|
|
222
233
|
return []; */
|
|
223
|
-
return
|
|
234
|
+
return this.getDeducedEntityFilters(deduceEntity, deduceFilter, actions[0] === 'select' ? actions : updateActions, context);
|
|
224
235
|
};
|
|
225
236
|
if (deduceEntity && deduceFilter) {
|
|
226
|
-
|
|
237
|
+
const deducedSelections = getRecursiveDeducedFilters(deduceEntity, deduceFilter);
|
|
227
238
|
if (deducedSelections instanceof Promise) {
|
|
228
|
-
return deducedSelections.then(
|
|
229
|
-
entityFilters.push
|
|
239
|
+
return deducedSelections.then((ds) => {
|
|
240
|
+
entityFilters.push(...ds);
|
|
230
241
|
return entityFilters;
|
|
231
242
|
});
|
|
232
243
|
}
|
|
233
|
-
entityFilters.push
|
|
244
|
+
entityFilters.push(...deducedSelections);
|
|
234
245
|
return entityFilters;
|
|
235
246
|
}
|
|
236
247
|
else {
|
|
@@ -239,89 +250,87 @@ var RelationAuth = /** @class */ (function () {
|
|
|
239
250
|
* 这种情况一般发生在entity1 -> entity2上,此时entity2应该是一个固定id查询的filter
|
|
240
251
|
* 在这里先假设如果碰到了list类型的filter,直接不使用deduce路径上的对象来推导
|
|
241
252
|
*/
|
|
242
|
-
|
|
253
|
+
const rows2 = context.select(entity, {
|
|
243
254
|
data: {
|
|
244
255
|
id: 1,
|
|
245
256
|
entity: 1,
|
|
246
257
|
entityId: 1,
|
|
247
258
|
},
|
|
248
|
-
filter
|
|
259
|
+
filter,
|
|
249
260
|
indexFrom: 0,
|
|
250
261
|
count: 10,
|
|
251
262
|
}, { dontCollect: true, blockTrigger: true });
|
|
252
|
-
|
|
263
|
+
const dealWithData = (rows) => {
|
|
253
264
|
// 这里如果entity指向不同的实体,一般出现这样的查询,则其权限应当不由这条deduce路径处理
|
|
254
265
|
// 同上,如果找到的行数大于1行,说明deduce路径上的对象不确定,也暂不处理 by Xc 20230725
|
|
255
266
|
if (rows.length > 1 || rows.length === 0) {
|
|
256
267
|
if (process.env.NODE_ENV === 'development') {
|
|
257
|
-
console.warn(
|
|
268
|
+
console.warn(`进行deduce推导时找到了${rows.length}行${entity}数据`);
|
|
258
269
|
}
|
|
259
270
|
return entityFilters;
|
|
260
271
|
}
|
|
261
|
-
|
|
272
|
+
const { entity: deducedEntity, entityId: deducedEntityId } = rows[0];
|
|
262
273
|
if (!deducedEntity || !deducedEntityId) {
|
|
263
274
|
// 这种情况会出现在前台缓存里
|
|
264
275
|
return entityFilters;
|
|
265
276
|
}
|
|
266
|
-
|
|
267
|
-
id:
|
|
277
|
+
const result = getRecursiveDeducedFilters(deducedEntity, {
|
|
278
|
+
id: deducedEntityId,
|
|
268
279
|
});
|
|
269
280
|
if (result instanceof Promise) {
|
|
270
|
-
return result.then(
|
|
271
|
-
entityFilters.push
|
|
281
|
+
return result.then((r2) => {
|
|
282
|
+
entityFilters.push(...r2);
|
|
272
283
|
return entityFilters;
|
|
273
284
|
});
|
|
274
285
|
}
|
|
275
|
-
entityFilters.push
|
|
286
|
+
entityFilters.push(...result);
|
|
276
287
|
return entityFilters;
|
|
277
288
|
};
|
|
278
289
|
if (rows2 instanceof Promise) {
|
|
279
|
-
return rows2.then(
|
|
290
|
+
return rows2.then((r2) => dealWithData(r2));
|
|
280
291
|
}
|
|
281
|
-
return
|
|
292
|
+
return dealWithData(rows2);
|
|
282
293
|
}
|
|
283
294
|
}
|
|
284
295
|
return entityFilters;
|
|
285
|
-
}
|
|
296
|
+
}
|
|
286
297
|
/**
|
|
287
298
|
* 对于selection,解构出最底层的对象,如果最底层的对象可以被访问,则父对象一定可以
|
|
288
299
|
* 但对于deduce的子对象,不必再向底层查看(假设deduce对象一般都位于树的最底层附近)
|
|
289
300
|
* @param entity
|
|
290
301
|
* @param operation
|
|
291
302
|
*/
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
for (var attr in data) {
|
|
300
|
-
var rel = (0, relation_1.judgeRelation)(_this.schema, entity2, attr);
|
|
303
|
+
destructSelection(entity, selection) {
|
|
304
|
+
const leafSelections = [];
|
|
305
|
+
const destructInner = (entity2, selection2) => {
|
|
306
|
+
const { data, filter } = selection2;
|
|
307
|
+
let hasOneToMany = false;
|
|
308
|
+
for (const attr in data) {
|
|
309
|
+
const rel = (0, relation_1.judgeRelation)(this.schema, entity2, attr);
|
|
301
310
|
if (rel instanceof Array) {
|
|
302
|
-
|
|
311
|
+
const [e, foreignKey] = rel;
|
|
303
312
|
if (foreignKey) {
|
|
304
|
-
(0, assert_1.default)(!
|
|
313
|
+
(0, assert_1.default)(!this.authDeduceRelationMap[e]);
|
|
305
314
|
hasOneToMany = true;
|
|
306
315
|
destructInner(e, {
|
|
307
316
|
data: data[attr].data,
|
|
308
|
-
filter: (0, filter_1.combineFilters)(e,
|
|
309
|
-
|
|
310
|
-
|
|
317
|
+
filter: (0, filter_1.combineFilters)(e, this.schema, [{
|
|
318
|
+
[foreignKey.slice(0, foreignKey.length - 2)]: filter,
|
|
319
|
+
}, data[attr].filter || {}]),
|
|
311
320
|
});
|
|
312
321
|
}
|
|
313
322
|
else {
|
|
314
|
-
if (!
|
|
323
|
+
if (!this.authDeduceRelationMap[e]) {
|
|
315
324
|
hasOneToMany = true;
|
|
316
325
|
destructInner(e, {
|
|
317
326
|
data: data[attr].data,
|
|
318
|
-
filter: (0, filter_1.combineFilters)(e,
|
|
319
|
-
|
|
320
|
-
|
|
327
|
+
filter: (0, filter_1.combineFilters)(e, this.schema, [{
|
|
328
|
+
[entity2]: filter,
|
|
329
|
+
}, data[attr].filter || {}]),
|
|
321
330
|
});
|
|
322
331
|
}
|
|
323
332
|
else {
|
|
324
|
-
(0, assert_1.default)(
|
|
333
|
+
(0, assert_1.default)(this.authDeduceRelationMap[e] === 'entity');
|
|
325
334
|
}
|
|
326
335
|
}
|
|
327
336
|
}
|
|
@@ -329,37 +338,39 @@ var RelationAuth = /** @class */ (function () {
|
|
|
329
338
|
if (!hasOneToMany) {
|
|
330
339
|
leafSelections.push({
|
|
331
340
|
entity: entity2,
|
|
332
|
-
filter
|
|
341
|
+
filter,
|
|
333
342
|
});
|
|
334
343
|
}
|
|
335
344
|
};
|
|
336
345
|
destructInner(entity, (0, lodash_1.cloneDeep)(selection));
|
|
337
346
|
return leafSelections;
|
|
338
|
-
}
|
|
347
|
+
}
|
|
339
348
|
/**
|
|
340
349
|
* 对于operation,解构出一个树形结构,以方便自顶向下的进行访问
|
|
341
350
|
* 但对于deduce的子对象,不必再向底层查看
|
|
342
351
|
* @param entity
|
|
343
352
|
* @param selection
|
|
344
353
|
*/
|
|
345
|
-
|
|
346
|
-
var _this = this;
|
|
354
|
+
destructOperation(entity2, operation2, userId) {
|
|
347
355
|
/**
|
|
348
356
|
* 对create动作,把data中的cascade部分剔除后作为filter参与后续的检验
|
|
349
357
|
* @param operation
|
|
350
358
|
* @returns
|
|
351
359
|
*/
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
var data = operation.data, filter = operation.filter;
|
|
360
|
+
const makeCreateFilter = (entity, operation) => {
|
|
361
|
+
const { data, filter } = operation;
|
|
355
362
|
(0, assert_1.default)(!(data instanceof Array));
|
|
356
363
|
if (data) {
|
|
357
|
-
|
|
358
|
-
for (
|
|
359
|
-
|
|
364
|
+
const data2 = {};
|
|
365
|
+
for (const attr in data) {
|
|
366
|
+
const rel = (0, relation_1.judgeRelation)(this.schema, entity, attr);
|
|
360
367
|
if (rel === 1) {
|
|
361
368
|
// 只需要记住id和各种外键属性,不这样处理有些古怪的属性比如coordinate,其作为createdata和作为filter并不同构
|
|
362
|
-
if ((['id', 'entity', 'entityId'].includes(attr) ||
|
|
369
|
+
/* if ((['id', 'entity', 'entityId'].includes(attr) || this.schema[entity].attributes[attr as any]?.type === 'ref') && typeof data[attr] === 'string') {
|
|
370
|
+
data2[attr] = data[attr];
|
|
371
|
+
} */
|
|
372
|
+
// 假设不再成立,userEntityGrant需要relationEntity这样的属性
|
|
373
|
+
if (!['geometry', 'geography', 'st_geometry', 'st_point'].includes(this.schema[entity].attributes[attr]?.type)) {
|
|
363
374
|
data2[attr] = data[attr];
|
|
364
375
|
}
|
|
365
376
|
}
|
|
@@ -368,12 +379,11 @@ var RelationAuth = /** @class */ (function () {
|
|
|
368
379
|
}
|
|
369
380
|
return filter;
|
|
370
381
|
};
|
|
371
|
-
|
|
372
|
-
var _a;
|
|
382
|
+
const addChild = (node, path, child) => {
|
|
373
383
|
// 在这里要把可以被node deduce出来的child处理掉
|
|
374
|
-
|
|
384
|
+
const paths = path.split('$');
|
|
375
385
|
(0, assert_1.default)(paths.length >= 2);
|
|
376
|
-
if (
|
|
386
|
+
if (this.authDeduceRelationMap[child.entity] === paths[1]) {
|
|
377
387
|
(0, assert_1.default)(paths[1] === 'entity', '当前只支持entity外键上的deduce');
|
|
378
388
|
return false;
|
|
379
389
|
}
|
|
@@ -386,86 +396,152 @@ var RelationAuth = /** @class */ (function () {
|
|
|
386
396
|
}
|
|
387
397
|
}
|
|
388
398
|
else {
|
|
389
|
-
Object.assign(node.children,
|
|
390
|
-
|
|
391
|
-
|
|
399
|
+
Object.assign(node.children, {
|
|
400
|
+
[path]: child,
|
|
401
|
+
});
|
|
392
402
|
}
|
|
393
403
|
return true;
|
|
394
404
|
};
|
|
395
|
-
|
|
405
|
+
const destructInner = (entity, operation,
|
|
396
406
|
// extraFilter?: ED[T2]['Selection']['filter'],
|
|
397
|
-
path, child, hasParent) {
|
|
398
|
-
|
|
399
|
-
|
|
407
|
+
path, child, hasParent, extraFilter) => {
|
|
408
|
+
const { action, data, filter } = operation;
|
|
409
|
+
const filter2 = action === 'create' ? makeCreateFilter(entity, operation) : (0, lodash_1.cloneDeep)(filter);
|
|
400
410
|
(0, assert_1.default)(filter2);
|
|
411
|
+
if (extraFilter) {
|
|
412
|
+
Object.assign(filter2, extraFilter);
|
|
413
|
+
}
|
|
401
414
|
// const filter3 = extraFilter ? combineFilters(entity, schema, [filter2, extraFilter]) : filter2;
|
|
402
|
-
|
|
415
|
+
const me = {
|
|
403
416
|
entity: entity,
|
|
404
417
|
filter: filter2,
|
|
405
418
|
children: {},
|
|
406
|
-
action
|
|
419
|
+
action,
|
|
407
420
|
};
|
|
408
|
-
|
|
421
|
+
let root = me;
|
|
409
422
|
// 如果当前对象是一个toModi的,意味着它的cascadeUpdate会全部被变为modi去缓存,因此不需要再向下检查了
|
|
410
423
|
// modi被apply时,这些modi产生的更新才会被实际检查
|
|
411
|
-
|
|
424
|
+
// 这里可能有问题,再思考思考 by Xc 20231111
|
|
425
|
+
const isModiUpdate = this.schema[entity].toModi && action !== 'remove';
|
|
412
426
|
if (child) {
|
|
413
427
|
(0, assert_1.default)(path);
|
|
414
428
|
addChild(me, path, child);
|
|
415
429
|
}
|
|
416
|
-
|
|
417
|
-
|
|
430
|
+
(0, assert_1.default)(!(data instanceof Array));
|
|
431
|
+
for (const attr in data) {
|
|
432
|
+
const rel = (0, relation_1.judgeRelation)(this.schema, entity, attr);
|
|
418
433
|
if (rel === 2 && !isModiUpdate) {
|
|
419
434
|
(0, assert_1.default)(root === me && !hasParent, 'cascadeUpdate必须是树结构,避免森林');
|
|
420
|
-
|
|
435
|
+
const mtoOperation = data[attr];
|
|
436
|
+
root = destructInner(attr, mtoOperation, `${entity}$entity`, me);
|
|
421
437
|
}
|
|
422
438
|
else if (typeof rel === 'string' && !isModiUpdate) {
|
|
423
439
|
(0, assert_1.default)(root === me && !hasParent, 'cascadeUpdate必须是树结构,避免森林');
|
|
424
|
-
root = destructInner(rel, data[attr],
|
|
440
|
+
root = destructInner(rel, data[attr], `${entity}$${attr}`, me);
|
|
425
441
|
}
|
|
426
442
|
else if (rel instanceof Array && !isModiUpdate) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
443
|
+
const [e, f] = rel;
|
|
444
|
+
const otmOperations = data[attr];
|
|
445
|
+
/**
|
|
446
|
+
* 这里目前在cascadeUpdate的过程中,只有当一对多个userRelation的操作需要将entity和entityId复制到子对象上
|
|
447
|
+
* 因为对userRelation的判断是走的特殊路径,无法利用父对象的actionAuth
|
|
448
|
+
* 其它对象情况不需要复制,因为应用中必须要能保证(前台传来的)父对象的filter不依赖于子对象的条件
|
|
449
|
+
*/
|
|
450
|
+
let extraFilter = undefined;
|
|
451
|
+
if (e === 'userRelation' && entity !== 'user') {
|
|
430
452
|
me.userRelations = [];
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
if (
|
|
438
|
-
|
|
453
|
+
extraFilter = {
|
|
454
|
+
entity,
|
|
455
|
+
entityId: filter2.id,
|
|
456
|
+
};
|
|
457
|
+
const dealWithUserRelation = (userRelation) => {
|
|
458
|
+
const { action, data } = userRelation;
|
|
459
|
+
if (action === 'create') {
|
|
460
|
+
const attrs = Object.keys(data);
|
|
461
|
+
(0, assert_1.default)((0, lodash_1.difference)(attrs, Object.keys(this.schema.userRelation.attributes).concat('id')).length === 0);
|
|
462
|
+
if (data.userId === userId) {
|
|
463
|
+
me.userRelations?.push(data);
|
|
464
|
+
}
|
|
465
|
+
(0, assert_1.default)(filter2.id);
|
|
439
466
|
}
|
|
440
467
|
};
|
|
441
468
|
if (otmOperations instanceof Array) {
|
|
442
|
-
otmOperations.forEach(
|
|
469
|
+
otmOperations.forEach((otmOperation) => dealWithUserRelation(otmOperation));
|
|
443
470
|
}
|
|
444
471
|
else {
|
|
445
|
-
|
|
472
|
+
dealWithUserRelation(otmOperations);
|
|
446
473
|
}
|
|
447
474
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
var son = destructInner(e_2, otmOperation, undefined, undefined, true);
|
|
452
|
-
addChild(me, attr, son);
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
else {
|
|
456
|
-
var son = destructInner(e_2, otmOperations, undefined, undefined, true);
|
|
475
|
+
if (otmOperations instanceof Array) {
|
|
476
|
+
otmOperations.forEach((otmOperation) => {
|
|
477
|
+
const son = destructInner(e, otmOperation, undefined, undefined, true, extraFilter);
|
|
457
478
|
addChild(me, attr, son);
|
|
458
|
-
}
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
const son = destructInner(e, otmOperations, undefined, undefined, true, extraFilter);
|
|
483
|
+
addChild(me, attr, son);
|
|
459
484
|
}
|
|
460
485
|
}
|
|
461
|
-
};
|
|
462
|
-
for (var attr in data) {
|
|
463
|
-
_loop_1(attr);
|
|
464
486
|
}
|
|
465
487
|
return root;
|
|
466
488
|
};
|
|
467
|
-
return destructInner(entity2,
|
|
468
|
-
}
|
|
489
|
+
return destructInner(entity2, operation2);
|
|
490
|
+
}
|
|
491
|
+
makePathFilter(entity, path, schema, filter) {
|
|
492
|
+
const { value, recursive } = path;
|
|
493
|
+
if (value === '') {
|
|
494
|
+
(0, assert_1.default)(!recursive);
|
|
495
|
+
return filter;
|
|
496
|
+
}
|
|
497
|
+
const paths = value.split('.');
|
|
498
|
+
const makeRecursiveFilter = (recursiveDepth) => {
|
|
499
|
+
if (recursiveDepth > 0) {
|
|
500
|
+
return {
|
|
501
|
+
$or: [
|
|
502
|
+
filter,
|
|
503
|
+
{
|
|
504
|
+
parent: makeRecursiveFilter(recursiveDepth - 1)
|
|
505
|
+
}
|
|
506
|
+
]
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
return filter;
|
|
510
|
+
};
|
|
511
|
+
const makeInner = (idx, e2) => {
|
|
512
|
+
const attr = paths[idx];
|
|
513
|
+
if (idx === paths.length) {
|
|
514
|
+
if (!recursive) {
|
|
515
|
+
return filter;
|
|
516
|
+
}
|
|
517
|
+
else {
|
|
518
|
+
// 在最后一个对象上存在递归,用or连接处理
|
|
519
|
+
const { recursiveDepth } = schema[e2];
|
|
520
|
+
(0, assert_1.default)(recursiveDepth > 0);
|
|
521
|
+
return makeRecursiveFilter(recursiveDepth);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
const rel = (0, relation_1.judgeRelation)(schema, e2, attr);
|
|
526
|
+
let e3;
|
|
527
|
+
if (rel === 2) {
|
|
528
|
+
e3 = attr;
|
|
529
|
+
}
|
|
530
|
+
else if (typeof rel === 'string') {
|
|
531
|
+
e3 = rel;
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
(0, assert_1.default)(rel instanceof Array);
|
|
535
|
+
e3 = rel[0];
|
|
536
|
+
}
|
|
537
|
+
const f = makeInner(idx + 1, e3);
|
|
538
|
+
return {
|
|
539
|
+
[attr]: f,
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
return makeInner(0, entity);
|
|
544
|
+
}
|
|
469
545
|
/**
|
|
470
546
|
* 对所有满足操作要求的actionAuth加以判断,找到可以满足当前用户身份的actionAuth
|
|
471
547
|
* @param entity
|
|
@@ -474,41 +550,30 @@ var RelationAuth = /** @class */ (function () {
|
|
|
474
550
|
* @param context
|
|
475
551
|
* @return
|
|
476
552
|
*/
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
553
|
+
filterActionAuths(entity, filter, actionAuths, context) {
|
|
554
|
+
const result = actionAuths.map((ele) => {
|
|
555
|
+
const { path, relation, relationId } = ele;
|
|
480
556
|
// 在cache中,可能出现relation外键指向的对象为null的情况,要容错
|
|
481
557
|
if (relationId) {
|
|
482
558
|
if (relation) {
|
|
483
|
-
|
|
559
|
+
const { userRelation$relation: userRelations } = relation;
|
|
484
560
|
if (userRelations.length > 0) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
var pathFilters_1 = paths.map(function (path) {
|
|
491
|
-
if (path) {
|
|
492
|
-
return (0, lodash_1.set)({}, path, {
|
|
493
|
-
id: idFilter_1,
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
return {
|
|
497
|
-
id: idFilter_1,
|
|
498
|
-
};
|
|
561
|
+
const entityIds = (0, lodash_1.uniq)(userRelations.map(ele => ele.entityId));
|
|
562
|
+
const pathFilter = this.makePathFilter(entity, path, this.schema, {
|
|
563
|
+
id: entityIds.length > 0 ? {
|
|
564
|
+
$in: entityIds,
|
|
565
|
+
} : entityIds[0],
|
|
499
566
|
});
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
if (contains_1 instanceof Promise) {
|
|
504
|
-
return contains_1.then(function (c) {
|
|
567
|
+
const contains = (0, filter_1.checkFilterContains)(entity, context, pathFilter, filter, true);
|
|
568
|
+
if (contains instanceof Promise) {
|
|
569
|
+
return contains.then((c) => {
|
|
505
570
|
if (c) {
|
|
506
571
|
return ele;
|
|
507
572
|
}
|
|
508
573
|
return;
|
|
509
574
|
});
|
|
510
575
|
}
|
|
511
|
-
if (
|
|
576
|
+
if (contains) {
|
|
512
577
|
return ele;
|
|
513
578
|
}
|
|
514
579
|
return;
|
|
@@ -517,11 +582,12 @@ var RelationAuth = /** @class */ (function () {
|
|
|
517
582
|
return;
|
|
518
583
|
}
|
|
519
584
|
// 说明是通过userId关联
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
585
|
+
const pathFilter = this.makePathFilter(entity, path, this.schema, {
|
|
586
|
+
id: context.getCurrentUserId(),
|
|
587
|
+
});
|
|
588
|
+
const contains = (0, filter_1.checkFilterContains)(entity, context, pathFilter, filter, true);
|
|
523
589
|
if (contains instanceof Promise) {
|
|
524
|
-
return contains.then(
|
|
590
|
+
return contains.then((c) => {
|
|
525
591
|
if (c) {
|
|
526
592
|
return ele;
|
|
527
593
|
}
|
|
@@ -532,11 +598,11 @@ var RelationAuth = /** @class */ (function () {
|
|
|
532
598
|
return ele;
|
|
533
599
|
}
|
|
534
600
|
});
|
|
535
|
-
if (result.find(
|
|
536
|
-
return Promise.all(result).then(
|
|
601
|
+
if (result.find(ele => ele instanceof Promise)) {
|
|
602
|
+
return Promise.all(result).then((r2) => r2.filter(ele => !!ele));
|
|
537
603
|
}
|
|
538
|
-
return result.filter(
|
|
539
|
-
}
|
|
604
|
+
return result.filter(ele => !!ele);
|
|
605
|
+
}
|
|
540
606
|
/**
|
|
541
607
|
* 对于有些特殊的查询(带很多$or的查询,多发生在系统级别),单个actionAuth无法满足,需要共同加以判定
|
|
542
608
|
* @param entity
|
|
@@ -545,51 +611,40 @@ var RelationAuth = /** @class */ (function () {
|
|
|
545
611
|
* @param context
|
|
546
612
|
* @param actions
|
|
547
613
|
*/
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
614
|
+
checkActionAuthInGroup(entity, filter, actionAuths, context) {
|
|
615
|
+
const filters = actionAuths.filter(ele => ele.path.destEntity === entity).map((ele) => {
|
|
616
|
+
const { path, relation, relationId } = ele;
|
|
551
617
|
if (relationId) {
|
|
552
618
|
(0, assert_1.default)(relation);
|
|
553
|
-
|
|
619
|
+
const { userRelation$relation: userRelations } = relation;
|
|
554
620
|
(0, assert_1.default)(userRelations.length > 0);
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
var pathFilters = paths.map(function (path) {
|
|
561
|
-
if (path) {
|
|
562
|
-
return (0, lodash_1.set)({}, path, {
|
|
563
|
-
id: idFilter_2,
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
return {
|
|
567
|
-
id: idFilter_2
|
|
568
|
-
};
|
|
621
|
+
const entityIds = (0, lodash_1.uniq)(userRelations.map(ele => ele.entityId));
|
|
622
|
+
const pathFilter = this.makePathFilter(entity, path, this.schema, {
|
|
623
|
+
id: entityIds.length > 0 ? {
|
|
624
|
+
$in: entityIds,
|
|
625
|
+
} : entityIds[0],
|
|
569
626
|
});
|
|
570
|
-
return
|
|
627
|
+
return pathFilter;
|
|
571
628
|
}
|
|
572
629
|
// 说明是通过userId关联
|
|
573
|
-
return
|
|
630
|
+
return this.makePathFilter(entity, path, this.schema, {
|
|
631
|
+
id: context.getCurrentUserId(),
|
|
632
|
+
});
|
|
574
633
|
});
|
|
575
|
-
|
|
634
|
+
const groupFilter = (0, filter_1.combineFilters)(entity, this.schema, filters, true);
|
|
576
635
|
if (groupFilter) {
|
|
577
636
|
return (0, filter_1.checkFilterContains)(entity, context, groupFilter, filter, true);
|
|
578
637
|
}
|
|
579
638
|
return false;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
});
|
|
588
|
-
var checkDeducedLeafSelections = function (dlSelections2) {
|
|
589
|
-
var dlSelections = dlSelections2.filter(function (ele) {
|
|
590
|
-
var entities = ele.map(function (ele2) { return ele2.entity; });
|
|
639
|
+
}
|
|
640
|
+
checkSelection(entity, selection, context) {
|
|
641
|
+
const leafSelections = this.destructSelection(entity, selection);
|
|
642
|
+
const deducedLeafSelections = leafSelections.map(({ entity, filter }) => this.getDeducedEntityFilters(entity, filter, ['select'], context));
|
|
643
|
+
const checkDeducedLeafSelections = (dlSelections2) => {
|
|
644
|
+
const dlSelections = dlSelections2.filter((ele) => {
|
|
645
|
+
const entities = ele.map(ele2 => ele2.entity);
|
|
591
646
|
// 同一个leaf的deducedSelections中只要有一个能通过就足够了
|
|
592
|
-
if ((0, lodash_1.intersection)(
|
|
647
|
+
if ((0, lodash_1.intersection)(this.selectFreeEntities, entities).length > 0) {
|
|
593
648
|
return false;
|
|
594
649
|
}
|
|
595
650
|
if ((0, lodash_1.intersection)(RelationAuth.SPECIAL_ENTITIES, entities).length > 0) {
|
|
@@ -604,16 +659,20 @@ var RelationAuth = /** @class */ (function () {
|
|
|
604
659
|
if (!context.getCurrentUserId()) {
|
|
605
660
|
throw new types_1.OakUnloggedInException();
|
|
606
661
|
}
|
|
607
|
-
|
|
608
|
-
dlSelections.forEach(
|
|
609
|
-
var entity = _a.entity;
|
|
662
|
+
const allEntities = [];
|
|
663
|
+
dlSelections.forEach((ele) => ele.forEach(({ entity }) => {
|
|
610
664
|
allEntities.push(entity);
|
|
611
|
-
})
|
|
612
|
-
|
|
665
|
+
}));
|
|
666
|
+
const actionAuths = context.select('actionAuth', {
|
|
613
667
|
data: {
|
|
614
668
|
id: 1,
|
|
615
|
-
|
|
616
|
-
|
|
669
|
+
path: {
|
|
670
|
+
id: 1,
|
|
671
|
+
value: 1,
|
|
672
|
+
sourceEntity: 1,
|
|
673
|
+
destEntity: 1,
|
|
674
|
+
recursive: 1,
|
|
675
|
+
},
|
|
617
676
|
deActions: 1,
|
|
618
677
|
relation: {
|
|
619
678
|
id: 1,
|
|
@@ -634,8 +693,10 @@ var RelationAuth = /** @class */ (function () {
|
|
|
634
693
|
deActions: {
|
|
635
694
|
$contains: 'select',
|
|
636
695
|
},
|
|
637
|
-
|
|
638
|
-
|
|
696
|
+
path: {
|
|
697
|
+
destEntity: {
|
|
698
|
+
$in: allEntities,
|
|
699
|
+
},
|
|
639
700
|
},
|
|
640
701
|
$or: [
|
|
641
702
|
{
|
|
@@ -652,48 +713,37 @@ var RelationAuth = /** @class */ (function () {
|
|
|
652
713
|
}
|
|
653
714
|
]
|
|
654
715
|
}
|
|
655
|
-
}, { dontCollect: true,
|
|
716
|
+
}, { dontCollect: true, ignoreAttrMiss: true });
|
|
656
717
|
/**
|
|
657
718
|
* 返回的结果中,第一层为leafNode,必须全通过,第二层为单个leafNode上的deduce,通过一个就可以
|
|
658
719
|
* @param result
|
|
659
720
|
* @returns
|
|
660
721
|
*/
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
if (!r2) {
|
|
669
|
-
if (process.env.NODE_ENV === 'development') {
|
|
670
|
-
console.warn('对象的select权限被否决,请检查', dlSelections[idx]);
|
|
671
|
-
}
|
|
672
|
-
return false;
|
|
722
|
+
const checkResult = (result) => {
|
|
723
|
+
let idx = 0;
|
|
724
|
+
for (const r1 of result) {
|
|
725
|
+
const r2 = r1.find(ele => ele === true);
|
|
726
|
+
if (!r2) {
|
|
727
|
+
if (process.env.NODE_ENV === 'development') {
|
|
728
|
+
console.warn('对象的select权限被否决,请检查', dlSelections[idx]);
|
|
673
729
|
}
|
|
730
|
+
return false;
|
|
674
731
|
}
|
|
675
732
|
}
|
|
676
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
677
|
-
finally {
|
|
678
|
-
try {
|
|
679
|
-
if (result_1_1 && !result_1_1.done && (_a = result_1.return)) _a.call(result_1);
|
|
680
|
-
}
|
|
681
|
-
finally { if (e_3) throw e_3.error; }
|
|
682
|
-
}
|
|
683
733
|
return true;
|
|
684
734
|
};
|
|
685
735
|
if (actionAuths instanceof Promise) {
|
|
686
736
|
(0, assert_1.default)(context instanceof AsyncRowStore_1.AsyncContext);
|
|
687
|
-
return actionAuths.then(
|
|
737
|
+
return actionAuths.then((aas) => Promise.all(dlSelections.map((ele) => Promise.all(ele.map((ele2) => this.checkActionAuthInGroup(ele2.entity, ele2.filter, aas, context))))).then((result) => checkResult(result)));
|
|
688
738
|
}
|
|
689
|
-
return checkResult(dlSelections.map(
|
|
739
|
+
return checkResult(dlSelections.map(ele => ele.map(ele2 => this.checkActionAuthInGroup(ele2.entity, ele2.filter, actionAuths, context))));
|
|
690
740
|
};
|
|
691
741
|
if (deducedLeafSelections[0] instanceof Promise) {
|
|
692
742
|
return Promise.all(deducedLeafSelections)
|
|
693
|
-
.then(
|
|
743
|
+
.then((dls) => checkDeducedLeafSelections(dls));
|
|
694
744
|
}
|
|
695
745
|
return checkDeducedLeafSelections(deducedLeafSelections);
|
|
696
|
-
}
|
|
746
|
+
}
|
|
697
747
|
/**
|
|
698
748
|
* 此函数判定一个结点是否能通过权限检测,同时寻找该结点本身对象上成立的actionAuth,用于本结点子孙结点的快速检测
|
|
699
749
|
* 如果结点因其deduce的对象通过了检测,其被推断对象的actionAuth无法用于更低对象的权限检测
|
|
@@ -701,41 +751,44 @@ var RelationAuth = /** @class */ (function () {
|
|
|
701
751
|
* @param context
|
|
702
752
|
* @returns
|
|
703
753
|
*/
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
var deducedEntityFilters2 = this.getDeducedEntityFilters(entity, filter, [action], context);
|
|
754
|
+
findActionAuthsOnNode(node, context) {
|
|
755
|
+
const { entity, filter, action, userRelations } = node;
|
|
756
|
+
const deducedEntityFilters2 = this.getDeducedEntityFilters(entity, filter, [action], context);
|
|
708
757
|
/**
|
|
709
758
|
* 搜索判定是否允许自建对象,自建的条件是 path = '',destEntity === entity
|
|
710
759
|
* @param actionAuths
|
|
711
760
|
* @returns
|
|
712
761
|
*/
|
|
713
|
-
|
|
762
|
+
const findOwnCreateUserRelation = (actionAuths) => {
|
|
714
763
|
if (userRelations && userRelations.length > 0) {
|
|
715
|
-
(
|
|
716
|
-
var ars = actionAuths.filter(function (ar) { return !!userRelations.find(function (ur) { return ur.relationId === ar.relationId; }) && ar.paths.includes('') && ar.destEntity === entity; });
|
|
764
|
+
const ars = actionAuths.filter((ar) => !!userRelations.find((ur) => ur.relationId === ar.relationId) && ar.path.value === '' && ar.path.destEntity === entity);
|
|
717
765
|
if (ars.length > 0) {
|
|
718
766
|
return ars;
|
|
719
767
|
}
|
|
720
768
|
}
|
|
721
769
|
};
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
770
|
+
const actionAuthOnEntities = [];
|
|
771
|
+
const dealWithDeducedEntityFilters = (deducedEntityFilters) => {
|
|
772
|
+
const specialEntities = deducedEntityFilters.filter(ele => RelationAuth.SPECIAL_ENTITIES.includes(ele.entity));
|
|
773
|
+
const unspecicalEntities = deducedEntityFilters.filter(ele => !RelationAuth.SPECIAL_ENTITIES.includes(ele.entity));
|
|
774
|
+
const result = [];
|
|
727
775
|
if (specialEntities.length > 0) {
|
|
728
776
|
// 对于deduce出来的special对象,直接判定create应该问题不大,否则写起来太烦琐(具体情况遇到了再调试)
|
|
729
|
-
result.push
|
|
777
|
+
result.push(...specialEntities.map(ele => this.checkOperateSpecialEntities2(ele.entity, ele.entity === entity ? node.action : 'create', ele.filter, context)));
|
|
730
778
|
}
|
|
731
779
|
if (unspecicalEntities.length > 0) {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
780
|
+
const allEntities = unspecicalEntities.map(ele => ele.entity);
|
|
781
|
+
const allActions = (0, lodash_1.uniq)(unspecicalEntities.map(ele => ele.actions).flat());
|
|
782
|
+
const actionAuths2 = context.select('actionAuth', {
|
|
735
783
|
data: {
|
|
736
784
|
id: 1,
|
|
737
|
-
|
|
738
|
-
|
|
785
|
+
path: {
|
|
786
|
+
id: 1,
|
|
787
|
+
destEntity: 1,
|
|
788
|
+
sourceEntity: 1,
|
|
789
|
+
value: 1,
|
|
790
|
+
recursive: 1,
|
|
791
|
+
},
|
|
739
792
|
deActions: 1,
|
|
740
793
|
relation: {
|
|
741
794
|
id: 1,
|
|
@@ -753,52 +806,54 @@ var RelationAuth = /** @class */ (function () {
|
|
|
753
806
|
},
|
|
754
807
|
},
|
|
755
808
|
filter: {
|
|
756
|
-
|
|
757
|
-
|
|
809
|
+
path: {
|
|
810
|
+
destEntity: {
|
|
811
|
+
$in: allEntities,
|
|
812
|
+
}
|
|
758
813
|
},
|
|
759
814
|
deActions: {
|
|
760
815
|
$overlaps: allActions,
|
|
761
816
|
},
|
|
762
817
|
}
|
|
763
|
-
}, { dontCollect: true,
|
|
764
|
-
|
|
765
|
-
|
|
818
|
+
}, { dontCollect: true, ignoreAttrMiss: true });
|
|
819
|
+
const checkActionAuths = (actionAuths) => {
|
|
820
|
+
const created = findOwnCreateUserRelation(actionAuths);
|
|
766
821
|
if (created) {
|
|
767
|
-
actionAuthOnEntities.push
|
|
822
|
+
actionAuthOnEntities.push(...created);
|
|
768
823
|
return true;
|
|
769
824
|
}
|
|
770
|
-
|
|
771
|
-
|
|
825
|
+
const result = deducedEntityFilters.map((ele) => {
|
|
826
|
+
const ars2 = actionAuths.filter(ele2 => ele2.path.destEntity === ele.entity && (0, lodash_1.intersection)(ele2.deActions, ele.actions).length > 0 // 这里只要overlap就可以了
|
|
772
827
|
);
|
|
773
|
-
|
|
774
|
-
|
|
828
|
+
const ars3 = this.filterActionAuths(ele.entity, ele.filter, ars2, context);
|
|
829
|
+
const checkFilteredArs = (actionAuths2) => {
|
|
775
830
|
if (actionAuths2.length > 0) {
|
|
776
831
|
if (ele.entity === entity) {
|
|
777
|
-
actionAuthOnEntities.push
|
|
832
|
+
actionAuthOnEntities.push(...actionAuths2);
|
|
778
833
|
}
|
|
779
834
|
return true;
|
|
780
835
|
}
|
|
781
836
|
return false;
|
|
782
837
|
};
|
|
783
838
|
if (ars3 instanceof Promise) {
|
|
784
|
-
return ars3.then(
|
|
839
|
+
return ars3.then((ars4) => checkFilteredArs(ars4));
|
|
785
840
|
}
|
|
786
841
|
return checkFilteredArs(ars3);
|
|
787
842
|
});
|
|
788
|
-
if (result.find(
|
|
789
|
-
return Promise.all(result).then(
|
|
843
|
+
if (result.find(ele => ele instanceof Promise)) {
|
|
844
|
+
return Promise.all(result).then((r2) => r2.includes(true));
|
|
790
845
|
}
|
|
791
846
|
return result.includes(true);
|
|
792
847
|
};
|
|
793
848
|
if (actionAuths2 instanceof Promise) {
|
|
794
|
-
result.push(actionAuths2.then(
|
|
849
|
+
result.push(actionAuths2.then((ars2) => checkActionAuths(ars2)));
|
|
795
850
|
}
|
|
796
851
|
else {
|
|
797
|
-
result.push(
|
|
852
|
+
result.push(checkActionAuths(actionAuths2));
|
|
798
853
|
}
|
|
799
854
|
}
|
|
800
|
-
if (result.find(
|
|
801
|
-
return Promise.all(result).then(
|
|
855
|
+
if (result.find(ele => ele instanceof Promise)) {
|
|
856
|
+
return Promise.all(result).then((r2) => {
|
|
802
857
|
// r2中只有一个通过就能通过
|
|
803
858
|
if (r2.includes(true)) {
|
|
804
859
|
return actionAuthOnEntities;
|
|
@@ -812,47 +867,46 @@ var RelationAuth = /** @class */ (function () {
|
|
|
812
867
|
return false;
|
|
813
868
|
};
|
|
814
869
|
if (deducedEntityFilters2 instanceof Promise) {
|
|
815
|
-
return deducedEntityFilters2.then(
|
|
870
|
+
return deducedEntityFilters2.then((def2) => dealWithDeducedEntityFilters(def2));
|
|
816
871
|
}
|
|
817
872
|
return dealWithDeducedEntityFilters(deducedEntityFilters2);
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
var childPath = Object.keys(children);
|
|
873
|
+
}
|
|
874
|
+
checkOperationTree2(tree, context) {
|
|
875
|
+
const checkNode = (node, actionAuths) => {
|
|
876
|
+
const checkChildren = (legalPaths) => {
|
|
877
|
+
const { children } = node;
|
|
878
|
+
const childPath = Object.keys(children);
|
|
825
879
|
if (childPath.length === 0) {
|
|
826
880
|
return true;
|
|
827
881
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
882
|
+
const childResult = childPath.map((childPath) => {
|
|
883
|
+
const child = children[childPath];
|
|
884
|
+
const childEntity = child instanceof Array ? child[0].entity : child.entity;
|
|
831
885
|
// 这里如果该子结点能deduce到父,则直接通过
|
|
832
|
-
if (
|
|
833
|
-
(0, assert_1.default)(
|
|
834
|
-
|
|
886
|
+
if (this.authDeduceRelationMap[childEntity]) {
|
|
887
|
+
(0, assert_1.default)(this.authDeduceRelationMap[childEntity] === 'entity');
|
|
888
|
+
const rel = (0, relation_1.judgeRelation)(this.schema, childEntity, childPath);
|
|
835
889
|
if (rel === 2) {
|
|
836
890
|
return true;
|
|
837
891
|
}
|
|
838
892
|
}
|
|
839
|
-
|
|
893
|
+
const pathToParent = childPath.endsWith('$entity') ? node.entity : childPath.split('$')[1];
|
|
840
894
|
if (child instanceof Array) {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
895
|
+
const childActions = child.map(ele => ele.action);
|
|
896
|
+
const childLegalAuths = legalPaths.map((ele) => {
|
|
897
|
+
const { path: { value: pv }, relationId } = ele;
|
|
898
|
+
const pv2 = pv ? `${pathToParent}.${pv}` : pathToParent;
|
|
845
899
|
return context.select('actionAuth', {
|
|
846
900
|
data: {
|
|
847
901
|
id: 1,
|
|
848
902
|
},
|
|
849
903
|
filter: {
|
|
850
|
-
|
|
851
|
-
|
|
904
|
+
path: {
|
|
905
|
+
value: pv2,
|
|
906
|
+
destEntity: childEntity,
|
|
852
907
|
},
|
|
853
|
-
destEntity: childEntity,
|
|
854
908
|
deActions: {
|
|
855
|
-
$overlaps:
|
|
909
|
+
$overlaps: childActions,
|
|
856
910
|
},
|
|
857
911
|
relationId: relationId || {
|
|
858
912
|
$exists: false,
|
|
@@ -860,23 +914,23 @@ var RelationAuth = /** @class */ (function () {
|
|
|
860
914
|
}
|
|
861
915
|
}, { dontCollect: true });
|
|
862
916
|
}).flat();
|
|
863
|
-
if (
|
|
864
|
-
return Promise.all(
|
|
917
|
+
if (childLegalAuths[0] instanceof Promise) {
|
|
918
|
+
return Promise.all(childLegalAuths).then((clas) => child.map((c) => checkNode(c, clas)));
|
|
865
919
|
}
|
|
866
|
-
return child.map(
|
|
920
|
+
return child.map((c) => checkNode(c, childLegalAuths));
|
|
867
921
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
922
|
+
const childLegalAuths = legalPaths.map((ele) => {
|
|
923
|
+
const { path: { value: pv }, relationId } = ele;
|
|
924
|
+
const pv2 = pv ? `${pathToParent}.${pv}` : pathToParent;
|
|
871
925
|
return context.select('actionAuth', {
|
|
872
926
|
data: {
|
|
873
927
|
id: 1,
|
|
874
928
|
},
|
|
875
929
|
filter: {
|
|
876
|
-
|
|
877
|
-
|
|
930
|
+
path: {
|
|
931
|
+
value: pv2,
|
|
932
|
+
destEntity: childEntity,
|
|
878
933
|
},
|
|
879
|
-
destEntity: childEntity,
|
|
880
934
|
deActions: {
|
|
881
935
|
$overlaps: child.action,
|
|
882
936
|
},
|
|
@@ -887,12 +941,12 @@ var RelationAuth = /** @class */ (function () {
|
|
|
887
941
|
}, { dontCollect: true });
|
|
888
942
|
}).flat();
|
|
889
943
|
if (childLegalAuths[0] instanceof Promise) {
|
|
890
|
-
return Promise.all(childLegalAuths).then(
|
|
944
|
+
return Promise.all(childLegalAuths).then((clas) => checkNode(child, clas.flat()));
|
|
891
945
|
}
|
|
892
946
|
return checkNode(child, childLegalAuths);
|
|
893
947
|
}).flat();
|
|
894
948
|
if (childResult[0] instanceof Promise) {
|
|
895
|
-
return Promise.all(childResult).then(
|
|
949
|
+
return Promise.all(childResult).then((r) => !r.includes(false));
|
|
896
950
|
}
|
|
897
951
|
return !childResult.includes(false);
|
|
898
952
|
};
|
|
@@ -902,8 +956,8 @@ var RelationAuth = /** @class */ (function () {
|
|
|
902
956
|
return checkChildren(actionAuths);
|
|
903
957
|
}
|
|
904
958
|
// 没有能根据父亲传下来的actionAuth判定,只能自己找
|
|
905
|
-
|
|
906
|
-
|
|
959
|
+
const result = this.findActionAuthsOnNode(node, context);
|
|
960
|
+
const checkResult = (result2) => {
|
|
907
961
|
if (result2 === false) {
|
|
908
962
|
return false;
|
|
909
963
|
}
|
|
@@ -911,224 +965,38 @@ var RelationAuth = /** @class */ (function () {
|
|
|
911
965
|
if (node.entity === 'user') {
|
|
912
966
|
result2.push({
|
|
913
967
|
id: 'temp',
|
|
914
|
-
|
|
968
|
+
pathId: 'path_temp',
|
|
969
|
+
path: {
|
|
970
|
+
id: 'path_temp',
|
|
971
|
+
destEntity: 'user',
|
|
972
|
+
sourceEntity: 'any',
|
|
973
|
+
value: '',
|
|
974
|
+
$$createAt$$: 1,
|
|
975
|
+
$$updateAt$$: 1,
|
|
976
|
+
$$seq$$: 'temp',
|
|
977
|
+
recursive: false,
|
|
978
|
+
},
|
|
915
979
|
$$createAt$$: 1,
|
|
916
980
|
$$updateAt$$: 1,
|
|
917
981
|
$$seq$$: 'temp',
|
|
918
|
-
destEntity: 'user',
|
|
919
982
|
deActions: [node.action],
|
|
920
983
|
});
|
|
921
984
|
}
|
|
922
985
|
return checkChildren(result2);
|
|
923
986
|
};
|
|
924
987
|
if (result instanceof Promise) {
|
|
925
|
-
return result.then(
|
|
988
|
+
return result.then((r2) => checkResult(r2));
|
|
926
989
|
}
|
|
927
990
|
return checkResult(result);
|
|
928
991
|
};
|
|
929
992
|
return checkNode(tree);
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
const checkChildNode = (actionAuths: ED['actionAuth']['Schema'][] | Promise<ED['actionAuth']['Schema'][]>, node: OperationTree<ED>): boolean | Promise<boolean> => {
|
|
935
|
-
const checkChildNodeInner = (legalAuths: ED['actionAuth']['Schema'][]) => {
|
|
936
|
-
// 因为如果children是数组的话,会把数组中所有的action并起来查询,所以在这里还要再确认一次
|
|
937
|
-
|
|
938
|
-
const realLegalPaths = legalAuths.filter(
|
|
939
|
-
(ele) => {
|
|
940
|
-
if (ele.destEntity === node.entity && ele.deActions.includes(node.action)) {
|
|
941
|
-
return true;
|
|
942
|
-
}
|
|
943
|
-
// 有一种例外情况,是在tree的根结点findActionAuthsOnNode时,deduce出了另外一个对象的权限,此时肯定可以通过,但不能再使用这条路径对children进行进一步判断了
|
|
944
|
-
if (node === tree) {
|
|
945
|
-
return true;
|
|
946
|
-
}
|
|
947
|
-
return false;
|
|
948
|
-
}
|
|
949
|
-
);
|
|
950
|
-
const checkChildren = () => {
|
|
951
|
-
const { children } = node;
|
|
952
|
-
const childPath = Object.keys(children);
|
|
953
|
-
if (childPath.length === 0) {
|
|
954
|
-
return true;
|
|
955
|
-
}
|
|
956
|
-
|
|
957
|
-
const selfLegalPaths = realLegalPaths.filter(
|
|
958
|
-
(ele) => {
|
|
959
|
-
if (ele.destEntity === node.entity && ele.deActions.includes(node.action)) {
|
|
960
|
-
return true;
|
|
961
|
-
}
|
|
962
|
-
return false;
|
|
963
|
-
}
|
|
964
|
-
);
|
|
965
|
-
// assert(selfLegalPaths.length > 0, `对象${node.entity as string}的权限检查是用deduce的对象通过的,无法再进一步对子对象加以判断`);
|
|
966
|
-
const childResult = childPath.map(
|
|
967
|
-
(childPath) => {
|
|
968
|
-
const child = children[childPath];
|
|
969
|
-
const childEntity = child instanceof Array ? child[0].entity : child.entity;
|
|
970
|
-
// 这里如果该子结点能deduce到父,则直接通过
|
|
971
|
-
if (this.authDeduceRelationMap[childEntity]) {
|
|
972
|
-
assert(this.authDeduceRelationMap[childEntity] === 'entity');
|
|
973
|
-
const rel = judgeRelation(this.schema, childEntity, childPath);
|
|
974
|
-
if (rel === 2) {
|
|
975
|
-
return true;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
const pathToParent = childPath.endsWith('$entity') ? node.entity as string : childPath.split('$')[1];
|
|
980
|
-
if (child instanceof Array) {
|
|
981
|
-
const childActions = child.map(ele => ele.action);
|
|
982
|
-
const childLegalAuths = selfLegalPaths.map(
|
|
983
|
-
(ele) => {
|
|
984
|
-
const { paths, relationId } = ele;
|
|
985
|
-
const paths2 = paths.map(
|
|
986
|
-
(path) => path ? `${pathToParent}.${path}` : pathToParent
|
|
987
|
-
);
|
|
988
|
-
return context.select('actionAuth', {
|
|
989
|
-
data: {
|
|
990
|
-
id: 1,
|
|
991
|
-
},
|
|
992
|
-
filter: {
|
|
993
|
-
paths: {
|
|
994
|
-
$overlaps: paths2,
|
|
995
|
-
},
|
|
996
|
-
destEntity: childEntity as string,
|
|
997
|
-
deActions: {
|
|
998
|
-
$overlaps: childActions,
|
|
999
|
-
},
|
|
1000
|
-
relationId: relationId || {
|
|
1001
|
-
$exists: false,
|
|
1002
|
-
},
|
|
1003
|
-
}
|
|
1004
|
-
}, { dontCollect: true })
|
|
1005
|
-
}
|
|
1006
|
-
).flat() as ED['actionAuth']['Schema'][] | Promise<ED['actionAuth']['Schema']>[];
|
|
1007
|
-
if (childLegalAuths[0] instanceof Promise) {
|
|
1008
|
-
return Promise.all(childLegalAuths).then(
|
|
1009
|
-
(clas) => child.map(
|
|
1010
|
-
(c) => checkChildNode(clas, c)
|
|
1011
|
-
)
|
|
1012
|
-
)
|
|
1013
|
-
}
|
|
1014
|
-
return child.map(
|
|
1015
|
-
(c) => checkChildNode(childLegalAuths as ED['actionAuth']['Schema'][], c)
|
|
1016
|
-
);
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
const childLegalAuths = realLegalPaths.map(
|
|
1020
|
-
(ele) => {
|
|
1021
|
-
const { paths, relationId } = ele;
|
|
1022
|
-
const paths2 = paths.map(
|
|
1023
|
-
(path) => path ? `${pathToParent}.${path}` : pathToParent
|
|
1024
|
-
);
|
|
1025
|
-
return context.select('actionAuth', {
|
|
1026
|
-
data: {
|
|
1027
|
-
id: 1,
|
|
1028
|
-
},
|
|
1029
|
-
filter: {
|
|
1030
|
-
paths: {
|
|
1031
|
-
$overlaps: paths2,
|
|
1032
|
-
},
|
|
1033
|
-
destEntity: childEntity as string,
|
|
1034
|
-
deActions: {
|
|
1035
|
-
$overlaps: child.action,
|
|
1036
|
-
},
|
|
1037
|
-
relationId: relationId || {
|
|
1038
|
-
$exists: false,
|
|
1039
|
-
},
|
|
1040
|
-
}
|
|
1041
|
-
}, { dontCollect: true })
|
|
1042
|
-
}
|
|
1043
|
-
).flat() as ED['actionAuth']['Schema'][] | Promise<ED['actionAuth']['Schema']>[];
|
|
1044
|
-
|
|
1045
|
-
if (childLegalAuths[0] instanceof Promise) {
|
|
1046
|
-
return Promise.all(childLegalAuths).then(
|
|
1047
|
-
(clas) => checkChildNode(clas.flat(), child)
|
|
1048
|
-
);
|
|
1049
|
-
}
|
|
1050
|
-
return checkChildNode(childLegalAuths as ED['actionAuth']['Schema'][], child);
|
|
1051
|
-
}
|
|
1052
|
-
).flat();
|
|
1053
|
-
|
|
1054
|
-
if (childResult[0] instanceof Promise) {
|
|
1055
|
-
return Promise.all(childResult).then(
|
|
1056
|
-
(r) => !r.includes(false)
|
|
1057
|
-
);
|
|
1058
|
-
}
|
|
1059
|
-
return !childResult.includes(false);
|
|
1060
|
-
};
|
|
1061
|
-
|
|
1062
|
-
if (RelationAuth.SPECIAL_ENTITIES.includes(node.entity as string)) {
|
|
1063
|
-
// 特殊entity走特别的路径判断
|
|
1064
|
-
const result = this.checkOperateSpecialEntities2(node.entity, node.action, node.filter, context);
|
|
1065
|
-
|
|
1066
|
-
if (result instanceof Promise) {
|
|
1067
|
-
return result.then(
|
|
1068
|
-
(r) => {
|
|
1069
|
-
if (r) {
|
|
1070
|
-
return checkChildren();
|
|
1071
|
-
}
|
|
1072
|
-
return false;
|
|
1073
|
-
}
|
|
1074
|
-
);
|
|
1075
|
-
}
|
|
1076
|
-
if (result) {
|
|
1077
|
-
if (node.entity === 'user') {
|
|
1078
|
-
// 如果当前是对user对象操作,需要加上一个指向它自身的actionAuth,否则剩下的子对象会判定不过
|
|
1079
|
-
// user的操作权限由应用自己决定,如果user的操作最终过不去,这里放过也没关系
|
|
1080
|
-
assert(node === tree && realLegalPaths.length === 0); // user不可能是非根结点
|
|
1081
|
-
realLegalPaths.push({
|
|
1082
|
-
id: 'temp',
|
|
1083
|
-
paths: [''],
|
|
1084
|
-
$$createAt$$: 1,
|
|
1085
|
-
$$updateAt$$: 1,
|
|
1086
|
-
$$seq$$: 'temp',
|
|
1087
|
-
destEntity: 'user',
|
|
1088
|
-
deActions: [node.action],
|
|
1089
|
-
});
|
|
1090
|
-
}
|
|
1091
|
-
return checkChildren();
|
|
1092
|
-
}
|
|
1093
|
-
if (process.env.NODE_ENV === 'development') {
|
|
1094
|
-
console.warn('对象operate权限检查不通过', node);
|
|
1095
|
-
}
|
|
1096
|
-
return false;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
if (realLegalPaths.length === 0) {
|
|
1100
|
-
if (node === tree) {
|
|
1101
|
-
if (process.env.NODE_ENV === 'development') {
|
|
1102
|
-
console.warn('对象operate权限检查不通过', node);
|
|
1103
|
-
}
|
|
1104
|
-
return false;
|
|
1105
|
-
}
|
|
1106
|
-
// 如果不是tree的根结点,相对路径上的actionAuth找不到,还可以尝试从自身的filter去重试其它路径
|
|
1107
|
-
return this.checkOperationTree(node, context);
|
|
1108
|
-
}
|
|
1109
|
-
|
|
1110
|
-
return checkChildren();
|
|
1111
|
-
};
|
|
1112
|
-
|
|
1113
|
-
if (actionAuths instanceof Promise) {
|
|
1114
|
-
return actionAuths.then(
|
|
1115
|
-
(aars) => checkChildNodeInner(aars)
|
|
1116
|
-
);
|
|
1117
|
-
}
|
|
1118
|
-
return checkChildNodeInner(actionAuths);
|
|
1119
|
-
};
|
|
1120
|
-
|
|
1121
|
-
return checkChildNode(actionAuths2, tree);
|
|
1122
|
-
} */
|
|
1123
|
-
RelationAuth.prototype.checkOperation = function (entity, operation, context) {
|
|
1124
|
-
var action = operation.action, filter = operation.filter, data = operation.data;
|
|
1125
|
-
if (action === 'create' && this.createFreeEntities.includes(entity)) {
|
|
1126
|
-
return true;
|
|
1127
|
-
}
|
|
1128
|
-
else if (action === 'update' && this.updateFreeEntities.includes(entity)) {
|
|
993
|
+
}
|
|
994
|
+
checkOperation(entity, operation, context) {
|
|
995
|
+
const { action, filter, data } = operation;
|
|
996
|
+
if (this.updateFreeDict[entity] && this.updateFreeDict[entity].includes(action)) {
|
|
1129
997
|
return true;
|
|
1130
998
|
}
|
|
1131
|
-
|
|
999
|
+
const userId = context.getCurrentUserId();
|
|
1132
1000
|
if (!userId) {
|
|
1133
1001
|
throw new types_1.OakUnloggedInException();
|
|
1134
1002
|
}
|
|
@@ -1138,9 +1006,9 @@ var RelationAuth = /** @class */ (function () {
|
|
|
1138
1006
|
}
|
|
1139
1007
|
return false;
|
|
1140
1008
|
}
|
|
1141
|
-
|
|
1009
|
+
const updateTree = this.destructOperation(entity, operation, userId);
|
|
1142
1010
|
return this.checkOperationTree2(updateTree, context);
|
|
1143
|
-
}
|
|
1011
|
+
}
|
|
1144
1012
|
/**
|
|
1145
1013
|
* 检查一个operation是否能被通过权限测试
|
|
1146
1014
|
* 一个cascadeOperation是一棵树形结构:
|
|
@@ -1153,25 +1021,25 @@ var RelationAuth = /** @class */ (function () {
|
|
|
1153
1021
|
* @param actions
|
|
1154
1022
|
* @returns
|
|
1155
1023
|
*/
|
|
1156
|
-
|
|
1157
|
-
|
|
1024
|
+
checkActions2(entity, operation, context, actions) {
|
|
1025
|
+
const { action } = operation;
|
|
1158
1026
|
if (!action || action_1.readOnlyActions.includes(action)) {
|
|
1159
|
-
|
|
1027
|
+
const result = this.checkSelection(entity, operation, context);
|
|
1160
1028
|
if (result instanceof Promise) {
|
|
1161
|
-
return result.then(
|
|
1029
|
+
return result.then((r) => {
|
|
1162
1030
|
if (!r) {
|
|
1163
|
-
throw new types_1.
|
|
1031
|
+
throw new types_1.OakUserInvisibleException();
|
|
1164
1032
|
}
|
|
1165
1033
|
});
|
|
1166
1034
|
}
|
|
1167
1035
|
if (!result) {
|
|
1168
|
-
throw new types_1.
|
|
1036
|
+
throw new types_1.OakUserInvisibleException();
|
|
1169
1037
|
}
|
|
1170
1038
|
}
|
|
1171
1039
|
else {
|
|
1172
|
-
|
|
1040
|
+
const result = this.checkOperation(entity, operation, context);
|
|
1173
1041
|
if (result instanceof Promise) {
|
|
1174
|
-
return result.then(
|
|
1042
|
+
return result.then((r) => {
|
|
1175
1043
|
if (!r) {
|
|
1176
1044
|
throw new types_1.OakUserUnpermittedException();
|
|
1177
1045
|
}
|
|
@@ -1181,10 +1049,8 @@ var RelationAuth = /** @class */ (function () {
|
|
|
1181
1049
|
throw new types_1.OakUserUnpermittedException();
|
|
1182
1050
|
}
|
|
1183
1051
|
}
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
return RelationAuth;
|
|
1187
|
-
}());
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1188
1054
|
exports.RelationAuth = RelationAuth;
|
|
1189
1055
|
;
|
|
1190
1056
|
/**
|
|
@@ -1193,300 +1059,276 @@ exports.RelationAuth = RelationAuth;
|
|
|
1193
1059
|
* @param context
|
|
1194
1060
|
* todo paths改成复数以后这里还未充分测试过
|
|
1195
1061
|
*/
|
|
1196
|
-
function getUserRelationsByActions(params, context) {
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1062
|
+
async function getUserRelationsByActions(params, context) {
|
|
1063
|
+
const { entity, filter, actions, overlap } = params;
|
|
1064
|
+
const actionAuthfilter = {
|
|
1065
|
+
path: {
|
|
1066
|
+
destEntity: entity,
|
|
1067
|
+
},
|
|
1068
|
+
};
|
|
1069
|
+
if (overlap) {
|
|
1070
|
+
Object.assign(actionAuthfilter, {
|
|
1071
|
+
deActions: {
|
|
1072
|
+
$overlaps: actions,
|
|
1073
|
+
},
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
else {
|
|
1077
|
+
Object.assign(actionAuthfilter, {
|
|
1078
|
+
deActions: {
|
|
1079
|
+
$contains: actions,
|
|
1080
|
+
},
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
const actionAuths = await context.select('actionAuth', {
|
|
1084
|
+
data: {
|
|
1085
|
+
id: 1,
|
|
1086
|
+
path: {
|
|
1087
|
+
id: 1,
|
|
1088
|
+
value: 1,
|
|
1089
|
+
destEntity: 1,
|
|
1090
|
+
recursive: 1,
|
|
1091
|
+
},
|
|
1092
|
+
relationId: 1,
|
|
1093
|
+
relation: {
|
|
1094
|
+
id: 1,
|
|
1095
|
+
entity: 1,
|
|
1096
|
+
},
|
|
1097
|
+
},
|
|
1098
|
+
filter: actionAuthfilter,
|
|
1099
|
+
}, { dontCollect: true });
|
|
1100
|
+
const getUserRelations = async (urAuths) => {
|
|
1101
|
+
const makeRelationIterator = (path, relationIds, recursive) => {
|
|
1102
|
+
(0, assert_1.default)(!recursive, 'recursive的情况还没处理,等跑出来再说, by Xc');
|
|
1103
|
+
if (path === '') {
|
|
1104
|
+
return {
|
|
1105
|
+
projection: {
|
|
1106
|
+
id: 1,
|
|
1107
|
+
userRelation$entity: {
|
|
1108
|
+
$entity: 'userRelation',
|
|
1222
1109
|
data: {
|
|
1223
1110
|
id: 1,
|
|
1224
|
-
paths: 1,
|
|
1225
1111
|
relationId: 1,
|
|
1226
1112
|
relation: {
|
|
1227
1113
|
id: 1,
|
|
1228
|
-
|
|
1114
|
+
name: 1,
|
|
1229
1115
|
},
|
|
1116
|
+
entity: 1,
|
|
1117
|
+
entityId: 1,
|
|
1118
|
+
userId: 1,
|
|
1230
1119
|
},
|
|
1231
|
-
filter:
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
}
|
|
1268
|
-
},
|
|
1269
|
-
getData: function (d) {
|
|
1270
|
-
return d.userRelation$entity;
|
|
1271
|
-
},
|
|
1272
|
-
};
|
|
1273
|
-
}
|
|
1274
|
-
var attr = paths[idx];
|
|
1275
|
-
var rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
|
|
1276
|
-
if (rel === 2) {
|
|
1277
|
-
var _d = makeIter(attr, idx + 1), projection = _d.projection, getData_1 = _d.getData;
|
|
1278
|
-
return {
|
|
1279
|
-
projection: (_a = {
|
|
1280
|
-
id: 1
|
|
1281
|
-
},
|
|
1282
|
-
_a[attr] = projection,
|
|
1283
|
-
_a),
|
|
1284
|
-
getData: function (d) { return d[attr] && getData_1(d[attr]); },
|
|
1285
|
-
};
|
|
1286
|
-
}
|
|
1287
|
-
else if (typeof rel === 'string') {
|
|
1288
|
-
var _e = makeIter(rel, idx + 1), projection = _e.projection, getData_2 = _e.getData;
|
|
1289
|
-
return {
|
|
1290
|
-
projection: (_b = {
|
|
1291
|
-
id: 1
|
|
1292
|
-
},
|
|
1293
|
-
_b[attr] = projection,
|
|
1294
|
-
_b),
|
|
1295
|
-
getData: function (d) { return d[attr] && getData_2(d[attr]); },
|
|
1296
|
-
};
|
|
1297
|
-
}
|
|
1298
|
-
else {
|
|
1299
|
-
(0, assert_1.default)(rel instanceof Array);
|
|
1300
|
-
var _f = tslib_1.__read(rel, 2), e2 = _f[0], fk = _f[1];
|
|
1301
|
-
var _g = makeIter(e2, idx + 1), projection = _g.projection, getData_3 = _g.getData;
|
|
1302
|
-
return {
|
|
1303
|
-
projection: (_c = {
|
|
1304
|
-
id: 1
|
|
1305
|
-
},
|
|
1306
|
-
_c[attr] = {
|
|
1307
|
-
$entity: e2,
|
|
1308
|
-
data: projection,
|
|
1309
|
-
},
|
|
1310
|
-
_c),
|
|
1311
|
-
getData: function (d) { return d[attr] && d[attr].map(function (ele) { return getData_3(ele); }); },
|
|
1312
|
-
};
|
|
1313
|
-
}
|
|
1314
|
-
};
|
|
1315
|
-
return makeIter(entity, 0);
|
|
1316
|
-
};
|
|
1317
|
-
urAuthDict2 = {};
|
|
1318
|
-
urAuths.forEach(function (auth) {
|
|
1319
|
-
var paths = auth.paths, relationId = auth.relationId;
|
|
1320
|
-
paths.forEach(function (path) {
|
|
1321
|
-
if (!urAuthDict2[path]) {
|
|
1322
|
-
urAuthDict2[path] = [relationId];
|
|
1323
|
-
}
|
|
1324
|
-
else if (!urAuthDict2[path].includes(relationId)) {
|
|
1325
|
-
urAuthDict2[path].push(relationId);
|
|
1326
|
-
}
|
|
1327
|
-
});
|
|
1328
|
-
});
|
|
1329
|
-
return [4 /*yield*/, Promise.all(Object.keys(urAuthDict2).map(function (path) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1330
|
-
var relationIds, _a, projection, getData, rows, urs;
|
|
1331
|
-
return tslib_1.__generator(this, function (_b) {
|
|
1332
|
-
switch (_b.label) {
|
|
1333
|
-
case 0:
|
|
1334
|
-
relationIds = urAuthDict2[path];
|
|
1335
|
-
_a = makeRelationIterator(path, relationIds), projection = _a.projection, getData = _a.getData;
|
|
1336
|
-
return [4 /*yield*/, context.select(entity, {
|
|
1337
|
-
data: projection,
|
|
1338
|
-
filter: filter,
|
|
1339
|
-
}, { dontCollect: true })];
|
|
1340
|
-
case 1:
|
|
1341
|
-
rows = _b.sent();
|
|
1342
|
-
urs = rows.map(function (ele) { return getData(ele); }).flat().filter(function (ele) { return !!ele; });
|
|
1343
|
-
return [2 /*return*/, urs];
|
|
1344
|
-
}
|
|
1345
|
-
});
|
|
1346
|
-
}); }))];
|
|
1347
|
-
case 1:
|
|
1348
|
-
userRelations = _a.sent();
|
|
1349
|
-
return [2 /*return*/, userRelations.flat()];
|
|
1350
|
-
}
|
|
1351
|
-
});
|
|
1352
|
-
}); };
|
|
1353
|
-
getDirectUserEntities = function (directAuths) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1354
|
-
var makeRelationIterator, userEntities;
|
|
1355
|
-
var _this = this;
|
|
1356
|
-
return tslib_1.__generator(this, function (_a) {
|
|
1357
|
-
switch (_a.label) {
|
|
1358
|
-
case 0:
|
|
1359
|
-
makeRelationIterator = function (path) {
|
|
1360
|
-
var paths = path.split('.');
|
|
1361
|
-
var makeIter = function (e, idx) {
|
|
1362
|
-
var _a, _b, _c, _d;
|
|
1363
|
-
var attr = paths[idx];
|
|
1364
|
-
var rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
|
|
1365
|
-
if (idx === paths.length - 1) {
|
|
1366
|
-
if (rel === 2) {
|
|
1367
|
-
(0, assert_1.default)(attr === 'user');
|
|
1368
|
-
return {
|
|
1369
|
-
projection: {
|
|
1370
|
-
id: 1,
|
|
1371
|
-
entity: 1,
|
|
1372
|
-
entityId: 1,
|
|
1373
|
-
},
|
|
1374
|
-
getData: function (d) {
|
|
1375
|
-
if (d) {
|
|
1376
|
-
return {
|
|
1377
|
-
entity: e,
|
|
1378
|
-
entityId: d.id,
|
|
1379
|
-
userId: d.entityId,
|
|
1380
|
-
};
|
|
1381
|
-
}
|
|
1382
|
-
},
|
|
1383
|
-
};
|
|
1384
|
-
}
|
|
1385
|
-
else {
|
|
1386
|
-
(0, assert_1.default)(rel === 'user');
|
|
1387
|
-
return {
|
|
1388
|
-
projection: (_a = {
|
|
1389
|
-
id: 1
|
|
1390
|
-
},
|
|
1391
|
-
_a["".concat(attr, "Id")] = 1,
|
|
1392
|
-
_a),
|
|
1393
|
-
getData: function (d) {
|
|
1394
|
-
if (d) {
|
|
1395
|
-
return {
|
|
1396
|
-
entity: e,
|
|
1397
|
-
entityId: d.id,
|
|
1398
|
-
userId: d["".concat(attr, "Id")]
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
},
|
|
1402
|
-
};
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
if (rel === 2) {
|
|
1406
|
-
var _e = makeIter(attr, idx + 1), projection = _e.projection, getData_4 = _e.getData;
|
|
1407
|
-
return {
|
|
1408
|
-
projection: (_b = {
|
|
1409
|
-
id: 1
|
|
1410
|
-
},
|
|
1411
|
-
_b[attr] = projection,
|
|
1412
|
-
_b),
|
|
1413
|
-
getData: function (d) { return d[attr] && getData_4(d[attr]); },
|
|
1414
|
-
};
|
|
1415
|
-
}
|
|
1416
|
-
else if (typeof rel === 'string') {
|
|
1417
|
-
var _f = makeIter(rel, idx + 1), projection = _f.projection, getData_5 = _f.getData;
|
|
1418
|
-
return {
|
|
1419
|
-
projection: (_c = {
|
|
1420
|
-
id: 1
|
|
1421
|
-
},
|
|
1422
|
-
_c[attr] = projection,
|
|
1423
|
-
_c),
|
|
1424
|
-
getData: function (d) { return d[attr] && getData_5(d[attr]); },
|
|
1425
|
-
};
|
|
1426
|
-
}
|
|
1427
|
-
else {
|
|
1428
|
-
(0, assert_1.default)(rel instanceof Array);
|
|
1429
|
-
var _g = tslib_1.__read(rel, 2), e2 = _g[0], fk = _g[1];
|
|
1430
|
-
var _h = makeIter(e2, idx + 1), projection = _h.projection, getData_6 = _h.getData;
|
|
1431
|
-
return {
|
|
1432
|
-
projection: (_d = {
|
|
1433
|
-
id: 1
|
|
1434
|
-
},
|
|
1435
|
-
_d[attr] = {
|
|
1436
|
-
$entity: e2,
|
|
1437
|
-
data: projection,
|
|
1438
|
-
},
|
|
1439
|
-
_d),
|
|
1440
|
-
getData: function (d) { return d[attr] && d[attr].map(function (ele) { return getData_6(ele); }); },
|
|
1441
|
-
};
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
return makeIter(entity, 0);
|
|
1445
|
-
};
|
|
1446
|
-
return [4 /*yield*/, Promise.all(directAuths.map(function (_a) {
|
|
1447
|
-
var paths = _a.paths;
|
|
1448
|
-
return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1449
|
-
var _this = this;
|
|
1450
|
-
return tslib_1.__generator(this, function (_b) {
|
|
1451
|
-
return [2 /*return*/, paths.map(function (path) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1452
|
-
var _a, getData, projection, rows, userEntities;
|
|
1453
|
-
return tslib_1.__generator(this, function (_b) {
|
|
1454
|
-
switch (_b.label) {
|
|
1455
|
-
case 0:
|
|
1456
|
-
_a = makeRelationIterator(path), getData = _a.getData, projection = _a.projection;
|
|
1457
|
-
return [4 /*yield*/, context.select(entity, {
|
|
1458
|
-
data: projection,
|
|
1459
|
-
filter: filter,
|
|
1460
|
-
}, { dontCollect: true })];
|
|
1461
|
-
case 1:
|
|
1462
|
-
rows = _b.sent();
|
|
1463
|
-
userEntities = rows.map(function (ele) { return getData(ele); }).flat().filter(function (ele) { return !!ele; });
|
|
1464
|
-
return [2 /*return*/, userEntities];
|
|
1465
|
-
}
|
|
1466
|
-
});
|
|
1467
|
-
}); })];
|
|
1468
|
-
});
|
|
1469
|
-
});
|
|
1470
|
-
}))];
|
|
1471
|
-
case 1:
|
|
1472
|
-
userEntities = _a.sent();
|
|
1473
|
-
return [2 /*return*/, userEntities.flat()];
|
|
1120
|
+
filter: {
|
|
1121
|
+
relationId: {
|
|
1122
|
+
$in: relationIds,
|
|
1123
|
+
},
|
|
1124
|
+
},
|
|
1125
|
+
},
|
|
1126
|
+
},
|
|
1127
|
+
getData: (d) => {
|
|
1128
|
+
return d.userRelation$entity;
|
|
1129
|
+
},
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
const paths = path.split('.');
|
|
1133
|
+
const makeIter = (e, idx) => {
|
|
1134
|
+
if (idx === paths.length) {
|
|
1135
|
+
return {
|
|
1136
|
+
projection: {
|
|
1137
|
+
id: 1,
|
|
1138
|
+
userRelation$entity: {
|
|
1139
|
+
$entity: 'userRelation',
|
|
1140
|
+
data: {
|
|
1141
|
+
id: 1,
|
|
1142
|
+
relationId: 1,
|
|
1143
|
+
relation: {
|
|
1144
|
+
id: 1,
|
|
1145
|
+
name: 1,
|
|
1146
|
+
},
|
|
1147
|
+
entity: 1,
|
|
1148
|
+
entityId: 1,
|
|
1149
|
+
userId: 1,
|
|
1150
|
+
},
|
|
1151
|
+
filter: {
|
|
1152
|
+
relationId: {
|
|
1153
|
+
$in: relationIds,
|
|
1154
|
+
},
|
|
1155
|
+
},
|
|
1474
1156
|
}
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1157
|
+
},
|
|
1158
|
+
getData: (d) => {
|
|
1159
|
+
return d.userRelation$entity;
|
|
1160
|
+
},
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
const attr = paths[idx];
|
|
1164
|
+
const rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
|
|
1165
|
+
if (rel === 2) {
|
|
1166
|
+
const { projection, getData } = makeIter(attr, idx + 1);
|
|
1167
|
+
return {
|
|
1168
|
+
projection: {
|
|
1169
|
+
id: 1,
|
|
1170
|
+
[attr]: projection,
|
|
1171
|
+
},
|
|
1172
|
+
getData: (d) => d[attr] && getData(d[attr]),
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
else if (typeof rel === 'string') {
|
|
1176
|
+
const { projection, getData } = makeIter(rel, idx + 1);
|
|
1177
|
+
return {
|
|
1178
|
+
projection: {
|
|
1179
|
+
id: 1,
|
|
1180
|
+
[attr]: projection,
|
|
1181
|
+
},
|
|
1182
|
+
getData: (d) => d[attr] && getData(d[attr]),
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
else {
|
|
1186
|
+
(0, assert_1.default)(rel instanceof Array);
|
|
1187
|
+
const [e2, fk] = rel;
|
|
1188
|
+
const { projection, getData } = makeIter(e2, idx + 1);
|
|
1189
|
+
return {
|
|
1190
|
+
projection: {
|
|
1191
|
+
id: 1,
|
|
1192
|
+
[attr]: {
|
|
1193
|
+
$entity: e2,
|
|
1194
|
+
data: projection,
|
|
1195
|
+
},
|
|
1196
|
+
},
|
|
1197
|
+
getData: (d) => d[attr] && d[attr].map((ele) => getData(ele)),
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1201
|
+
return makeIter(entity, 0);
|
|
1202
|
+
};
|
|
1203
|
+
// 相同的path可以groupBy掉
|
|
1204
|
+
const urAuthDict2 = {};
|
|
1205
|
+
urAuths.forEach((auth) => {
|
|
1206
|
+
const { path, relationId } = auth;
|
|
1207
|
+
const { value, recursive } = path;
|
|
1208
|
+
if (!urAuthDict2[value]) {
|
|
1209
|
+
urAuthDict2[value] = [[relationId], recursive];
|
|
1210
|
+
}
|
|
1211
|
+
else if (!urAuthDict2[value][0].includes(relationId)) {
|
|
1212
|
+
(0, assert_1.default)(urAuthDict2[value][1] === recursive);
|
|
1213
|
+
urAuthDict2[value][0].push(relationId);
|
|
1488
1214
|
}
|
|
1489
1215
|
});
|
|
1490
|
-
|
|
1216
|
+
const userRelations = await Promise.all(Object.keys(urAuthDict2).map(async (path) => {
|
|
1217
|
+
const [relationIds, recursive] = urAuthDict2[path];
|
|
1218
|
+
const { projection, getData } = makeRelationIterator(path, relationIds, recursive);
|
|
1219
|
+
const rows = await context.select(entity, {
|
|
1220
|
+
data: projection,
|
|
1221
|
+
filter,
|
|
1222
|
+
}, { dontCollect: true });
|
|
1223
|
+
const urs = rows.map(ele => getData(ele)).flat().filter(ele => !!ele);
|
|
1224
|
+
return urs;
|
|
1225
|
+
}));
|
|
1226
|
+
return userRelations.flat();
|
|
1227
|
+
};
|
|
1228
|
+
const getDirectUserEntities = async (directAuths) => {
|
|
1229
|
+
const makeRelationIterator = (path) => {
|
|
1230
|
+
const paths = path.split('.');
|
|
1231
|
+
const makeIter = (e, idx) => {
|
|
1232
|
+
const attr = paths[idx];
|
|
1233
|
+
const rel = (0, relation_1.judgeRelation)(context.getSchema(), e, attr);
|
|
1234
|
+
if (idx === paths.length - 1) {
|
|
1235
|
+
if (rel === 2) {
|
|
1236
|
+
(0, assert_1.default)(attr === 'user');
|
|
1237
|
+
return {
|
|
1238
|
+
projection: {
|
|
1239
|
+
id: 1,
|
|
1240
|
+
entity: 1,
|
|
1241
|
+
entityId: 1,
|
|
1242
|
+
},
|
|
1243
|
+
getData: (d) => {
|
|
1244
|
+
if (d) {
|
|
1245
|
+
return {
|
|
1246
|
+
entity: e,
|
|
1247
|
+
entityId: d.id,
|
|
1248
|
+
userId: d.entityId,
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
},
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
else {
|
|
1255
|
+
(0, assert_1.default)(rel === 'user');
|
|
1256
|
+
return {
|
|
1257
|
+
projection: {
|
|
1258
|
+
id: 1,
|
|
1259
|
+
[`${attr}Id`]: 1,
|
|
1260
|
+
},
|
|
1261
|
+
getData: (d) => {
|
|
1262
|
+
if (d) {
|
|
1263
|
+
return {
|
|
1264
|
+
entity: e,
|
|
1265
|
+
entityId: d.id,
|
|
1266
|
+
userId: d[`${attr}Id`]
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
},
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
if (rel === 2) {
|
|
1274
|
+
const { projection, getData } = makeIter(attr, idx + 1);
|
|
1275
|
+
return {
|
|
1276
|
+
projection: {
|
|
1277
|
+
id: 1,
|
|
1278
|
+
[attr]: projection,
|
|
1279
|
+
},
|
|
1280
|
+
getData: (d) => d[attr] && getData(d[attr]),
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
else if (typeof rel === 'string') {
|
|
1284
|
+
const { projection, getData } = makeIter(rel, idx + 1);
|
|
1285
|
+
return {
|
|
1286
|
+
projection: {
|
|
1287
|
+
id: 1,
|
|
1288
|
+
[attr]: projection,
|
|
1289
|
+
},
|
|
1290
|
+
getData: (d) => d[attr] && getData(d[attr]),
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
else {
|
|
1294
|
+
(0, assert_1.default)(rel instanceof Array);
|
|
1295
|
+
const [e2, fk] = rel;
|
|
1296
|
+
const { projection, getData } = makeIter(e2, idx + 1);
|
|
1297
|
+
return {
|
|
1298
|
+
projection: {
|
|
1299
|
+
id: 1,
|
|
1300
|
+
[attr]: {
|
|
1301
|
+
$entity: e2,
|
|
1302
|
+
data: projection,
|
|
1303
|
+
},
|
|
1304
|
+
},
|
|
1305
|
+
getData: (d) => d[attr] && d[attr].map((ele) => getData(ele)),
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
return makeIter(entity, 0);
|
|
1310
|
+
};
|
|
1311
|
+
const userEntities = await Promise.all(directAuths.map(async ({ path }) => {
|
|
1312
|
+
const { value, recursive } = path;
|
|
1313
|
+
(0, assert_1.default)(!recursive);
|
|
1314
|
+
const { getData, projection } = makeRelationIterator(value);
|
|
1315
|
+
const rows = await context.select(entity, {
|
|
1316
|
+
data: projection,
|
|
1317
|
+
filter,
|
|
1318
|
+
}, { dontCollect: true });
|
|
1319
|
+
const userEntities = rows.map(ele => getData(ele)).flat().filter(ele => !!ele);
|
|
1320
|
+
return userEntities;
|
|
1321
|
+
}));
|
|
1322
|
+
return userEntities.flat();
|
|
1323
|
+
};
|
|
1324
|
+
const urAuths2 = actionAuths.filter(ele => !!ele.relationId // 有relation说明通过userRelation关联
|
|
1325
|
+
);
|
|
1326
|
+
const directAuths2 = actionAuths.filter(ele => !ele.relationId // 没relation说明通过user关联
|
|
1327
|
+
);
|
|
1328
|
+
const [userRelations, userEntities] = await Promise.all([getUserRelations(urAuths2), getDirectUserEntities(directAuths2)]);
|
|
1329
|
+
return {
|
|
1330
|
+
userRelations,
|
|
1331
|
+
userEntities,
|
|
1332
|
+
};
|
|
1491
1333
|
}
|
|
1492
1334
|
exports.getUserRelationsByActions = getUserRelationsByActions;
|