Skip to content
This repository was archived by the owner on Dec 14, 2023. It is now read-only.

Commit d30306c

Browse files
authored
Enhancement/permission engine (#191)
* Add support for config-oriented permissions first draft for permission per act * Adapt to new strcture of cp-perms * Fix unreachable context Change cb for an object for cross µs calls as bollean (true) get lost through seneca-transport * Add missing dep * Change repo for cp-perms
1 parent bf0d95e commit d30306c

File tree

9 files changed

+365
-1
lines changed

9 files changed

+365
-1
lines changed

config/perm/profiles.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
'use strict';
2+
3+
module.exports = function(){
4+
return {
5+
'create': [{
6+
role: 'basic-user',
7+
}],
8+
'user_profile_data': [{
9+
role: 'basic-user',
10+
customValidator: [{
11+
role: 'cd-users',
12+
cmd: 'is_self'
13+
}]
14+
}, {
15+
role: 'basic-user',
16+
userType: 'parent-guardian',
17+
customValidator: [{
18+
role: 'cd-users',
19+
cmd: 'is_parent_of'
20+
}]
21+
}, {
22+
role: 'basic-user',
23+
userType: 'champion',
24+
customValidator: [{
25+
role: 'cd-dojos',
26+
cmd: 'belongs_to_dojo'
27+
}]
28+
}],
29+
'load': [{
30+
role: 'basic-user',
31+
customValidator: [{
32+
role: 'cd-users',
33+
cmd: 'is_self'
34+
}]
35+
}, {
36+
role: 'basic-user',
37+
userType: 'parent-guardian',
38+
customValidator: [{
39+
role: 'cd-users',
40+
cmd: 'is_parent_of'
41+
}]
42+
}
43+
],
44+
'load_user_profile': [{
45+
role: 'basic-user',
46+
customValidator: [{
47+
role: 'cd-users',
48+
cmd: 'is_self'
49+
}]
50+
}, {
51+
role: 'basic-user',
52+
userType: 'parent-guardian',
53+
customValidator: [{
54+
role: 'cd-users',
55+
cmd: 'is_parent_of'
56+
}]
57+
}],
58+
'save-youth-profile': [{
59+
role: 'basic-user',
60+
userType: 'parent-guardian'
61+
}],
62+
'save': [{
63+
role: 'basic-user',
64+
}],
65+
'update-youth-profile': [{
66+
role: 'basic-user',
67+
userType: 'parent-guardian',
68+
customValidator: [{
69+
role: 'cd-users',
70+
cmd: 'is_parent_of'
71+
}]
72+
}, { role: 'basic-user',
73+
userType: 'attendee-u13',
74+
customValidator: [{
75+
role: 'cd-users',
76+
cmd: 'is_self'
77+
}]
78+
}, { role: 'basic-user',
79+
userType: 'attendee-o13',
80+
customValidator: [{
81+
role: 'cd-users',
82+
cmd: 'is_self'
83+
}]
84+
}],
85+
// TODO : ensure you're calling it for yourself?
86+
// TODO : strict mode to avoid the permission hierarchy
87+
'invite-parent-guardian': [{
88+
role: 'basic-user',
89+
userType: 'attendee-o13'
90+
}],
91+
92+
'accept-parent-invite': [{
93+
role: 'basic-user',
94+
userType: 'parent-guardian',
95+
}],
96+
// TODO: ??usage
97+
'search': [{
98+
role: 'basic-user',
99+
100+
}],
101+
102+
'load_hidden_fields': [{
103+
role: 'none'
104+
}],
105+
'list': [{
106+
role: 'basic-user',
107+
}],
108+
'change_avatar': [{
109+
role: 'basic-user',
110+
customValidator: [{
111+
role: 'cd-users',
112+
cmd: 'is_self'
113+
}]}],
114+
'get_avatar': [{
115+
role: 'none',
116+
}],
117+
'load_parents_for_user': [
118+
{ role: 'basic-user',
119+
userType: 'champion'
120+
},
121+
{ role: 'basic-user',
122+
customValidator: [{
123+
role: 'cd-users',
124+
cmd: 'is_self'
125+
}]
126+
},
127+
{ role: 'basic-user',
128+
customValidator: [{
129+
role: 'cd-users',
130+
cmd: 'is_parent_of'
131+
}]
132+
}],
133+
134+
'invite_ninja': [{
135+
role: 'basic-user',
136+
userType: 'parent-guardian'
137+
},
138+
{
139+
role: 'basic-user',
140+
userType: 'champion'
141+
},
142+
{
143+
role: 'basic-user',
144+
userType: 'mentor'
145+
}],
146+
// TODO : check if approved = the one supposed to open
147+
'approve_invite_ninja': [{
148+
role: 'basic-user',
149+
userType: 'attendee-o13'
150+
}],
151+
'ninjas_for_user': [{
152+
role: 'basic-user',
153+
userType: 'parent-guardian'
154+
},
155+
{ role: 'basic-user',
156+
userType: 'champion'
157+
},
158+
{ role: 'basic-user',
159+
customValidator:[ {
160+
role: 'cd-users',
161+
cmd: 'is_self'
162+
}]}],
163+
};
164+
};

config/perm/users.js

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
'use strict';
2+
3+
module.exports = function(){
4+
return {
5+
'load': [{
6+
role: 'basic-user',
7+
userTypes: 'champion'
8+
},
9+
{ role: 'basic-user',
10+
customValidator: [{
11+
role: 'cd-users',
12+
cmd: 'is_self'
13+
}]
14+
},
15+
{ role: 'basic-user',
16+
userType: 'parent',
17+
customValidator: [{
18+
role: 'cd-users',
19+
cmd: 'is_parent_of',
20+
}]
21+
}],
22+
'list': [{
23+
role: 'basic-user',
24+
userTypes: 'champion'
25+
}],
26+
'register': [{
27+
role: 'none',
28+
}],
29+
'promote': [{
30+
role: 'cdf-admin',
31+
}],
32+
33+
// TODO : check if own dojo members?
34+
'get_users_by_emails': [{ role: 'basic-user',
35+
//NOTE: isn't perm a customVal now ?
36+
customValidator: [{
37+
role: 'cd-dojos',
38+
cmd: 'is_having_perm',
39+
param: {
40+
perm: 'dojo-admin'
41+
}
42+
}]
43+
}],
44+
45+
'update': [{
46+
role: 'basic-user',
47+
customValidator: [{
48+
role: 'cd-users',
49+
cmd: 'is_self'
50+
}]
51+
},
52+
{ role: 'basic-user',
53+
userType: 'parent',
54+
customValidator: [{
55+
role: 'cd-users',
56+
cmd: 'is_parent_of'
57+
}]
58+
}],
59+
60+
'get_init_user_types': [{
61+
role: 'none',
62+
}],
63+
// Could be public as champion are public by design
64+
'is_champion': [{
65+
role: 'basic-user',
66+
}],
67+
68+
'reset_password': [{
69+
role: 'none',
70+
}],
71+
72+
'execute_reset': [{
73+
role: 'none',
74+
}],
75+
76+
'load_champions_for_user': [{
77+
role: 'basic-user',
78+
customValidator: [
79+
{ role: 'cd-users',
80+
cmd: 'is_self'
81+
}]
82+
}, {
83+
role: 'basic-user',
84+
userType: 'champion',
85+
customValidator: [{
86+
role: 'cd-dojos',
87+
cmd: 'belongs_to_dojo'
88+
}]
89+
}],
90+
'load_dojo_admins_for_user': [{
91+
role: 'basic-user',
92+
customValidator: [
93+
{ role: 'cd-users',
94+
cmd: 'is_self'
95+
}]
96+
}, {
97+
role: 'basic-user',
98+
userType: 'champion',
99+
customValidator: [{
100+
role: 'cd-dojos',
101+
cmd: 'belongs_to_dojo'
102+
}]
103+
}],
104+
'record_login': [{
105+
role: 'basic-user',
106+
}],
107+
108+
// TODO: lookup
109+
'load_prev_founder': [{
110+
role: 'basic-user',
111+
//TODO : how to pass a require a context which is not accessible in the first place ?
112+
// customValidator: [{
113+
// role: 'cd-dojos',
114+
// cmd: 'have_permissions',
115+
// perm: 'dojo-admin'
116+
// }]
117+
}],
118+
'kpi_number_of_youths_registered': [{
119+
role: 'cdf-admin',
120+
}],
121+
'kpi_number_of_champions_and_mentors_registered': [{
122+
role: 'cdf-admin',
123+
}],
124+
'kpi_number_of_youth_females_registered': [{
125+
role: 'cdf-admin',
126+
}],
127+
};
128+
};

config/permissions.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
module.exports = function(){
4+
return {
5+
'cd-users': require('./perm/users.js')(),
6+
'cd-profiles': require('./perm/profiles.js')(),
7+
8+
'auth': {
9+
'create_reset': [{
10+
role: 'none',
11+
}],
12+
},
13+
'user': {
14+
'login': [{
15+
role: 'none',
16+
}],
17+
'logout': [{
18+
role: 'none',
19+
}],
20+
},
21+
22+
};
23+
};

lib/users/is-parent-of.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
var async = require('async');
3+
var _ = require('lodash');
4+
5+
6+
function isParentOf (args, cb) {
7+
var seneca = this;
8+
var plugin = args.role;
9+
var userId = args.user.id;
10+
var childrenId = args.params.userId
11+
if(_.isUndefined(childrenId) && args.params.profile) childrenId = args.params.profile.userId;
12+
if(_.isUndefined(childrenId) && args.params.query) childrenId = args.params.query.userId;
13+
var isParent = false;
14+
// Could also check the opposite way, from child to Parent
15+
seneca.act({role: 'cd-profiles', cmd: 'load_user_profile', userId: userId},
16+
function(err, user){
17+
if(err) return cb(null, {'allowed': false});
18+
if(_.includes(user.children, childrenId )) isParent = true;
19+
return cb(null, {'allowed': isParent});
20+
});
21+
}
22+
23+
module.exports = isParentOf;

lib/users/is-self.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
var async = require('async');
3+
var _ = require('lodash');
4+
5+
6+
function isSelf (args, cb) {
7+
var seneca = this;
8+
var plugin = args.role;
9+
var userId = args.user.id;
10+
var refUserId = args.params.userId || args.params.id ;
11+
if(args.params.query && _.isUndefined(refUserId))
12+
refUserId = args.params.query.userId || args.params.query.id ;
13+
var isSelf = false;
14+
// Could check upon profile, but seems like an overkill to me
15+
if( userId === refUserId ){
16+
isSelf = true;
17+
}
18+
return cb(null, {'allowed': isSelf});
19+
}
20+
21+
module.exports = isSelf;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"seneca-mail": "0.2.1",
4040
"seneca-postgresql-store": "1.1.3",
4141
"seneca-user": "0.2.10",
42+
"cp-permissions": "git://github.com/CoderDojo/cp-permissions-plugin#0.0.1",
4243
"shortid": "2.2.2",
4344
"xoauth2": "1.1.0"
4445
},

