适配了domain的修正,去掉了relation类型的checker

This commit is contained in:
Xu Chang 2024-03-17 18:24:06 +08:00
parent 2b3d4d2dcb
commit b65744dacd
30 changed files with 231 additions and 254 deletions

1
.gitignore vendored
View File

@ -66,3 +66,4 @@ build
package-lock.json
scripts/local
*tsbuildinfo
src/oak-app-domain

View File

@ -1,2 +1,2 @@
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt>)[];
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt>)[];
export default checkers;

View File

@ -3,3 +3,4 @@ import { EntityDict } from '../oak-app-domain';
import { RuntimeCxt } from "../types/RuntimeCxt";
declare const checkers: Checker<EntityDict, 'user', RuntimeCxt>[];
export default checkers;
export declare const UserCheckers: Checker<EntityDict, 'user', RuntimeCxt>[];

View File

@ -1,5 +1,6 @@
import { judgeRelation } from "oak-domain/lib/store/relation";
import { OakInputIllegalException, OakUserUnpermittedException } from "oak-domain/lib/types";
import { checkFilterContains } from 'oak-domain/lib/store/filter';
const checkers = [
{
type: 'row',
@ -10,14 +11,15 @@ const checkers = [
}
},
{
type: 'relation',
type: 'logical',
action: ['remove', 'disable', 'enable'],
entity: 'user',
relationFilter: () => {
checker: (operation, context) => {
// 只有root才能进行操作
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
},
errMsg: '越权操作',
if (!context.isRoot()) {
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
}
}
},
{
type: 'data',
@ -38,48 +40,41 @@ const checkers = [
},
errMsg: '不能禁用root用户',
},
// {
// type: 'row',
// action: 'select',
// entity: 'user',
// filter: (operation, context) => {
// const systemId = context.getSystemId();
// // todo 查询用户 先不加systemId
// if (systemId) {
// return {
// id: {
// $in: {
// entity: 'userSystem',
// data: {
// userId: 1,
// },
// filter: {
// systemId,
// },
// },
// },
// };
// }
// },
// },
];
export default checkers;
export const UserCheckers = [
{
entity: 'user',
action: 'update',
type: 'relation',
relationFilter: (operation, context) => {
type: 'logical',
checker: (operation, context) => {
// 在大部分应用中除了root其他人不应该有权利更新其他人信息但是shadow用户应当除外
// 但这些条件不一定对所有的应用都成立应用如果有更复杂的用户相互更新策略就不要引入这个checker
// 这也是个例子如何对user这样的特殊对象进行权限控制
const userId = context.getCurrentUserId();
const { data } = operation;
if (context.isRoot()) {
return;
}
const { filter, data } = operation;
for (const attr in data) {
const rel = judgeRelation(context.getSchema(), 'user', attr);
if (rel === 1) {
return {
id: userId,
};
if (rel !== 1) {
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
}
return undefined;
const result = checkFilterContains('user', context, {
id: userId,
}, filter, true);
if (result instanceof Promise) {
return result.then((r) => {
if (!r) {
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
});
}
if (!result) {
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
},
errMsg: '您不能更新他人信息',
}
];
export default checkers;

View File

@ -1,7 +1,7 @@
import { Style } from '../../../../types/Style';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../../oak-app-domain").EntityDict, keyof import("../../../../oak-app-domain").EntityDict, false, {
style: Style;
entity: "application" | "system" | "platform";
entity: "platform" | "application" | "system";
entityId: string;
name: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;

View File

@ -1,7 +1,7 @@
import { Config } from '../../../types/Config';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
config: Config;
entity: "system" | "platform";
entity: "platform" | "system";
name: string;
entityId: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;

View File

@ -12,9 +12,9 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
type?: ButtonProps['type'] | AmButtonProps['type'];
executeText?: string | undefined;
buttonProps?: (ButtonProps & {
color?: "primary" | "success" | "warning" | "default" | "danger" | undefined;
color?: "success" | "default" | "warning" | "primary" | "danger" | undefined;
fill?: "none" | "solid" | "outline" | undefined;
size?: "small" | "large" | "middle" | "mini" | undefined;
size?: "small" | "middle" | "large" | "mini" | undefined;
block?: boolean | undefined;
loading?: boolean | "auto" | undefined;
loadingText?: string | undefined;
@ -24,7 +24,7 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
type?: "reset" | "submit" | "button" | undefined;
shape?: "default" | "rounded" | "rectangular" | undefined;
children?: import("react").ReactNode;
} & Pick<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement>, "id" | "onMouseUp" | "onMouseDown" | "onTouchStart" | "onTouchEnd"> & {
} & Pick<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement>, "id" | "onMouseDown" | "onMouseUp" | "onTouchStart" | "onTouchEnd"> & {
className?: string | undefined;
style?: (import("react").CSSProperties & Partial<Record<"--text-color" | "--background-color" | "--border-radius" | "--border-width" | "--border-style" | "--border-color", string>>) | undefined;
tabIndex?: number | undefined;

View File

@ -124,39 +124,9 @@ export default OakComponent({
},
},
};
/* filter.relationId = {
$in: {
entity: 'relationAuth',
data: {
destRelationId: 1,
},
filter: {
sourceRelationId: {
$in: {
entity: 'userRelation',
data: {
relationId: 1,
},
filter: {
userId,
},
},
},
},
},
}; */
}
return {
userRelation$user: filter,
/* id: {
$in: {
entity: 'userRelation',
data: {
userId: 1,
},
filter,
},
}, */
};
},
},
@ -167,19 +137,15 @@ export default OakComponent({
const filter = this.getFilterByName('fulltext');
const users = props.disableDisplay
? rows?.filter((ele) => {
const userRelations = ele.userRelation$user?.filter(
(ele) => !ele.$$deleteAt$$
);
return !!(userRelations && userRelations.length > 0);
})
const userRelations = ele.userRelation$user?.filter((ele) => !ele.$$deleteAt$$);
return !!(userRelations && userRelations.length > 0);
})
: rows;
return {
users: users?.map((ele) => {
const { mobile$user, extraFile$entity } = ele;
const mobile = mobile$user && mobile$user[0]?.mobile;
const avatar = features.extraFile.getUrl(
extraFile$entity && extraFile$entity[0]
);
const avatar = features.extraFile.getUrl(extraFile$entity && extraFile$entity[0]);
const user2 = Object.assign({}, ele, {
mobile,
avatar,
@ -195,8 +161,8 @@ export default OakComponent({
redirectToAfterConfirm: {},
claimUrl: '',
qrCodeType: '',
onUpdate: (id) => {},
onCreate: () => {},
onUpdate: (id) => { },
onCreate: () => { },
disableDisplay: false,
},
data: {
@ -217,10 +183,8 @@ export default OakComponent({
listeners: {
'entity,entityId'(prev, next) {
if (this.state.oakFullpath) {
if (
prev.entity !== next.entity ||
prev.entityId !== next.entityId
) {
if (prev.entity !== next.entity ||
prev.entityId !== next.entityId) {
this.refresh();
}
}
@ -236,45 +200,33 @@ export default OakComponent({
},
methods: {
goUpsert() {
const {
entity,
entityId,
redirectToAfterConfirm,
qrCodeType,
claimUrl,
onCreate,
} = this.props;
const { entity, entityId, redirectToAfterConfirm, qrCodeType, claimUrl, onCreate, } = this.props;
if (onCreate) {
onCreate();
} else {
}
else {
if (process.env.NODE_ENV === 'development') {
console.warn(
'userRelation将不再作为page直接使用请使用回调函数处理'
);
console.warn('userRelation将不再作为page直接使用请使用回调函数处理');
}
this.navigateTo(
{
url: '/userRelation/upsert',
entity,
entityId,
},
{
redirectToAfterConfirm,
qrCodeType,
claimUrl,
}
);
this.navigateTo({
url: '/userRelation/upsert',
entity,
entityId,
}, {
redirectToAfterConfirm,
qrCodeType,
claimUrl,
});
}
},
goUpdate(id) {
const { entity, entityId, onUpdate } = this.props;
if (onUpdate) {
onUpdate(id);
} else {
}
else {
if (process.env.NODE_ENV === 'development') {
console.warn(
'userRelation将不再作为page直接使用请使用回调函数处理'
);
console.warn('userRelation将不再作为page直接使用请使用回调函数处理');
}
this.navigateTo({
url: '/userRelation/upsert/byUser',
@ -291,26 +243,23 @@ export default OakComponent({
const user = users.find((ele) => ele.id === idRemove);
const relations = user.userRelation$user;
try {
this.updateItem(
{
userRelation$user: [
{
id: generateNewId(),
action: 'remove',
data: {},
filter: {
id: {
$in: relations.map((ele) => ele.id),
},
this.updateItem({
userRelation$user: [
{
id: generateNewId(),
action: 'remove',
data: {},
filter: {
id: {
$in: relations.map((ele) => ele.id),
},
},
],
},
idRemove,
'revoke'
);
},
],
}, idRemove, 'revoke');
await this.execute();
} catch (err) {
}
catch (err) {
if (err instanceof OakUserUnpermittedException) {
this.setMessage({
type: 'error',
@ -338,18 +287,16 @@ export default OakComponent({
this.refresh();
},
chooseActionMp(e) {
const { entity, entityId, redirectToAfterConfirm, qrCodeType } =
this.props;
const {
item: { mode },
} = e.detail;
const { entity, entityId, redirectToAfterConfirm, qrCodeType } = this.props;
const { item: { mode }, } = e.detail;
if (mode === 'byMobile') {
this.navigateTo({
url: '/userRelation/upsert/byMobile',
entity,
entityId,
});
} else {
}
else {
this.navigateTo({
url: '/userRelation/upsert/byUserEntityGrant',
entity,
@ -394,7 +341,8 @@ export default OakComponent({
const { idRemoveMp } = this.state;
try {
await this.confirmDelete(idRemoveMp);
} catch (err) {
}
catch (err) {
this.setState({
idRemoveMp: '',
});

View File

@ -1,6 +1,6 @@
import { EntityDict } from '../../../oak-app-domain';
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
type: "bind" | "login";
type: "login" | "bind";
url: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -399,11 +399,6 @@
}
}
}
:global {
.ant-popover-inner {
padding: 0 !important;
}
}
.subMenuContent {
display: flex;
flex-direction: row;

View File

@ -8,7 +8,7 @@ export type OpSchema = EntityShape & {
targetEntity: String<32>;
entity: String<32>;
entityId: String<64>;
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;
@ -19,7 +19,7 @@ export type Schema = EntityShape & {
targetEntity: String<32>;
entity: String<32>;
entityId: String<64>;
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;

View File

@ -26,7 +26,7 @@ export const desc = {
notNull: true,
type: "varchar",
params: {
length: 16
length: 24
}
},
data: {

View File

@ -7,7 +7,7 @@ import { String, Datetime } from "oak-domain/lib/types/DataType";
import * as User from "../User/Schema";
import * as OperEntity from "../OperEntity/Schema";
export type OpSchema = EntityShape & {
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;
@ -17,7 +17,7 @@ export type OpSchema = EntityShape & {
};
export type OpAttr = keyof OpSchema;
export type Schema = EntityShape & {
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;

View File

@ -5,7 +5,7 @@ export const desc = {
notNull: true,
type: "varchar",
params: {
length: 16
length: 24
}
},
data: {
@ -35,5 +35,19 @@ export const desc = {
}
},
actionType: "appendOnly",
actions
actions,
indexes: [
{
name: 'index_bornAt_operatorId',
attributes: [
{
name: 'bornAt',
direction: 'DESC',
},
{
name: "operatorId",
},
]
}
]
};

View File

@ -1,2 +1,2 @@
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>>)[];
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>>)[];
export default _default;

View File

@ -57,4 +57,4 @@ export declare function makeException<ED extends EntityDict & BaseEntityDict>(da
message?: string;
opRecords: SelectOpResult<ED>;
[A: string]: any;
}): OakException<BaseEntityDict> | undefined;
}): OakUploadException<EntityDict & BaseEntityDict> | OakTokenExpiredException<EntityDict & BaseEntityDict> | OakUserDisabledException<EntityDict & BaseEntityDict> | OakDistinguishUserException<EntityDict & BaseEntityDict> | OakException<ED> | OakNotEnoughMoneyException<EntityDict & BaseEntityDict> | OakMobileUnsetException<EntityDict & BaseEntityDict> | OakUserInfoUncompletedException<EntityDict & BaseEntityDict> | undefined;

View File

@ -1,2 +1,2 @@
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt>)[];
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt>)[];
export default checkers;

View File

@ -3,3 +3,4 @@ import { EntityDict } from '../oak-app-domain';
import { RuntimeCxt } from "../types/RuntimeCxt";
declare const checkers: Checker<EntityDict, 'user', RuntimeCxt>[];
export default checkers;
export declare const UserCheckers: Checker<EntityDict, 'user', RuntimeCxt>[];

View File

@ -1,7 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserCheckers = void 0;
const relation_1 = require("oak-domain/lib/store/relation");
const types_1 = require("oak-domain/lib/types");
const filter_1 = require("oak-domain/lib/store/filter");
const checkers = [
{
type: 'row',
@ -12,14 +14,15 @@ const checkers = [
}
},
{
type: 'relation',
type: 'logical',
action: ['remove', 'disable', 'enable'],
entity: 'user',
relationFilter: () => {
checker: (operation, context) => {
// 只有root才能进行操作
throw new types_1.OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
},
errMsg: '越权操作',
if (!context.isRoot()) {
throw new types_1.OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
}
}
},
{
type: 'data',
@ -40,48 +43,41 @@ const checkers = [
},
errMsg: '不能禁用root用户',
},
// {
// type: 'row',
// action: 'select',
// entity: 'user',
// filter: (operation, context) => {
// const systemId = context.getSystemId();
// // todo 查询用户 先不加systemId
// if (systemId) {
// return {
// id: {
// $in: {
// entity: 'userSystem',
// data: {
// userId: 1,
// },
// filter: {
// systemId,
// },
// },
// },
// };
// }
// },
// },
];
exports.default = checkers;
exports.UserCheckers = [
{
entity: 'user',
action: 'update',
type: 'relation',
relationFilter: (operation, context) => {
type: 'logical',
checker: (operation, context) => {
// 在大部分应用中除了root其他人不应该有权利更新其他人信息但是shadow用户应当除外
// 但这些条件不一定对所有的应用都成立应用如果有更复杂的用户相互更新策略就不要引入这个checker
// 这也是个例子如何对user这样的特殊对象进行权限控制
const userId = context.getCurrentUserId();
const { data } = operation;
if (context.isRoot()) {
return;
}
const { filter, data } = operation;
for (const attr in data) {
const rel = (0, relation_1.judgeRelation)(context.getSchema(), 'user', attr);
if (rel === 1) {
return {
id: userId,
};
if (rel !== 1) {
throw new types_1.OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
}
return undefined;
const result = (0, filter_1.checkFilterContains)('user', context, {
id: userId,
}, filter, true);
if (result instanceof Promise) {
return result.then((r) => {
if (!r) {
throw new types_1.OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
});
}
if (!result) {
throw new types_1.OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
},
errMsg: '您不能更新他人信息',
}
];
exports.default = checkers;

View File

@ -8,7 +8,7 @@ export type OpSchema = EntityShape & {
targetEntity: String<32>;
entity: String<32>;
entityId: String<64>;
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;
@ -19,7 +19,7 @@ export type Schema = EntityShape & {
targetEntity: String<32>;
entity: String<32>;
entityId: String<64>;
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;

View File

@ -29,7 +29,7 @@ exports.desc = {
notNull: true,
type: "varchar",
params: {
length: 16
length: 24
}
},
data: {

View File

@ -7,7 +7,7 @@ import { String, Datetime } from "oak-domain/lib/types/DataType";
import * as User from "../User/Schema";
import * as OperEntity from "../OperEntity/Schema";
export type OpSchema = EntityShape & {
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;
@ -17,7 +17,7 @@ export type OpSchema = EntityShape & {
};
export type OpAttr = keyof OpSchema;
export type Schema = EntityShape & {
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;

View File

@ -8,7 +8,7 @@ exports.desc = {
notNull: true,
type: "varchar",
params: {
length: 16
length: 24
}
},
data: {
@ -38,5 +38,19 @@ exports.desc = {
}
},
actionType: "appendOnly",
actions: action_1.appendOnlyActions
actions: action_1.appendOnlyActions,
indexes: [
{
name: 'index_bornAt_operatorId',
attributes: [
{
name: 'bornAt',
direction: 'DESC',
},
{
name: "operatorId",
},
]
}
]
};

View File

@ -1,2 +1,2 @@
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>>)[];
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "account", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").RuntimeCxt> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BackendRuntimeContext<import("../oak-app-domain").EntityDict>>)[];
export default _default;

View File

@ -57,4 +57,4 @@ export declare function makeException<ED extends EntityDict & BaseEntityDict>(da
message?: string;
opRecords: SelectOpResult<ED>;
[A: string]: any;
}): OakException<BaseEntityDict> | undefined;
}): OakUploadException<EntityDict & BaseEntityDict> | OakTokenExpiredException<EntityDict & BaseEntityDict> | OakUserDisabledException<EntityDict & BaseEntityDict> | OakDistinguishUserException<EntityDict & BaseEntityDict> | OakException<ED> | OakNotEnoughMoneyException<EntityDict & BaseEntityDict> | OakMobileUnsetException<EntityDict & BaseEntityDict> | OakUserInfoUncompletedException<EntityDict & BaseEntityDict> | undefined;

View File

@ -1,6 +1,6 @@
import { judgeRelation } from "oak-domain/lib/store/relation";
import { OakInputIllegalException, Checker, OakUserUnpermittedException } from "oak-domain/lib/types";
import { ROOT_ROLE_ID } from "../constants";
import { checkFilterContains } from 'oak-domain/lib/store/filter';
import { EntityDict } from '../oak-app-domain';
import { RuntimeCxt } from "../types/RuntimeCxt";
@ -14,14 +14,15 @@ const checkers: Checker<EntityDict, 'user', RuntimeCxt> [] = [
}
},
{
type: 'relation',
type: 'logical',
action: ['remove', 'disable', 'enable'],
entity: 'user',
relationFilter: () => {
checker: (operation, context) => {
// 只有root才能进行操作
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
},
errMsg: '越权操作',
if (!context.isRoot()) {
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
}
}
},
{
type: 'data',
@ -42,49 +43,46 @@ const checkers: Checker<EntityDict, 'user', RuntimeCxt> [] = [
},
errMsg: '不能禁用root用户',
},
// {
// type: 'row',
// action: 'select',
// entity: 'user',
// filter: (operation, context) => {
// const systemId = context.getSystemId();
// // todo 查询用户 先不加systemId
// if (systemId) {
// return {
// id: {
// $in: {
// entity: 'userSystem',
// data: {
// userId: 1,
// },
// filter: {
// systemId,
// },
// },
// },
// };
// }
// },
// },
{
entity: 'user',
action: 'update',
type: 'relation',
relationFilter: (operation, context) => {
const userId = context.getCurrentUserId();
const { data } = operation as EntityDict['user']['Update'];
for (const attr in data) {
const rel = judgeRelation(context.getSchema(), 'user', attr);
if (rel === 1) {
return {
id: userId,
};
}
}
return undefined;
},
errMsg: '您不能更新他人信息',
}
];
export default checkers;
export const UserCheckers: Checker<EntityDict, 'user', RuntimeCxt>[] = [
{
entity: 'user',
action: 'update',
type: 'logical',
checker: (operation, context) => {
// 在大部分应用中除了root其他人不应该有权利更新其他人信息但是shadow用户应当除外
// 但这些条件不一定对所有的应用都成立应用如果有更复杂的用户相互更新策略就不要引入这个checker
// 这也是个例子如何对user这样的特殊对象进行权限控制
const userId = context.getCurrentUserId();
if (context.isRoot()) {
return;
}
const { filter, data } = operation as EntityDict['user']['Update'];
for (const attr in data) {
const rel = judgeRelation(context.getSchema(), 'user', attr);
if (rel !== 1) {
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
}
const result = checkFilterContains<EntityDict, 'user', RuntimeCxt>('user', context, {
id: userId,
}, filter, true);
if (result instanceof Promise) {
return result.then(
(r) => {
if (!r) {
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
}
);
}
if (!result) {
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
}
},
}
];

View File

@ -10,7 +10,7 @@ export type OpSchema = EntityShape & {
targetEntity: String<32>;
entity: String<32>;
entityId: String<64>;
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;
@ -21,7 +21,7 @@ export type Schema = EntityShape & {
targetEntity: String<32>;
entity: String<32>;
entityId: String<64>;
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;

View File

@ -28,7 +28,7 @@ export const desc: StorageDesc<OpSchema> = {
notNull: true,
type: "varchar",
params: {
length: 16
length: 24
}
},
data: {

View File

@ -7,7 +7,7 @@ import { String, Datetime } from "oak-domain/lib/types/DataType";
import * as User from "../User/Schema";
import * as OperEntity from "../OperEntity/Schema";
export type OpSchema = EntityShape & {
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;
@ -17,7 +17,7 @@ export type OpSchema = EntityShape & {
};
export type OpAttr = keyof OpSchema;
export type Schema = EntityShape & {
action: String<16>;
action: String<24>;
data: Object;
filter?: Object | null;
extra?: Object | null;

View File

@ -7,7 +7,7 @@ export const desc: StorageDesc<OpSchema> = {
notNull: true,
type: "varchar",
params: {
length: 16
length: 24
}
},
data: {
@ -37,5 +37,19 @@ export const desc: StorageDesc<OpSchema> = {
}
},
actionType: "appendOnly",
actions
actions,
indexes: [
{
name: 'index_bornAt_operatorId',
attributes: [
{
name: 'bornAt',
direction: 'DESC',
},
{
name: "operatorId",
},
]
}
]
};