mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 14:56:00 +00:00
fix: set acl role
This commit is contained in:
parent
b586d370f0
commit
0fd41c9036
@ -1,4 +1,5 @@
|
|||||||
import { useFieldSchema } from '@formily/react';
|
import { useFieldSchema } from '@formily/react';
|
||||||
|
import { useCookieState } from 'ahooks';
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import React, { createContext, useContext } from 'react';
|
import React, { createContext, useContext } from 'react';
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
@ -20,6 +21,7 @@ export const ACLProvider = (props) => {
|
|||||||
|
|
||||||
export const ACLRolesCheckProvider = (props) => {
|
export const ACLRolesCheckProvider = (props) => {
|
||||||
const { setDesignable } = useDesignable();
|
const { setDesignable } = useDesignable();
|
||||||
|
const [roleName, setRoleName] = useCookieState('currentRoleName');
|
||||||
const result = useRequest(
|
const result = useRequest(
|
||||||
{
|
{
|
||||||
url: 'roles:check',
|
url: 'roles:check',
|
||||||
@ -29,6 +31,9 @@ export const ACLRolesCheckProvider = (props) => {
|
|||||||
if (!data?.data?.allowConfigure && !data?.data?.allowAll) {
|
if (!data?.data?.allowConfigure && !data?.data?.allowAll) {
|
||||||
setDesignable(false);
|
setDesignable(false);
|
||||||
}
|
}
|
||||||
|
if (data?.data?.role !== roleName) {
|
||||||
|
setRoleName(data?.data?.role);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
104
packages/plugin-users/src/__tests__/setCurrentRole.test.ts
Normal file
104
packages/plugin-users/src/__tests__/setCurrentRole.test.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import Database from '@nocobase/database';
|
||||||
|
import PluginACL from '@nocobase/plugin-acl';
|
||||||
|
import UsersPlugin from '@nocobase/plugin-users';
|
||||||
|
import { MockServer, mockServer } from '@nocobase/test';
|
||||||
|
import { setCurrentRole } from '../middlewares/parseToken';
|
||||||
|
import { userPluginConfig } from './utils';
|
||||||
|
|
||||||
|
describe('role', () => {
|
||||||
|
let api: MockServer;
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
let usersPlugin: UsersPlugin;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
api = mockServer();
|
||||||
|
await api.cleanDb();
|
||||||
|
api.plugin(UsersPlugin, userPluginConfig);
|
||||||
|
api.plugin(PluginACL);
|
||||||
|
await api.loadAndInstall();
|
||||||
|
|
||||||
|
db = api.db;
|
||||||
|
usersPlugin = api.getPlugin('@nocobase/plugin-users');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await api.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set role with X-Role when exists', async () => {
|
||||||
|
const currentUser = await db.getRepository('users').findOne({
|
||||||
|
appends: ['roles'],
|
||||||
|
});
|
||||||
|
const ctx = {
|
||||||
|
get(name) {
|
||||||
|
if (name === 'X-Role') {
|
||||||
|
return 'admin';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
currentUser,
|
||||||
|
currentRole: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentRole(ctx);
|
||||||
|
expect(ctx.state.currentRole).toBe('admin');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set role with default', async () => {
|
||||||
|
const currentUser = await db.getRepository('users').findOne({
|
||||||
|
appends: ['roles'],
|
||||||
|
});
|
||||||
|
const ctx = {
|
||||||
|
get(name) {
|
||||||
|
if (name === 'X-Role') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
currentUser,
|
||||||
|
currentRole: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentRole(ctx);
|
||||||
|
expect(ctx.state.currentRole).toBe('root');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set role with default when x-role does not exist', async () => {
|
||||||
|
const currentUser = await db.getRepository('users').findOne({
|
||||||
|
appends: ['roles'],
|
||||||
|
});
|
||||||
|
const ctx = {
|
||||||
|
get(name) {
|
||||||
|
if (name === 'X-Role') {
|
||||||
|
return 'abc';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
currentUser,
|
||||||
|
currentRole: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentRole(ctx);
|
||||||
|
expect(ctx.state.currentRole).toBe('root');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set role with anonymous', async () => {
|
||||||
|
const currentUser = await db.getRepository('users').findOne({
|
||||||
|
appends: ['roles'],
|
||||||
|
});
|
||||||
|
const ctx = {
|
||||||
|
get(name) {
|
||||||
|
if (name === 'X-Role') {
|
||||||
|
return 'anonymous';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
currentUser,
|
||||||
|
currentRole: '',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCurrentRole(ctx);
|
||||||
|
expect(ctx.state.currentRole).toBe('anonymous');
|
||||||
|
});
|
||||||
|
});
|
@ -155,31 +155,7 @@ export async function setDefaultRole(ctx: Context, next: Next) {
|
|||||||
values: { roleName },
|
values: { roleName },
|
||||||
} = ctx.action.params;
|
} = ctx.action.params;
|
||||||
|
|
||||||
if (roleName == 'anonymous') {
|
await ctx.state.currentUser.setDefaultRole(roleName);
|
||||||
ctx.body = 'ok';
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentUserId = ctx.state.currentUser.id;
|
|
||||||
|
|
||||||
await ctx.db.getRepository('rolesUsers').update({
|
|
||||||
filter: {
|
|
||||||
userId: currentUserId,
|
|
||||||
},
|
|
||||||
values: {
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await ctx.db.getRepository('rolesUsers').update({
|
|
||||||
filter: {
|
|
||||||
userId: currentUserId,
|
|
||||||
roleName,
|
|
||||||
},
|
|
||||||
values: {
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.body = 'ok';
|
ctx.body = 'ok';
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ export default {
|
|||||||
name: 'users',
|
name: 'users',
|
||||||
title: '{{t("Users")}}',
|
title: '{{t("Users")}}',
|
||||||
sortable: 'sort',
|
sortable: 'sort',
|
||||||
|
model: 'UserModel',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
interface: 'input',
|
interface: 'input',
|
||||||
|
@ -6,32 +6,34 @@ export function parseToken(options?: { plugin: UsersPlugin }) {
|
|||||||
const user = await findUserByToken(ctx, options.plugin);
|
const user = await findUserByToken(ctx, options.plugin);
|
||||||
if (user) {
|
if (user) {
|
||||||
ctx.state.currentUser = user;
|
ctx.state.currentUser = user;
|
||||||
setCurrentRole(ctx, user);
|
setCurrentRole(ctx);
|
||||||
}
|
}
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function setCurrentRole(ctx, user) {
|
export function setCurrentRole(ctx) {
|
||||||
const roleName = ctx.get('X-Role');
|
let currentRole = ctx.get('X-Role');
|
||||||
|
|
||||||
if (roleName === 'anonymous') {
|
if (currentRole === 'anonymous') {
|
||||||
ctx.state.currentRole = roleName;
|
ctx.state.currentRole = currentRole;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const userRoles = user.get('roles');
|
const userRoles = ctx.state.currentUser.roles;
|
||||||
let userRole;
|
|
||||||
|
|
||||||
if (userRoles.length == 1) {
|
if (userRoles.length == 1) {
|
||||||
userRole = userRoles[0].get('name');
|
currentRole = userRoles[0].name;
|
||||||
} else if (userRoles.length > 1) {
|
} else if (userRoles.length > 1) {
|
||||||
const defaultRole = userRoles.findIndex((role) => role.get('rolesUsers').default);
|
const role = userRoles.find((role) => role.name === currentRole);
|
||||||
userRole = (defaultRole !== -1 ? userRoles[defaultRole] : userRoles[0]).get('name');
|
if (!role) {
|
||||||
|
const defaultRole = userRoles.find((role) => role.rolesUsers?.default);
|
||||||
|
currentRole = (defaultRole || userRoles[0])?.name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userRole) {
|
if (currentRole) {
|
||||||
ctx.state.currentRole = userRole;
|
ctx.state.currentRole = currentRole;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
packages/plugin-users/src/models/UserModel.ts
Normal file
41
packages/plugin-users/src/models/UserModel.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import Database, { Model, TransactionAble } from '@nocobase/database';
|
||||||
|
|
||||||
|
export class UserModel extends Model {
|
||||||
|
async setDefaultRole(roleName: string, options: TransactionAble = {}) {
|
||||||
|
if (roleName == 'anonymous') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const db = (this.constructor as any).database as Database;
|
||||||
|
const transaction = options.transaction || (await db.sequelize.transaction());
|
||||||
|
|
||||||
|
try {
|
||||||
|
await db.getRepository('rolesUsers').update({
|
||||||
|
filter: {
|
||||||
|
userId: this.get('id'),
|
||||||
|
},
|
||||||
|
values: {
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.getRepository('rolesUsers').update({
|
||||||
|
filter: {
|
||||||
|
userId: this.get('id'),
|
||||||
|
roleName,
|
||||||
|
},
|
||||||
|
values: {
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
await transaction.commit();
|
||||||
|
} catch (error) {
|
||||||
|
await transaction.rollback();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import { resolve } from 'path';
|
|||||||
import * as actions from './actions/users';
|
import * as actions from './actions/users';
|
||||||
import { JwtOptions, JwtService } from './jwt-service';
|
import { JwtOptions, JwtService } from './jwt-service';
|
||||||
import * as middlewares from './middlewares';
|
import * as middlewares from './middlewares';
|
||||||
|
import { UserModel } from './models/UserModel';
|
||||||
|
|
||||||
export interface UserPluginConfig {
|
export interface UserPluginConfig {
|
||||||
jwt: JwtOptions;
|
jwt: JwtOptions;
|
||||||
@ -24,6 +25,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async beforeLoad() {
|
async beforeLoad() {
|
||||||
|
this.db.registerModels({ UserModel });
|
||||||
this.db.on('users.afterCreateWithAssociations', async (model, options) => {
|
this.db.on('users.afterCreateWithAssociations', async (model, options) => {
|
||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
|
|
||||||
@ -113,7 +115,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
|||||||
const { adminNickname, adminPassword, adminEmail } = this.getRootUserInfo();
|
const { adminNickname, adminPassword, adminEmail } = this.getRootUserInfo();
|
||||||
|
|
||||||
const User = this.db.getCollection('users');
|
const User = this.db.getCollection('users');
|
||||||
await User.repository.create({
|
const user = await User.repository.create<UserModel>({
|
||||||
values: {
|
values: {
|
||||||
nickname: adminNickname,
|
nickname: adminNickname,
|
||||||
email: adminEmail,
|
email: adminEmail,
|
||||||
@ -122,6 +124,8 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await user.setDefaultRole('root');
|
||||||
|
|
||||||
const repo = this.db.getRepository<any>('collections');
|
const repo = this.db.getRepository<any>('collections');
|
||||||
if (repo) {
|
if (repo) {
|
||||||
await repo.db2cm('users');
|
await repo.db2cm('users');
|
||||||
|
Loading…
Reference in New Issue
Block a user