适配了domain的修正,去掉了relation类型的checker
This commit is contained in:
parent
2b3d4d2dcb
commit
b65744dacd
|
|
@ -66,3 +66,4 @@ build
|
||||||
package-lock.json
|
package-lock.json
|
||||||
scripts/local
|
scripts/local
|
||||||
*tsbuildinfo
|
*tsbuildinfo
|
||||||
|
src/oak-app-domain
|
||||||
|
|
@ -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;
|
export default checkers;
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ import { EntityDict } from '../oak-app-domain';
|
||||||
import { RuntimeCxt } from "../types/RuntimeCxt";
|
import { RuntimeCxt } from "../types/RuntimeCxt";
|
||||||
declare const checkers: Checker<EntityDict, 'user', RuntimeCxt>[];
|
declare const checkers: Checker<EntityDict, 'user', RuntimeCxt>[];
|
||||||
export default checkers;
|
export default checkers;
|
||||||
|
export declare const UserCheckers: Checker<EntityDict, 'user', RuntimeCxt>[];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { judgeRelation } from "oak-domain/lib/store/relation";
|
import { judgeRelation } from "oak-domain/lib/store/relation";
|
||||||
import { OakInputIllegalException, OakUserUnpermittedException } from "oak-domain/lib/types";
|
import { OakInputIllegalException, OakUserUnpermittedException } from "oak-domain/lib/types";
|
||||||
|
import { checkFilterContains } from 'oak-domain/lib/store/filter';
|
||||||
const checkers = [
|
const checkers = [
|
||||||
{
|
{
|
||||||
type: 'row',
|
type: 'row',
|
||||||
|
|
@ -10,14 +11,15 @@ const checkers = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'relation',
|
type: 'logical',
|
||||||
action: ['remove', 'disable', 'enable'],
|
action: ['remove', 'disable', 'enable'],
|
||||||
entity: 'user',
|
entity: 'user',
|
||||||
relationFilter: () => {
|
checker: (operation, context) => {
|
||||||
// 只有root才能进行操作
|
// 只有root才能进行操作
|
||||||
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
|
if (!context.isRoot()) {
|
||||||
},
|
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
|
||||||
errMsg: '越权操作',
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'data',
|
type: 'data',
|
||||||
|
|
@ -38,48 +40,41 @@ const checkers = [
|
||||||
},
|
},
|
||||||
errMsg: '不能禁用root用户',
|
errMsg: '不能禁用root用户',
|
||||||
},
|
},
|
||||||
// {
|
];
|
||||||
// type: 'row',
|
export default checkers;
|
||||||
// action: 'select',
|
export const UserCheckers = [
|
||||||
// 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',
|
entity: 'user',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
type: 'relation',
|
type: 'logical',
|
||||||
relationFilter: (operation, context) => {
|
checker: (operation, context) => {
|
||||||
|
// 在大部分应用中,除了root,其他人不应该有权利更新其他人信息,但是shadow用户应当除外
|
||||||
|
// 但这些条件不一定对所有的应用都成立,应用如果有更复杂的用户相互更新策略,就不要引入这个checker
|
||||||
|
// 这也是个例子,如何对user这样的特殊对象进行权限控制
|
||||||
const userId = context.getCurrentUserId();
|
const userId = context.getCurrentUserId();
|
||||||
const { data } = operation;
|
if (context.isRoot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { filter, data } = operation;
|
||||||
for (const attr in data) {
|
for (const attr in data) {
|
||||||
const rel = judgeRelation(context.getSchema(), 'user', attr);
|
const rel = judgeRelation(context.getSchema(), 'user', attr);
|
||||||
if (rel === 1) {
|
if (rel !== 1) {
|
||||||
return {
|
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
|
||||||
id: userId,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Style } from '../../../../types/Style';
|
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, {
|
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../../oak-app-domain").EntityDict, keyof import("../../../../oak-app-domain").EntityDict, false, {
|
||||||
style: Style;
|
style: Style;
|
||||||
entity: "application" | "system" | "platform";
|
entity: "platform" | "application" | "system";
|
||||||
entityId: string;
|
entityId: string;
|
||||||
name: string;
|
name: string;
|
||||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Config } from '../../../types/Config';
|
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, {
|
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||||
config: Config;
|
config: Config;
|
||||||
entity: "system" | "platform";
|
entity: "platform" | "system";
|
||||||
name: string;
|
name: string;
|
||||||
entityId: string;
|
entityId: string;
|
||||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
||||||
type?: ButtonProps['type'] | AmButtonProps['type'];
|
type?: ButtonProps['type'] | AmButtonProps['type'];
|
||||||
executeText?: string | undefined;
|
executeText?: string | undefined;
|
||||||
buttonProps?: (ButtonProps & {
|
buttonProps?: (ButtonProps & {
|
||||||
color?: "primary" | "success" | "warning" | "default" | "danger" | undefined;
|
color?: "success" | "default" | "warning" | "primary" | "danger" | undefined;
|
||||||
fill?: "none" | "solid" | "outline" | undefined;
|
fill?: "none" | "solid" | "outline" | undefined;
|
||||||
size?: "small" | "large" | "middle" | "mini" | undefined;
|
size?: "small" | "middle" | "large" | "mini" | undefined;
|
||||||
block?: boolean | undefined;
|
block?: boolean | undefined;
|
||||||
loading?: boolean | "auto" | undefined;
|
loading?: boolean | "auto" | undefined;
|
||||||
loadingText?: string | undefined;
|
loadingText?: string | undefined;
|
||||||
|
|
@ -24,7 +24,7 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
||||||
type?: "reset" | "submit" | "button" | undefined;
|
type?: "reset" | "submit" | "button" | undefined;
|
||||||
shape?: "default" | "rounded" | "rectangular" | undefined;
|
shape?: "default" | "rounded" | "rectangular" | undefined;
|
||||||
children?: import("react").ReactNode;
|
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;
|
className?: string | undefined;
|
||||||
style?: (import("react").CSSProperties & Partial<Record<"--text-color" | "--background-color" | "--border-radius" | "--border-width" | "--border-style" | "--border-color", 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;
|
tabIndex?: number | undefined;
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
return {
|
||||||
userRelation$user: filter,
|
userRelation$user: filter,
|
||||||
/* id: {
|
|
||||||
$in: {
|
|
||||||
entity: 'userRelation',
|
|
||||||
data: {
|
|
||||||
userId: 1,
|
|
||||||
},
|
|
||||||
filter,
|
|
||||||
},
|
|
||||||
}, */
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -167,19 +137,15 @@ export default OakComponent({
|
||||||
const filter = this.getFilterByName('fulltext');
|
const filter = this.getFilterByName('fulltext');
|
||||||
const users = props.disableDisplay
|
const users = props.disableDisplay
|
||||||
? rows?.filter((ele) => {
|
? rows?.filter((ele) => {
|
||||||
const userRelations = ele.userRelation$user?.filter(
|
const userRelations = ele.userRelation$user?.filter((ele) => !ele.$$deleteAt$$);
|
||||||
(ele) => !ele.$$deleteAt$$
|
return !!(userRelations && userRelations.length > 0);
|
||||||
);
|
})
|
||||||
return !!(userRelations && userRelations.length > 0);
|
|
||||||
})
|
|
||||||
: rows;
|
: rows;
|
||||||
return {
|
return {
|
||||||
users: users?.map((ele) => {
|
users: users?.map((ele) => {
|
||||||
const { mobile$user, extraFile$entity } = ele;
|
const { mobile$user, extraFile$entity } = ele;
|
||||||
const mobile = mobile$user && mobile$user[0]?.mobile;
|
const mobile = mobile$user && mobile$user[0]?.mobile;
|
||||||
const avatar = features.extraFile.getUrl(
|
const avatar = features.extraFile.getUrl(extraFile$entity && extraFile$entity[0]);
|
||||||
extraFile$entity && extraFile$entity[0]
|
|
||||||
);
|
|
||||||
const user2 = Object.assign({}, ele, {
|
const user2 = Object.assign({}, ele, {
|
||||||
mobile,
|
mobile,
|
||||||
avatar,
|
avatar,
|
||||||
|
|
@ -195,8 +161,8 @@ export default OakComponent({
|
||||||
redirectToAfterConfirm: {},
|
redirectToAfterConfirm: {},
|
||||||
claimUrl: '',
|
claimUrl: '',
|
||||||
qrCodeType: '',
|
qrCodeType: '',
|
||||||
onUpdate: (id) => {},
|
onUpdate: (id) => { },
|
||||||
onCreate: () => {},
|
onCreate: () => { },
|
||||||
disableDisplay: false,
|
disableDisplay: false,
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -217,10 +183,8 @@ export default OakComponent({
|
||||||
listeners: {
|
listeners: {
|
||||||
'entity,entityId'(prev, next) {
|
'entity,entityId'(prev, next) {
|
||||||
if (this.state.oakFullpath) {
|
if (this.state.oakFullpath) {
|
||||||
if (
|
if (prev.entity !== next.entity ||
|
||||||
prev.entity !== next.entity ||
|
prev.entityId !== next.entityId) {
|
||||||
prev.entityId !== next.entityId
|
|
||||||
) {
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -236,45 +200,33 @@ export default OakComponent({
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
goUpsert() {
|
goUpsert() {
|
||||||
const {
|
const { entity, entityId, redirectToAfterConfirm, qrCodeType, claimUrl, onCreate, } = this.props;
|
||||||
entity,
|
|
||||||
entityId,
|
|
||||||
redirectToAfterConfirm,
|
|
||||||
qrCodeType,
|
|
||||||
claimUrl,
|
|
||||||
onCreate,
|
|
||||||
} = this.props;
|
|
||||||
if (onCreate) {
|
if (onCreate) {
|
||||||
onCreate();
|
onCreate();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
console.warn(
|
console.warn('userRelation将不再作为page直接使用,请使用回调函数处理');
|
||||||
'userRelation将不再作为page直接使用,请使用回调函数处理'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
this.navigateTo(
|
this.navigateTo({
|
||||||
{
|
url: '/userRelation/upsert',
|
||||||
url: '/userRelation/upsert',
|
entity,
|
||||||
entity,
|
entityId,
|
||||||
entityId,
|
}, {
|
||||||
},
|
redirectToAfterConfirm,
|
||||||
{
|
qrCodeType,
|
||||||
redirectToAfterConfirm,
|
claimUrl,
|
||||||
qrCodeType,
|
});
|
||||||
claimUrl,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
goUpdate(id) {
|
goUpdate(id) {
|
||||||
const { entity, entityId, onUpdate } = this.props;
|
const { entity, entityId, onUpdate } = this.props;
|
||||||
if (onUpdate) {
|
if (onUpdate) {
|
||||||
onUpdate(id);
|
onUpdate(id);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
console.warn(
|
console.warn('userRelation将不再作为page直接使用,请使用回调函数处理');
|
||||||
'userRelation将不再作为page直接使用,请使用回调函数处理'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
this.navigateTo({
|
this.navigateTo({
|
||||||
url: '/userRelation/upsert/byUser',
|
url: '/userRelation/upsert/byUser',
|
||||||
|
|
@ -291,26 +243,23 @@ export default OakComponent({
|
||||||
const user = users.find((ele) => ele.id === idRemove);
|
const user = users.find((ele) => ele.id === idRemove);
|
||||||
const relations = user.userRelation$user;
|
const relations = user.userRelation$user;
|
||||||
try {
|
try {
|
||||||
this.updateItem(
|
this.updateItem({
|
||||||
{
|
userRelation$user: [
|
||||||
userRelation$user: [
|
{
|
||||||
{
|
id: generateNewId(),
|
||||||
id: generateNewId(),
|
action: 'remove',
|
||||||
action: 'remove',
|
data: {},
|
||||||
data: {},
|
filter: {
|
||||||
filter: {
|
id: {
|
||||||
id: {
|
$in: relations.map((ele) => ele.id),
|
||||||
$in: relations.map((ele) => ele.id),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
},
|
||||||
},
|
],
|
||||||
idRemove,
|
}, idRemove, 'revoke');
|
||||||
'revoke'
|
|
||||||
);
|
|
||||||
await this.execute();
|
await this.execute();
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
if (err instanceof OakUserUnpermittedException) {
|
if (err instanceof OakUserUnpermittedException) {
|
||||||
this.setMessage({
|
this.setMessage({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
|
|
@ -338,18 +287,16 @@ export default OakComponent({
|
||||||
this.refresh();
|
this.refresh();
|
||||||
},
|
},
|
||||||
chooseActionMp(e) {
|
chooseActionMp(e) {
|
||||||
const { entity, entityId, redirectToAfterConfirm, qrCodeType } =
|
const { entity, entityId, redirectToAfterConfirm, qrCodeType } = this.props;
|
||||||
this.props;
|
const { item: { mode }, } = e.detail;
|
||||||
const {
|
|
||||||
item: { mode },
|
|
||||||
} = e.detail;
|
|
||||||
if (mode === 'byMobile') {
|
if (mode === 'byMobile') {
|
||||||
this.navigateTo({
|
this.navigateTo({
|
||||||
url: '/userRelation/upsert/byMobile',
|
url: '/userRelation/upsert/byMobile',
|
||||||
entity,
|
entity,
|
||||||
entityId,
|
entityId,
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
this.navigateTo({
|
this.navigateTo({
|
||||||
url: '/userRelation/upsert/byUserEntityGrant',
|
url: '/userRelation/upsert/byUserEntityGrant',
|
||||||
entity,
|
entity,
|
||||||
|
|
@ -394,7 +341,8 @@ export default OakComponent({
|
||||||
const { idRemoveMp } = this.state;
|
const { idRemoveMp } = this.state;
|
||||||
try {
|
try {
|
||||||
await this.confirmDelete(idRemoveMp);
|
await this.confirmDelete(idRemoveMp);
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
this.setState({
|
this.setState({
|
||||||
idRemoveMp: '',
|
idRemoveMp: '',
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { EntityDict } from '../../../oak-app-domain';
|
import { EntityDict } from '../../../oak-app-domain';
|
||||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
|
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, keyof EntityDict, false, {
|
||||||
type: "bind" | "login";
|
type: "login" | "bind";
|
||||||
url: string;
|
url: string;
|
||||||
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
||||||
export default _default;
|
export default _default;
|
||||||
|
|
|
||||||
|
|
@ -399,11 +399,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:global {
|
|
||||||
.ant-popover-inner {
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.subMenuContent {
|
.subMenuContent {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export type OpSchema = EntityShape & {
|
||||||
targetEntity: String<32>;
|
targetEntity: String<32>;
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
@ -19,7 +19,7 @@ export type Schema = EntityShape & {
|
||||||
targetEntity: String<32>;
|
targetEntity: String<32>;
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export const desc = {
|
||||||
notNull: true,
|
notNull: true,
|
||||||
type: "varchar",
|
type: "varchar",
|
||||||
params: {
|
params: {
|
||||||
length: 16
|
length: 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { String, Datetime } from "oak-domain/lib/types/DataType";
|
||||||
import * as User from "../User/Schema";
|
import * as User from "../User/Schema";
|
||||||
import * as OperEntity from "../OperEntity/Schema";
|
import * as OperEntity from "../OperEntity/Schema";
|
||||||
export type OpSchema = EntityShape & {
|
export type OpSchema = EntityShape & {
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
@ -17,7 +17,7 @@ export type OpSchema = EntityShape & {
|
||||||
};
|
};
|
||||||
export type OpAttr = keyof OpSchema;
|
export type OpAttr = keyof OpSchema;
|
||||||
export type Schema = EntityShape & {
|
export type Schema = EntityShape & {
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export const desc = {
|
||||||
notNull: true,
|
notNull: true,
|
||||||
type: "varchar",
|
type: "varchar",
|
||||||
params: {
|
params: {
|
||||||
length: 16
|
length: 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -35,5 +35,19 @@ export const desc = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actionType: "appendOnly",
|
actionType: "appendOnly",
|
||||||
actions
|
actions,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'index_bornAt_operatorId',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'bornAt',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "operatorId",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
export default _default;
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,4 @@ export declare function makeException<ED extends EntityDict & BaseEntityDict>(da
|
||||||
message?: string;
|
message?: string;
|
||||||
opRecords: SelectOpResult<ED>;
|
opRecords: SelectOpResult<ED>;
|
||||||
[A: string]: any;
|
[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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
export default checkers;
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ import { EntityDict } from '../oak-app-domain';
|
||||||
import { RuntimeCxt } from "../types/RuntimeCxt";
|
import { RuntimeCxt } from "../types/RuntimeCxt";
|
||||||
declare const checkers: Checker<EntityDict, 'user', RuntimeCxt>[];
|
declare const checkers: Checker<EntityDict, 'user', RuntimeCxt>[];
|
||||||
export default checkers;
|
export default checkers;
|
||||||
|
export declare const UserCheckers: Checker<EntityDict, 'user', RuntimeCxt>[];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.UserCheckers = void 0;
|
||||||
const relation_1 = require("oak-domain/lib/store/relation");
|
const relation_1 = require("oak-domain/lib/store/relation");
|
||||||
const types_1 = require("oak-domain/lib/types");
|
const types_1 = require("oak-domain/lib/types");
|
||||||
|
const filter_1 = require("oak-domain/lib/store/filter");
|
||||||
const checkers = [
|
const checkers = [
|
||||||
{
|
{
|
||||||
type: 'row',
|
type: 'row',
|
||||||
|
|
@ -12,14 +14,15 @@ const checkers = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'relation',
|
type: 'logical',
|
||||||
action: ['remove', 'disable', 'enable'],
|
action: ['remove', 'disable', 'enable'],
|
||||||
entity: 'user',
|
entity: 'user',
|
||||||
relationFilter: () => {
|
checker: (operation, context) => {
|
||||||
// 只有root才能进行操作
|
// 只有root才能进行操作
|
||||||
throw new types_1.OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
|
if (!context.isRoot()) {
|
||||||
},
|
throw new types_1.OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
|
||||||
errMsg: '越权操作',
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'data',
|
type: 'data',
|
||||||
|
|
@ -40,48 +43,41 @@ const checkers = [
|
||||||
},
|
},
|
||||||
errMsg: '不能禁用root用户',
|
errMsg: '不能禁用root用户',
|
||||||
},
|
},
|
||||||
// {
|
];
|
||||||
// type: 'row',
|
exports.default = checkers;
|
||||||
// action: 'select',
|
exports.UserCheckers = [
|
||||||
// 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',
|
entity: 'user',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
type: 'relation',
|
type: 'logical',
|
||||||
relationFilter: (operation, context) => {
|
checker: (operation, context) => {
|
||||||
|
// 在大部分应用中,除了root,其他人不应该有权利更新其他人信息,但是shadow用户应当除外
|
||||||
|
// 但这些条件不一定对所有的应用都成立,应用如果有更复杂的用户相互更新策略,就不要引入这个checker
|
||||||
|
// 这也是个例子,如何对user这样的特殊对象进行权限控制
|
||||||
const userId = context.getCurrentUserId();
|
const userId = context.getCurrentUserId();
|
||||||
const { data } = operation;
|
if (context.isRoot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { filter, data } = operation;
|
||||||
for (const attr in data) {
|
for (const attr in data) {
|
||||||
const rel = (0, relation_1.judgeRelation)(context.getSchema(), 'user', attr);
|
const rel = (0, relation_1.judgeRelation)(context.getSchema(), 'user', attr);
|
||||||
if (rel === 1) {
|
if (rel !== 1) {
|
||||||
return {
|
throw new types_1.OakUserUnpermittedException('user', operation, '您不能更新他人信息');
|
||||||
id: userId,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export type OpSchema = EntityShape & {
|
||||||
targetEntity: String<32>;
|
targetEntity: String<32>;
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
@ -19,7 +19,7 @@ export type Schema = EntityShape & {
|
||||||
targetEntity: String<32>;
|
targetEntity: String<32>;
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ exports.desc = {
|
||||||
notNull: true,
|
notNull: true,
|
||||||
type: "varchar",
|
type: "varchar",
|
||||||
params: {
|
params: {
|
||||||
length: 16
|
length: 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { String, Datetime } from "oak-domain/lib/types/DataType";
|
||||||
import * as User from "../User/Schema";
|
import * as User from "../User/Schema";
|
||||||
import * as OperEntity from "../OperEntity/Schema";
|
import * as OperEntity from "../OperEntity/Schema";
|
||||||
export type OpSchema = EntityShape & {
|
export type OpSchema = EntityShape & {
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
@ -17,7 +17,7 @@ export type OpSchema = EntityShape & {
|
||||||
};
|
};
|
||||||
export type OpAttr = keyof OpSchema;
|
export type OpAttr = keyof OpSchema;
|
||||||
export type Schema = EntityShape & {
|
export type Schema = EntityShape & {
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ exports.desc = {
|
||||||
notNull: true,
|
notNull: true,
|
||||||
type: "varchar",
|
type: "varchar",
|
||||||
params: {
|
params: {
|
||||||
length: 16
|
length: 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -38,5 +38,19 @@ exports.desc = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actionType: "appendOnly",
|
actionType: "appendOnly",
|
||||||
actions: action_1.appendOnlyActions
|
actions: action_1.appendOnlyActions,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'index_bornAt_operatorId',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'bornAt',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "operatorId",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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;
|
export default _default;
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,4 @@ export declare function makeException<ED extends EntityDict & BaseEntityDict>(da
|
||||||
message?: string;
|
message?: string;
|
||||||
opRecords: SelectOpResult<ED>;
|
opRecords: SelectOpResult<ED>;
|
||||||
[A: string]: any;
|
[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;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { judgeRelation } from "oak-domain/lib/store/relation";
|
import { judgeRelation } from "oak-domain/lib/store/relation";
|
||||||
import { OakInputIllegalException, Checker, OakUserUnpermittedException } from "oak-domain/lib/types";
|
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 { EntityDict } from '../oak-app-domain';
|
||||||
import { RuntimeCxt } from "../types/RuntimeCxt";
|
import { RuntimeCxt } from "../types/RuntimeCxt";
|
||||||
|
|
||||||
|
|
@ -14,14 +14,15 @@ const checkers: Checker<EntityDict, 'user', RuntimeCxt> [] = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'relation',
|
type: 'logical',
|
||||||
action: ['remove', 'disable', 'enable'],
|
action: ['remove', 'disable', 'enable'],
|
||||||
entity: 'user',
|
entity: 'user',
|
||||||
relationFilter: () => {
|
checker: (operation, context) => {
|
||||||
// 只有root才能进行操作
|
// 只有root才能进行操作
|
||||||
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
|
if (!context.isRoot()) {
|
||||||
},
|
throw new OakUserUnpermittedException('user', { id: 'disable', action: 'disable', data: {} });
|
||||||
errMsg: '越权操作',
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'data',
|
type: 'data',
|
||||||
|
|
@ -42,49 +43,46 @@ const checkers: Checker<EntityDict, 'user', RuntimeCxt> [] = [
|
||||||
},
|
},
|
||||||
errMsg: '不能禁用root用户',
|
errMsg: '不能禁用root用户',
|
||||||
},
|
},
|
||||||
// {
|
];
|
||||||
// type: 'row',
|
|
||||||
// action: 'select',
|
export default checkers;
|
||||||
// entity: 'user',
|
|
||||||
// filter: (operation, context) => {
|
export const UserCheckers: Checker<EntityDict, 'user', RuntimeCxt>[] = [
|
||||||
// const systemId = context.getSystemId();
|
|
||||||
// // todo 查询用户 先不加systemId
|
|
||||||
// if (systemId) {
|
|
||||||
// return {
|
|
||||||
// id: {
|
|
||||||
// $in: {
|
|
||||||
// entity: 'userSystem',
|
|
||||||
// data: {
|
|
||||||
// userId: 1,
|
|
||||||
// },
|
|
||||||
// filter: {
|
|
||||||
// systemId,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
entity: 'user',
|
entity: 'user',
|
||||||
action: 'update',
|
action: 'update',
|
||||||
type: 'relation',
|
type: 'logical',
|
||||||
relationFilter: (operation, context) => {
|
checker: (operation, context) => {
|
||||||
const userId = context.getCurrentUserId();
|
// 在大部分应用中,除了root,其他人不应该有权利更新其他人信息,但是shadow用户应当除外
|
||||||
const { data } = operation as EntityDict['user']['Update'];
|
// 但这些条件不一定对所有的应用都成立,应用如果有更复杂的用户相互更新策略,就不要引入这个checker
|
||||||
|
// 这也是个例子,如何对user这样的特殊对象进行权限控制
|
||||||
|
const userId = context.getCurrentUserId();
|
||||||
|
if (context.isRoot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { filter, data } = operation as EntityDict['user']['Update'];
|
||||||
for (const attr in data) {
|
for (const attr in data) {
|
||||||
const rel = judgeRelation(context.getSchema(), 'user', attr);
|
const rel = judgeRelation(context.getSchema(), 'user', attr);
|
||||||
if (rel === 1) {
|
if (rel !== 1) {
|
||||||
return {
|
throw new OakUserUnpermittedException('user', operation, '您不能更新他人信息');
|
||||||
id: userId,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undefined;
|
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, '您不能更新他人信息');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
errMsg: '您不能更新他人信息',
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
export default checkers;
|
|
||||||
|
|
@ -10,7 +10,7 @@ export type OpSchema = EntityShape & {
|
||||||
targetEntity: String<32>;
|
targetEntity: String<32>;
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
@ -21,7 +21,7 @@ export type Schema = EntityShape & {
|
||||||
targetEntity: String<32>;
|
targetEntity: String<32>;
|
||||||
entity: String<32>;
|
entity: String<32>;
|
||||||
entityId: String<64>;
|
entityId: String<64>;
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ export const desc: StorageDesc<OpSchema> = {
|
||||||
notNull: true,
|
notNull: true,
|
||||||
type: "varchar",
|
type: "varchar",
|
||||||
params: {
|
params: {
|
||||||
length: 16
|
length: 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { String, Datetime } from "oak-domain/lib/types/DataType";
|
||||||
import * as User from "../User/Schema";
|
import * as User from "../User/Schema";
|
||||||
import * as OperEntity from "../OperEntity/Schema";
|
import * as OperEntity from "../OperEntity/Schema";
|
||||||
export type OpSchema = EntityShape & {
|
export type OpSchema = EntityShape & {
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
@ -17,7 +17,7 @@ export type OpSchema = EntityShape & {
|
||||||
};
|
};
|
||||||
export type OpAttr = keyof OpSchema;
|
export type OpAttr = keyof OpSchema;
|
||||||
export type Schema = EntityShape & {
|
export type Schema = EntityShape & {
|
||||||
action: String<16>;
|
action: String<24>;
|
||||||
data: Object;
|
data: Object;
|
||||||
filter?: Object | null;
|
filter?: Object | null;
|
||||||
extra?: Object | null;
|
extra?: Object | null;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export const desc: StorageDesc<OpSchema> = {
|
||||||
notNull: true,
|
notNull: true,
|
||||||
type: "varchar",
|
type: "varchar",
|
||||||
params: {
|
params: {
|
||||||
length: 16
|
length: 24
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
|
|
@ -37,5 +37,19 @@ export const desc: StorageDesc<OpSchema> = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actionType: "appendOnly",
|
actionType: "appendOnly",
|
||||||
actions
|
actions,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
name: 'index_bornAt_operatorId',
|
||||||
|
attributes: [
|
||||||
|
{
|
||||||
|
name: 'bornAt',
|
||||||
|
direction: 'DESC',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "operatorId",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
};
|
};
|
||||||
Loading…
Reference in New Issue