@nocobase/plugin-acl 0.7.2-alpha.7 → 0.7.4-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,9 @@
1
1
  import { ACL } from '@nocobase/acl';
2
2
  import { Database } from '@nocobase/database';
3
- import PluginACL from '@nocobase/plugin-acl';
4
- import PluginCollectionManager from '@nocobase/plugin-collection-manager';
5
- import PluginUiSchema from '@nocobase/plugin-ui-schema-storage';
6
3
  import PluginUser from '@nocobase/plugin-users';
7
- import { mockServer, MockServer } from '@nocobase/test';
8
- import supertest from 'supertest';
4
+ import { MockServer } from '@nocobase/test';
5
+
6
+ import { prepareApp } from './prepare';
9
7
 
10
8
  describe('own test', () => {
11
9
  let app: MockServer;
@@ -21,28 +19,15 @@ describe('own test', () => {
21
19
 
22
20
  let role;
23
21
  let agent;
22
+ let adminAgent;
23
+ let userAgent;
24
24
 
25
25
  afterEach(async () => {
26
26
  await app.destroy();
27
27
  });
28
28
 
29
29
  beforeEach(async () => {
30
- app = mockServer({
31
- registerActions: true,
32
- });
33
-
34
- await app.cleanDb();
35
-
36
- app.plugin(PluginUiSchema);
37
- app.plugin(PluginCollectionManager);
38
- app.plugin(PluginUser, {
39
- jwt: {
40
- secret: process.env.APP_KEY || 'test-key',
41
- },
42
- });
43
-
44
- app.plugin(PluginACL);
45
- await app.loadAndInstall();
30
+ app = await prepareApp();
46
31
  db = app.db;
47
32
 
48
33
  const PostCollection = db.collection({
@@ -68,9 +53,9 @@ describe('own test', () => {
68
53
  fields: [{ type: 'string', name: 'name' }],
69
54
  });
70
55
 
71
- await app.db.sync();
56
+ await db.sync();
72
57
 
73
- agent = supertest.agent(app.callback());
58
+ agent = app.agent();
74
59
 
75
60
  acl = app.acl;
76
61
 
@@ -86,6 +71,8 @@ describe('own test', () => {
86
71
 
87
72
  adminToken = pluginUser.jwtService.sign({ userId: admin.get('id') });
88
73
 
74
+ adminAgent = app.agent().auth(adminToken, { type: 'bearer' });
75
+
89
76
  user = await db.getRepository('users').create({
90
77
  values: {
91
78
  nickname: 'test',
@@ -94,10 +81,12 @@ describe('own test', () => {
94
81
  });
95
82
 
96
83
  userToken = pluginUser.jwtService.sign({ userId: user.get('id') });
84
+
85
+ userAgent = app.agent().auth(userToken, { type: 'bearer' });
97
86
  });
98
87
 
99
88
  it('should list without createBy', async () => {
100
- let response = await agent
89
+ await adminAgent
101
90
  .patch('/roles/admin')
102
91
  .send({
103
92
  strategy: {
@@ -106,33 +95,38 @@ describe('own test', () => {
106
95
  })
107
96
  .set({ Authorization: 'Bearer ' + adminToken });
108
97
 
109
- response = await agent.get('/tests:list').set({ Authorization: 'Bearer ' + userToken });
98
+ const response = await userAgent.get('/tests:list');
110
99
  expect(response.statusCode).toEqual(200);
111
100
  });
112
101
 
113
102
  it('should delete with createdBy', async () => {
114
- let response = await agent
115
- .patch('/roles/admin')
116
- .send({
117
- strategy: {
118
- actions: ['view:own', 'create', 'destroy:own'],
119
- },
120
- })
121
- .set({ Authorization: 'Bearer ' + adminToken });
122
-
123
- response = await agent
124
- .get('/posts:create')
125
- .send({
126
- title: 't1',
127
- })
128
- .set({ Authorization: 'Bearer ' + userToken });
103
+ await adminAgent
104
+ .resource('roles')
105
+ .update({
106
+ filterByTk: 'admin',
107
+ values: {
108
+ strategy: {
109
+ actions: ['view:own', 'create', 'destroy:own'],
110
+ },
111
+ }
112
+ });
113
+
114
+ let response = await userAgent
115
+ .resource('posts')
116
+ .create({
117
+ values: {
118
+ title: 't1',
119
+ }
120
+ });
129
121
 
130
122
  expect(response.statusCode).toEqual(200);
131
123
 
132
124
  const data = response.body;
133
125
  const id = data.data['id'];
134
126
 
135
- response = await agent.delete(`/posts/${id}`).set({ Authorization: 'Bearer ' + userToken });
127
+ response = await userAgent.resource('posts').destroy({
128
+ filterByTk: id
129
+ });
136
130
  expect(response.statusCode).toEqual(200);
137
131
  expect(await db.getRepository('posts').count()).toEqual(0);
138
132
  });
@@ -1,18 +1,10 @@
1
+ import PluginUsers from '@nocobase/plugin-users';
1
2
  import PluginCollectionManager from '@nocobase/plugin-collection-manager';
2
3
  import PluginUiSchema from '@nocobase/plugin-ui-schema-storage';
3
4
  import { mockServer } from '@nocobase/test';
4
5
  import PluginACL from '../server';
5
6
 
6
- let mockRole: string = 'admin';
7
- let mockUser = {};
8
7
 
9
- export function changeMockRole(role: string) {
10
- mockRole = role;
11
- }
12
-
13
- export function changeMockUser(user: any) {
14
- mockUser = user;
15
- }
16
8
 
17
9
  export async function prepareApp() {
18
10
  const app = mockServer({
@@ -21,15 +13,10 @@ export async function prepareApp() {
21
13
 
22
14
  await app.cleanDb();
23
15
 
16
+ app.plugin(PluginUsers);
24
17
  app.plugin(PluginUiSchema);
25
18
  app.plugin(PluginCollectionManager);
26
19
 
27
- app.resourcer.use(async (ctx, next) => {
28
- ctx.state.currentRole = mockRole;
29
- ctx.state.currentUser = mockUser;
30
- await next();
31
- });
32
-
33
20
  app.plugin(PluginACL);
34
21
  await app.loadAndInstall();
35
22
 
@@ -1,6 +1,8 @@
1
1
  import { MockServer } from '@nocobase/test';
2
- import { changeMockRole, changeMockUser, prepareApp } from './prepare';
3
2
  import { Database } from '@nocobase/database';
3
+ import UsersPlugin from '@nocobase/plugin-users';
4
+
5
+ import { prepareApp } from './prepare';
4
6
 
5
7
  describe('role check action', () => {
6
8
  let app: MockServer;
@@ -21,14 +23,18 @@ describe('role check action', () => {
21
23
  name: 'test',
22
24
  },
23
25
  });
24
-
25
- changeMockUser({
26
- id: 2,
26
+ const user = await db.getRepository('users').create({
27
+ values: {
28
+ roles: ['test']
29
+ }
27
30
  });
31
+ const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
32
+ const agent = app.agent().auth(userPlugin.jwtService.sign({
33
+ userId: user.get('id'),
34
+ }), { type: 'bearer' });
28
35
 
29
- changeMockRole('test');
30
-
31
- const response = await app.agent().get('/roles:check');
36
+ // @ts-ignore
37
+ const response = await agent.resource('roles').check();
32
38
 
33
39
  expect(response.statusCode).toEqual(200);
34
40
  });
@@ -1,4 +1,5 @@
1
1
  import { Database, Model } from '@nocobase/database';
2
+ import UsersPlugin from '@nocobase/plugin-users';
2
3
  import { CollectionRepository } from '@nocobase/plugin-collection-manager';
3
4
  import { MockServer } from '@nocobase/test';
4
5
  import { prepareApp } from './prepare';
@@ -7,6 +8,8 @@ describe('role resource api', () => {
7
8
  let app: MockServer;
8
9
  let db: Database;
9
10
  let role: Model;
11
+ let admin;
12
+ let adminAgent;
10
13
 
11
14
  afterEach(async () => {
12
15
  await app.destroy();
@@ -16,19 +19,23 @@ describe('role resource api', () => {
16
19
  app = await prepareApp();
17
20
  db = app.db;
18
21
 
19
- await db.getRepository('roles').create({
20
- values: {
21
- name: 'admin',
22
- title: 'Admin User',
23
- allowConfigure: true,
24
- },
25
- });
26
-
27
22
  role = await db.getRepository('roles').findOne({
28
23
  filter: {
29
24
  name: 'admin',
30
25
  },
31
26
  });
27
+
28
+ const UserRepo = db.getCollection('users').repository;
29
+ admin = await UserRepo.create({
30
+ values: {
31
+ roles: ['admin']
32
+ }
33
+ });
34
+
35
+ const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
36
+ adminAgent = app.agent().auth(userPlugin.jwtService.sign({
37
+ userId: admin.get('id'),
38
+ }), { type: 'bearer' });
32
39
  });
33
40
 
34
41
  it('should grant resource by createRepository', async () => {
@@ -91,8 +98,7 @@ describe('role resource api', () => {
91
98
  });
92
99
 
93
100
  // get collections list
94
- let response = await app
95
- .agent()
101
+ let response = await adminAgent
96
102
  .resource('roles.collections', 'admin')
97
103
  .list({
98
104
  filter: {
@@ -119,8 +125,7 @@ describe('role resource api', () => {
119
125
  ]);
120
126
 
121
127
  // set resource actions
122
- response = await app
123
- .agent()
128
+ response = await adminAgent
124
129
  .resource('roles.resources', 'admin')
125
130
  .create({
126
131
  values: {
@@ -137,8 +142,7 @@ describe('role resource api', () => {
137
142
  expect(response.statusCode).toEqual(200);
138
143
 
139
144
  // get collections list
140
- response = await app
141
- .agent()
145
+ response = await adminAgent
142
146
  .resource('roles.collections')
143
147
  .list({
144
148
  associatedIndex: role.get('name') as string,
@@ -149,8 +153,7 @@ describe('role resource api', () => {
149
153
 
150
154
  expect(response.body.data[0]['usingConfig']).toEqual('resourceAction');
151
155
 
152
- response = await app
153
- .agent()
156
+ response = await adminAgent
154
157
  .resource('roles.resources')
155
158
  .list({
156
159
  associatedIndex: role.get('name') as string,
@@ -164,8 +167,7 @@ describe('role resource api', () => {
164
167
  expect(resourceAction['name']).toEqual('create');
165
168
 
166
169
  // update resource actions
167
- response = await app
168
- .agent()
170
+ response = await adminAgent
169
171
  .resource('roles.resources')
170
172
  .update({
171
173
  associatedIndex: role.get('name') as string,
@@ -0,0 +1,123 @@
1
+ import Database, { BelongsToManyRepository } from '@nocobase/database';
2
+ import PluginACL from '@nocobase/plugin-acl';
3
+ import UsersPlugin from '@nocobase/plugin-users';
4
+ import { MockServer, mockServer } from '@nocobase/test';
5
+
6
+ describe('role', () => {
7
+ let api: MockServer;
8
+ let db: Database;
9
+
10
+ let usersPlugin: UsersPlugin;
11
+
12
+ beforeEach(async () => {
13
+ api = mockServer();
14
+ await api.cleanDb();
15
+ api.plugin(UsersPlugin);
16
+ api.plugin(PluginACL);
17
+ await api.loadAndInstall();
18
+
19
+ db = api.db;
20
+ usersPlugin = api.getPlugin('@nocobase/plugin-users');
21
+ });
22
+
23
+ afterEach(async () => {
24
+ await api.destroy();
25
+ });
26
+
27
+ it('should set default role', async () => {
28
+ await db.getRepository('roles').create({
29
+ values: {
30
+ name: 'test1',
31
+ title: 'Admin User',
32
+ allowConfigure: true,
33
+ default: true,
34
+ },
35
+ });
36
+
37
+ const user = await db.getRepository('users').create({});
38
+
39
+ // @ts-ignore
40
+ const roles = await user.getRoles();
41
+
42
+ expect(roles.length).toEqual(1);
43
+ expect(roles[0].get('name')).toEqual('test1');
44
+ });
45
+
46
+ it('should not add role when user has role', async () => {
47
+ await db.getRepository('roles').create({
48
+ values: {
49
+ name: 'test1',
50
+ default: true,
51
+ },
52
+ });
53
+
54
+ await db.getRepository('roles').create({
55
+ values: {
56
+ name: 'test2',
57
+ },
58
+ });
59
+
60
+ const user = await db.getRepository('users').create({
61
+ values: {
62
+ roles: [
63
+ {
64
+ name: 'test2',
65
+ },
66
+ ],
67
+ },
68
+ });
69
+
70
+ // @ts-ignore
71
+ const roles = await user.getRoles();
72
+
73
+ expect(roles.length).toEqual(1);
74
+ expect(roles[0].get('name')).toEqual('test2');
75
+ });
76
+
77
+ it('should set users default role', async () => {
78
+ await db.getRepository('roles').create({
79
+ values: {
80
+ name: 'test1',
81
+ title: 'Admin User',
82
+ allowConfigure: true,
83
+ default: true,
84
+ },
85
+ });
86
+
87
+ await db.getRepository('roles').create({
88
+ values: {
89
+ name: 'test2',
90
+ title: 'test2 user',
91
+ allowConfigure: true,
92
+ },
93
+ });
94
+
95
+ const user = await db.getRepository('users').create({
96
+ values: {
97
+ token: '123',
98
+ },
99
+ });
100
+
101
+ const userRolesRepo = db.getRepository<BelongsToManyRepository>('users.roles', user.get('id') as string);
102
+ await userRolesRepo.add('test1');
103
+ await userRolesRepo.add('test2');
104
+
105
+ const userToken = usersPlugin.jwtService.sign({ userId: user.get('id') });
106
+ const response = await api
107
+ .agent()
108
+ .post('/users:setDefaultRole')
109
+ .send({
110
+ roleName: 'test2',
111
+ })
112
+ .set({
113
+ Authorization: `Bearer ${userToken}`,
114
+ });
115
+
116
+ expect(response.statusCode).toEqual(200);
117
+
118
+ const userRoles = await userRolesRepo.find();
119
+ const defaultRole = userRoles.find((userRole) => userRole.get('rolesUsers').default);
120
+
121
+ expect(defaultRole['name']).toEqual('test2');
122
+ });
123
+ });
@@ -1,6 +1,6 @@
1
1
  import { MockServer } from '@nocobase/test';
2
- import { CollectionRepository } from '@nocobase/plugin-collection-manager';
3
2
  import { Database, Model } from '@nocobase/database';
3
+ import UsersPlugin from '@nocobase/plugin-users';
4
4
 
5
5
  import { prepareApp } from './prepare';
6
6
 
@@ -19,32 +19,37 @@ describe('role api', () => {
19
19
 
20
20
  describe('grant', () => {
21
21
  let role: Model;
22
+ let admin: Model;
23
+ let adminAgent;
22
24
 
23
25
  beforeEach(async () => {
24
- await db.getRepository('roles').create({
25
- values: {
26
- name: 'admin',
27
- title: 'Admin User',
28
- allowConfigure: true,
29
- },
30
- });
31
-
32
26
  role = await db.getRepository('roles').findOne({
33
27
  filter: {
34
28
  name: 'admin',
35
29
  },
36
30
  });
31
+
32
+ const UserRepo = db.getCollection('users').repository;
33
+ admin = await UserRepo.create({
34
+ values: {
35
+ roles: ['admin']
36
+ }
37
+ });
38
+
39
+ const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
40
+ adminAgent = app.agent().auth(userPlugin.jwtService.sign({
41
+ userId: admin.get('id'),
42
+ }), { type: 'bearer' });
37
43
  });
38
44
 
39
45
  it('should list actions', async () => {
40
- const response = await app.agent().resource('availableActions').list();
46
+ const response = await adminAgent.resource('availableActions').list();
41
47
  expect(response.statusCode).toEqual(200);
42
48
  });
43
49
 
44
50
  it('should grant universal role actions', async () => {
45
51
  // grant role actions
46
- const response = await app
47
- .agent()
52
+ const response = await adminAgent
48
53
  .resource('roles')
49
54
  .update({
50
55
  values: {
@@ -1,11 +1,15 @@
1
1
  import { prepareApp } from './prepare';
2
2
  import { MockServer } from '@nocobase/test';
3
3
  import { Database } from '@nocobase/database';
4
+ import UsersPlugin from '@nocobase/plugin-users';
4
5
 
5
6
  describe('scope api', () => {
6
7
  let app: MockServer;
7
8
  let db: Database;
8
9
 
10
+ let admin;
11
+ let adminAgent;
12
+
9
13
  afterEach(async () => {
10
14
  await app.destroy();
11
15
  });
@@ -13,18 +17,22 @@ describe('scope api', () => {
13
17
  beforeEach(async () => {
14
18
  app = await prepareApp();
15
19
  db = app.db;
16
- await db.getRepository('roles').create({
20
+
21
+ const UserRepo = db.getCollection('users').repository;
22
+ admin = await UserRepo.create({
17
23
  values: {
18
- name: 'admin',
19
- title: 'Admin User',
20
- allowConfigure: true,
21
- },
24
+ roles: ['admin']
25
+ }
22
26
  });
27
+
28
+ const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
29
+ adminAgent = app.agent().auth(userPlugin.jwtService.sign({
30
+ userId: admin.get('id'),
31
+ }), { type: 'bearer' });
23
32
  });
24
33
 
25
34
  it('should create scope of resource', async () => {
26
- const response = await app
27
- .agent()
35
+ const response = await adminAgent
28
36
  .resource('rolesResourcesScopes')
29
37
  .create({
30
38
  values: {
@@ -0,0 +1,83 @@
1
+ import Database from '@nocobase/database';
2
+ import UsersPlugin from '@nocobase/plugin-users';
3
+ import { MockServer } from '@nocobase/test';
4
+ import { setCurrentRole } from '../middlewares/setCurrentRole';
5
+ import { prepareApp } from './prepare';
6
+
7
+ describe('role', () => {
8
+ let api: MockServer;
9
+ let db: Database;
10
+
11
+ let usersPlugin: UsersPlugin;
12
+ let ctx;
13
+
14
+ beforeEach(async () => {
15
+ api = await prepareApp();
16
+
17
+ db = api.db;
18
+ usersPlugin = api.getPlugin('@nocobase/plugin-users');
19
+
20
+ ctx = {
21
+ db,
22
+ state: {
23
+ currentRole: '',
24
+ }
25
+ }
26
+ });
27
+
28
+ afterEach(async () => {
29
+ await api.destroy();
30
+ });
31
+
32
+ it('should set role with X-Role when exists', async () => {
33
+ ctx.state.currentUser = await db.getRepository('users').findOne({
34
+ appends: ['roles'],
35
+ });
36
+ ctx.get = function(name) {
37
+ if (name === 'X-Role') {
38
+ return 'admin';
39
+ }
40
+ };
41
+ await setCurrentRole(ctx, () => {});
42
+ expect(ctx.state.currentRole).toBe('admin');
43
+ });
44
+
45
+ it('should set role with default', async () => {
46
+ ctx.state.currentUser = await db.getRepository('users').findOne({
47
+ appends: ['roles'],
48
+ });
49
+ ctx.get = function (name) {
50
+ if (name === 'X-Role') {
51
+ return '';
52
+ }
53
+ };
54
+ await setCurrentRole(ctx, () => {});
55
+ expect(ctx.state.currentRole).toBe('root');
56
+ });
57
+
58
+ it('should set role with default when x-role does not exist', async () => {
59
+ ctx.state.currentUser = await db.getRepository('users').findOne({
60
+ appends: ['roles'],
61
+ });
62
+ ctx.get = function (name) {
63
+ if (name === 'X-Role') {
64
+ return 'abc';
65
+ }
66
+ };
67
+ await setCurrentRole(ctx, () => {});
68
+ expect(ctx.state.currentRole).toBe('root');
69
+ });
70
+
71
+ it('should set role with anonymous', async () => {
72
+ ctx.state.currentUser = await db.getRepository('users').findOne({
73
+ appends: ['roles'],
74
+ });
75
+ ctx.get = function (name) {
76
+ if (name === 'X-Role') {
77
+ return 'anonymous';
78
+ }
79
+ };
80
+ await setCurrentRole(ctx, () => {});
81
+ expect(ctx.state.currentRole).toBe('anonymous');
82
+ });
83
+ });
@@ -0,0 +1,45 @@
1
+ import { Context, Next } from '@nocobase/actions';
2
+
3
+ export async function setDefaultRole(ctx: Context, next: Next) {
4
+ const {
5
+ values: { roleName },
6
+ } = ctx.action.params;
7
+
8
+ const {
9
+ db,
10
+ state: { currentUser },
11
+ action: { params: { values } }
12
+ } = ctx;
13
+
14
+ if (values.roleName == 'anonymous') {
15
+ return next();
16
+ }
17
+
18
+ const repository = db.getRepository('rolesUsers');
19
+
20
+ await db.sequelize.transaction(async transaction => {
21
+ await repository.update({
22
+ filter: {
23
+ userId: currentUser.get('id'),
24
+ },
25
+ values: {
26
+ default: false,
27
+ },
28
+ transaction,
29
+ });
30
+ await repository.update({
31
+ filter: {
32
+ userId: currentUser.get('id'),
33
+ roleName,
34
+ },
35
+ values: {
36
+ default: true,
37
+ },
38
+ transaction,
39
+ });
40
+ });
41
+
42
+ ctx.body = 'ok';
43
+
44
+ await next();
45
+ }
@@ -0,0 +1,6 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ name: 'rolesUsers',
5
+ fields: [{ type: 'boolean', name: 'default' }],
6
+ } as CollectionOptions;
@@ -0,0 +1,30 @@
1
+ import { extend } from '@nocobase/database';
2
+
3
+ export default extend({
4
+ name: 'users',
5
+ fields: [
6
+ {
7
+ interface: 'm2m',
8
+ type: 'belongsToMany',
9
+ name: 'roles',
10
+ target: 'roles',
11
+ foreignKey: 'userId',
12
+ otherKey: 'roleName',
13
+ sourceKey: 'id',
14
+ targetKey: 'name',
15
+ through: 'rolesUsers',
16
+ uiSchema: {
17
+ type: 'array',
18
+ title: '{{t("Roles")}}',
19
+ 'x-component': 'RecordPicker',
20
+ 'x-component-props': {
21
+ multiple: true,
22
+ fieldNames: {
23
+ label: 'title',
24
+ value: 'name',
25
+ },
26
+ },
27
+ },
28
+ }
29
+ ],
30
+ });