mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 03:46:08 +00:00
fix(custom-request): permission issues (#3306)
* fix(custom-request-plugin): cannot see custom request action in non-root role when acl doesn't set * fix: list all roles * feat: display all roles * feat: support * fix: remove unused code * fix: options is null * fix: translation * fix: migration error --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
1adaa53c2b
commit
8ab69500c7
@ -191,6 +191,7 @@
|
||||
"Insert if not exists, or update": "Insert if not exists, or update",
|
||||
"Determine whether a record exists by the following fields": "Determine whether a record exists by the following fields",
|
||||
"Update": "Update",
|
||||
"Update record": "Update record",
|
||||
"View": "View",
|
||||
"View record": "View record",
|
||||
"Refresh": "Refresh",
|
||||
|
@ -200,6 +200,7 @@
|
||||
"Action type": "操作类型",
|
||||
"Actions": "操作",
|
||||
"Update": "更新",
|
||||
"Update record": "更新数据",
|
||||
"View": "查看",
|
||||
"View record": "查看数据",
|
||||
"Refresh": "刷新",
|
||||
|
@ -13,6 +13,7 @@ export const BlockInitializer = (props) => {
|
||||
const s = merge(schema || {}, item.schema || {});
|
||||
item?.schemaInitialize?.(s);
|
||||
insert(s);
|
||||
props.onClick?.(s);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Action, useAPIClient, useRequest } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
import { CustomRequestActionDesigner } from './CustomRequestActionDesigner';
|
||||
import { useFieldSchema } from '@formily/react';
|
||||
import { listByCurrentRoleUrl } from '../constants';
|
||||
import { useCustomizeRequestActionProps } from '../hooks';
|
||||
import { CustomRequestActionDesigner } from './CustomRequestActionDesigner';
|
||||
|
||||
export const CustomRequestActionACLDecorator = (props) => {
|
||||
const apiClient = useAPIClient();
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
SchemaSettingsActionModalItem,
|
||||
actionSettingsItems,
|
||||
useCollection,
|
||||
useCurrentRoles,
|
||||
useRequest,
|
||||
} from '@nocobase/client';
|
||||
import React from 'react';
|
||||
@ -74,14 +73,11 @@ function CustomRequestACL() {
|
||||
},
|
||||
);
|
||||
|
||||
const currentRoles = useCurrentRoles();
|
||||
|
||||
return (
|
||||
<>
|
||||
<SchemaSettingsActionModalItem
|
||||
title={t('Access Control')}
|
||||
schema={CustomRequestACLSchema}
|
||||
scope={{ currentRoles }}
|
||||
initialValues={{
|
||||
roles: data?.data?.roles,
|
||||
}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useCollection, useCollectionFilterOptions, useCompile } from '@nocobase/client';
|
||||
import { useTranslation } from '../locale';
|
||||
import { useMemo } from 'react';
|
||||
import { useTranslation } from '../locale';
|
||||
|
||||
export const useCustomRequestVariableOptions = () => {
|
||||
const collection = useCollection();
|
||||
@ -16,17 +16,17 @@ export const useCustomRequestVariableOptions = () => {
|
||||
return [
|
||||
{
|
||||
name: 'currentRecord',
|
||||
title: t('Current record'),
|
||||
title: t('Current record', { ns: 'client' }),
|
||||
children: [...fields],
|
||||
},
|
||||
{
|
||||
name: 'currentUser',
|
||||
title: t('Current user'),
|
||||
title: t('Current user', { ns: 'client' }),
|
||||
children: userFields,
|
||||
},
|
||||
{
|
||||
name: 'currentTime',
|
||||
title: t('Current time'),
|
||||
title: t('Current time', { ns: 'client' }),
|
||||
children: null,
|
||||
},
|
||||
];
|
||||
|
@ -24,12 +24,10 @@ export const useCustomizeRequestActionProps = () => {
|
||||
const actionSchema = useFieldSchema();
|
||||
const compile = useCompile();
|
||||
const form = useForm();
|
||||
const { fields, getField, getPrimaryKey } = useCollection();
|
||||
const { field, resource, __parent, service } = useBlockRequestContext();
|
||||
const { getActiveFieldsName } = useFormActiveFields() || {};
|
||||
const { getPrimaryKey } = useCollection();
|
||||
const { resource, __parent, service } = useBlockRequestContext();
|
||||
const record = useRecord();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { data, runAsync } = useGetCustomRequest();
|
||||
const actionField = useField();
|
||||
const { setVisible } = useActionContext();
|
||||
const { modal, message } = App.useApp();
|
||||
@ -38,29 +36,14 @@ export const useCustomizeRequestActionProps = () => {
|
||||
return {
|
||||
async onClick() {
|
||||
const { skipValidator, onSuccess } = actionSchema?.['x-action-settings'] ?? {};
|
||||
const options = data ? data?.data?.options : (await runAsync())?.data?.options;
|
||||
if (!options?.['url']) {
|
||||
return message.error(t('Please configure the request settings first'));
|
||||
}
|
||||
const xAction = actionSchema?.['x-action'];
|
||||
if (skipValidator !== true && xAction === 'customize:form:request') {
|
||||
await form.submit();
|
||||
}
|
||||
|
||||
let formValues = {};
|
||||
const methods = ['POST', 'PUT', 'PATCH'];
|
||||
if (xAction === 'customize:form:request' && methods.includes(options['method'])) {
|
||||
const fieldNames = fields.map((field) => field.name);
|
||||
const values = getFormValues({
|
||||
filterByTk,
|
||||
field,
|
||||
form,
|
||||
fieldNames,
|
||||
getField,
|
||||
resource,
|
||||
actionFields: getActiveFieldsName?.('form') || [],
|
||||
});
|
||||
formValues = values;
|
||||
if (xAction === 'customize:form:request') {
|
||||
formValues = form.values;
|
||||
}
|
||||
|
||||
actionField.data ??= {};
|
||||
|
@ -27,14 +27,13 @@ export const CustomRequestInitializer: React.FC<any> = (props) => {
|
||||
<BlockInitializer
|
||||
{...itemConfig}
|
||||
item={itemConfig}
|
||||
insert={async (s) => {
|
||||
await customRequestsResource.updateOrCreate({
|
||||
onClick={async (s) => {
|
||||
// create a custom request
|
||||
await customRequestsResource.create({
|
||||
values: {
|
||||
key: s['x-uid'],
|
||||
},
|
||||
filterKeys: ['key'],
|
||||
});
|
||||
await props?.insert(s);
|
||||
}}
|
||||
schema={schema}
|
||||
/>
|
||||
|
@ -10,15 +10,18 @@ export const CustomRequestACLSchema = {
|
||||
'x-decorator-props': {
|
||||
tooltip: generateNTemplate('If not set, all roles can see this action'),
|
||||
},
|
||||
'x-component': 'Select',
|
||||
'x-component': 'RemoteSelect',
|
||||
'x-component-props': {
|
||||
multiple: true,
|
||||
objectValue: true,
|
||||
service: {
|
||||
resource: 'roles',
|
||||
},
|
||||
manual: false,
|
||||
fieldNames: {
|
||||
label: 'title',
|
||||
value: 'name',
|
||||
},
|
||||
objectValue: true,
|
||||
options: '{{ currentRoles }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Context, Next } from '@nocobase/actions';
|
||||
import { parse } from '@nocobase/utils';
|
||||
|
||||
import { appendArrayColumn } from '@nocobase/evaluators';
|
||||
import axios from 'axios';
|
||||
import CustomRequestPlugin from '../plugin';
|
||||
import { appendArrayColumn } from '@nocobase/evaluators';
|
||||
|
||||
const getHeaders = (headers: Record<string, any>) => {
|
||||
return Object.keys(headers).reduce((hds, key) => {
|
||||
@ -84,7 +84,10 @@ export async function send(this: CustomRequestPlugin, ctx: Context, next: Next)
|
||||
|
||||
ctx.withoutDataWrapping = true;
|
||||
|
||||
const { collectionName, url, headers = [], params = [], data = {}, ...options } = requestConfig.options;
|
||||
const { collectionName, url, headers = [], params = [], data = {}, ...options } = requestConfig.options || {};
|
||||
if (!url) {
|
||||
return ctx.throw(400, ctx.t('Please configure the request settings first', { ns: 'custom-request' }));
|
||||
}
|
||||
let currentRecordValues = {};
|
||||
if (collectionName && typeof currentRecord.id !== 'undefined') {
|
||||
const recordRepo = ctx.db.getRepository(collectionName);
|
||||
|
@ -36,7 +36,7 @@ export class CustomRequestPlugin extends Plugin {
|
||||
|
||||
this.app.acl.registerSnippet({
|
||||
name: `ui.${this.name}`,
|
||||
actions: ['customRequests:*'],
|
||||
actions: ['customRequests:*', 'roles:list'],
|
||||
});
|
||||
|
||||
this.app.acl.allow('customRequests', ['send', 'listByCurrentRole'], 'loggedIn');
|
||||
|
@ -23,10 +23,14 @@ export default class AddUsersPhoneMigration extends Migration {
|
||||
type: DataTypes.STRING,
|
||||
});
|
||||
}
|
||||
await this.db.sequelize.getQueryInterface().addConstraint(tableNameWithSchema, {
|
||||
type: 'unique',
|
||||
fields: [field.columnName()],
|
||||
});
|
||||
try {
|
||||
await this.db.sequelize.getQueryInterface().addConstraint(tableNameWithSchema, {
|
||||
type: 'unique',
|
||||
fields: [field.columnName()],
|
||||
});
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
this.db.removeCollection('users');
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,14 @@ export default class AddUserNameMigration extends Migration {
|
||||
type: DataTypes.STRING,
|
||||
});
|
||||
}
|
||||
await this.db.sequelize.getQueryInterface().addConstraint(tableNameWithSchema, {
|
||||
type: 'unique',
|
||||
fields: [field.columnName()],
|
||||
});
|
||||
try {
|
||||
await this.db.sequelize.getQueryInterface().addConstraint(tableNameWithSchema, {
|
||||
type: 'unique',
|
||||
fields: [field.columnName()],
|
||||
});
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
this.db.removeCollection('users');
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user