diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..48b56b4 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,6 @@ +{ + "node": true, + "predef": [ "module" ], + "esnext": true +} + diff --git a/index.js b/index.js new file mode 100644 index 0000000..2adfee5 --- /dev/null +++ b/index.js @@ -0,0 +1,49 @@ +'use strict'; + +var _CONST = { + 'ROOT_RIGHT_SYMBOL': '*' +}; + +var mod = {}; +module.exports = mod; + +mod.isAllowed = function(has, requires) { + has = has || []; + requires = requires || []; + requires = (isArray(requires)) ? requires : [requires]; + + return isEmpty(requires) || isRoot(has) || checkOr(has, requires); +}; + +function isArray(maybe) { + return maybe && typeof maybe === 'object' && maybe.hasOwnProperty('length'); +} + +function isEmpty(requires) { + var isEmptyList = (!requires || requires.length === 0); + var hasEmptyEntry = (requires[0] === '' && requires.length === 1); + return isEmptyList || hasEmptyEntry; +} + +function isRoot(has) { + has = has || []; + return has.indexOf(_CONST.ROOT_RIGHT_SYMBOL) > -1; +} + +function checkOr(has, requires) { + var found = false; + + has.forEach(function(right) { + requires.forEach(function(required) { + right = escapeRegExp(right); + var regExp = new RegExp('^' + right + '(\\.[a-zA-Z\\.]*)*$'); + found = found || regExp.test(required); + }); + }); + return found; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions +function escapeRegExp(string){ + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..97e8fab --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "access.js", + "version": "0.0.1", + "description": "Littl' lib that checks access to parts of your webapp", + "main": "index.js", + "scripts": { + "test": "npm test" + }, + "keywords": [ + "access", + "rights", + "user" + ], + "author": "Dennis Saenger ", + "license": "MIT", + "devDependencies": { + "jasmine-node": "^1.14.5" + } +} diff --git a/spec/.jshintrc b/spec/.jshintrc new file mode 100644 index 0000000..1e36ce3 --- /dev/null +++ b/spec/.jshintrc @@ -0,0 +1,4 @@ +{ + "node": "true", + "predef": [ "describe", "it", "expect" ] +} diff --git a/spec/index.spec.js b/spec/index.spec.js new file mode 100644 index 0000000..d367f2f --- /dev/null +++ b/spec/index.spec.js @@ -0,0 +1,50 @@ +'use strict'; + +var uut = require('../'); + +describe('access.js', function() { + + it('should export a `isAllowed` method', function() { + expect(uut.isAllowed).toBeDefined(); + expect(typeof uut.isAllowed).toEqual('function'); + }); + + describe('isAllowed()', function() { + + it('should return true if required right is empty string', function() { + var bool = uut.isAllowed(['some'], ''); + expect(bool).toBe(true); + }); + + it('should return true if required right is undefined', function() { + var bool = uut.isAllowed(['some']); + expect(bool).toBe(true); + }); + + it('should return true for ([*], "foo")', function() { + var bool = uut.isAllowed(['*'], 'foo'); + expect(bool).toBe(true); + }); + + it('should acceppt array for requires', function() { + var bool = uut.isAllowed(['x'], ['y', 'x']); + expect(bool).toBe(true); + }); + + it('should return true for ([x], "x.y")', function() { + var bool = uut.isAllowed(['x'], 'x.y'); + expect(bool).toBe(true); + }); + + // + // TODO + // uut.isAllowed(['x', 'y'], ['a', ['x','y']]) + // this means: user needs (right a) OR (right x AND y) + // + // uut.isAllowed(['x', 'y'], ['a', ['x', 'y']]) => true + // uut.isAllowed(['x'], ['a', ['x', 'y']]) => false + // uut.isAllowed(['a'], ['a', ['x', 'y']]) => true + // + }); + +});