-
Notifications
You must be signed in to change notification settings - Fork 13
/
roles_server.js
108 lines (97 loc) · 2.77 KB
/
roles_server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import {Meteor} from 'meteor/meteor'
import {check, Match} from 'meteor/check'
/**
* Publish user roles
*/
Meteor.publish('nicolaslopezj_roles', function () {
return Meteor.users.find({ _id: this.userId }, { fields: { roles: 1 } })
})
/**
* Migrate
*/
Meteor.methods({
nicolaslopezj_roles_migrate: function () {
var selector = Roles._oldCollection.find({})
console.log('migrating ' + selector.count() + ' roles...')
selector.forEach(function (userRoles) {
Meteor.users.update(userRoles.userId, { $set: { roles: userRoles.roles } })
Roles._oldCollection.remove(userRoles)
})
console.log('roles migrated')
},
})
/**
* Adds roles to a user
*/
Roles.addUserToRoles = function (userId, roles) {
check(userId, String)
check(roles, Match.OneOf(String, Array))
if (!_.isArray(roles)) {
roles = [roles]
}
return Meteor.users.update({ _id: userId }, { $addToSet: { roles: { $each: roles } } })
}
/**
* Set user roles
*/
Roles.setUserRoles = function (userId, roles) {
check(userId, String)
check(roles, Match.OneOf(String, Array))
if (!_.isArray(roles)) {
roles = [roles]
}
return Meteor.users.update({ _id: userId }, { $set: { roles: roles } })
}
/**
* Removes roles from a user
*/
Roles.removeUserFromRoles = function (userId, roles) {
check(userId, String)
check(roles, Match.OneOf(String, Array))
if (!_.isArray(roles)) {
roles = [roles]
}
return Meteor.users.update({ _id: userId }, { $pullAll: { roles: roles } })
}
/**
* Requires a permission to run a resolver
*/
const defaultOptions = {
returnNull: false,
showKey: true,
mapArgs: (...args) => args
}
Roles.action = function (action, userOptions) {
const options = {...defaultOptions, ...userOptions}
return function (target, key, descriptor) {
let fn = descriptor.value || target[key]
if (typeof fn !== 'function') {
throw new Error(`@Roles.action decorator can only be applied to methods not: ${typeof fn}`)
}
return {
configurable: true,
get () {
const newFn = (root, params, context, ...other) => {
const args = options.mapArgs(root, params, context, ...other)
const hasPermission = Roles.userHasPermission(context.userId, action, ...args)
if (hasPermission) {
return fn(root, params, context, ...other)
} else {
if (options.returnNull) {
return null
} else {
const keyText = options.showKey ? ` "${action}" in "${key}"` : ''
throw new Error(`The user has no permission to perform the action${keyText}`)
}
}
}
Object.defineProperty(this, key, {
value: newFn,
configurable: true,
writable: true
})
return newFn
}
}
}
}