chore(acl): write role to acl if it exists in database and not found … (#2001)
* chore(acl): write role to acl if it exists in database and not found in acl * fix: test
This commit is contained in:
parent
c3c02d8925
commit
43f3cb7cfe
@ -99,7 +99,7 @@ describe('actions', () => {
|
|||||||
const rolesCheckResponse2 = (await loggedAgent.set('Accept', 'application/json').get('/roles:check')) as any;
|
const rolesCheckResponse2 = (await loggedAgent.set('Accept', 'application/json').get('/roles:check')) as any;
|
||||||
|
|
||||||
expect(rolesCheckResponse2.status).toEqual(500);
|
expect(rolesCheckResponse2.status).toEqual(500);
|
||||||
expect(rolesCheckResponse2.body.errors[0].message).toEqual('Role not found');
|
expect(rolesCheckResponse2.body.errors[0].message).toEqual('User role not found');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should destroy through table record when destroy role', async () => {
|
it('should destroy through table record when destroy role', async () => {
|
||||||
|
48
packages/plugins/acl/src/__tests__/write-role-to-acl.test.ts
Normal file
48
packages/plugins/acl/src/__tests__/write-role-to-acl.test.ts
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { MockServer } from '@nocobase/test';
|
||||||
|
import { Database } from '@nocobase/database';
|
||||||
|
import { prepareApp } from './prepare';
|
||||||
|
import UsersPlugin from '@nocobase/plugin-users';
|
||||||
|
|
||||||
|
describe('write role to acl', () => {
|
||||||
|
let app: MockServer;
|
||||||
|
let db: Database;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
app = await prepareApp();
|
||||||
|
db = app.db;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await app.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should write role to acl if role instance exists in db', async () => {
|
||||||
|
const role = await db.getRepository('roles').create({
|
||||||
|
values: {
|
||||||
|
name: 'test',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove role from acl
|
||||||
|
app.acl.removeRole('test');
|
||||||
|
|
||||||
|
const user = await db.getRepository('users').create({
|
||||||
|
values: {
|
||||||
|
roles: ['test'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||||
|
const agent = app.agent().auth(
|
||||||
|
userPlugin.jwtService.sign({
|
||||||
|
userId: user.get('id'),
|
||||||
|
}),
|
||||||
|
{ type: 'bearer' },
|
||||||
|
);
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const response = await agent.resource('roles').check();
|
||||||
|
|
||||||
|
expect(response.statusCode).toEqual(200);
|
||||||
|
});
|
||||||
|
});
|
@ -8,36 +8,46 @@ const map2obj = (map: Map<string, string>) => {
|
|||||||
|
|
||||||
export async function checkAction(ctx, next) {
|
export async function checkAction(ctx, next) {
|
||||||
const currentRole = ctx.state.currentRole;
|
const currentRole = ctx.state.currentRole;
|
||||||
if (currentRole) {
|
if (!currentRole) {
|
||||||
const roleInstance = await ctx.db.getRepository('roles').findOne({
|
throw new Error('User role not found');
|
||||||
filter: {
|
|
||||||
name: currentRole,
|
|
||||||
},
|
|
||||||
appends: ['menuUiSchemas'],
|
|
||||||
});
|
|
||||||
|
|
||||||
const anonymous = await ctx.db.getRepository('roles').findOne({
|
|
||||||
filter: {
|
|
||||||
name: 'anonymous',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const role = ctx.app.acl.getRole(currentRole);
|
|
||||||
const availableActions = ctx.app.acl.getAvailableActions();
|
|
||||||
|
|
||||||
ctx.body = {
|
|
||||||
...role.toJSON(),
|
|
||||||
availableActions: [...availableActions.keys()],
|
|
||||||
resources: [...role.resources.keys()],
|
|
||||||
actionAlias: map2obj(ctx.app.acl.actionAlias),
|
|
||||||
allowAll: currentRole === 'root',
|
|
||||||
allowConfigure: roleInstance.get('allowConfigure'),
|
|
||||||
allowMenuItemIds: roleInstance.get('menuUiSchemas').map((uiSchema) => uiSchema.get('x-uid')),
|
|
||||||
allowAnonymous: !!anonymous,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
throw new Error('Role not found');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const roleInstance = await ctx.db.getRepository('roles').findOne({
|
||||||
|
filter: {
|
||||||
|
name: currentRole,
|
||||||
|
},
|
||||||
|
appends: ['menuUiSchemas'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!roleInstance) {
|
||||||
|
throw new Error(`Role ${currentRole} not exists`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const anonymous = await ctx.db.getRepository('roles').findOne({
|
||||||
|
filter: {
|
||||||
|
name: 'anonymous',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let role = ctx.app.acl.getRole(currentRole);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
await ctx.app.emit('acl:writeRoleToACL', roleInstance);
|
||||||
|
role = ctx.app.acl.getRole(currentRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
const availableActions = ctx.app.acl.getAvailableActions();
|
||||||
|
|
||||||
|
ctx.body = {
|
||||||
|
...role.toJSON(),
|
||||||
|
availableActions: [...availableActions.keys()],
|
||||||
|
resources: [...role.resources.keys()],
|
||||||
|
actionAlias: map2obj(ctx.app.acl.actionAlias),
|
||||||
|
allowAll: currentRole === 'root',
|
||||||
|
allowConfigure: roleInstance.get('allowConfigure'),
|
||||||
|
allowMenuItemIds: roleInstance.get('menuUiSchemas').map((uiSchema) => uiSchema.get('x-uid')),
|
||||||
|
allowAnonymous: !!anonymous,
|
||||||
|
};
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
|
@ -128,11 +128,21 @@ export class PluginACL extends Plugin {
|
|||||||
})) as RoleModel[];
|
})) as RoleModel[];
|
||||||
|
|
||||||
for (const role of roles) {
|
for (const role of roles) {
|
||||||
role.writeToAcl({ acl: this.acl });
|
await this.writeRoleToACL(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const resource of role.get('resources') as RoleResourceModel[]) {
|
async writeRoleToACL(role: RoleModel, transaction: any = null) {
|
||||||
await this.writeResourceToACL(resource, null);
|
role.writeToAcl({ acl: this.acl });
|
||||||
}
|
|
||||||
|
let resources = role.get('resources') as RoleResourceModel[];
|
||||||
|
|
||||||
|
if (!resources) {
|
||||||
|
resources = await role.getResources({ transaction });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const resource of resources as RoleResourceModel[]) {
|
||||||
|
await this.writeResourceToACL(resource, transaction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,16 +227,14 @@ export class PluginACL extends Plugin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.app.on('acl:writeRoleToACL', async (roleModel: RoleModel) => {
|
||||||
|
await this.writeRoleToACL(roleModel);
|
||||||
|
});
|
||||||
|
|
||||||
this.app.db.on('roles.afterSaveWithAssociations', async (model, options) => {
|
this.app.db.on('roles.afterSaveWithAssociations', async (model, options) => {
|
||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
|
|
||||||
model.writeToAcl({
|
await this.writeRoleToACL(model, transaction);
|
||||||
acl: this.acl,
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const resource of (await model.getResources({ transaction })) as RoleResourceModel[]) {
|
|
||||||
await this.writeResourceToACL(resource, transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
// model is default
|
// model is default
|
||||||
if (model.get('default')) {
|
if (model.get('default')) {
|
||||||
|
Loading…
Reference in New Issue
Block a user