Merge branch 'main' into next

This commit is contained in:
nocobase[bot]
2025-12-16 01:25:50 +00:00
5 changed files with 83 additions and 29 deletions
@@ -0,0 +1,40 @@
/**
* This file is part of the NocoBase (R) project.
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
* Authors: NocoBase Team.
*
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { MockServer, createMockServer } from '@nocobase/test';
describe('root', async () => {
let app: MockServer;
beforeEach(async () => {
app = await createMockServer({
plugins: ['users', 'field-sort', 'error-handler', 'acl', 'data-source-main', 'data-source-manager'],
});
});
afterEach(async () => {
await app.destroy();
});
it('can not set root', async () => {
const initUser = await app.db.getRepository('users').findOne({
appends: ['roles'],
});
expect(initUser).toBeTruthy();
expect(initUser.get('roles').map((role) => role.get('name'))).toContain('root');
await expect(
app.db.getRepository('users').create({
values: {
username: 'test',
roles: ['root'],
},
}),
).rejects.toThrow(/No permissions/);
});
});
@@ -9,7 +9,7 @@
import { Context, utils as actionUtils } from '@nocobase/actions';
import { Cache } from '@nocobase/cache';
import { Collection, RelationField, Transaction } from '@nocobase/database';
import { Collection, Model, RelationField, Transaction } from '@nocobase/database';
import { Plugin } from '@nocobase/server';
import lodash from 'lodash';
import { resolve } from 'path';
@@ -428,6 +428,17 @@ export class PluginACLServer extends Plugin {
],
});
this.app.on('afterLoad', async (app) => {
app.db.on('rolesUsers.beforeSave', async (model: Model) => {
if (!model._changed.has('roleName')) {
return;
}
if (model.roleName === 'root') {
throw new Error('No permissions');
}
});
});
const rolesResourcesScopes = this.app.db.getRepository('dataSourcesRolesResourcesScopes');
await rolesResourcesScopes.createMany({
records: [
@@ -24,7 +24,7 @@ describe('actions', () => {
let user;
let testUser;
let role;
const role = { name: 'admin' };
let testRole;
let createData;
const expiresIn = 60 * 60 * 24;
@@ -50,7 +50,7 @@ describe('actions', () => {
testUser = await userRepo.create({
values: {
nickname: 'test',
roles: user.roles,
roles: ['admin', 'member'],
},
});
const roleRepo = await app.db.getRepository('roles');
@@ -60,11 +60,6 @@ describe('actions', () => {
},
});
role = await (app.db.getRepository('users.roles', user.id) as unknown as Repository).findOne({
where: {
default: true,
},
});
createData = {
values: {
name: 'TEST',
@@ -49,8 +49,10 @@ describe('desktopRoutes:listAccessible', () => {
});
it('should return all routes for root role', async () => {
const rootUser = await db.getRepository('users').create({
values: { roles: ['root'] },
const rootUser = await db.getRepository('users').findOne({
filter: {
'roles.name': 'root',
},
});
const agent = await app.agent().login(rootUser);
@@ -82,8 +84,10 @@ describe('desktopRoutes:listAccessible', () => {
it('should return filtered routes with children', async () => {
// 使用 root 角色配置 member 的可访问路由
const rootUser = await db.getRepository('users').create({
values: { roles: ['root'] },
const rootUser = await db.getRepository('users').findOne({
filter: {
'roles.name': 'root',
},
});
const rootAgent = await app.agent().login(rootUser);
@@ -111,8 +115,10 @@ describe('desktopRoutes:listAccessible', () => {
it('should return an empty response when there are no accessible routes', async () => {
// 使用 root 角色配置 member 的可访问路由
const rootUser = await db.getRepository('users').create({
values: { roles: ['root'] },
const rootUser = await db.getRepository('users').findOne({
filter: {
'roles.name': 'root',
},
});
const rootAgent = await app.agent().login(rootUser);
@@ -151,8 +157,10 @@ describe('desktopRoutes:listAccessible', () => {
// 配置 member 角色只能访问 page4
const routes = await db.getRepository('desktopRoutes').find({ limit: 6 });
const rootUser = await db.getRepository('users').create({
values: { roles: ['root'] },
const rootUser = await db.getRepository('users').findOne({
filter: {
'roles.name': 'root',
},
});
const rootAgent = await app.agent().login(rootUser);
await rootAgent.resource('roles.desktopRoutes', 'member').remove({
@@ -112,9 +112,9 @@ describe('data source with acl', () => {
await next();
});
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
const adminUser = await app.db.getRepository('users').findOne({
filter: {
'roles.name': 'root',
},
});
@@ -125,9 +125,9 @@ describe('data source with acl', () => {
});
it.skipIf(os.platform() === 'win32')('should allow root user', async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
const adminUser = await app.db.getRepository('users').findOne({
filter: {
'roles.name': 'root',
},
});
@@ -139,7 +139,7 @@ describe('data source with acl', () => {
it('should update roles resources', async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});
@@ -166,7 +166,7 @@ describe('data source with acl', () => {
it('should set main data source strategy', async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});
@@ -235,7 +235,7 @@ describe('data source with acl', () => {
it('should create strategy', async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});
@@ -297,7 +297,7 @@ describe('data source with acl', () => {
it('should create resources', async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});
@@ -414,7 +414,7 @@ describe('data source with acl', () => {
it('should update roles strategy', async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});
@@ -456,7 +456,7 @@ describe('data source with acl', () => {
it(`should list response meta include new data sources`, async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});
@@ -522,7 +522,7 @@ describe('data source with acl', () => {
it(`should update data sources`, async () => {
const adminUser = await app.db.getRepository('users').create({
values: {
roles: ['root'],
roles: ['admin'],
},
});