The most advanced roles package for meteor.
This roles package introduces a new way of thinking about roles. It makes you think first about actions and then define the different responses for each role to that action and makes it very easy to add more roles later.
Now roles are saved in the users collection. You need to migrate the db to update. The api is the same.
To migrate run:
Meteor.call('nicolaslopezj_roles_migrate');
meteor add nicolaslopezj:roles
You can use roles as a normal roles package
Only on server
To add roles to a user.
Roles.addUserToRoles(userId, roles)
userId
String. The id of the user.roles
Array or String. The name of the roles you want to add to the user.
To set roles.
Roles.setUserRoles(userId, roles)
userId
String. The id of the user.roles
Array or String. The name of the roles you want to set to the user.
To remove roles from a user
Roles.removeUserFromRoles(userId, roles)
userId
String. The id of the user.roles
Array or String. The name of the roles you want to remove from the user.
Roles.userHasRole(userId, role)
userId
String. The id of the user.role
String. The name of the role.
Roles also attach helpers to the Meteor.users
collection.
var user = Meteor.user();
var roles = user.roles();
var user = Meteor.user();
var hasRole = user.hasRole();
Roles allows you to define actions and have differente responses for each role on that action.
Roles.registerAction(name, adminAllow, adminDeny)
name
String. The name of the action.adminAllow
,adminDeny
Any. Optional. The response for the admin role on this action.
If the value you pass to adminAllow
and/or adminDeny
is not a function Roles will convert it to a Function that returns that value.
If you use Roles as the basic way this is not necesary, but if you wan't to use actions, this is needed.
myRole = new Roles.Role(name)
name
String. The name of the new role.
Now, to set responses of a role on a action
myRole.allow(action, func)
action
String. The name of the action.func
Function. Return true to allow the role to perform this action. You can get the user id usingthis.userId
. To pass arguments to this function pass extra arguments when checking, example: Roles.allow(userId, action, arg1, arg2)
myRole.deny(action, func)
action
String. The name of the action.func
Function. Return true to deny the role to perform this action. You can get the user id usingthis.userId
. To pass arguments to this function pass extra arguments when checking, example: Roles.deny(userId, action, arg1, arg2)
Now that we have our allow/deny rules we want to check if the user has permissions. Note that a user can have more than one role, so Roles will check every action. If a role doesn't have allow/deny rules for a action they won't be considered.
To check if a user is allowed to perform an action. Roles will check all the roles the user has and if at least one role return true
on a action, this function will return true
.
Roles.allow(userId, action, [extra])
userId
String. The id of the user.action
String. The name of the action.[extra]
Each argument that you add to this function will be passed to the allow/deny functions you defined.
To check if a user is denied to perform an action. Roles will check all the roles the user has and if at least one role return true
on a action, this function will return true
.
Roles.deny(userId, action, [extra])
userId
String. The id of the user.action
String. The name of the action.[extra]
Each argument that you add to this function will be passed to the allow/deny functions you defined.
This function will return true
if the user is allowed and not denied to perform an action.
Roles.userHasPermission(userId, action, [extra])
userId
String. The id of the user.action
String. The name of the action.[extra]
Each argument that you add to this function will be passed to the allow/deny functions you defined.
To throw a error if the user doesn't has permission (userful for methods)
Roles.checkPermission(userId, action, [extra])
We will create a collection and create a action to update it.
// We create the collection
Posts = new Mongo.Collection('posts');
// Create the action
Roles.registerAction('posts.update', true); // The admin (which is automatically created) role can update posts always
// Use the action
Posts.allow({
update: function (userId, doc, fields, modifier) {
return Roles.allow(userId, 'posts.update', userId, doc, fields, modifier);
},
});
Posts.deny({
update: function (userId, doc, fields, modifier) {
return Roles.deny(userId, 'posts.update', userId, doc, fields, modifier);
},
});
// Create a new role
EditorRole = new Roles.Role('editor');
// Set the allow/deny rules
EditorRole.allow('posts.update', function(userId, doc, fields, modifier) {
return doc.userId === userId; // Will be allowed to edit his own posts
})
EditorRole.deny('posts.update', function(userId, doc, fields, modifier) {
return !_.contains(fields, 'userId') // Can't update userId field.
})
Now, we will create a publication only for editors.
// Register the action
Roles.registerAction('posts.subscribeToMyPosts');
// Create the publication
if (Meteor.isServer) {
Meteor.publish('myPosts', function () {
// Roles.userHasPermission checks allow and deny rules
if (!Roles.userHasPermission(this.userId, 'posts.subscribeToMyPosts')) {
return [];
} else {
return Posts.find({ userId: this.userId })
}
});
}
// Now we will allow editor to subscribe to their posts
EditorRole.allow('posts.subscribeToMyPosts', true)
Instead of registering and implementing the actions for a collection, there is a helper that do that for you.
myCollection.attachRoles('myCollectionRolesPrefix')
That code will register the following actions:
myCollectionRolesPrefix.insert
myCollectionRolesPrefix.update
myCollectionRolesPrefix.remove
And automatically attach the allow/deny rules to the collection.
Check if the logged in has permissions over a action
<template name="myTemplate">
{{# if userHasPermission 'myCollection.insert' }}
<h1>Insert a document</h1>
{{ else }}
<p>You don't have permissions!</p>
{{/ if }}
</template>
Check if roles are ready
<template name="myTemplate">
{{# if rolesIsReady }}
<p>Roles are loaded</p>
{{ else }}
<p>We don't know if you have permissions yet...</p>
{{/ if }}
</template>