mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-11-30 03:08:31 +08:00
fix: set acl role
This commit is contained in:
parent
b586d370f0
commit
0fd41c9036
@ -1,4 +1,5 @@
|
||||
import { useFieldSchema } from '@formily/react';
|
||||
import { useCookieState } from 'ahooks';
|
||||
import { Spin } from 'antd';
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
@ -20,6 +21,7 @@ export const ACLProvider = (props) => {
|
||||
|
||||
export const ACLRolesCheckProvider = (props) => {
|
||||
const { setDesignable } = useDesignable();
|
||||
const [roleName, setRoleName] = useCookieState('currentRoleName');
|
||||
const result = useRequest(
|
||||
{
|
||||
url: 'roles:check',
|
||||
@ -29,6 +31,9 @@ export const ACLRolesCheckProvider = (props) => {
|
||||
if (!data?.data?.allowConfigure && !data?.data?.allowAll) {
|
||||
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 },
|
||||
} = ctx.action.params;
|
||||
|
||||
if (roleName == 'anonymous') {
|
||||
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,
|
||||
},
|
||||
});
|
||||
await ctx.state.currentUser.setDefaultRole(roleName);
|
||||
|
||||
ctx.body = 'ok';
|
||||
|
||||
|
@ -4,6 +4,7 @@ export default {
|
||||
name: 'users',
|
||||
title: '{{t("Users")}}',
|
||||
sortable: 'sort',
|
||||
model: 'UserModel',
|
||||
fields: [
|
||||
{
|
||||
interface: 'input',
|
||||
|
@ -6,32 +6,34 @@ export function parseToken(options?: { plugin: UsersPlugin }) {
|
||||
const user = await findUserByToken(ctx, options.plugin);
|
||||
if (user) {
|
||||
ctx.state.currentUser = user;
|
||||
setCurrentRole(ctx, user);
|
||||
setCurrentRole(ctx);
|
||||
}
|
||||
return next();
|
||||
};
|
||||
}
|
||||
|
||||
function setCurrentRole(ctx, user) {
|
||||
const roleName = ctx.get('X-Role');
|
||||
export function setCurrentRole(ctx) {
|
||||
let currentRole = ctx.get('X-Role');
|
||||
|
||||
if (roleName === 'anonymous') {
|
||||
ctx.state.currentRole = roleName;
|
||||
if (currentRole === 'anonymous') {
|
||||
ctx.state.currentRole = currentRole;
|
||||
return;
|
||||
}
|
||||
|
||||
const userRoles = user.get('roles');
|
||||
let userRole;
|
||||
const userRoles = ctx.state.currentUser.roles;
|
||||
|
||||
if (userRoles.length == 1) {
|
||||
userRole = userRoles[0].get('name');
|
||||
currentRole = userRoles[0].name;
|
||||
} else if (userRoles.length > 1) {
|
||||
const defaultRole = userRoles.findIndex((role) => role.get('rolesUsers').default);
|
||||
userRole = (defaultRole !== -1 ? userRoles[defaultRole] : userRoles[0]).get('name');
|
||||
const role = userRoles.find((role) => role.name === currentRole);
|
||||
if (!role) {
|
||||
const defaultRole = userRoles.find((role) => role.rolesUsers?.default);
|
||||
currentRole = (defaultRole || userRoles[0])?.name;
|
||||
}
|
||||
}
|
||||
|
||||
if (userRole) {
|
||||
ctx.state.currentRole = userRole;
|
||||
if (currentRole) {
|
||||
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 { JwtOptions, JwtService } from './jwt-service';
|
||||
import * as middlewares from './middlewares';
|
||||
import { UserModel } from './models/UserModel';
|
||||
|
||||
export interface UserPluginConfig {
|
||||
jwt: JwtOptions;
|
||||
@ -24,6 +25,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
}
|
||||
|
||||
async beforeLoad() {
|
||||
this.db.registerModels({ UserModel });
|
||||
this.db.on('users.afterCreateWithAssociations', async (model, options) => {
|
||||
const { transaction } = options;
|
||||
|
||||
@ -113,7 +115,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
const { adminNickname, adminPassword, adminEmail } = this.getRootUserInfo();
|
||||
|
||||
const User = this.db.getCollection('users');
|
||||
await User.repository.create({
|
||||
const user = await User.repository.create<UserModel>({
|
||||
values: {
|
||||
nickname: adminNickname,
|
||||
email: adminEmail,
|
||||
@ -122,6 +124,8 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
},
|
||||
});
|
||||
|
||||
await user.setDefaultRole('root');
|
||||
|
||||
const repo = this.db.getRepository<any>('collections');
|
||||
if (repo) {
|
||||
await repo.db2cm('users');
|
||||
|
Loading…
Reference in New Issue
Block a user