Vulcan/packages/nova-users/lib/groups.js

207 lines
5.2 KiB
JavaScript
Raw Normal View History

import Telescope from 'meteor/nova:lib';
2016-07-19 17:30:59 +09:00
import Users from './collection.js';
2016-07-20 10:25:05 +09:00
/**
* @summary Users.groups object
*/
Users.groups = {};
2016-07-19 17:30:59 +09:00
/**
* @summary Group class
*/
class Group {
constructor() {
this.actions = [];
}
can(actions) {
2016-09-11 14:49:56 +08:00
actions = Array.isArray(actions) ? actions : [actions];
2016-07-19 17:30:59 +09:00
this.actions = this.actions.concat(actions);
}
cannot(actions) {
2016-09-11 14:49:56 +08:00
actions = Array.isArray(actions) ? actions : [actions];
2016-07-19 17:30:59 +09:00
this.actions = _.difference(this.actions, actions);
}
}
2016-07-21 15:02:20 +09:00
////////////////////
// Helpers //
////////////////////
2016-07-19 17:30:59 +09:00
/**
* @summary create a new group
* @param {String} groupName
*/
Users.createGroup = groupName => {
Users.groups[groupName] = new Group();
};
/**
* @summary get a list of a user's groups
* @param {Object} user
*/
Users.getGroups = user => {
let userGroups = [];
if (!user) { // anonymous user
userGroups = ["anonymous"];
} else {
userGroups = ["default"];
if (user.telescope.groups) { // custom groups
userGroups = userGroups.concat(user.telescope.groups);
}
2016-07-21 14:51:58 +09:00
if (Users.isAdmin(user)) { // admin
2016-07-19 17:30:59 +09:00
userGroups.push("admins");
}
}
return userGroups;
};
/**
* @summary get a list of all the actions a user can perform
* @param {Object} user
*/
Users.getActions = user => {
const userGroups = Users.getGroups(user);
2016-07-21 12:38:11 +09:00
const groupActions = userGroups.map(groupName => {
// note: make sure groupName corresponds to an actual group
const group = Users.groups[groupName];
return group && group.actions;
});
2016-07-19 17:30:59 +09:00
return _.unique(_.flatten(groupActions));
};
/**
* @summary check if a user can perform a specific action
* @param {Object} user
* @param {String} action
*/
Users.canDo = (user, action) => {
return Users.getActions(user).indexOf(action) !== -1;
};
2016-07-20 10:25:05 +09:00
/**
* @summary Check if a given user can view a specific document
* @param {Object} user - can be undefined!
* @param {Object} document - Note: only actually works with posts for now
*/
Users.canView = function (user, document) {
const status = _.findWhere(Telescope.statuses, {value: document.status}).label;
2016-07-20 10:25:05 +09:00
const collectionName = document.getCollectionName();
if (!document) {
return false;
}
if (Users.owns(user, document)) {
return Users.canDo(user, `${collectionName}.view.${status}.own`);
} else {
return Users.canDo(user, `${collectionName}.view.${status}.all`);
}
};
/**
* @summary Check if a user can edit a document
* @param {Object} user - The user performing the action
* @param {Object} document - The document being edited
*/
Users.canEdit = function (user, document) {
user = (typeof user === 'undefined') ? Meteor.user() : user;
const collectionName = document.getCollectionName();
if (!user || !document) {
return false;
}
if (document.hasOwnProperty('isDeleted') && document.isDeleted) return false;
if (Users.owns(user, document)) {
// if this is user's document, check if user can edit own documents
return Users.canDo(user, `${collectionName}.edit.own`);
} else {
// if this is not user's document, check if they can edit all documents
return Users.canDo(user, `${collectionName}.edit.all`);
}
};
2016-07-21 15:02:20 +09:00
/**
* @summary Check if a user owns a document
* @param {Object|string} userOrUserId - The user or their userId
* @param {Object} document - The document to check (post, comment, user object, etc.)
*/
Users.owns = function (user, document) {
try {
if (!!document.userId) {
// case 1: document is a post or a comment, use userId to check
return user._id === document.userId;
} else {
// case 2: document is a user, use _id to check
return user._id === document._id;
}
} catch (e) {
return false; // user not logged in
}
};
Users.helpers({owns: function (document) {return Users.owns(this, document);}});
/**
* @summary Check if a user is an admin
* @param {Object|string} userOrUserId - The user or their userId
*/
Users.isAdmin = function (userOrUserId) {
try {
var user = Users.getUser(userOrUserId);
return !!user && !!user.isAdmin;
} catch (e) {
return false; // user not logged in
}
};
Users.isAdminById = Users.isAdmin;
// use _isAdmin because there is an isAdmin property on the User schema already
Users.helpers({_isAdmin: function () {return Users.isAdmin(this);}});
2016-07-20 10:25:05 +09:00
/**
* @summary Check if a user can submit a field
* @param {Object} user - The user performing the action
* @param {Object} field - The field being edited or inserted
*/
Users.canSubmitField = function (user, field) {
return user && field.insertableIf && field.insertableIf(user);
};
/** @function
* Check if a user can edit a field for now, identical to Users.canSubmitField
* @param {Object} user - The user performing the action
* @param {Object} field - The field being edited or inserted
*/
Users.canEditField = function (user, field, document) {
return user && field.editableIf && field.editableIf(user, document);
};
2016-07-19 17:30:59 +09:00
2016-07-21 15:02:20 +09:00
////////////////////
// Initialize //
////////////////////
2016-07-19 17:30:59 +09:00
/**
* @summary initialize the 3 out-of-the-box groups
*/
Users.createGroup("anonymous"); // non-logged-in users
Users.createGroup("default"); // regular users
Users.createGroup("admins"); // admin users