Skip to content

Commit

Permalink
Daily commit. All tests fail, even if reporting pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
yanickrochon committed Dec 30, 2015
1 parent 57bd0f2 commit c50fd19
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 142 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: node_js
node_js:
- "0.11"
- "0.12"
- "iojs"
- "4.2"
- "5.3"
matrix:
fast_finish: true
script: "npm run-script test-travis"
Expand Down
4 changes: 4 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Migration from 0.x to 1.x

The notable change is that this module now relies on the [RBAC-A](https://www.npmjs.com/package/rbac-a) module. Essentially, the same API is still used and some compatibility remains.

2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./lib/rbac');
module.exports = require('./lib/rbac');
2 changes: 1 addition & 1 deletion lib/exceptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var errorFactory = require('error-factory');
/**
Expose InvalidProviderException
*/
module.exports.InvalidProviderException = errorFactory('rbac.InvalidProviderException');
module.exports.InvalidOptionException = errorFactory('rbac.InvalidOptionException');

/**
Expose InvalidProviderException
Expand Down
103 changes: 49 additions & 54 deletions lib/rbac.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,63 @@

const PERMISSION_SEP_OR = ',';
const PERMISSION_SEP_AND = '&&';

const RBAC = require('rbac-a');

var InvalidProviderException = require('./exceptions').InvalidProviderException;
var InvalidRuleException = require('./exceptions').InvalidRuleException;


module.exports.middleware = middleware;
module.exports.middleware = module.exports = middleware;
module.exports.allow = allow;
module.exports.deny = deny;
module.exports.check = check;

/**
Koa middleware.
@param {Object} provider an object offering two methods : getRolePermissions and getUserRoles
@return {Function} the middleware function
Options
- rbac {RBAC} (optional) the RBAC-A instance (will create one if omitted)
- identify {Function} (optional) the identity function. By default, a function returning ctx.user will be used.
@param options {Object}
@return {Function} the middleware function
*/
function middleware(provider) {
var ctxProperty;

if (!provider || typeof provider !== 'object') {
throw InvalidProviderException('Invalid provider');
} else if (!(provider.getRolePermissions instanceof Function)) {
throw InvalidProviderException('Missing function `getRolePermissions` in provider');
} else if (!(provider.getUserRoles instanceof Function)) {
throw InvalidProviderException('Missing function `getUserRoles` in provider');
function middleware(options) {
options = options || {};

if (!('rbac' in options)) {
options.rbac = new RBAC();
} else if (!(options.rbac instanceof RBAC)) {
throw InvalidOptionException('Invalid RBAC instance');
}

ctxProperty = Object.create(null, {
accessProvider: {
enumerable: true,
get: function getAccessProvider() { return provider; }
}
});
if (!('identity' in options)) {
options.identity = defaultIdentity;
} else if (typeof options.identity !== 'function') {
throw InvalidOptionException('Invalid identity function');
}

return function * (next) {
const ctx = this; // koa 1.x style


return function * rbac(next) {
var ctx = this;

Object.defineProperty(this, 'rbac', {
enumerable: true,
writable: false,
value: Object.create(ctxProperty, {
value: Object.create(rbac, {
// compat with 0.x
allowedWeight: {
enumerable: false,
get: function () {
return this.allowedPriority;
}
},
// current allowed priority
allowedPriority: {
enumerable: false,
writable: true,
value: null
},
// current user's roles (optimize checking; assume roles don't change within request)
rolesCache: {
enumerable: false,
writable: false,
Expand Down Expand Up @@ -74,6 +85,20 @@ function middleware(provider) {
}


/**
Default identity function.
Try to return most common used user property.
@param ctx the request context
@return mixed
*/
function defaultIdentity(ctx) {
return ctx && ctx.user;
}



function * findMatchingRuleWeight(ctxRbac, depth, roles, permissions, permissionMatches, roleStack) {
var i, ilen;
var j, jlen;
Expand Down Expand Up @@ -184,36 +209,6 @@ function * isDenied(ctx, permissions) {
}


/**
Prepare the given permissions list to be used for validation
@param {String|Array} permissions a list of permissions to allow
*/
function preparePermissionList(permissions) {
if (typeof permissions === 'string') {
permissions = permissions.split(PERMISSION_SEP_OR);
} else if (!Array.isArray(permissions)) {
throw InvalidRuleException('Invalid permissions');
}

permissions = permissions.filter(function (perm) {
return (typeof perm === 'string' || Array.isArray(perm)) && perm.length;
}).map(function (perm) {
perm = Array.isArray(perm) ? perm : perm.split(PERMISSION_SEP_AND);
return perm.filter(function (p) {
return (typeof p === 'string') && p.length;
}).map(function (p) {
return p.trim();
})
;
});

if (!permissions.length) {
throw InvalidRuleException('Invalid permissions');
}

return permissions;
}


/**
Expand Down
22 changes: 12 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koa-rbac",
"version": "0.1.3",
"version": "1.0.0",
"description": "Role-Based Acess Control for Koa",
"author": "Yanick Rochon <yanick.rochon@gmail.com>",
"keywords": [
Expand All @@ -10,9 +10,9 @@
],
"main": "index.js",
"scripts": {
"test": "mocha --harmony",
"test-cov": "node --harmony node_modules/istanbul-harmony/lib/cli.js cover node_modules/mocha/bin/_mocha",
"test-travis": "node --harmony node_modules/istanbul-harmony/lib/cli.js cover node_modules/mocha/bin/_mocha --report lcovonly"
"test": "mocha",
"test-cov": "istanbul cover _mocha",
"test-travis": "istanbul cover _mocha --report lcovonly"
},
"homepage": "https://github.com/yanickrochon/koa-rbac",
"repository": {
Expand All @@ -23,14 +23,16 @@
"url": "https://github.com/yanickrochon/koa-rbac/issues"
},
"dependencies": {
"error-factory": "0.1.5"
"error-factory": "0.1.6",
"rbac-a": "^0.1.1"
},
"devDependencies": {
"co-mocha": "1.1.0",
"istanbul-harmony": "^0.3.1",
"koa": "^0.18.1",
"should": "^5.2.0",
"supertest": "^0.15.0"
"co": "^4.6.0",
"istanbul": "^0.4.1",
"koa": "^1.1.2",
"mocha": "^2.3.4",
"should": "^8.0.2",
"supertest": "^1.1.0"
},
"license": "MIT"
}
126 changes: 53 additions & 73 deletions test/lib/rbac.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,84 +2,64 @@

describe('Test RBAC', function () {

var request = require('supertest');
var koa = require('koa');
var rbac = require('../../lib/rbac');

var roles = {
'guest': {
//name: 'Guest',
permissions: ['foo']
},
'reader': {
//name: 'Reader',
permissions: ['read'],
inherited: ['guest']
},
'writer': {
//name: 'Writer',
permissions: ['create'],
inherited: ['reader']
},
'editor': {
//name: 'Editor',
permissions: ['update'],
inherited: ['reader']
},
'director': {
//name: 'Director',
permissions: ['delete'],
inherited: ['editor']
},
'admin': {
//name: 'Administrator',
permissions: ['manage']
},
const request = require('supertest');
const koa = require('koa');
const rbac = require('../../lib/rbac');

const RULES = {
roles: {
'guest': {
//name: 'Guest',
permissions: ['foo']
},
'reader': {
//name: 'Reader',
permissions: ['read'],
inherited: ['guest']
},
'writer': {
//name: 'Writer',
permissions: ['create'],
inherited: ['reader']
},
'editor': {
//name: 'Editor',
permissions: ['update'],
inherited: ['reader']
},
'director': {
//name: 'Director',
permissions: ['delete'],
inherited: ['editor']
},
'admin': {
//name: 'Administrator',
permissions: ['manage']
},

'cyclic1': {
permissions: ['crc1'],
inherited: ['cyclic2']
},
'cyclic2': {
permissions: ['crc2'],
inherited: ['cyclic1']
},
'cyclic1': {
permissions: ['crc1'],
inherited: ['cyclic2']
},
'cyclic2': {
permissions: ['crc2'],
inherited: ['cyclic1']
},

'special': {
// note: no permissions
'special': {
// note: no permissions
}
},
users: {
'bart': ['guest', 'reader'],
'marge': ['editor'],
'homer': ['admin', 'director'],
'burns': ['admin'],
'phsycho bob': ['cyclic1'],
'ralph': ['special', 'learned'] // unknown role 'learned'!
}
};

var userRoles = {
'bart': ['guest', 'reader'],
'marge': ['editor'],
'homer': ['admin', 'director'],
'burns': ['admin'],
'phsycho bob': ['cyclic1'],
'ralph': ['special', 'learned'] // unknown role 'learned'!
};

var accessProvider = new function AccessProvider() {
this.getRolePermissions = getRolePermissions;
this.getUserRoles = getUserRoles;
}

/**
Return the role defined by `roleName`
*/
function * getRolePermissions(roleName) {
// NOTE : the method should return an object similar to the one described here
return roles[roleName];
}

/**
Return the roles assigned to the user. Each item of the returned array will
invoke `getRole` with it's item value
*/
function * getUserRoles(ctx) {
return userRoles[ctx.identity];
}


function validate(useRbacMiddleware, identity, validateionMiddleware, status, accept) {
var app = koa();
Expand Down
1 change: 0 additions & 1 deletion test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
--require should
--require co-mocha
--require ./test/init
--timeout 60000
--reporter spec
Expand Down

0 comments on commit c50fd19

Please sign in to comment.