修正了检查权限时同时存在deduce和self路径的情形,编译器处理了在检查权限时的递归处理和同时存在deduce/self的处理
This commit is contained in:
parent
4f0654a039
commit
ff1d1cfe8c
|
|
@ -47,6 +47,8 @@ export declare class RelationAuth<ED extends EntityDict & BaseEntityDict> {
|
|||
*/
|
||||
private getGrantedRelationIds;
|
||||
private checkSpecialEntity;
|
||||
private tryCheckDeducedAuth;
|
||||
private tryCheckSelfAuth;
|
||||
private checkActions;
|
||||
checkRelationAsync<T extends keyof ED, Cxt extends AsyncContext<ED>>(entity: T, operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt): Promise<void>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ var RelationAuth = /** @class */ (function () {
|
|||
var excludePaths = [];
|
||||
var anchors = findHighestAnchors(entity, filter2, '', excludePaths);
|
||||
if (anchors.length === 0) {
|
||||
throw new types_1.OakException('本次查询找不到锚定权限的入口,请确认查询条件合法');
|
||||
return '本次查询找不到锚定权限的入口,请确认查询条件合法';
|
||||
}
|
||||
anchors.sort(function (a1, a2) { return a2.relativePath.length - a1.relativePath.length; });
|
||||
// 将这些找到的锚点和authCascadePaths进行锚定,确认userRelation的搜索范围
|
||||
|
|
@ -675,8 +675,8 @@ var RelationAuth = /** @class */ (function () {
|
|||
// 有filter优先判断filter
|
||||
deduceEntity = filter.entity;
|
||||
deduceEntityId = filter.entityId;
|
||||
(0, assert_1.default)(deduceEntity, "".concat(entity, "\u5BF9\u8C61\u4E0A\u7684").concat(action, "\u884C\u4E3A\uFF0Cfilter\u4E2D\u5FC5\u987B\u5E26\u4E0A").concat(deduceAttr, "\u7684\u5916\u952E\u6761\u4EF6"));
|
||||
(0, assert_1.default)(deduceEntityId, "".concat(entity, "\u5BF9\u8C61\u4E0A\u7684").concat(action, "\u884C\u4E3A\uFF0Cfilter\u4E2D\u5FC5\u987B\u5E26\u4E0A").concat(deduceAttr, "Id\u7684\u5916\u952E\u6761\u4EF6"));
|
||||
// assert(deduceEntity, `${entity as string}对象上的${action}行为,filter中必须带上${deduceAttr as string}的外键条件`);
|
||||
// assert(deduceEntityId, `${entity as string}对象上的${action}行为,filter中必须带上${deduceAttr as string}Id的外键条件`);
|
||||
}
|
||||
else if (data instanceof Array) {
|
||||
try {
|
||||
|
|
@ -706,42 +706,12 @@ var RelationAuth = /** @class */ (function () {
|
|||
else {
|
||||
deduceEntity = data.entity;
|
||||
deduceEntityId = data.entityId;
|
||||
(0, assert_1.default)(deduceEntity);
|
||||
(0, assert_1.default)(deduceEntityId);
|
||||
// assert(deduceEntity);
|
||||
// assert(deduceEntityId);
|
||||
}
|
||||
var excludeActions_1 = action_1.readOnlyActions.concat(['create', 'remove']);
|
||||
var updateActions = this.schema[deduceEntity].actions.filter(function (a) { return !excludeActions_1.includes(a); });
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'update',
|
||||
data: {},
|
||||
filter: {
|
||||
id: deduceEntityId,
|
||||
},
|
||||
},
|
||||
actions: updateActions,
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 目前应该都有这两个属性,包括select
|
||||
var _b = filter, deduceEntity = _b.entity, deduceEntityId = _b.entityId;
|
||||
(0, assert_1.default)(deduceEntity, "".concat(entity, "\u5BF9\u8C61\u4E0A\u7684").concat(action, "\u884C\u4E3A\uFF0C\u5FC5\u987B\u5E26\u4E0A").concat(deduceAttr, "\u7684\u5916\u952E\u6761\u4EF6"));
|
||||
(0, assert_1.default)(deduceEntityId, "".concat(entity, "\u5BF9\u8C61\u4E0A\u7684").concat(action, "\u884C\u4E3A\uFF0C\u5FC5\u987B\u5E26\u4E0A").concat(deduceAttr, "Id\u7684\u5916\u952E\u6761\u4EF6"));
|
||||
if (action === 'select') {
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'select',
|
||||
data: { id: 1 },
|
||||
filter: { id: deduceEntityId },
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 目前对于非select和create的action,只要有其父对象的update/remove属性即可以
|
||||
var excludeActions_2 = action_1.readOnlyActions.concat(['create']);
|
||||
var updateActions = this.schema[deduceEntity].actions.filter(function (a) { return !excludeActions_2.includes(a); });
|
||||
if (deduceEntity && deduceEntityId) {
|
||||
var excludeActions_1 = action_1.readOnlyActions.concat(['create', 'remove']);
|
||||
var updateActions = this.schema[deduceEntity].actions.filter(function (a) { return !excludeActions_1.includes(a); });
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
|
|
@ -755,6 +725,40 @@ var RelationAuth = /** @class */ (function () {
|
|||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 目前应该都有这两个属性,包括select
|
||||
var _b = filter, deduceEntity = _b.entity, deduceEntityId = _b.entityId;
|
||||
// assert(deduceEntity, `${entity as string}对象上的${action}行为,必须带上${deduceAttr as string}的外键条件`);
|
||||
// assert(deduceEntityId, `${entity as string}对象上的${action}行为,必须带上${deduceAttr as string}Id的外键条件`);
|
||||
if (deduceEntity && deduceEntityId) {
|
||||
if (action === 'select') {
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'select',
|
||||
data: { id: 1 },
|
||||
filter: { id: deduceEntityId },
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 目前对于非select和create的action,只要有其父对象的update/remove属性即可以
|
||||
var excludeActions_2 = action_1.readOnlyActions.concat(['create']);
|
||||
var updateActions = this.schema[deduceEntity].actions.filter(function (a) { return !excludeActions_2.includes(a); });
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'update',
|
||||
data: {},
|
||||
filter: {
|
||||
id: deduceEntityId,
|
||||
},
|
||||
},
|
||||
actions: updateActions,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 查询当前用户在对应entity上可以操作的relationIds
|
||||
|
|
@ -814,12 +818,12 @@ var RelationAuth = /** @class */ (function () {
|
|||
switch (action) {
|
||||
case 'select': {
|
||||
if (['relation', 'actionAuth', 'relationAuth', 'user', 'userEntityGrant'].includes(entity)) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
if (entity === 'userRelation') {
|
||||
var filter = operation.filter;
|
||||
if ((filter === null || filter === void 0 ? void 0 : filter.userId) === context.getCurrentUserId()) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
// 查询某一对象的relation,意味着该用户有权利管辖该对象上至少某一种relation的操作权限
|
||||
|
|
@ -847,7 +851,7 @@ var RelationAuth = /** @class */ (function () {
|
|||
},
|
||||
},
|
||||
}, operation.filter);
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -865,12 +869,13 @@ var RelationAuth = /** @class */ (function () {
|
|||
if (destRelations instanceof Promise) {
|
||||
return destRelations.then(function (r2) {
|
||||
if (!r2.find(function (ele) { return ele.id === relationId_1; })) {
|
||||
throw new types_1.OakUserUnpermittedException("\u5F53\u524D\u7528\u6237\u6CA1\u6709\u4E3Aid\u4E3A\u300C".concat(entityId_1, "\u300D\u7684\u300C").concat(entity_3, "\u300D\u5BF9\u8C61\u521B\u5EFA\u300C").concat(relationId_1, "\u300D\u4EBA\u5458\u5173\u7CFB\u7684\u6743\u9650"));
|
||||
return "\u5F53\u524D\u7528\u6237\u6CA1\u6709\u4E3Aid\u4E3A\u300C".concat(entityId_1, "\u300D\u7684\u300C").concat(entity_3, "\u300D\u5BF9\u8C61\u521B\u5EFA\u300C").concat(relationId_1, "\u300D\u4EBA\u5458\u5173\u7CFB\u7684\u6743\u9650");
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
if (!destRelations.find(function (ele) { return ele.id === relationId_1; })) {
|
||||
throw new types_1.OakUserUnpermittedException("\u5F53\u524D\u7528\u6237\u6CA1\u6709\u4E3Aid\u4E3A\u300C".concat(entityId_1, "\u300D\u7684\u300C").concat(entity_3, "\u300D\u5BF9\u8C61\u521B\u5EFA\u300C").concat(relationId_1, "\u300D\u4EBA\u5458\u5173\u7CFB\u7684\u6743\u9650"));
|
||||
return "\u5F53\u524D\u7528\u6237\u6CA1\u6709\u4E3Aid\u4E3A\u300C".concat(entityId_1, "\u300D\u7684\u300C").concat(entity_3, "\u300D\u5BF9\u8C61\u521B\u5EFA\u300C").concat(relationId_1, "\u300D\u4EBA\u5458\u5173\u7CFB\u7684\u6743\u9650");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -901,7 +906,7 @@ var RelationAuth = /** @class */ (function () {
|
|||
},
|
||||
}, filter);
|
||||
}
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
case 'user': {
|
||||
// 对用户的操作由应用自己去管理权限,这里只检查grant/revoke
|
||||
|
|
@ -912,13 +917,13 @@ var RelationAuth = /** @class */ (function () {
|
|||
if (userRelation$user instanceof Array) {
|
||||
var result = userRelation$user.map(function (ur) { return checkUrOperation_1(ur); });
|
||||
if (result[0] instanceof Promise) {
|
||||
return Promise.all(result);
|
||||
return Promise.all(result).then(function (r2) { return r2.join(''); });
|
||||
}
|
||||
return;
|
||||
return result.join('');
|
||||
}
|
||||
return checkUrOperation_1(userRelation$user);
|
||||
}
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
|
|
@ -929,13 +934,21 @@ var RelationAuth = /** @class */ (function () {
|
|||
}
|
||||
(0, assert_1.default)(false, "".concat(entity, "\u7684").concat(action, "\u6743\u9650\u8FD8\u672A\u8BE6\u5316\u5904\u7406"));
|
||||
};
|
||||
RelationAuth.prototype.checkActions = function (entity, operation, context, actions) {
|
||||
RelationAuth.prototype.tryCheckDeducedAuth = function (entity, operation, context, actions) {
|
||||
if (this.authDeduceRelationMap[entity]) {
|
||||
var deducedResult = this.getDeducedCheckOperation(entity, operation);
|
||||
if (deducedResult) {
|
||||
var deduceEntity = deducedResult.entity, deduceOperation = deducedResult.operation, deduceActions = deducedResult.actions;
|
||||
(0, assert_1.default)(!this.authDeduceRelationMap[deduceEntity], '目前不应出现连续的deduceRelationAuth');
|
||||
return this.tryCheckSelfAuth(deduceEntity, deduceOperation, context, deduceActions);
|
||||
}
|
||||
return "".concat(entity, "\u4E0A\u867D\u7136\u6709deduce\u6743\u9650\u4F46\u4E0D\u5B58\u5728\u76F8\u5E94\u7684\u67E5\u8BE2\u8DEF\u5F84");
|
||||
}
|
||||
return "".concat(entity, "\u4E0A\u4E0D\u5B58\u5728\u6709\u6548\u7684deduce\u6743\u9650");
|
||||
};
|
||||
RelationAuth.prototype.tryCheckSelfAuth = function (entity, operation, context, actions) {
|
||||
var action = operation.action || 'select';
|
||||
var userId = context.getCurrentUserId();
|
||||
if (this.authDeduceRelationMap[entity]) {
|
||||
var _a = this.getDeducedCheckOperation(entity, operation), deduceEntity = _a.entity, deduceOperation = _a.operation, actions_1 = _a.actions;
|
||||
return this.checkActions(deduceEntity, deduceOperation, context, actions_1);
|
||||
}
|
||||
if (action === 'select') {
|
||||
// select的权限检查发生在每次cascadeSelect时,如果有多对一的join,被join的实体不需要检查
|
||||
if (['user', 'relation', 'oper', 'operEntity', 'modi', 'modiEntity', 'userRelation', 'actionAuth',
|
||||
|
|
@ -946,23 +959,27 @@ var RelationAuth = /** @class */ (function () {
|
|||
throw new types_1.OakUserUnpermittedException("\u5904\u7406".concat(entity, "\u4E0A\u4E0D\u5B58\u5728\u6709\u6548\u7684actionPath"));
|
||||
}
|
||||
var checker = this.relationalChecker[entity](userId, actions || ['select'], undefined, operation.filter);
|
||||
if (typeof checker === 'string') {
|
||||
return checker;
|
||||
}
|
||||
var result = checker(context, true);
|
||||
if (result instanceof Promise) {
|
||||
return result.then(function (r2) {
|
||||
if (r2.length === 0) {
|
||||
throw new types_1.OakUserUnpermittedException("\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743"));
|
||||
return "\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743");
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
if (result.length === 0) {
|
||||
throw new types_1.OakUserUnpermittedException("\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743"));
|
||||
return "\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// operate的权限检查只发生一次,需要在这次检查中将所有cascade的对象的权限检查完成
|
||||
// 算法是先将整个update的根结点对象找到,并找到为其赋权的relation,再用此relation去查找所有子对象上的actionAuth
|
||||
var result = [];
|
||||
var _b = this.destructCascadeOperation(entity, operation), root = _b.root, children_1 = _b.children, userRelations = _b.userRelations;
|
||||
var _a = this.destructCascadeOperation(entity, operation), root = _a.root, children_1 = _a.children, userRelations = _a.userRelations;
|
||||
var e_3 = root.entity, d = root.data, f = root.filter, a = root.action;
|
||||
if (userRelations.length > 0) {
|
||||
(0, assert_1.default)(e_3 !== 'user');
|
||||
|
|
@ -987,15 +1004,16 @@ var RelationAuth = /** @class */ (function () {
|
|||
var relationIds = aas2.map(function (ele) { return ele.relationId; });
|
||||
var diff = (0, lodash_1.difference)(createIds_1, relationIds);
|
||||
if (diff.length > 0) {
|
||||
throw new types_1.OakUserUnpermittedException("\u60A8\u65E0\u6743\u521B\u5EFA\u300C".concat(e_3, "\u300D\u5BF9\u8C61\u4E0Aid\u4E3A\u300C").concat(diff.join(','), "\u300D\u7684\u7528\u6237\u6743\u9650"));
|
||||
return "\u60A8\u65E0\u6743\u521B\u5EFA\u300C".concat(e_3, "\u300D\u5BF9\u8C61\u4E0Aid\u4E3A\u300C").concat(diff.join(','), "\u300D\u7684\u7528\u6237\u6743\u9650");
|
||||
}
|
||||
return '';
|
||||
}));
|
||||
}
|
||||
else {
|
||||
var relationIds = aas.map(function (ele) { return ele.relationId; });
|
||||
var diff = (0, lodash_1.difference)(createIds_1, relationIds);
|
||||
if (diff.length > 0) {
|
||||
throw new types_1.OakUserUnpermittedException("\u60A8\u65E0\u6743\u521B\u5EFA\u300C".concat(e_3, "\u300D\u5BF9\u8C61\u4E0Aid\u4E3A\u300C").concat(diff.join(','), "\u300D\u7684\u7528\u6237\u6743\u9650"));
|
||||
return "\u60A8\u65E0\u6743\u521B\u5EFA\u300C".concat(e_3, "\u300D\u5BF9\u8C61\u4E0Aid\u4E3A\u300C").concat(diff.join(','), "\u300D\u7684\u7528\u6237\u6743\u9650");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1016,6 +1034,9 @@ var RelationAuth = /** @class */ (function () {
|
|||
throw new types_1.OakUserUnpermittedException("".concat(root.entity, "\u4E0A\u4E0D\u5B58\u5728\u6709\u6548\u7684actionPath"));
|
||||
}
|
||||
var checker = this.relationalChecker[root.entity](userId, actions || [root.action], root.data, root.filter, userRelations);
|
||||
if (typeof checker === 'string') {
|
||||
return checker;
|
||||
}
|
||||
var r = checker(context, children_1.length === 0);
|
||||
var checkChildrenAuth_1 = function (relativePath, relationId) {
|
||||
var filters = children_1.map(function (_a) {
|
||||
|
|
@ -1051,8 +1072,9 @@ var RelationAuth = /** @class */ (function () {
|
|||
return !actionAuths.find(function (ele) { var _a; return ele.path === path && ((_a = ele.deActions) === null || _a === void 0 ? void 0 : _a.includes(action)) && ele.destEntity === entity; });
|
||||
});
|
||||
if (missedChild) {
|
||||
return new types_1.OakUserUnpermittedException("\u5BF9\u300C".concat(missedChild.entity, "\u300D\u8FDB\u884C\u300C").concat(missedChild.action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743"));
|
||||
return "\u5BF9\u300C".concat(missedChild.entity, "\u300D\u8FDB\u884C\u300C").concat(missedChild.action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743");
|
||||
}
|
||||
return '';
|
||||
};
|
||||
if (r2 instanceof Promise) {
|
||||
return r2.then(function (r3) { return checkActionAuth_1(r3); });
|
||||
|
|
@ -1061,7 +1083,7 @@ var RelationAuth = /** @class */ (function () {
|
|||
}
|
||||
else {
|
||||
// 取消directActionAuth,发现root对象能过,则子对象全部自动通过
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
};
|
||||
if (r instanceof Promise) {
|
||||
|
|
@ -1070,13 +1092,13 @@ var RelationAuth = /** @class */ (function () {
|
|||
return checkChildrenAuth_1(relativePath, relationId);
|
||||
})); }).then(function (r3) {
|
||||
if (r3.length === 0) {
|
||||
throw new types_1.OakUserUnpermittedException("\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743"));
|
||||
return "\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743");
|
||||
}
|
||||
if (r3.indexOf(undefined) >= 0) {
|
||||
if (r3.indexOf('') >= 0) {
|
||||
// 有一个过就证明能过
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
throw r3[0];
|
||||
return r3.find(function (ele) { return !!ele; });
|
||||
}));
|
||||
}
|
||||
else {
|
||||
|
|
@ -1084,18 +1106,65 @@ var RelationAuth = /** @class */ (function () {
|
|||
var relativePath = _a.relativePath, relationId = _a.relationId;
|
||||
return checkChildrenAuth_1(relativePath, relationId);
|
||||
});
|
||||
if (r3.length > 0 && r3.includes(undefined)) {
|
||||
if (r3.length > 0 && r3.includes('')) {
|
||||
// 有一个过就证明能过
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
throw r3[0] || new types_1.OakUserUnpermittedException("\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743"));
|
||||
}
|
||||
return r3.find(function (ele) { return !!ele; }) || "\u5BF9\u300C".concat(entity, "\u300D\u8FDB\u884C\u300C").concat(action, "\u300D\u64CD\u4F5C\u65F6\u627E\u4E0D\u5230\u5BF9\u5E94\u7684\u6388\u6743");
|
||||
}
|
||||
}
|
||||
if (result.length > 0) {
|
||||
return Promise.all(result);
|
||||
return Promise.all(result).then(function (r2) {
|
||||
var r3 = r2.find(function (ele) { return !!ele; });
|
||||
if (r3) {
|
||||
return r3;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
RelationAuth.prototype.checkActions = function (entity, operation, context, actions) {
|
||||
var _this = this;
|
||||
// 现在checkDeducedAuth和checkSelfAuth是一个或的关系,两者能过一个就算过(message对象就两种可能都有)
|
||||
var result = this.tryCheckDeducedAuth(entity, operation, context, actions);
|
||||
if (result instanceof Promise) {
|
||||
return result.then(function (rt) {
|
||||
if (!rt) {
|
||||
return;
|
||||
}
|
||||
var result2 = _this.tryCheckSelfAuth(entity, operation, context, actions);
|
||||
if (result2 instanceof Promise) {
|
||||
return result2.then(function (rt2) {
|
||||
if (!rt2) {
|
||||
return;
|
||||
}
|
||||
throw new types_1.OakUserUnpermittedException(rt2);
|
||||
});
|
||||
}
|
||||
if (!result2) {
|
||||
return;
|
||||
}
|
||||
throw new types_1.OakUserUnpermittedException(result2);
|
||||
});
|
||||
}
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
var result2 = this.tryCheckSelfAuth(entity, operation, context, actions);
|
||||
if (result2 instanceof Promise) {
|
||||
return result2.then(function (rt2) {
|
||||
if (!rt2) {
|
||||
return;
|
||||
}
|
||||
throw new types_1.OakUserUnpermittedException(rt2);
|
||||
});
|
||||
}
|
||||
if (!result2) {
|
||||
return;
|
||||
}
|
||||
throw new types_1.OakUserUnpermittedException(result2);
|
||||
};
|
||||
// 后台检查filter是否满足relation约束
|
||||
RelationAuth.prototype.checkRelationAsync = function (entity, operation, context) {
|
||||
|
|
|
|||
|
|
@ -6359,9 +6359,9 @@ function outputRelation(outputDir: string, printer: ts.Printer) {
|
|||
if (paths.length > 12) {
|
||||
throw new Error('对象之间的关系深度过长,请优化设计加以避免');
|
||||
}
|
||||
if (!DEDUCED_RELATION_MAP[entity]) {
|
||||
actionPath.push([firstLetterLowerCase(entity), path, root, isRelation]);
|
||||
}
|
||||
|
||||
actionPath.push([firstLetterLowerCase(entity), path, root, isRelation]);
|
||||
|
||||
if (Schema[entity].hasRelationDef) {
|
||||
// assert(!DEDUCED_RELATION_MAP[entity], `${entity}对象定义了deducedRelationMap,但它有relation`);
|
||||
relationPath.push([firstLetterLowerCase(entity), path, root, isRelation]);
|
||||
|
|
@ -6370,12 +6370,37 @@ function outputRelation(outputDir: string, printer: ts.Printer) {
|
|||
if (parent) {
|
||||
parent.forEach(
|
||||
([child, foreignKey]) => {
|
||||
if (child !== entity && !paths.includes(firstLetterLowerCase(child)) && !IGNORED_FOREIGN_KEY_MAP[firstLetterLowerCase(child)]?.includes(foreignKey)) {
|
||||
// 如果有递归直接忽略,递归对象在设计时不要进入这个链条
|
||||
const fk = foreignKey === 'entity' ? firstLetterLowerCase(entity) : foreignKey;
|
||||
const path2 = path ? `${fk}.${path}` : fk;
|
||||
outputRecursively(root, child, path2, paths.concat([firstLetterLowerCase(entity)]), isRelation);
|
||||
const child2 = firstLetterLowerCase(child);
|
||||
if (child === entity && Schema[entity].hasRelationDef) {
|
||||
// 如果有层级关系对象,最多找3层。同时这里只找本身存在relation关系的对象,因为如果对象上没有relation,则其上的公共路径应当可以维护住层级关系
|
||||
// 例如在jichuang项目中,house上没有relation,通过其park外键所维护的路径不需要遍历其父亲。而parkCluster因为有relation,所以必须构造所有的可能路径
|
||||
const firstRepeated = paths.indexOf(child2);
|
||||
if (firstRepeated > 0) {
|
||||
const paths2 = paths.slice(firstRepeated);
|
||||
if (paths2.length >= 3) {
|
||||
return;
|
||||
}
|
||||
if (paths2.find(ele => ele !== child2)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (paths.indexOf(child2) > 0) {
|
||||
// 除了层级之外的递归直接忽略
|
||||
return;
|
||||
}
|
||||
if (IGNORED_FOREIGN_KEY_MAP[child2]?.includes(foreignKey)) {
|
||||
// 忽略的路径放弃
|
||||
return;
|
||||
}
|
||||
if (DEDUCED_RELATION_MAP[child] === foreignKey) {
|
||||
// 如果子对象本身由父对象推定,也放弃
|
||||
return;
|
||||
}
|
||||
|
||||
const fk = foreignKey === 'entity' ? firstLetterLowerCase(entity) : foreignKey;
|
||||
const path2 = path ? `${fk}.${path}` : fk;
|
||||
outputRecursively(root, child, path2, paths.concat([firstLetterLowerCase(entity)]), isRelation);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
data?: ED[T]['Operation']['data'],
|
||||
filter?: ED[T]['Selection']['filter'],
|
||||
userRelations?: Array<ED['userRelation']['OpSchema']>,
|
||||
) => <Cxt extends AsyncContext<ED> | SyncContext<ED>>(context: Cxt, oneIsEnough?: boolean) => CheckRelationResult[] | Promise<CheckRelationResult[]>
|
||||
) => (<Cxt extends AsyncContext<ED> | SyncContext<ED>>(context: Cxt, oneIsEnough?: boolean) => CheckRelationResult[] | Promise<CheckRelationResult[]>) | string;
|
||||
};
|
||||
private selectFreeEntities: (keyof ED)[];
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
const excludePaths: string[] = [];
|
||||
const anchors = findHighestAnchors(entity, filter2 as NonNullable<ED[keyof ED]['Selection']['filter']>, '', excludePaths);
|
||||
if (anchors.length === 0) {
|
||||
throw new OakException('本次查询找不到锚定权限的入口,请确认查询条件合法');
|
||||
return '本次查询找不到锚定权限的入口,请确认查询条件合法';
|
||||
}
|
||||
anchors.sort(
|
||||
(a1, a2) => a2.relativePath.length - a1.relativePath.length
|
||||
|
|
@ -833,7 +833,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
entity: keyof ED;
|
||||
operation: ED[keyof ED]['Operation'] | ED[keyof ED]['Selection'];
|
||||
actions?: ED[keyof ED]['Action'][];
|
||||
} {
|
||||
} | undefined {
|
||||
// 如果是deduce的对象,将之转化为所deduce的对象上的权限检查
|
||||
const deduceAttr = this.authDeduceRelationMap[entity]!;
|
||||
assert(deduceAttr === 'entity', `当前只支持entity作为deduce外键,entity是「${entity as string}」`);
|
||||
|
|
@ -845,8 +845,8 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
// 有filter优先判断filter
|
||||
deduceEntity = filter.entity;
|
||||
deduceEntityId = filter.entityId;
|
||||
assert(deduceEntity, `${entity as string}对象上的${action}行为,filter中必须带上${deduceAttr as string}的外键条件`);
|
||||
assert(deduceEntityId, `${entity as string}对象上的${action}行为,filter中必须带上${deduceAttr as string}Id的外键条件`);
|
||||
// assert(deduceEntity, `${entity as string}对象上的${action}行为,filter中必须带上${deduceAttr as string}的外键条件`);
|
||||
// assert(deduceEntityId, `${entity as string}对象上的${action}行为,filter中必须带上${deduceAttr as string}Id的外键条件`);
|
||||
}
|
||||
else if (data instanceof Array) {
|
||||
for (const d of data) {
|
||||
|
|
@ -866,45 +866,12 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
else {
|
||||
deduceEntity = (data as ED[T]['CreateSingle']['data']).entity;
|
||||
deduceEntityId = (data as ED[T]['CreateSingle']['data']).entityId;
|
||||
assert(deduceEntity);
|
||||
assert(deduceEntityId);
|
||||
// assert(deduceEntity);
|
||||
// assert(deduceEntityId);
|
||||
}
|
||||
|
||||
const excludeActions = readOnlyActions.concat(['create', 'remove']);
|
||||
const updateActions = this.schema[deduceEntity].actions.filter(
|
||||
(a) => !excludeActions.includes(a)
|
||||
);
|
||||
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'update',
|
||||
data: {},
|
||||
filter: {
|
||||
id: deduceEntityId,
|
||||
},
|
||||
},
|
||||
actions: updateActions,
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 目前应该都有这两个属性,包括select
|
||||
const { entity: deduceEntity, entityId: deduceEntityId } = filter!;
|
||||
assert(deduceEntity, `${entity as string}对象上的${action}行为,必须带上${deduceAttr as string}的外键条件`);
|
||||
assert(deduceEntityId, `${entity as string}对象上的${action}行为,必须带上${deduceAttr as string}Id的外键条件`);
|
||||
if (action === 'select') {
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'select',
|
||||
data: { id: 1 },
|
||||
filter: { id: deduceEntityId },
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 目前对于非select和create的action,只要有其父对象的update/remove属性即可以
|
||||
const excludeActions = readOnlyActions.concat(['create']);
|
||||
if (deduceEntity && deduceEntityId) {
|
||||
const excludeActions = readOnlyActions.concat(['create', 'remove']);
|
||||
const updateActions = this.schema[deduceEntity].actions.filter(
|
||||
(a) => !excludeActions.includes(a)
|
||||
);
|
||||
|
|
@ -922,6 +889,43 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 目前应该都有这两个属性,包括select
|
||||
const { entity: deduceEntity, entityId: deduceEntityId } = filter!;
|
||||
// assert(deduceEntity, `${entity as string}对象上的${action}行为,必须带上${deduceAttr as string}的外键条件`);
|
||||
// assert(deduceEntityId, `${entity as string}对象上的${action}行为,必须带上${deduceAttr as string}Id的外键条件`);
|
||||
if (deduceEntity && deduceEntityId) {
|
||||
if (action === 'select') {
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'select',
|
||||
data: { id: 1 },
|
||||
filter: { id: deduceEntityId },
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
// 目前对于非select和create的action,只要有其父对象的update/remove属性即可以
|
||||
const excludeActions = readOnlyActions.concat(['create']);
|
||||
const updateActions = this.schema[deduceEntity].actions.filter(
|
||||
(a) => !excludeActions.includes(a)
|
||||
);
|
||||
|
||||
return {
|
||||
entity: deduceEntity,
|
||||
operation: {
|
||||
action: 'update',
|
||||
data: {},
|
||||
filter: {
|
||||
id: deduceEntityId,
|
||||
},
|
||||
},
|
||||
actions: updateActions,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -983,17 +987,17 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
entity: T,
|
||||
operation: ED[T]['Operation'] | ED[T]['Selection'],
|
||||
context: Cxt,
|
||||
): any | Promise<any> {
|
||||
): string | Promise<string> {
|
||||
const action = (operation as ED[T]['Operation']).action || 'select';
|
||||
switch (action) {
|
||||
case 'select': {
|
||||
if (['relation', 'actionAuth', 'relationAuth', 'user', 'userEntityGrant'].includes(entity as string)) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
if (entity === 'userRelation') {
|
||||
const { filter } = operation as ED[T]['Selection'];
|
||||
if (filter?.userId === context.getCurrentUserId()) {
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
// 查询某一对象的relation,意味着该用户有权利管辖该对象上至少某一种relation的操作权限
|
||||
|
|
@ -1021,7 +1025,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
},
|
||||
},
|
||||
}, operation.filter);
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1040,13 +1044,14 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
return destRelations.then(
|
||||
(r2) => {
|
||||
if (!r2.find(ele => ele.id === relationId)) {
|
||||
throw new OakUserUnpermittedException(`当前用户没有为id为「${entityId}」的「${entity}」对象创建「${relationId}」人员关系的权限`);
|
||||
return `当前用户没有为id为「${entityId}」的「${entity}」对象创建「${relationId}」人员关系的权限`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
if (!destRelations.find(ele => ele.id === relationId)) {
|
||||
throw new OakUserUnpermittedException(`当前用户没有为id为「${entityId}」的「${entity}」对象创建「${relationId}」人员关系的权限`);
|
||||
return `当前用户没有为id为「${entityId}」的「${entity}」对象创建「${relationId}」人员关系的权限`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -1077,7 +1082,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
},
|
||||
}, filter);
|
||||
}
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
case 'user': {
|
||||
// 对用户的操作由应用自己去管理权限,这里只检查grant/revoke
|
||||
|
|
@ -1088,13 +1093,15 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
if (userRelation$user instanceof Array) {
|
||||
const result = userRelation$user.map(ur => checkUrOperation(ur));
|
||||
if (result[0] instanceof Promise) {
|
||||
return Promise.all(result);
|
||||
return Promise.all(result).then(
|
||||
(r2) => r2.join('')
|
||||
);
|
||||
}
|
||||
return;
|
||||
return result.join('');
|
||||
}
|
||||
return checkUrOperation(userRelation$user!);
|
||||
}
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
|
|
@ -1106,18 +1113,33 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
assert(false, `${entity as string}的${action}权限还未详化处理`);
|
||||
}
|
||||
|
||||
private checkActions<T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>>(
|
||||
private tryCheckDeducedAuth<T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>>(
|
||||
entity: T,
|
||||
operation: ED[T]['Operation'] | ED[T]['Selection'],
|
||||
context: Cxt,
|
||||
actions?: ED[T]['Action'][],
|
||||
): any | Promise<any> {
|
||||
): string | Promise<string> {
|
||||
if (this.authDeduceRelationMap[entity]) {
|
||||
const deducedResult = this.getDeducedCheckOperation(entity, operation);
|
||||
if (deducedResult) {
|
||||
const { entity: deduceEntity, operation: deduceOperation, actions: deduceActions } = deducedResult;
|
||||
assert(!this.authDeduceRelationMap[deduceEntity], '目前不应出现连续的deduceRelationAuth');
|
||||
return this.tryCheckSelfAuth(deduceEntity, deduceOperation, context, deduceActions);
|
||||
}
|
||||
return `${entity as string}上虽然有deduce权限但不存在相应的查询路径`;
|
||||
}
|
||||
return `${entity as string}上不存在有效的deduce权限`;
|
||||
}
|
||||
|
||||
private tryCheckSelfAuth<T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>>(
|
||||
entity: T,
|
||||
operation: ED[T]['Operation'] | ED[T]['Selection'],
|
||||
context: Cxt,
|
||||
actions?: ED[T]['Action'][],
|
||||
): string | Promise<string> {
|
||||
const action = (operation as ED[T]['Operation']).action || 'select';
|
||||
const userId = context.getCurrentUserId()!;
|
||||
if (this.authDeduceRelationMap[entity]) {
|
||||
const { entity: deduceEntity, operation: deduceOperation, actions } = this.getDeducedCheckOperation(entity, operation);
|
||||
return this.checkActions(deduceEntity, deduceOperation, context, actions);
|
||||
}
|
||||
|
||||
if (action === 'select') {
|
||||
// select的权限检查发生在每次cascadeSelect时,如果有多对一的join,被join的实体不需要检查
|
||||
if (['user', 'relation', 'oper', 'operEntity', 'modi', 'modiEntity', 'userRelation', 'actionAuth',
|
||||
|
|
@ -1128,24 +1150,28 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
throw new OakUserUnpermittedException(`处理${entity as string}上不存在有效的actionPath`);
|
||||
}
|
||||
const checker = this.relationalChecker[entity]!(userId, actions || ['select'], undefined, operation.filter!);
|
||||
if (typeof checker === 'string') {
|
||||
return checker;
|
||||
}
|
||||
const result = checker(context, true);
|
||||
if (result instanceof Promise) {
|
||||
return result.then(
|
||||
(r2) => {
|
||||
if (r2.length === 0) {
|
||||
throw new OakUserUnpermittedException(`对「${entity as string}」进行「${action}」操作时找不到对应的授权`);
|
||||
return `对「${entity as string}」进行「${action}」操作时找不到对应的授权`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
)
|
||||
}
|
||||
if (result.length === 0) {
|
||||
throw new OakUserUnpermittedException(`对「${entity as string}」进行「${action}」操作时找不到对应的授权`);
|
||||
return `对「${entity as string}」进行「${action}」操作时找不到对应的授权`;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// operate的权限检查只发生一次,需要在这次检查中将所有cascade的对象的权限检查完成
|
||||
// 算法是先将整个update的根结点对象找到,并找到为其赋权的relation,再用此relation去查找所有子对象上的actionAuth
|
||||
const result = [] as Array<Promise<any>>;
|
||||
const result = [] as Array<Promise<string>>;
|
||||
const { root, children, userRelations } = this.destructCascadeOperation(entity, operation as ED[T]['Operation']);
|
||||
|
||||
const { entity: e, data: d, filter: f, action: a } = root;
|
||||
|
|
@ -1174,8 +1200,9 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
const relationIds = aas2.map(ele => ele.relationId);
|
||||
const diff = difference(createIds, relationIds);
|
||||
if (diff.length > 0) {
|
||||
throw new OakUserUnpermittedException(`您无权创建「${e as string}」对象上id为「${diff.join(',')}」的用户权限`);
|
||||
return `您无权创建「${e as string}」对象上id为「${diff.join(',')}」的用户权限`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -1184,7 +1211,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
const relationIds = aas.map(ele => ele.relationId!);
|
||||
const diff = difference(createIds, relationIds);
|
||||
if (diff.length > 0) {
|
||||
throw new OakUserUnpermittedException(`您无权创建「${e as string}」对象上id为「${diff.join(',')}」的用户权限`);
|
||||
return `您无权创建「${e as string}」对象上id为「${diff.join(',')}」的用户权限`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1205,6 +1232,9 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
throw new OakUserUnpermittedException(`${root.entity as string}上不存在有效的actionPath`);
|
||||
}
|
||||
const checker = this.relationalChecker[root.entity]!(userId, actions || [root.action], root.data, root.filter, userRelations);
|
||||
if (typeof checker === 'string') {
|
||||
return checker;
|
||||
}
|
||||
const r = checker(context, children.length === 0);
|
||||
const checkChildrenAuth = (relativePath: string, relationId?: string) => {
|
||||
const filters = children.map(
|
||||
|
|
@ -1245,8 +1275,9 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
}
|
||||
);
|
||||
if (missedChild) {
|
||||
return new OakUserUnpermittedException(`对「${missedChild.entity as string}」进行「${missedChild.action}」操作时找不到对应的授权`)
|
||||
return `对「${missedChild.entity as string}」进行「${missedChild.action}」操作时找不到对应的授权`;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
if (r2 instanceof Promise) {
|
||||
return r2.then(
|
||||
|
|
@ -1257,7 +1288,7 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
}
|
||||
else {
|
||||
// 取消directActionAuth,发现root对象能过,则子对象全部自动通过
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
};
|
||||
if (r instanceof Promise) {
|
||||
|
|
@ -1268,13 +1299,15 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
))).then(
|
||||
(r3) => {
|
||||
if (r3.length === 0) {
|
||||
throw new OakUserUnpermittedException(`对「${entity as string}」进行「${action}」操作时找不到对应的授权`);
|
||||
return `对「${entity as string}」进行「${action}」操作时找不到对应的授权`;
|
||||
}
|
||||
if (r3.indexOf(undefined) >= 0) {
|
||||
if (r3.indexOf('') >= 0) {
|
||||
// 有一个过就证明能过
|
||||
return;
|
||||
return '';
|
||||
}
|
||||
throw r3[0];
|
||||
return r3.find(
|
||||
ele => !!ele
|
||||
)!;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
|
@ -1284,18 +1317,82 @@ export class RelationAuth<ED extends EntityDict & BaseEntityDict>{
|
|||
({ relativePath, relationId }) => checkChildrenAuth(relativePath, relationId)
|
||||
);
|
||||
|
||||
if (r3.length > 0 && r3.includes(undefined)) {
|
||||
if (r3.length > 0 && r3.includes('')) {
|
||||
// 有一个过就证明能过
|
||||
return '';
|
||||
}
|
||||
else {
|
||||
throw r3[0] || new OakUserUnpermittedException(`对「${entity as string}」进行「${action}」操作时找不到对应的授权`);
|
||||
}
|
||||
return r3.find(
|
||||
ele => !!ele
|
||||
) || `对「${entity as string}」进行「${action}」操作时找不到对应的授权`;
|
||||
}
|
||||
}
|
||||
if (result.length > 0) {
|
||||
return Promise.all(result);
|
||||
return Promise.all(result).then(
|
||||
(r2) => {
|
||||
const r3 = r2.find(
|
||||
ele => !!ele
|
||||
);
|
||||
if (r3) {
|
||||
return r3;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
private checkActions<T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>>(
|
||||
entity: T,
|
||||
operation: ED[T]['Operation'] | ED[T]['Selection'],
|
||||
context: Cxt,
|
||||
actions?: ED[T]['Action'][],
|
||||
): void | Promise<void> {
|
||||
// 现在checkDeducedAuth和checkSelfAuth是一个或的关系,两者能过一个就算过(message对象就两种可能都有)
|
||||
const result = this.tryCheckDeducedAuth(entity, operation, context, actions);
|
||||
if (result instanceof Promise) {
|
||||
return result.then(
|
||||
(rt) => {
|
||||
if (!rt) {
|
||||
return;
|
||||
}
|
||||
const result2 = this.tryCheckSelfAuth(entity, operation, context, actions);
|
||||
if (result2 instanceof Promise) {
|
||||
return result2.then(
|
||||
(rt2) => {
|
||||
if (!rt2) {
|
||||
return;
|
||||
}
|
||||
throw new OakUserUnpermittedException(rt2);
|
||||
}
|
||||
);
|
||||
}
|
||||
if (!result2) {
|
||||
return;
|
||||
}
|
||||
throw new OakUserUnpermittedException(result2);
|
||||
}
|
||||
);
|
||||
}
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
const result2 = this.tryCheckSelfAuth(entity, operation, context, actions);
|
||||
if (result2 instanceof Promise) {
|
||||
return result2.then(
|
||||
(rt2) => {
|
||||
if (!rt2) {
|
||||
return;
|
||||
}
|
||||
throw new OakUserUnpermittedException(rt2);
|
||||
}
|
||||
);
|
||||
}
|
||||
if (!result2) {
|
||||
return;
|
||||
}
|
||||
throw new OakUserUnpermittedException(result2);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { randomBytes } from 'node:crypto';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
export async function getRandomValues(length: number): Promise<Uint8Array> {
|
||||
if (length > 65536) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue