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