Skip to content

Commit

Permalink
Merge pull request #1 from mastilver/nested-factories
Browse files Browse the repository at this point in the history
support nested factories
  • Loading branch information
mastilver committed Jun 21, 2015
2 parents 12159ab + b317cf8 commit 6a42ee8
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 30 deletions.
85 changes: 62 additions & 23 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

var esprima = require('esprima');



Expand All @@ -12,46 +12,85 @@ module.exports = function(sails){
},

configure: function(){
sails.config.policies = this.parse(sails.config.policies);
sails.config.policies = this.parsePolicies(sails.config.policies);
},

parse: function(obj){
parsePolicies: parsePolicies,
parseEsprima: parseEsprima,
};
}

var type = typeof obj;

if(type === 'object'){
for(var i in obj){
obj[i] = this.parse(obj[i]);
}
/*
input [Any]
*/
function parsePolicies(input){
var type = typeof input;

return obj;
}
if(type === 'object'){
for(var i in input){
input[i] = this.parsePolicies(input[i]);
}

return input;
}

if(type === 'string'){

var functionMatches = obj.match(/(.*)\((.*)\)/);
if(type === 'string'){
var parsedString = esprima.parse(input).body[0].expression;
return this.parseEsprima(parsedString);
}


// the policy is a function
if(functionMatches !== null){
return input;
}

var functionName = functionMatches[1];
var args = JSON.parse('[' + functionMatches[2].replace(/'/g, '"') + ']');

var policyFactory = require(sails.config.paths.policiesFactories + '/' + functionName);
/*
input [Esprima Object]
fromFactory [Boolean] set to true the result will be interpreted by a factory
*/
function parseEsprima(input, fromFactory){

var policy = policyFactory.apply(this, args);
var type = input.type;

return policy;
}
}
if(type === esprimaType.value){
return input.value;
}


if(type === esprimaType.policy){

var policyName = input.name;

return obj;
if(fromFactory){
return require(sails.config.paths.policies + '/' + policyName);
}
};

return policyName;
}


if(type === esprimaType.factory){

var factoryName = input.callee.name;

var factory = require(sails.config.paths.policiesFactories + '/' + factoryName);

var args = input.arguments.map(function(arg){
return this.parseEsprima(arg, true);
}, this);

return factory.apply(this, args);
}


throw new Error('esprima type unhandled: ' + type);
}


var esprimaType = {
value: 'Literal',
policy: 'Identifier',
factory: 'CallExpression',
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sails-hook-parametized-policies",
"version": "0.1.1",
"version": "0.2.1",
"description": "",
"main": "index.js",
"directories": {
Expand Down Expand Up @@ -30,5 +30,8 @@
},
"sails": {
"isHook": true
},
"dependencies": {
"esprima": "^2.3.0"
}
}
20 changes: 14 additions & 6 deletions test/index.js → test/basicSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var request = require('supertest');
var Sails = require('sails').Sails;


describe('parametized policies hook', function(){
describe('parametized policies hook - basic', function(){

var sails;

Expand All @@ -31,13 +31,15 @@ describe('parametized policies hook', function(){
'GET /user': 'MainController.user',
'GET /admin': 'MainController.admin',
'GET /multiple': 'MainController.multiple',
'GET /json': 'MainController.json',
},
policies: {
'MainController': {
'admin': ['is(\'Admin\')'],
'user': 'is(\'User\')',
'ok': 'accept',
'multiple': 'multiple(1, \'one\')',
'json': 'json(\'["json"]\')',
}
}
}, function(err, _sails){
Expand All @@ -58,13 +60,14 @@ describe('parametized policies hook', function(){

});



it('should start the sails server', function(){
return true;
});

it('should not modify non function policies', function(done){

sails.config.policies.MainController.ok.should.be.equal('accept');

request(sails.hooks.http.app)
.get('/ok')
.expect(200, done);
Expand All @@ -74,18 +77,23 @@ describe('parametized policies hook', function(){
request(sails.hooks.http.app)
.get('/user')
.expect('User', done);
})
});

it('should parse function policy into an array', function(done){
request(sails.hooks.http.app)
.get('/admin')
.expect('Admin', done);
})
});

it('shoule handle multiple arguments policy', function(done){
it('should handle multiple arguments policy', function(done){
request(sails.hooks.http.app)
.get('/multiple')
.expect('1-one', done);
});

it('should handle json', function(done){
request(sails.hooks.http.app)
.get('/json')
.expect('json', done);
})
})
4 changes: 4 additions & 0 deletions test/controllers/MainController.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ module.exports.ok = function(req, res){
module.exports.multiple = function(req, res){
res.send();
};

module.exports.json = function(req, res){
res.send();
}
12 changes: 12 additions & 0 deletions test/controllers/NestedController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

module.exports.policiesArgs = function(req, res){
res.ok();
};

module.exports.mixedArgs = function(req, res){
res.ok();
};

module.exports.factoriesArgs = function(req, res){
res.ok();
}
80 changes: 80 additions & 0 deletions test/nestedSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
require('should');
var request = require('supertest');

var Sails = require('sails').Sails;


describe('parametized policies hook - nested factories', function(){

var sails;

before(function(done){


this.timeout(11000);

Sails().lift({
hooks: {
'parametized-policies': require('../'),
grunt: false,
},
log: {
level: 'error'
},
paths: {
controllers: __dirname + '/controllers',
policies: __dirname + '/policies',
policiesFactories: __dirname + '/policiesFactories',
},
routes: {
'GET /policies-args': 'NestedController.policiesArgs',
'GET /mixed-args': 'NestedController.mixedArgs',
'GET /factories-args': 'NestedController.factoriesArgs',
},
policies: {
'NestedController': {
'policiesArgs': ['and(isAdmin, accept)'],
'mixedArgs': 'and(isAdmin, is(\'User\'))',
'factoriesArgs': 'and(is(\'Admin\'), is(\'User\'))',
}
}
}, function(err, _sails){

if(err) return done(err);

sails = _sails;

return done();
});
});

after(function(done){

if(sails){
sails.lower(done);
}

});

it('should start the sails server', function(){
return true;
});

it('should handle factory with policies as arguments', function(done){
request(sails.hooks.http.app)
.get('/policies-args')
.expect('Admin', done);
});

it('should handle factory with mixed arguments', function(done){
request(sails.hooks.http.app)
.get('/mixed-args')
.expect('AdminUser', done);
});

it('should handle factory with factories as arguments', function(done){
request(sails.hooks.http.app)
.get('/factories-args')
.expect('AdminUser', done);
});
})
6 changes: 6 additions & 0 deletions test/policies/isAdmin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

module.exports = function(req, res, next){

res.write('Admin');
next();
};
11 changes: 11 additions & 0 deletions test/policiesFactories/and.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

module.exports = function(firstFn, secondFn){

return function(req, res, next){

firstFn(req, res, function(){

secondFn(req, res, next);
});
};
};
6 changes: 6 additions & 0 deletions test/policiesFactories/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function(json){
return function(req, res, next){
res.write(JSON.parse(json)[0]);
next();
};
};

0 comments on commit 6a42ee8

Please sign in to comment.