UNPKG

built.io

Version:

SDK for Built.io Backend

482 lines (464 loc) 15 kB
/* TO DO // make constant strings // can do */ var R = require('ramda'); var utility = require('./utilities/utility'); var instanceMethodBuilder = require('./utilities/instanceMethodBuilder')(); var getData = R.prop('data'); var getOthers = R.compose(R.prop('others'),getData); /** * @class ACL * @classdesc * Access Control List (ACL) allows you to control who can access the content of your application. * @description * Use this to get an ACL instance which can then be passed to any method that accepts an ACL instance as argument. * @param {object} data Plain JavaScript object specifying initial ACL. * @example * // Constructor with blank ACL * var acl = Built.ACL(); * //Constructor with initial ACL * var acl = Built.ACL({ * others:{ * read:true * } * }) * @return {ACL} */ var aclCons = module.exports = function(data) { var newData = R.mixin({},data); if (!data.users || !utility.isArray(data.users)) //setting blank array if nothing already exist newData.users = []; if (!data.roles || !utility.isArray(data.roles)) newData.roles = []; if (!data.others || !utility.isObject(data.others)) newData.others = {}; if(!data.can || !utility.isArray(data.can)) newData.can = []; var returnObj = { toJSON:function(){ return data; }, data: newData } return instanceMethodBuilder.build(module.exports,returnObj); }; var setWithUid = R.curry(function(permision,type,uid,allowed,acl){ var newData = getClonedData(acl); newData[type] = [].concat(acl.data[type]); var perForUid = R.mixin({},R.find(R.propEq('uid',uid),getData(acl)[type])); if(perForUid.uid){ newData[type] = removeItem(perForUid,newData[type]); // removes the item and returns new array perForUid[permision] = allowed; newData[type].push(perForUid); } else{ var newObj = {}; newObj['uid'] = uid; newObj[permision] = allowed; newData[type].push(newObj); } return aclCons(newData); }); /** * Checks whether the object can be deleted by anyone * @function getPublicDeleteAccess * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getPublicDeleteAccess(); * @return {Boolean} */ module.exports.getPublicDeleteAccess = function(acl) { return !!getOthers(acl).delete; } instanceMethodBuilder.define('getPublicDeleteAccess',1); /** * Determines whether the object can be read by anyone * @function getPublicReadAccess * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getPublicReadAccess(); * @return {Boolean} */ module.exports.getPublicReadAccess = function(acl) { return !!getOthers(acl).read; } instanceMethodBuilder.define('getPublicReadAccess',1); /** * Determines whether the object can be updated by anyone * @function getPublicUpdateAccess * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getPublicUpdateAccess(); * @return {Boolean} */ module.exports.getPublicUpdateAccess = function(acl) { return !!getOthers(acl).update; } instanceMethodBuilder.define('getPublicUpdateAccess',1); /** * Determines whether the user with the given role is allowed to delete the object. Even if this returns false, * the user may still be able to access it, if getPublicDeleteAccess() returns true, or if the user belongs to another role that has delete access. * @function getRoleDeleteAccess * @param {String} uid Role's uid * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getRoleDeleteAccess('uid'); * @return {Boolean} */ module.exports.getRoleDeleteAccess = R.curry(function(uid,acl){ return findWithUid(uid,'roles',acl).delete; }); instanceMethodBuilder.define('getRoleDeleteAccess',2); /** * Determines whether the user with the given role is allowed to read the object. Even if this returns false, * the user may still be able to read it, if getPublicReadAccess() returns true, or if the user belongs to another role that has read access. * @function getRoleReadAccess * @param {String} uid Role's uid * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getRoleReadAccess('uid'); * @return {Boolean} */ module.exports.getRoleReadAccess = R.curry(function(uid,acl){ return findWithUid(uid,'roles',acl).read; }); instanceMethodBuilder.define('getRoleReadAccess',2); /** * Determines whether the user with the given role is allowed to update this object. Even if this returns false, * the user may still be able to update it, if getPublicUpdateAccess() returns true, or if the user belongs to another role that has update access. * @function getRoleUpdateAccess * @param {String} uid Role's uid * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getRoleUpdateAccess('uid'); * @return {Boolean} */ module.exports.getRoleUpdateAccess = R.curry(function(uid,acl){ return findWithUid(uid,'roles',acl).update; }) instanceMethodBuilder.define('getRoleUpdateAccess',2); /** * Checks whether the user is allowed to delete the object. Even if this returns false, * the user may still be able to delete it, if getPublicDeleteAccess() returns true, or if the user belongs to a role that has delete access. * @function getUserDeleteAccess * @param {String} uid Role's uid * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getUserDeleteAccess('uid'); * @return {Boolean} */ module.exports.getUserDeleteAccess = R.curry(function(uid,acl){ return findWithUid(uid,'users',acl).delete; }) instanceMethodBuilder.define('getUserDeleteAccess',2); /** * Determines whether the user is allowed to read the object. Even if this returns false, * the user may still be able to read it, if getPublicReadAccess() returns true, or if the user belongs to a role that has read access. * @function getUserReadAccess * @memberof ACL * @param {String} uid Application User's uid * @instance * @example * var acl = Built.ACL(); * var boolean = acl.getUserReadAccess('uid'); * @return {Boolean} */ module.exports.getUserReadAccess = R.curry(function(uid,acl){ return findWithUid(uid,'users',acl).read; }) instanceMethodBuilder.define('getUserReadAccess',2); /** * Determines whether the user is allowed to update this object. Even if this returns false, * the user may still be able to update it, if getPublicUpdateAccess() returns true, or if the user belongs to a role that has update access. * @function getUserUpdateAccess * @param {String} uid Application User's uid * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.getUserUpdateAccess('uid'); * @return {Boolean} */ module.exports.getUserUpdateAccess = R.curry(function(uid,acl){ return findWithUid(uid,'users',acl).update; }) instanceMethodBuilder.define('getUserUpdateAccess',2); /** * Determines whether the ACL is disabled or not * @function isDisabled * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.isDisabled(); * @return {Boolean} */ module.exports.isDisabled = function(acl){ return !!getData(acl).disable; } instanceMethodBuilder.define('isDisabled',1); /** * Sets whether users' falling into 'others' category are allowed to delete this object or not * @function setPublicDeleteAccess * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setPublicDeleteAccess(true); * @return {ACL} */ module.exports.setPublicDeleteAccess = R.curry(function(allowed,acl){ var newData = getClonedData(acl); newData.others = R.mixin({},acl.data.others); newData.others['delete'] = allowed; //Others won't be undefined as we have handled it in constructor return aclCons(newData); }); instanceMethodBuilder.define('setPublicDeleteAccess',2); /** * Sets whether users' falling into 'others' category are allowed to update this object or not * @function setPublicUpdateAccess * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setPublicUpdateAccess(true); * @return {ACL} */ module.exports.setPublicUpdateAccess = R.curry(function(allowed,acl){ var newData = getClonedData(acl); newData.others = R.mixin({},acl.data.others); newData.others['update'] = allowed; //Others won't be undefined as we have handled it in constructor return aclCons(newData); }); instanceMethodBuilder.define('setPublicUpdateAccess',2); /** * Sets whether users' falling into 'others' category are allowed to read access or not * @function setPublicReadAccess * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setPublicReadAccess(true); * @return {ACL} */ module.exports.setPublicReadAccess = R.curry(function(allowed,acl){ var newData = getClonedData(acl); newData.others = R.mixin({},acl.data.others); newData.others['read'] = allowed; //Others won't be undefined as we have handled it in constructor return aclCons(newData); }); instanceMethodBuilder.define('setPublicReadAccess',2); /** * Delete permission will be assigned/unassigned to the role whose uid is provided * @function setRoleDeleteAccess * @param {String} uid Uid of role * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setRoleDeleteAccess('uid',true); * @return {ACL} */ module.exports.setRoleDeleteAccess = setWithUid('delete','roles'); instanceMethodBuilder.define('setRoleDeleteAccess',3); /** * Update permission will be assigned/unassigned to the role whose uid is provided * @function setRoleUpdateAccess * @param {String} uid Uid of role * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setRoleUpdateAccess('uid',true); * @return {ACL} */ module.exports.setRoleUpdateAccess = setWithUid('update','roles'); instanceMethodBuilder.define('setRoleUpdateAccess',3); /** * Read permission will be assigned/unassigned to the role whose uid is provided * @function setRoleReadAccess * @param {String} uid Uid of role * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setRoleReadAccess('uid',true); * @return {ACL} */ module.exports.setRoleReadAccess = setWithUid('read','roles'); instanceMethodBuilder.define('setRoleReadAccess',3); /** * Delete permission will be assigned/unassigned to the user whose uid is provided * @function setUserDeleteAcces * @param {String} uid Uid of user * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setUserDeleteAccess('uid',true); * @return {ACL} */ module.exports.setUserDeleteAccess = setWithUid('delete','users'); instanceMethodBuilder.define('setUserDeleteAccess',3); /** * Update permission will be assigned/unassigned to the user whose uid is provided * @function setUserUpdateAccess * @param {String} uid Uid of user * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setUserUpdateAccess('uid',true); * @return {ACL} */ module.exports.setUserUpdateAccess = setWithUid('update','users'); instanceMethodBuilder.define('setUserUpdateAccess',3); /** * Read permission will be assigned/unassigned to the user whose uid is provided * @function setUserReadAccess * @param {String} uid Uid of user * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setUserReadAccess('uid',true); * @return {ACL} */ module.exports.setUserReadAccess = setWithUid('read','users'); instanceMethodBuilder.define('setUserReadAccess',3); /** * Delete permission will be assigned/unassigned to the anonymous users(non logged-in users). * @function setAnonymousDeleteAccess * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setAnonymousDeleteAccess(true); * @return {ACL} */ module.exports.setAnonymousDeleteAccess = module.exports.setUserDeleteAccess('anonymous'); instanceMethodBuilder.define('setAnonymousDeleteAccess',2); /** * Update permission will be assigned/unassigned to the anonymous users(non logged-in users). * @function setAnonymousUpdateAccess * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setAnonymousUpdateAccess(true); * @return {ACL} */ module.exports.setAnonymousUpdateAccess = module.exports.setUserUpdateAccess('anonymous'); instanceMethodBuilder.define('setAnonymousUpdateAccess',2); /** * Read permission will be assigned/unassigned to the anonymous users(non logged-in users). * @function setAnonymousReadAccess * @param {Boolean} allowed Access allowed or not (true|false) * @instance * @memberof ACL * @example * var acl = Built.ACL(); * acl = acl.setAnonymousReadAccess(true); * @return {ACL} */ module.exports.setAnonymousReadAccess = module.exports.setUserReadAccess('anonymous'); instanceMethodBuilder.define('setAnonymousReadAccess',2); /** *Disables ACL. *@function disable *@instance *@memberof ACL *@example *var acl = Built.ACL(); *acl = acl.disable(); *@return {ACL} */ module.exports.disable = function(acl){ var newData = R.mixin({},getData(acl)); newData['disable'] = true; return aclCons(newData); } instanceMethodBuilder.define('disable',1); /** *Enables ACL *@function enable *@instance *@memberof ACL *@example *var acl = Built.ACL(); *acl = acl.enable(); *@return {ACL} */ module.exports.enable = function(acl){ var newData = R.mixin({},getData(acl)); newData['disable'] = false; return aclCons(newData); } instanceMethodBuilder.define('enable',1); /** * Tells whether the user has update access * @function canUpdate * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.canUpdate(); * @return {Boolean} */ module.exports.canUpdate = function(acl){ return (getData(acl).can.indexOf('update') > -1); } instanceMethodBuilder.define('canUpdate',1); /** * Tells whether the user has delete access * @function canDelete * @instance * @memberof ACL * @example * var acl = Built.ACL(); * var boolean = acl.canDelete(); * @return {Boolean} */ module.exports.canDelete = function(acl){ return (getData(acl).can.indexOf('delete') > -1); } instanceMethodBuilder.define('canDelete',1); function getClonedData(acl){ return R.mixin({},getData(acl)); } function findWithUid(uid,type,acl) { return R.find(R.where({ uid: uid }), acl.data[type]) || {}; } function removeItem(item, list) { var index = R.indexOf(item.uid, R.map(R.prop('uid'), list)) return R.remove(index, 1, list); }