sails-permissions
Advanced tools
Comparing version 1.2.1 to 1.3.1
@@ -26,11 +26,21 @@ var permissionPolicies = [ | ||
if (!validateDependencies(sails)) { | ||
sails.log.error('Cannot find sails-auth hook. Did you "npm install sails-auth --save"?'); | ||
sails.log.error('Please see README for installation instructions: https://github.com/tjwebb/sails-permissions'); | ||
return sails.lower(); | ||
} | ||
if (!validatePolicyConfig(sails)) { | ||
sails.log.error('One or more required policies are missing.'); | ||
sails.log.error('Please see README for installation instructions: https://github.com/tjwebb/sails-permissions'); | ||
return next(new Error('sails-permissions policies not correctly installed in sails.config.policies.')); | ||
return sails.lower(); | ||
} | ||
installModelOwnership(sails); | ||
sails.after(sails.config.permissions.afterEvent, function () { | ||
installModelOwnership(sails); | ||
}); | ||
sails.after('hook:orm:loaded', function () { | ||
installModelOwnership(sails); | ||
Model.count() | ||
@@ -116,4 +126,8 @@ .then(function (count) { | ||
_.intersection(permissionPolicies, policies['*']).length === permissionPolicies.length, | ||
policies.AuthController['*'] | ||
policies.AuthController && _.contains(policies.AuthController['*'], 'passport') | ||
]); | ||
} | ||
function validateDependencies (sails) { | ||
return !!sails.hooks['sails-auth']; | ||
} |
@@ -26,3 +26,3 @@ var fnv = require('fnv-plus'); | ||
protocol: req.protocol, | ||
host: sails.getHost(), | ||
host: req.host || sails.getHost(), | ||
pathname: req.originalUrl || req.url, | ||
@@ -29,0 +29,0 @@ query: req.query |
@@ -51,3 +51,3 @@ /** | ||
if (!PermissionService.hasPassingCriteria(objects, permissions, body)) { | ||
if (!PermissionService.hasPassingCriteria(objects, permissions, body, req.user.id)) { | ||
return res.badRequest({ | ||
@@ -97,3 +97,5 @@ error: 'Can\'t ' + action + ', because of failing where clause or attribute permissions' | ||
if (crit.blacklist && crit.blacklist.length) { | ||
item = _.omit(item, crit.blacklist); | ||
crit.blacklist.forEach(function (term) { | ||
delete item[term]; | ||
}); | ||
} | ||
@@ -100,0 +102,0 @@ memo.push(item); |
@@ -27,3 +27,10 @@ var actionUtil = require('sails/lib/hooks/blueprints/actionUtil'); | ||
if (!_.isObject(model)) { | ||
return next(new Error('Model definition not found: '+ req.options.modelIdentity)); | ||
req.options.unknownModel = true; | ||
if (!sails.config.permissions.allowUnknownModelDefinition) { | ||
return next(new Error('Model definition not found: '+ req.options.modelIdentity)); | ||
} | ||
else { | ||
model = sails.models[req.options.modelIdentity]; | ||
} | ||
} | ||
@@ -30,0 +37,0 @@ |
@@ -29,2 +29,6 @@ var Promise = require('bluebird'); | ||
if (req.options.unknownModel) { | ||
return next(); | ||
} | ||
PermissionService | ||
@@ -31,0 +35,0 @@ .findModelPermissions(options) |
@@ -18,6 +18,9 @@ /** | ||
} | ||
if (req.options.unknownModel) { | ||
return next(); | ||
} | ||
// inject 'owner' as a query criterion and continue if we are not mutating | ||
// an existing object | ||
if (!_.contains(['update', 'delete'], action)) { | ||
if (!_.contains(['update', 'delete'], action) && req.options.modelDefinition.attributes.owner) { | ||
req.query.owner = req.user.id; | ||
@@ -24,0 +27,0 @@ _.isObject(req.body) && (req.body.owner = req.user.id); |
@@ -96,3 +96,3 @@ var Promise = require('bluebird'); | ||
*/ | ||
hasPassingCriteria: function (objects, permissions, attributes) { | ||
hasPassingCriteria: function (objects, permissions, attributes, user) { | ||
// return success if there are no permissions or objects | ||
@@ -109,2 +109,7 @@ if (_.isEmpty(permissions) || _.isEmpty(objects)) return true; | ||
} | ||
if (perm.relation === 'owner') { | ||
perm.criteria.forEach(function (criteria) { | ||
criteria.owner = true; | ||
}); | ||
} | ||
return memo; | ||
@@ -126,3 +131,7 @@ }, []); | ||
var hasUnpermittedAttributes = PermissionService.hasUnpermittedAttributes(attributes, criteria.blacklist); | ||
return match.length === 1 && !hasUnpermittedAttributes; | ||
var hasOwnership = true; // edge case for scenario where a user has some permissions that are owner based and some that are role based | ||
if (criteria.owner) { | ||
hasOwnership = !PermissionService.isForeignObject(user)(obj); | ||
} | ||
return match.length === 1 && !hasUnpermittedAttributes && hasOwnership; | ||
}); | ||
@@ -129,0 +138,0 @@ }); |
@@ -8,3 +8,5 @@ global._ = require('lodash'); | ||
afterEvent: 'hook:orm:loaded' | ||
afterEvent: 'hook:orm:loaded', | ||
allowUnknownModelDefinitions: false | ||
}; |
{ | ||
"name": "sails-permissions", | ||
"version": "1.2.1", | ||
"version": "1.3.1", | ||
"description": "Comprehensive user permissions and entitlements system for sails.js and Waterline. Supports user authentication with passport.js, role-based permissioning, object ownership, and row-level security.", | ||
"main": "index.js", | ||
"main": "api/hooks/sails-permissions.js", | ||
"scripts": { | ||
@@ -25,2 +25,4 @@ "test": "rm -rf .tmp && mocha --reporter spec" | ||
"security", | ||
"rbac", | ||
"acl", | ||
"enterprise", | ||
@@ -39,5 +41,4 @@ "audit", | ||
"jshint": "^2.8.0", | ||
"lodash": ">2.4.0", | ||
"mocha": "^1.21.4", | ||
"request": "^2.53.0", | ||
"mocha": "^2.x.x", | ||
"request": "^2.58.0", | ||
"sails": ">0.10.0", | ||
@@ -52,10 +53,16 @@ "sails-disk": "^0.10.7", | ||
"pluralize": "^1.0.1", | ||
"sails-auth": "^1.2.6", | ||
"sails-auth": "^1.3", | ||
"sails-generate-entities": "latest", | ||
"waterline-criteria": "^0.11.1" | ||
}, | ||
"peerDependencies": { | ||
"sails-auth": ">=1.3" | ||
}, | ||
"engines": { | ||
"node": ">= 0.10", | ||
"npm": ">= 2.3" | ||
}, | ||
"sails": { | ||
"isHook": true | ||
} | ||
} |
@@ -25,3 +25,3 @@ # <img src="http://cdn.tjw.io/images/sails-logo.png" height='43px' />-permissions | ||
"modules": { | ||
"permissions-api": "sails-permissions" | ||
"permissions-api": "sails-permissions/generator" | ||
} | ||
@@ -28,0 +28,0 @@ } |
@@ -108,3 +108,3 @@ var assert = require('assert'); | ||
it('should be able to create a new permission', function(done) { | ||
it('should be able to create a new permission for updating active roles', function(done) { | ||
request(sails.hooks.http.app) | ||
@@ -142,2 +142,33 @@ .get('/model?name=role') | ||
it('should be able to create a new permission for updating owned roles', function(done) { | ||
request(sails.hooks.http.app) | ||
.get('/model?name=role') | ||
.set('Authorization', adminAuth.Authorization) | ||
.expect(200) | ||
.end(function(err, res) { | ||
// haha roleModel | ||
var roleModel = res.body[0]; | ||
request(sails.hooks.http.app) | ||
.post('/permission') | ||
.set('Authorization', adminAuth.Authorization) | ||
.send({ | ||
model: roleModel.id, | ||
action: 'update', | ||
role: roleId, | ||
createdBy: adminUserId, | ||
criteria: { | ||
blacklist: ['id'] | ||
}, | ||
relation: 'owner' | ||
}) | ||
.expect(201) | ||
.end(function(err, res) { | ||
done(err); | ||
}); | ||
}); | ||
}); | ||
it('should be able to create a new role and set it as inactive', function(done) { | ||
@@ -144,0 +175,0 @@ request(sails.hooks.http.app) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
89935
6
2437
8
60
Updatedsails-auth@^1.3