修改了checker和auth的逻辑(未放开)
This commit is contained in:
parent
bd8fd47df5
commit
c1eae2142f
|
|
@ -2,14 +2,13 @@
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createDynamicCheckers = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var checker_1 = require("../store/checker");
|
||||
var modi_1 = require("../store/modi");
|
||||
function createDynamicCheckers(schema, authDict) {
|
||||
var checkers = [];
|
||||
checkers.push.apply(checkers, tslib_1.__spreadArray([], tslib_1.__read((0, modi_1.createModiRelatedCheckers)(schema)), false));
|
||||
if (authDict) {
|
||||
checkers.push.apply(checkers, tslib_1.__spreadArray([], tslib_1.__read((0, checker_1.createAuthCheckers)(schema, authDict)), false));
|
||||
}
|
||||
/* if (authDict) {
|
||||
checkers.push(...createAuthCheckers<ED, Cxt>(schema, authDict));
|
||||
} */
|
||||
return checkers;
|
||||
}
|
||||
exports.createDynamicCheckers = createDynamicCheckers;
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ var TriggerExecutor = /** @class */ (function () {
|
|||
var trigger = {
|
||||
checkerType: type,
|
||||
name: triggerName,
|
||||
priority: checker.priority || 2,
|
||||
priority: checker.priority || 20,
|
||||
entity: entity,
|
||||
action: action,
|
||||
fn: fn,
|
||||
when: 'before',
|
||||
when: checker.when || 'before',
|
||||
filter: conditionalFilter,
|
||||
};
|
||||
this.registerTrigger(trigger);
|
||||
|
|
@ -59,7 +59,7 @@ var TriggerExecutor = /** @class */ (function () {
|
|||
throw new Error("\u4E0D\u53EF\u6709\u540C\u540D\u7684\u89E6\u53D1\u5668\u300C".concat(trigger.name, "\u300D"));
|
||||
}
|
||||
if (typeof trigger.priority !== 'number') {
|
||||
trigger.priority = 1; // 默认最低
|
||||
trigger.priority = 10; // 默认值
|
||||
}
|
||||
if (trigger.filter) {
|
||||
(0, assert_1.default)(typeof trigger.action === 'string' && trigger.action !== 'create'
|
||||
|
|
|
|||
|
|
@ -413,9 +413,9 @@ function translateActionAuthFilterMaker(schema, relationItem, entity) {
|
|||
function createAuthCheckers(schema, authDict) {
|
||||
var checkers = [];
|
||||
var _loop_1 = function (entity) {
|
||||
var _a, _b;
|
||||
var _a;
|
||||
if (authDict[entity]) {
|
||||
var _c = authDict[entity], relationAuth = _c.relationAuth, actionAuth = _c.actionAuth;
|
||||
var _b = authDict[entity], relationAuth = _b.relationAuth, actionAuth = _b.actionAuth;
|
||||
if (relationAuth) {
|
||||
var raFilterMakerDict_1 = {};
|
||||
for (var r in relationAuth) {
|
||||
|
|
@ -440,7 +440,7 @@ function createAuthCheckers(schema, authDict) {
|
|||
var filter = raFilterMakerDict_1[relation](userId);
|
||||
return {
|
||||
entity: entity,
|
||||
filter: filter,
|
||||
filter: (0, filter_1.combineFilters)([filter, { id: entityId }]),
|
||||
expr: {
|
||||
$gt: [{
|
||||
'#attr': '$$createAt$$',
|
||||
|
|
@ -493,36 +493,58 @@ function createAuthCheckers(schema, authDict) {
|
|||
// todo 等实现的时候再写
|
||||
}
|
||||
if (actionAuth) {
|
||||
var aaFilterMakerDict = {};
|
||||
for (var a in actionAuth) {
|
||||
Object.assign(aaFilterMakerDict, (_b = {},
|
||||
_b[a] = translateActionAuthFilterMaker(schema, actionAuth[a], entity),
|
||||
_b));
|
||||
var _loop_2 = function (a) {
|
||||
var filterMaker = translateActionAuthFilterMaker(schema, actionAuth[a], entity);
|
||||
if (a === 'create') {
|
||||
/**
|
||||
* create动作所增加的auth约束只可能在外键的对象上,所以需要对此外键对象进行查找
|
||||
* create动作所增加的auth约束只可能在外键的对象上,但因为还有级联和触发器,不太容易在创建前检查,先放在创建后
|
||||
*/
|
||||
var _d = actionAuth[a];
|
||||
/* checkers.push({
|
||||
entity,
|
||||
var _c = actionAuth[a];
|
||||
checkers.push({
|
||||
entity: entity,
|
||||
action: a,
|
||||
type: 'expressionRelation',
|
||||
expression: (operation, context) => {
|
||||
// create要保证数据的外键指向关系满足filter的约束,因为这行还没有插入,所以要
|
||||
|
||||
}
|
||||
}); */
|
||||
when: 'after',
|
||||
expression: function (operation, context) {
|
||||
// 在插入后检查
|
||||
var makeExprInner = function (data) {
|
||||
var id = data.id;
|
||||
return {
|
||||
entity: entity,
|
||||
filter: (0, filter_1.combineFilters)([filter, { id: id }]),
|
||||
expr: {
|
||||
$gt: [{
|
||||
'#attr': '$$createAt$$',
|
||||
}, 0]
|
||||
},
|
||||
};
|
||||
};
|
||||
var filter = filterMaker(context.getCurrentUserId());
|
||||
var data = operation.data;
|
||||
if (data instanceof Array) {
|
||||
throw new Error('需要expr支持count');
|
||||
}
|
||||
return makeExprInner(data);
|
||||
},
|
||||
errMsg: '定义的actionAuth中检查出来越权操作',
|
||||
});
|
||||
}
|
||||
else {
|
||||
/* checkers.push({
|
||||
entity,
|
||||
checkers.push({
|
||||
entity: entity,
|
||||
action: a,
|
||||
type: 'relation',
|
||||
relationFilter: (operation, context) => {
|
||||
const { filter } = operation;
|
||||
}
|
||||
}); */
|
||||
relationFilter: function (operation, context) {
|
||||
// const { filter } = operation;
|
||||
var filter = filterMaker(context.getCurrentUserId());
|
||||
return filter;
|
||||
},
|
||||
errMsg: '定义的actionAuth中检查出来越权操作',
|
||||
});
|
||||
}
|
||||
};
|
||||
for (var a in actionAuth) {
|
||||
_loop_2(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ export declare type ExpressionTaskCombination<ED extends EntityDict> = Expressio
|
|||
export declare type ExpressionChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
||||
priority?: number;
|
||||
type: 'expression';
|
||||
when?: 'after';
|
||||
entity: T;
|
||||
action: ED[T]['Action'] | Array<ED[T]['Action']>;
|
||||
expression: <T2 extends keyof ED>(operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => ExpressionTaskCombination<ED> | undefined | string | Promise<ExpressionTaskCombination<ED> | string | undefined>;
|
||||
|
|
@ -56,6 +57,7 @@ export declare type ExpressionChecker<ED extends EntityDict, T extends keyof ED,
|
|||
export declare type ExpressionRelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
||||
priority?: number;
|
||||
type: 'expressionRelation';
|
||||
when?: 'after';
|
||||
entity: T;
|
||||
action: ED[T]['Action'] | Array<ED[T]['Action']>;
|
||||
expression: <T2 extends keyof ED>(operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => ExpressionTaskCombination<ED> | undefined | string | Promise<ExpressionTaskCombination<ED> | string | undefined>;
|
||||
|
|
|
|||
|
|
@ -122,7 +122,23 @@ interface GeoDistance<A> {
|
|||
$distance: [RefOrExpression<A> | Geo, RefOrExpression<A> | Geo];
|
||||
}
|
||||
declare type GeoExpression<A> = GeoContains<A> | GeoDistance<A>;
|
||||
export declare type Expression<A> = GeoExpression<A> | DateExpression<A> | LogicExpression<A> | BoolExpression<A> | CompareExpression<A> | MathExpression<A> | StringExpression<A>;
|
||||
interface AggrCountExpression<A> {
|
||||
$$count: RefOrExpression<A>;
|
||||
}
|
||||
interface AggrSumExpression<A> {
|
||||
$$sum: RefOrExpression<A>;
|
||||
}
|
||||
interface AggrMaxExpression<A> {
|
||||
$$max: RefOrExpression<A>;
|
||||
}
|
||||
interface AggrMinExpression<A> {
|
||||
$$min: RefOrExpression<A>;
|
||||
}
|
||||
interface AggrAvgExpression<A> {
|
||||
$$avg: RefOrExpression<A>;
|
||||
}
|
||||
export declare type AggrExpression<A> = AggrAvgExpression<A> | AggrCountExpression<A> | AggrSumExpression<A> | AggrMaxExpression<A> | AggrMinExpression<A>;
|
||||
export declare type Expression<A> = GeoExpression<A> | DateExpression<A> | LogicExpression<A> | BoolExpression<A> | CompareExpression<A> | MathExpression<A> | StringExpression<A> | AggrExpression<A>;
|
||||
export declare type ExpressionConstant = Geo | number | Date | string | boolean;
|
||||
export declare function isGeoExpression<A>(expression: any): expression is GeoExpression<A>;
|
||||
export declare function isDateExpression<A>(expression: any): expression is DateExpression<A>;
|
||||
|
|
@ -131,6 +147,7 @@ export declare function isBoolExpression<A>(expression: any): expression is Bool
|
|||
export declare function isCompareExpression<A>(expression: any): expression is CompareExpression<A>;
|
||||
export declare function isMathExpression<A>(expression: any): expression is MathExpression<A>;
|
||||
export declare function isStringExpression<A>(expression: any): expression is StringExpression<A>;
|
||||
export declare function isAggrExpression<A>(expression: any): expression is AggrExpression<A>;
|
||||
export declare function isExpression<A>(expression: any): expression is Expression<A>;
|
||||
export declare function opMultipleParams(op: string): boolean;
|
||||
export declare function execOp(op: string, params: any, obscure?: boolean): ExpressionConstant;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getAttrRefInExpression = exports.execOp = exports.opMultipleParams = exports.isExpression = exports.isStringExpression = exports.isMathExpression = exports.isCompareExpression = exports.isBoolExpression = exports.isLogicExpression = exports.isDateExpression = exports.isGeoExpression = void 0;
|
||||
exports.getAttrRefInExpression = exports.execOp = exports.opMultipleParams = exports.isExpression = exports.isAggrExpression = exports.isStringExpression = exports.isMathExpression = exports.isCompareExpression = exports.isBoolExpression = exports.isLogicExpression = exports.isDateExpression = exports.isGeoExpression = void 0;
|
||||
var tslib_1 = require("tslib");
|
||||
var assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
var dayjs_1 = tslib_1.__importDefault(require("dayjs"));
|
||||
|
|
@ -42,6 +42,7 @@ dayjs_1.default.extend(dayOfYear_1.default);
|
|||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
function isGeoExpression(expression) {
|
||||
if (Object.keys(expression).length == 1) {
|
||||
var op = Object.keys(expression)[0];
|
||||
|
|
@ -115,6 +116,16 @@ function isStringExpression(expression) {
|
|||
return false;
|
||||
}
|
||||
exports.isStringExpression = isStringExpression;
|
||||
function isAggrExpression(expression) {
|
||||
if (Object.keys(expression).length == 1) {
|
||||
var op = Object.keys(expression)[0];
|
||||
if (['$$max', '$$min', '$$sum', '$$avg', '$$count'].includes(op)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
exports.isAggrExpression = isAggrExpression;
|
||||
function isExpression(expression) {
|
||||
return typeof expression === 'object' && Object.keys(expression).length === 1 && Object.keys(expression)[0].startsWith('$');
|
||||
}
|
||||
|
|
@ -122,7 +133,7 @@ exports.isExpression = isExpression;
|
|||
function opMultipleParams(op) {
|
||||
return !['$year', '$month', '$weekday', '$weekOfYear', '$day', '$dayOfMonth',
|
||||
'$dayOfWeek', '$dayOfYear', '$not', '$true', '$false', '$abs',
|
||||
'$round', '$floor', '$ceil'].includes(op);
|
||||
'$round', '$floor', '$ceil', '$$max', '$$min', '$$sum', '$$avg', '$$count'].includes(op);
|
||||
}
|
||||
exports.opMultipleParams = opMultipleParams;
|
||||
function execOp(op, params, obscure) {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import { StorageSchema, EntityDict as BaseEntityDict, Checker, AuthDef, AuthDefD
|
|||
export function createDynamicCheckers<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED> | SyncContext<ED>>(schema: StorageSchema<ED>, authDict?: AuthDefDict<ED>){
|
||||
const checkers: Checker<ED, keyof ED, Cxt>[] = [];
|
||||
checkers.push(...createModiRelatedCheckers<ED, Cxt>(schema));
|
||||
if (authDict) {
|
||||
/* if (authDict) {
|
||||
checkers.push(...createAuthCheckers<ED, Cxt>(schema, authDict));
|
||||
}
|
||||
} */
|
||||
return checkers;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { addFilterSegment, checkFilterRepel } from "../store/filter";
|
|||
import { DeduceCreateOperation, EntityDict, OperateOption, SelectOption, TriggerDataAttribute, TriggerTimestampAttribute } from "../types/Entity";
|
||||
import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
||||
import { Logger } from "../types/Logger";
|
||||
import { Checker, CheckerType } from '../types/Auth';
|
||||
import { Checker, CheckerType, ExpressionChecker, RelationChecker } from '../types/Auth';
|
||||
import { Trigger, CreateTriggerCrossTxn, CreateTrigger, CreateTriggerInTxn, SelectTriggerAfter, UpdateTrigger } from "../types/Trigger";
|
||||
import { AsyncContext } from './AsyncRowStore';
|
||||
import { SyncContext } from './SyncRowStore';
|
||||
|
|
@ -53,11 +53,11 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict> {
|
|||
const trigger = {
|
||||
checkerType: type,
|
||||
name: triggerName,
|
||||
priority: checker.priority || 2, // checker的默认优先级稍高一点点
|
||||
priority: checker.priority || 20, // checker的默认优先级稍高
|
||||
entity,
|
||||
action: action as 'update',
|
||||
fn,
|
||||
when: 'before',
|
||||
when: (checker as ExpressionChecker<ED, T, Cxt>).when || 'before',
|
||||
filter: conditionalFilter,
|
||||
} as UpdateTrigger<ED, T, Cxt>;
|
||||
this.registerTrigger(trigger);
|
||||
|
|
@ -77,7 +77,7 @@ export class TriggerExecutor<ED extends EntityDict & BaseEntityDict> {
|
|||
throw new Error(`不可有同名的触发器「${trigger.name}」`);
|
||||
}
|
||||
if (typeof trigger.priority !== 'number') {
|
||||
trigger.priority = 1; // 默认最低
|
||||
trigger.priority = 10; // 默认值
|
||||
}
|
||||
if ((trigger as UpdateTrigger<ED, T, Cxt>).filter) {
|
||||
assert(typeof trigger.action === 'string' && trigger.action !== 'create'
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ export function createAuthCheckers<ED extends EntityDict & BaseEntityDict, Cxt e
|
|||
const filter = raFilterMakerDict[relation]!(userId!);
|
||||
return {
|
||||
entity,
|
||||
filter,
|
||||
filter: combineFilters([filter, { id: entityId }]),
|
||||
expr: {
|
||||
$gt: [{
|
||||
'#attr': '$$createAt$$',
|
||||
|
|
@ -458,36 +458,54 @@ export function createAuthCheckers<ED extends EntityDict & BaseEntityDict, Cxt e
|
|||
}
|
||||
|
||||
if (actionAuth) {
|
||||
const aaFilterMakerDict = {} as Record<string, (suserId: string) => ED[keyof ED]['Selection']['filter']>;
|
||||
for (const a in actionAuth) {
|
||||
Object.assign(aaFilterMakerDict, {
|
||||
[a]: translateActionAuthFilterMaker(schema, actionAuth[a as ED[keyof ED]['Action']]!, entity),
|
||||
});
|
||||
|
||||
const filterMaker = translateActionAuthFilterMaker(schema, actionAuth[a as ED[keyof ED]['Action']]!, entity);
|
||||
if (a === 'create') {
|
||||
/**
|
||||
* create动作所增加的auth约束只可能在外键的对象上,所以需要对此外键对象进行查找
|
||||
* create动作所增加的auth约束只可能在外键的对象上,但因为还有级联和触发器,不太容易在创建前检查,先放在创建后
|
||||
*/
|
||||
const { } = actionAuth[a as ED[keyof ED]['Action']]!;
|
||||
/* checkers.push({
|
||||
checkers.push({
|
||||
entity,
|
||||
action: a,
|
||||
type: 'expressionRelation',
|
||||
when: 'after',
|
||||
expression: (operation, context) => {
|
||||
// create要保证数据的外键指向关系满足filter的约束,因为这行还没有插入,所以要
|
||||
|
||||
}
|
||||
}); */
|
||||
// 在插入后检查
|
||||
const makeExprInner = (data: ED[keyof ED]['CreateSingle']['data']) => {
|
||||
const { id } = data;
|
||||
return {
|
||||
entity,
|
||||
filter: combineFilters([filter, { id }]),
|
||||
expr: {
|
||||
$gt: [{
|
||||
'#attr': '$$createAt$$',
|
||||
}, 0] as any
|
||||
},
|
||||
};
|
||||
};
|
||||
const filter = filterMaker(context.getCurrentUserId()!);
|
||||
const { data } = operation as ED[keyof ED]['Create'];
|
||||
if (data instanceof Array) {
|
||||
throw new Error('需要expr支持count');
|
||||
}
|
||||
return makeExprInner(data);
|
||||
},
|
||||
errMsg: '定义的actionAuth中检查出来越权操作',
|
||||
});
|
||||
}
|
||||
else {
|
||||
/* checkers.push({
|
||||
checkers.push({
|
||||
entity,
|
||||
action: a,
|
||||
action: a as ED[keyof ED]['Action'],
|
||||
type: 'relation',
|
||||
relationFilter: (operation, context) => {
|
||||
const { filter } = operation;
|
||||
}
|
||||
}); */
|
||||
// const { filter } = operation;
|
||||
const filter = filterMaker(context.getCurrentUserId()!);
|
||||
return filter;
|
||||
},
|
||||
errMsg: '定义的actionAuth中检查出来越权操作',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ export type ExpressionTaskCombination<ED extends EntityDict> = ExpressionTask<ED
|
|||
export type ExpressionChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
||||
priority?: number;
|
||||
type: 'expression';
|
||||
when?: 'after';
|
||||
entity: T;
|
||||
action: ED[T]['Action'] | Array<ED[T]['Action']>;
|
||||
expression: <T2 extends keyof ED>(
|
||||
|
|
@ -76,6 +77,7 @@ export type ExpressionChecker<ED extends EntityDict, T extends keyof ED, Cxt ext
|
|||
export type ExpressionRelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
|
||||
priority?: number;
|
||||
type: 'expressionRelation';
|
||||
when?: 'after';
|
||||
entity: T;
|
||||
action: ED[T]['Action'] | Array<ED[T]['Action']>;
|
||||
expression: <T2 extends keyof ED>(
|
||||
|
|
|
|||
|
|
@ -154,8 +154,31 @@ interface GeoDistance<A> {
|
|||
|
||||
type GeoExpression<A> = GeoContains<A> | GeoDistance<A>;
|
||||
|
||||
//// Aggr
|
||||
interface AggrCountExpression<A> {
|
||||
$$count: RefOrExpression<A>;
|
||||
};
|
||||
|
||||
interface AggrSumExpression<A> {
|
||||
$$sum: RefOrExpression<A>;
|
||||
}
|
||||
|
||||
interface AggrMaxExpression<A> {
|
||||
$$max: RefOrExpression<A>;
|
||||
}
|
||||
|
||||
interface AggrMinExpression<A> {
|
||||
$$min: RefOrExpression<A>;
|
||||
}
|
||||
|
||||
interface AggrAvgExpression<A> {
|
||||
$$avg: RefOrExpression<A>;
|
||||
}
|
||||
|
||||
export type AggrExpression<A> = AggrAvgExpression<A> | AggrCountExpression<A> | AggrSumExpression<A> | AggrMaxExpression<A> | AggrMinExpression<A>;
|
||||
|
||||
export type Expression<A> = GeoExpression<A> | DateExpression<A> | LogicExpression<A>
|
||||
| BoolExpression<A> | CompareExpression<A> | MathExpression<A> | StringExpression<A>;
|
||||
| BoolExpression<A> | CompareExpression<A> | MathExpression<A> | StringExpression<A> | AggrExpression<A>;
|
||||
|
||||
export type ExpressionConstant = Geo | number | Date | string | boolean;
|
||||
|
||||
|
|
@ -233,6 +256,16 @@ export function isStringExpression<A>(expression: any): expression is StringExpr
|
|||
return false;
|
||||
}
|
||||
|
||||
export function isAggrExpression<A>(expression: any): expression is AggrExpression<A> {
|
||||
if (Object.keys(expression).length == 1) {
|
||||
const op = Object.keys(expression)[0];
|
||||
if (['$$max', '$$min', '$$sum', '$$avg', '$$count'].includes(op)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isExpression<A>(expression: any): expression is Expression<A> {
|
||||
return typeof expression === 'object' && Object.keys(expression).length === 1 && Object.keys(expression)[0].startsWith('$');
|
||||
}
|
||||
|
|
@ -240,7 +273,7 @@ export function isExpression<A>(expression: any): expression is Expression<A> {
|
|||
export function opMultipleParams(op: string) {
|
||||
return !['$year', '$month', '$weekday', '$weekOfYear', '$day', '$dayOfMonth',
|
||||
'$dayOfWeek', '$dayOfYear', '$not', '$true', '$false', '$abs',
|
||||
'$round', '$floor', '$ceil'].includes(op);
|
||||
'$round', '$floor', '$ceil', '$$max', '$$min', '$$sum', '$$avg', '$$count'].includes(op);
|
||||
}
|
||||
|
||||
export function execOp(op: string, params: any, obscure?: boolean): ExpressionConstant {
|
||||
|
|
|
|||
Loading…
Reference in New Issue