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;
|
||||
|
||||
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 () => {
|
||||
|
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) {
|
||||
const currentRole = ctx.state.currentRole;
|
||||
if (currentRole) {
|
||||
const roleInstance = await ctx.db.getRepository('roles').findOne({
|
||||
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');
|
||||
if (!currentRole) {
|
||||
throw new Error('User 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();
|
||||
}
|
||||
|
@ -128,11 +128,21 @@ export class PluginACL extends Plugin {
|
||||
})) as RoleModel[];
|
||||
|
||||
for (const role of roles) {
|
||||
role.writeToAcl({ acl: this.acl });
|
||||
await this.writeRoleToACL(role);
|
||||
}
|
||||
}
|
||||
|
||||
for (const resource of role.get('resources') as RoleResourceModel[]) {
|
||||
await this.writeResourceToACL(resource, null);
|
||||
}
|
||||
async writeRoleToACL(role: RoleModel, transaction: any = 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) => {
|
||||
const { transaction } = options;
|
||||
|
||||
model.writeToAcl({
|
||||
acl: this.acl,
|
||||
});
|
||||
|
||||
for (const resource of (await model.getResources({ transaction })) as RoleResourceModel[]) {
|
||||
await this.writeResourceToACL(resource, transaction);
|
||||
}
|
||||
await this.writeRoleToACL(model, transaction);
|
||||
|
||||
// model is default
|
||||
if (model.get('default')) {
|
||||
|
Loading…
Reference in New Issue
Block a user