profiles.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,6 @@ module.exports = function (options) {
419419
if (err) {
420420
return done(err);
421421
}
422-
423422
return done(null, profile, usersDojos);
424423
});
425424
}

service.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ require('./migrate-psql-db.js')(function (err) {
3636
'users': config['users']
3737
});
3838
seneca.use(require('./nodebb-api.js'), config.nodebb);
39+
seneca.use(require('cp-permissions'), {
40+
config: __dirname + '/config/permissions'
41+
});
3942

4043
seneca.listen()
4144
.client({ type: 'web', port: 10304, pin: { role: 'cd-salesforce', cmd: '*' } })

users.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ module.exports = function (options) {
3232
seneca.add({role: plugin, cmd: 'kpi_number_of_youths_registered'}, cmd_kpi_number_of_youths_registered);
3333
seneca.add({role: plugin, cmd: 'kpi_number_of_champions_and_mentors_registered'}, cmd_kpi_number_of_champions_and_mentors_registered);
3434
seneca.add({role: plugin, cmd: 'kpi_number_of_youth_females_registered'}, cmd_kpi_number_of_youth_females_registered);
35+
seneca.add({role: 'cd-users', cmd: 'is_self'}, require('./lib/users/is-self'));
36+
seneca.add({role: 'cd-users', cmd: 'is_parent_of'}, require('./lib/users/is-parent-of'));
3537

3638
function cmd_load_prev_founder (args, done) {
3739
var seneca = this;

0 commit comments

Comments
 (0)