identity
Version:
Identity client
207 lines (164 loc) • 6.33 kB
JavaScript
var PermissionHelper = module.exports = function(api, config, options){
options = options || {};
this.errors = api.config.errors;
this.config = config;
this.options = options;
this.sanitizeConfig();
this.firstMatch = options.firstMatch || false;
};
var hooks = [
require('./permissions/find'),
require('./permissions/create'),
require('./permissions/update'),
require('./permissions/destroy')
];
for(var i = 0; i < hooks.length; i++){
for(var name in hooks[i]){
if(hooks[i].hasOwnProperty(name)){
PermissionHelper.prototype[name] = hooks[i][name];
}
}
}
PermissionHelper.prototype.sanitizeConfig = function(){
for(var role in this.config){ //first level = role
if(this.config.hasOwnProperty(role)){
if(typeof this.config[role] == 'boolean'){ // if `role:true`
this.config[role] = {
all: this.config[role]
};
}
if(typeof this.config[role] == 'string'){ // if `role:'find'`
this.config[role] = [this.config[role]];
}
if(this.config[role] instanceof Array){ // if `role:['find', 'create']`
var tmp = this.config[role];
this.config[role] = {};
for(var i = 0; i < tmp.length; i++){
this.config[role][tmp[i]] = true;
}
}
for(var type in this.config[role]){ // second level = type (create, update, destroy, find...)
if(this.config[role].hasOwnProperty(type)){
switch(type){
case 'all': // change all to find and modify...
this.config[role]['find'] = this.config[role][type];
case 'modify': // change modify to create, update and destroy
this.config[role]['create'] = this.config[role][type];
this.config[role]['update'] = this.config[role][type];
this.config[role]['destroy'] = this.config[role][type];
break;
}
}
}
}
}
}
PermissionHelper.prototype.getTypeCallbacks = function(context, type){
var callbacks = [];
var config = this.config;
for(var role in config){ //first level = role name
if(config.hasOwnProperty(role)){
if(context.user){
if(context.user.hasRole(role)){ //check role
if(config[role][type]){ //check config for type (param)
if(typeof config[role][type] == 'boolean' || typeof config[role][type] == 'function'){ // only accept a boolean value or a function
callbacks.push(config[role][type]);
if(this.firstMatch) return callbacks;
}
}
}
}else{
//no current user
if(role === 'anonym'){
if(config[role][type]){ //check config for type (param)
if(typeof config[role][type] == 'boolean' || typeof config[role][type] == 'function'){ // only accept a boolean value or a function
callbacks.push(config[role][type]);
if(this.firstMatch) return callbacks;
}
}
}
}
}
}
return callbacks;
};
PermissionHelper.prototype.getFieldCallbacks = function(context, field, type){
var callbacks = [];
var config = this.config;
for(var role in config){ //first level = role name
if(config.hasOwnProperty(role)){
if(context.user.hasRole(role)){ //check role
if(config[role].fields){ //check if there is a fields config
if(typeof config[role].fields === 'object'){ // only accept objects
var fields = config[role].fields;
if(fields[field] === undefined && fields.all !== undefined){
fields[field] = fields.all;
}
if(fields[field] !== undefined){
if(typeof fields[field] == 'boolean' || typeof fields[field] == 'function'){ //if it's a boolean or a function
callbacks.push(fields[field]);
if(this.firstMatch) return callbacks;
}else{
if(!(fields[field] instanceof Array) && typeof fields[field] == 'object'){ //if it's an object {find: true, create: function()}
if(typeof fields[field][type] == 'boolean' || typeof fields[field][type] == 'function'){ //if it's a boolean or a function
callbacks.push(fields[field][type]);
if(this.firstMatch) return callbacks;
}
}else{
if(!(fields[field] instanceof Array)) fields[field] = [fields[field]]; //otherwise convert it to an array and search the type
callbacks.push(fields[field].indexOf(type) !== -1);
if(this.firstMatch) return callbacks;
}
}
}
}
}else{
//set a default for the fields of no config is given.
if(config[role] && config[role][type]){
callbacks.push(true);
}else{
callbacks.push(false);
}
if(this.firstMatch) return callbacks;
}
}
}
}
return callbacks;
};
PermissionHelper.prototype.getAllowedAttributes = function(record, type){
var allowed_fields = [];
var attributes = []
//loop over field definition
for(var name in record.model.definition.attributes){
if(record.model.definition.attributes.hasOwnProperty(name)){
attributes.push(name);
}
}
//loop over relation definition
for(var name in record.model.definition.relations){
if(record.model.definition.relations.hasOwnProperty(name)){
attributes.push(name);
}
}
//loop over attributes
for(var p = 0; p < attributes.length; p++){
var name = attributes[p];
var callbacks = this.getFieldCallbacks(record.context, name, type);
if(callbacks.length > 0){
if(callbacks.indexOf(true) === -1){
for(var i = 0; i < callbacks.length; i++){
if(typeof callbacks[i] == 'function'){
if(callbacks[i].call(record, record)){
allowed_fields.push(name);
break;
}
}
}
}else{
allowed_fields.push(name);
}
}
}
return allowed_fields;
};