From 7e3ab3af9cf818a561c709ab9055dd8b12c3f065 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 21:53:25 +0100 Subject: [PATCH 01/13] Cleanup from V1 --- README.md | 208 ----------------------------- admittance.coffee | 217 ------------------------------ admittance.js | 298 ------------------------------------------ file-adaptor.coffee | 35 ----- file-adaptor.js | 50 ------- index.coffee | 5 - index.js | 13 -- package.json | 6 +- tests/rights-src.json | 53 -------- tests/rights.json | 1 - tests/test.coffee | 126 ------------------ tests/test.js | 138 ------------------- 12 files changed, 5 insertions(+), 1145 deletions(-) delete mode 100644 README.md delete mode 100644 admittance.coffee delete mode 100644 admittance.js delete mode 100644 file-adaptor.coffee delete mode 100644 file-adaptor.js delete mode 100644 index.coffee delete mode 100644 index.js delete mode 100644 tests/rights-src.json delete mode 100644 tests/rights.json delete mode 100644 tests/test.coffee delete mode 100644 tests/test.js diff --git a/README.md b/README.md deleted file mode 100644 index 4e5db6e..0000000 --- a/README.md +++ /dev/null @@ -1,208 +0,0 @@ -Admittance -========== - -Role based access control module for node. The interface is based off the Yii php framework's RBAC interface. The implementation is written in coffee script and is entirely original. - -This module is under heavy development at the moment and well anyway, you probably shouldn't use it beyond testing it out yet. Do contribute though! Accepting pull requests! - -I wrote this module in coffeescript for the main reason of trying coffeescript out. I will most likely re-write a version in javascript at some point as well. - -## Usage - -### include in your node project with npm - -```javascript -npm install admittance - -admittance = require("admittance"); - -Admittance = admittance.Admittance -FileAdaptor = admittance.FileAdaptor - -am = new Admittance(new FileAdaptor("path/to/jsonfile")); -am.on('load', function () { - //perform operations here -}); -``` - -### define roles and operations - -eg. -```javascript -am.createAuthItem('admin', 2, 'System admin user'); //role -am.createAuthItem('editPosts', 0, 'Allows editing of posts'); //operation -``` - -### build permissions. - -A role could contain a series of operations (or can be used alone) - -eg. -```javascript -am.addItemChild('admin', 'editPosts'); -``` - -### Assign roles or operations - -Assign roles or operations to your existing users - -eg. -```javascript -am.assign('admin', 43); // 43 = some existing system user id -``` - -### Check access - -You will then be able to check user access in your application - -eg. -```javascript -am.checkAccess('admin', 43) // true -am.checkAccess('editPosts', 43) // true -``` - -## Other methods - -### clearAll - -Clears all permissions, you need to call save after to persist changes - -### clearAuthAssignments - -Clears all auth assignments, you need to call save after to persist changes - -### executeBizRule - -Business rules not yet implemented - -### getAuthAssignment - -Gets a Auth assignment object - -### getAuthAssignments - -gets all auth assignments for a user - -### getAuthItem - -gets the object that represents an auth item - -### getAuthItems - -gets all auth items for a user - -### hasItemChild - -Checks if an auth item has the specified child - -### isAssigned - -Checks if a user has a certain auth item assigned - -### removeAuthItem - -Removes an auth item - -### removeItemChild - -Removes the reference between a parent and child auth item - -### revoke - -Revokes access for a certain auth item to a user - -### save - -Persists any changes - -## Events - -### load -### save -### empty -### error - -## Adaptor - -Admittance comes with an in file storage adaptor. It should be pretty easy to implement new adpators if you prefer to use database engines to store access control data. - -Take a look at file-adaptor.coffee, implement the load and save methods and pass an instance of your adaptor in to Admittance when you start it up. - -eg. -```javascript -am = new Admittance(new myAdaptor) -``` - -The adaptor must load data in the following 3 (json) forms: - -defines assignments between user Ids and auth items with additional -data and business rules - -```json -"assignments": { - "501": { - "admin": { - "itemName": "admin", - "id": "501", - "bizRule": null, - "data": "N;" - }, - "tmc": { - "itemName": "tmc", - "id": "501", - "bizRule": null, - "data": "N;" - } - }, - "12": { - "tmc": { - "itemName": "tmc", - "id": "12", - "bizRule": null, - "data": "N;" - } - } - } -``` - -defines all auth items, each item is unique -name is the unique id for each auth item. Type corresponds -to 1 of 3 values 0: operation, 1: task, 2: role -description is purely for reference -business rules can be defined -data can be defined - -```json -"items": { - "admin": { - "name": "admin", - "type": 2, - "description": "Admin user", - "bizRule": null, - "data": "N;" - }, - "tmc": { - "name": "tmc", - "type": 2, - "description": "TMC user", - "bizRule": null, - "data": "N;" - }, - "acceptTMP": { - "name": "acceptTMP", - "type": 0, - "description": "Accept TMPs", - "bizRule": null, - "data": "N;" - } -} -``` - -maps parent auth items to child auth items - -```json -"children": { - "admin": ["acceptTMP", "tmc"], - "tmc": ["acceptTMP"] -} -``` \ No newline at end of file diff --git a/admittance.coffee b/admittance.coffee deleted file mode 100644 index deadaad..0000000 --- a/admittance.coffee +++ /dev/null @@ -1,217 +0,0 @@ -_ = require 'underscore' -EventEmitter = require("events").EventEmitter -util = require "util" - -class Admittance extends EventEmitter - - _this = null - - # Internal data structures to hold data - # about auth items (roles, operations, etc) - items = {} - assignments = {} - children = {} - - constructor: (@adaptor) -> - - _this = this - - @adaptor.load (err, pItems, pAssignments, pChildren) -> - items = pItems - assignments = pAssignments - children = pChildren - _this.emit "load" - - ### - Adds an auth item to another auth item as a child - This stored as an id reference. - eg. 'parent' = ['child1', 'child2'] - An error event is triggered if either the item or the - child being referenced do not exist - @param {string} itemName - @param {string} childName - ### - addItemChild: (itemName, childName) -> - if items[childName] and items[itemName] - children[itemName] = children[itemName] or [] - children[itemName].push childName - else - # @emit "error", "parent or child do not exist" - - ### - Assigns a auth item (given by id) to a user (given by id) - @param {string} itemName - name of auth item - @param {string} userId - id of user - @param {string} bizRule - expression - ### - assign: (itemName, userId, bizRule, data) -> - item = - itemName: itemName - userId: userId - bizRule: bizRule - data: data - - assignments[userId] = assignments[userId] or {} - assignments[userId][itemName] = item - - ### - Checks if a user (give by id) has the requested - permission (specified by id) - if the requested permission is in any of the - assigned auth item trees that have been assigned - to the user, this method will return true - @param {string} itemName - auth item - @param {string} userId - user id - @param {array} params - - @return {boolean} - true if the user has the - appropriate permissions - ### - checkAccess: (itemName, userId, params = []) -> - #get assignments - userAssignments = [] - userItems = @getAuthItems(null, userId) - for own key, item of userItems - userAssignments.push item.name - - _.contains userAssignments, itemName - - ### - Clears all permissions. The save method must be called - after calling clearAll if you want the wipe to be - persisted. If you dont call save after clearAll, when you - next load the application, permissions will be restored - via the adaptor - ### - clearAll: -> - items = {} - assignments = {} - children = {} - # @emit "empty" - ### - Clears all auth assignment. The save method must be called - after calling clearAuthAssignments if you want the wipe to be - persisted. If you dont call save after clearAuthAssignments, - when you next load the application, permissions will be restored - via the adaptor - ### - clearAuthAssignments: -> - assignments = {} - - ### - Creates an auth item with a given name, type and description - You may also specify a business rule expression and any - data - @param {string} name - name for the auth item eg. admin - @param {int} type - type int, either 0, 1, or 2 - 0: operation, 1: task, 2: role - @param {string} descrition - information about the auth item - @param {string} bizRule - expression to evaluate - @param {string} data - - ### - createAuthItem: (name, type, description = "", bizRule, data) -> - item = - name: name - type: type - description: description - bizRule: bizRule - data: data - items[name] = item - - ### - Evaluates and checks give business rule - ### - executeBizRule: (bizRule, params, data) -> - - ### - Corresponds to directly assigned auth items - for a user. ie, child items not directly - assigned to a user will not be returned - @param {string} itemName - name of auth item eg. admin - @param {string} userId - user id to return against - @return {object} - assignment data in an object - ### - getAuthAssignment: (itemName, userId) -> - if assignments[userId] and assignments[userId][itemName] - assignments[userId][itemName] - - - ### - Returns directly assigned user auth items - ie, implied auth assignments are not returned - @param {string} userId - id of user - @return {object} - object where each key is an - assignment for the given user - ### - getAuthAssignments: (userId) -> - assignments[userId] - - getAuthItem: (name) -> - items[name] - - getAuthItems: (type = null, userId) -> - authItems = [] - # get all item keys for user recursively - userItems = @traverseItems(assignments[userId]) - - # for each item, index into items - for own key, value of userItems - authItems.push items[key] - - authItems - - hasItemChild: (itemName, childName) -> - if children[itemName] and _.contains(children[itemName], childName) - true - else false - - isAssigned: (itemName, userId) -> - if assignments[userId] and assignments[userId][itemName] - true - else false - - removeAuthItem: (name) -> - if items[name] - items[name] = null - - removeItemChild: (itemName, childName) -> - if children[itemName] and children[itemName][childName] - children[itemName][childName] = null - - revoke: (itemName, userId) -> - if assignments[userId] and assignments[userId][itemName] - assignments[userId][itemName] = null - - save: (cb) -> - @adaptor.save items, assignments, children, () -> - _this.emit "save" - cb() - - # saveAuthAssignment: (assignment, cb) -> - # @adaptor.saveAssignment assignment, cb - - # saveAuthItem: (item, oldName, cb) -> - # @adaptor.saveAuthItem item, oldName, cb - - ### - Recursively traverse items into a flat array - @param {object} items - map of items - @return {array} - flattened array of all children - ### - traverseItems: (assignedItems) -> - collection = {} - for own key, item of assignedItems - collection[key] = item - if children[key] and children[key].length > 0 - recurseResult = @traverseItems(@getItemChildren key) - collection = _.extend collection, recurseResult - - collection - - getItemChildren: (itemName) -> - childItemNames = children[itemName] - childItems = {} - for own key, name of childItemNames - childItems[name] = items[name] - childItems - -module.exports = Admittance diff --git a/admittance.js b/admittance.js deleted file mode 100644 index e1303c6..0000000 --- a/admittance.js +++ /dev/null @@ -1,298 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Admittance, EventEmitter, util, _, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - - _ = require('underscore'); - - EventEmitter = require("events").EventEmitter; - - util = require("util"); - - Admittance = (function(_super) { - var assignments, children, items, _this; - - __extends(Admittance, _super); - - _this = null; - - items = {}; - - assignments = {}; - - children = {}; - - function Admittance(adaptor) { - this.adaptor = adaptor; - _this = this; - this.adaptor.load(function(err, pItems, pAssignments, pChildren) { - items = pItems; - assignments = pAssignments; - children = pChildren; - return _this.emit("load"); - }); - } - - /* - Adds an auth item to another auth item as a child - This stored as an id reference. - eg. 'parent' = ['child1', 'child2'] - An error event is triggered if either the item or the - child being referenced do not exist - @param {string} itemName - @param {string} childName - */ - - - Admittance.prototype.addItemChild = function(itemName, childName) { - if (items[childName] && items[itemName]) { - children[itemName] = children[itemName] || []; - return children[itemName].push(childName); - } else { - - } - }; - - /* - Assigns a auth item (given by id) to a user (given by id) - @param {string} itemName - name of auth item - @param {string} userId - id of user - @param {string} bizRule - expression - */ - - - Admittance.prototype.assign = function(itemName, userId, bizRule, data) { - var item; - item = { - itemName: itemName, - userId: userId, - bizRule: bizRule, - data: data - }; - assignments[userId] = assignments[userId] || {}; - return assignments[userId][itemName] = item; - }; - - /* - Checks if a user (give by id) has the requested - permission (specified by id) - if the requested permission is in any of the - assigned auth item trees that have been assigned - to the user, this method will return true - @param {string} itemName - auth item - @param {string} userId - user id - @param {array} params - - @return {boolean} - true if the user has the - appropriate permissions - */ - - - Admittance.prototype.checkAccess = function(itemName, userId, params) { - var item, key, userAssignments, userItems; - if (params == null) { - params = []; - } - userAssignments = []; - userItems = this.getAuthItems(null, userId); - for (key in userItems) { - if (!__hasProp.call(userItems, key)) continue; - item = userItems[key]; - userAssignments.push(item.name); - } - return _.contains(userAssignments, itemName); - }; - - /* - Clears all permissions. The save method must be called - after calling clearAll if you want the wipe to be - persisted. If you dont call save after clearAll, when you - next load the application, permissions will be restored - via the adaptor - */ - - - Admittance.prototype.clearAll = function() { - items = {}; - assignments = {}; - return children = {}; - }; - - /* - Clears all auth assignment. The save method must be called - after calling clearAuthAssignments if you want the wipe to be - persisted. If you dont call save after clearAuthAssignments, - when you next load the application, permissions will be restored - via the adaptor - */ - - - Admittance.prototype.clearAuthAssignments = function() { - return assignments = {}; - }; - - /* - Creates an auth item with a given name, type and description - You may also specify a business rule expression and any - data - @param {string} name - name for the auth item eg. admin - @param {int} type - type int, either 0, 1, or 2 - 0: operation, 1: task, 2: role - @param {string} descrition - information about the auth item - @param {string} bizRule - expression to evaluate - @param {string} data - - */ - - - Admittance.prototype.createAuthItem = function(name, type, description, bizRule, data) { - var item; - if (description == null) { - description = ""; - } - item = { - name: name, - type: type, - description: description, - bizRule: bizRule, - data: data - }; - return items[name] = item; - }; - - /* - Evaluates and checks give business rule - */ - - - Admittance.prototype.executeBizRule = function(bizRule, params, data) {}; - - /* - Corresponds to directly assigned auth items - for a user. ie, child items not directly - assigned to a user will not be returned - @param {string} itemName - name of auth item eg. admin - @param {string} userId - user id to return against - @return {object} - assignment data in an object - */ - - - Admittance.prototype.getAuthAssignment = function(itemName, userId) { - if (assignments[userId] && assignments[userId][itemName]) { - return assignments[userId][itemName]; - } - }; - - /* - Returns directly assigned user auth items - ie, implied auth assignments are not returned - @param {string} userId - id of user - @return {object} - object where each key is an - assignment for the given user - */ - - - Admittance.prototype.getAuthAssignments = function(userId) { - return assignments[userId]; - }; - - Admittance.prototype.getAuthItem = function(name) { - return items[name]; - }; - - Admittance.prototype.getAuthItems = function(type, userId) { - var authItems, key, userItems, value; - if (type == null) { - type = null; - } - authItems = []; - userItems = this.traverseItems(assignments[userId]); - for (key in userItems) { - if (!__hasProp.call(userItems, key)) continue; - value = userItems[key]; - authItems.push(items[key]); - } - return authItems; - }; - - Admittance.prototype.hasItemChild = function(itemName, childName) { - if (children[itemName] && _.contains(children[itemName], childName)) { - return true; - } else { - return false; - } - }; - - Admittance.prototype.isAssigned = function(itemName, userId) { - if (assignments[userId] && assignments[userId][itemName]) { - return true; - } else { - return false; - } - }; - - Admittance.prototype.removeAuthItem = function(name) { - if (items[name]) { - return items[name] = null; - } - }; - - Admittance.prototype.removeItemChild = function(itemName, childName) { - if (children[itemName] && children[itemName][childName]) { - return children[itemName][childName] = null; - } - }; - - Admittance.prototype.revoke = function(itemName, userId) { - if (assignments[userId] && assignments[userId][itemName]) { - return assignments[userId][itemName] = null; - } - }; - - Admittance.prototype.save = function(cb) { - return this.adaptor.save(items, assignments, children, function() { - _this.emit("save"); - return cb(); - }); - }; - - /* - Recursively traverse items into a flat array - @param {object} items - map of items - @return {array} - flattened array of all children - */ - - - Admittance.prototype.traverseItems = function(assignedItems) { - var collection, item, key, recurseResult; - collection = {}; - for (key in assignedItems) { - if (!__hasProp.call(assignedItems, key)) continue; - item = assignedItems[key]; - collection[key] = item; - if (children[key] && children[key].length > 0) { - recurseResult = this.traverseItems(this.getItemChildren(key)); - collection = _.extend(collection, recurseResult); - } - } - return collection; - }; - - Admittance.prototype.getItemChildren = function(itemName) { - var childItemNames, childItems, key, name; - childItemNames = children[itemName]; - childItems = {}; - for (key in childItemNames) { - if (!__hasProp.call(childItemNames, key)) continue; - name = childItemNames[key]; - childItems[name] = items[name]; - } - return childItems; - }; - - return Admittance; - - })(EventEmitter); - - module.exports = Admittance; - -}).call(this); diff --git a/file-adaptor.coffee b/file-adaptor.coffee deleted file mode 100644 index c9e1e87..0000000 --- a/file-adaptor.coffee +++ /dev/null @@ -1,35 +0,0 @@ -fs = require "fs" -util = require "util" - -class FileAdaptor - - constructor: (@fileName) -> - - load: (cb) -> - #load up items, assignments and childrena and - #send them through callback - fs.readFile @fileName, 'utf8', (err, data) -> - if err - cb err - else - json = JSON.parse data - cb null, json.items, json.assignments, json.children - - save: (items, assignments, children, cb) -> - json = - items: items, - assignments: assignments, - children: children - - data = JSON.stringify json - #when save is done call callback - fs.writeFile @fileName, data, (err, data) -> - if err then cb err else cb() - - # saveAuthItem: (item, oldName, cb) -> - # cb() - - # saveAuthAssignment: (assignment, cb) -> - # cb() - -module.exports = FileAdaptor \ No newline at end of file diff --git a/file-adaptor.js b/file-adaptor.js deleted file mode 100644 index f33ae87..0000000 --- a/file-adaptor.js +++ /dev/null @@ -1,50 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var FileAdaptor, fs, util; - - fs = require("fs"); - - util = require("util"); - - FileAdaptor = (function() { - - function FileAdaptor(fileName) { - this.fileName = fileName; - } - - FileAdaptor.prototype.load = function(cb) { - return fs.readFile(this.fileName, 'utf8', function(err, data) { - var json; - if (err) { - return cb(err); - } else { - json = JSON.parse(data); - return cb(null, json.items, json.assignments, json.children); - } - }); - }; - - FileAdaptor.prototype.save = function(items, assignments, children, cb) { - var data, json; - json = { - items: items, - assignments: assignments, - children: children - }; - data = JSON.stringify(json); - return fs.writeFile(this.fileName, data, function(err, data) { - if (err) { - return cb(err); - } else { - return cb(); - } - }); - }; - - return FileAdaptor; - - })(); - - module.exports = FileAdaptor; - -}).call(this); diff --git a/index.coffee b/index.coffee deleted file mode 100644 index 43deb67..0000000 --- a/index.coffee +++ /dev/null @@ -1,5 +0,0 @@ -Admittance = require "./admittance" -FileAdaptor = require "./file-adaptor" - -module.exports.Admittance = Admittance -module.exports.FileAdaptor = FileAdaptor \ No newline at end of file diff --git a/index.js b/index.js deleted file mode 100644 index c69d344..0000000 --- a/index.js +++ /dev/null @@ -1,13 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Admittance, FileAdaptor; - - Admittance = require("./admittance"); - - FileAdaptor = require("./file-adaptor"); - - module.exports.Admittance = Admittance; - - module.exports.FileAdaptor = FileAdaptor; - -}).call(this); diff --git a/package.json b/package.json index 9fb94ce..ffd812a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Role based access control implementation for node", "main": "index.js", "scripts": { - "test": "mocha tests/test.coffee --compilers coffee:coffee-script" + "test": "mocha tests/test.coffee --compilers coffee:coffee-script", + "jshint": "node_modules/.bin/jshint ." }, "repository": "git@github.com:digitalsadhu/admittance.git", "keywords": [ @@ -22,5 +23,8 @@ "mocha": "1.12.0", "chai": "1.7.2", "coffee-script": "1.6.3" + }, + "devDependencies": { + "jshint": "~2.4.4" } } diff --git a/tests/rights-src.json b/tests/rights-src.json deleted file mode 100644 index 339cbf4..0000000 --- a/tests/rights-src.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "assignments": { - "501": { - "admin": { - "itemName": "admin", - "id": 501, - "bizRule": null, - "data": "N;" - }, - "tmc": { - "itemName": "tmc", - "id": 501, - "bizRule": null, - "data": "N;" - } - }, - "12": { - "tmc": { - "itemName": "tmc", - "id": 12, - "bizRule": null, - "data": "N;" - } - } - }, - "items": { - "admin": { - "name": "admin", - "type": 2, - "description": "Admin user", - "bizRule": null, - "data": "N;" - }, - "tmc": { - "name": "tmc", - "type": 2, - "description": "TMC user", - "bizRule": null, - "data": "N;" - }, - "acceptTMP": { - "name": "acceptTMP", - "type": 0, - "description": "Accept TMPs", - "bizRule": null, - "data": "N;" - } - }, - "children": { - "admin": ["acceptTMP", "tmc"], - "tmc": ["acceptTMP"] - } -} \ No newline at end of file diff --git a/tests/rights.json b/tests/rights.json deleted file mode 100644 index 95229a3..0000000 --- a/tests/rights.json +++ /dev/null @@ -1 +0,0 @@ -{"items":{"admin":{"name":"admin","type":2,"description":"Admin user","bizRule":null,"data":"N;"},"tmc":{"name":"tmc","type":2,"description":"TMC user","bizRule":null,"data":"N;"},"acceptTMP":{"name":"acceptTMP","type":0,"description":"Accept TMPs","bizRule":null,"data":"N;"},"my-test":{"name":"my-test","type":2,"description":"this is a test"}},"assignments":{"12":{"tmc":{"itemName":"tmc","id":12,"bizRule":null,"data":"N;"}},"501":{"admin":{"itemName":"admin","id":501,"bizRule":null,"data":"N;"},"tmc":{"itemName":"tmc","id":501,"bizRule":null,"data":"N;"}}},"children":{"admin":["acceptTMP","tmc"],"tmc":["acceptTMP"]}} \ No newline at end of file diff --git a/tests/test.coffee b/tests/test.coffee deleted file mode 100644 index c2cd1ec..0000000 --- a/tests/test.coffee +++ /dev/null @@ -1,126 +0,0 @@ -chai = require 'chai' -chai.should() - -AdmittanceModule = require '../index' -Admittance = AdmittanceModule.Admittance -FileAdaptor = AdmittanceModule.FileAdaptor -fs = require 'fs' - - -am = new Admittance(new FileAdaptor('tests/rights.json')) - -describe 'The Admittance class', -> - - afterEach (done) -> - am.clearAll() - done() - - describe 'createAuthItem method', -> - - it 'should add an item to the auth collection', -> - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.getAuthItem('admin').name.should.equal('admin') - - describe 'assign method', -> - - it 'should assign an item to a user id', -> - am.checkAccess('admin', 1).should.equal(false) - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.assign 'admin', 1, '', 'N;' - am.checkAccess('admin', 1).should.equal(true) - - describe 'addItemChild method', -> - - it 'should add an item child to an item', -> - am.checkAccess('admin', 1).should.equal(false) - am.checkAccess('retard', 1).should.equal(false) - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.createAuthItem 'retard', 2, 'Retarded user', '', 'N;' - am.addItemChild 'admin', 'retard' - am.assign 'admin', 1, '', 'N;' - am.checkAccess('admin', 1).should.equal(true) - am.checkAccess('retard', 1).should.equal(true) - - describe 'hasItemChild method', -> - - it 'should return true if item has a child', -> - am.hasItemChild('admin', 'retard').should.equal(false) - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.createAuthItem 'retard', 2, 'Retarded user', '', 'N;' - am.addItemChild 'admin', 'retard' - am.hasItemChild('admin', 'retard').should.equal(true) - - describe 'isAssigned method', -> - - it 'should return true if user has a given item assigned', -> - am.isAssigned('admin', 1).should.equal(false) - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.assign 'admin', 1, '', 'N;' - am.isAssigned('admin', 1).should.equal(true) - - describe 'getAuthAssignment method', -> - - it 'should return auth assignment for a given user by itemname', -> - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.assign 'admin', 1, '', 'N;' - am.getAuthAssignment('admin', 1).itemName.should.equal('admin') - - describe 'getAuthAssignments method', -> - - it 'should return auth assignments for a given user', -> - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.createAuthItem 'monkey', 2, 'Admin user', '', 'N;' - am.assign 'admin', 1, '', 'N;' - am.assign 'monkey', 1, '', 'N;' - am.getAuthAssignments(1).should.be.an('object') - am.getAuthAssignments(1)['admin']['itemName'].should.equal('admin') - am.getAuthAssignments(1)['monkey']['itemName'].should.equal('monkey') - - describe 'getAuthItem method', -> - - it 'should return auth item for a given auth item name', -> - am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - am.getAuthItem('admin').should.be.an('object') - am.getAuthItem('admin').name.should.equal('admin') - - describe 'clearAll method', -> - - it 'should clear all items from memory', -> - # am.createAuthItem 'admin', 2, 'Admin user', '', 'N;' - # am.assign 'admin', 1, '', 'N;' - -### - FileAdaptor Tests -### -describe 'The FileAdaptor class', -> - - beforeEach (done) -> - am = new Admittance(new FileAdaptor('tests/rights.json')) - done() - - afterEach (done) -> - am.clearAll() - fs.readFile 'tests/rights-src.json', 'utf8', (err, data) -> - fs.writeFile 'tests/rights.json', data, () -> - done() - - describe 'load method', () -> - - it 'should load existing rights file', (done) -> - am.on 'load', () -> - am.getAuthItem('admin').should.be.an('object') - am.getAuthItem('admin').name.should.equal('admin') - done() - - describe 'save method', -> - it 'should save rights to file', (done) -> - am.on 'load', () -> - am.createAuthItem 'my-test', 2, 'this is a test' - am.save () -> - aam = new Admittance(new FileAdaptor('tests/rights.json')) - aam.getAuthItem('my-test').should.be.an('object') - done() - - - - diff --git a/tests/test.js b/tests/test.js deleted file mode 100644 index 4ba1fd9..0000000 --- a/tests/test.js +++ /dev/null @@ -1,138 +0,0 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - var Admittance, AdmittanceModule, FileAdaptor, am, chai, fs; - - chai = require('chai'); - - chai.should(); - - AdmittanceModule = require('../index'); - - Admittance = AdmittanceModule.Admittance; - - FileAdaptor = AdmittanceModule.FileAdaptor; - - fs = require('fs'); - - am = new Admittance(new FileAdaptor('tests/rights.json')); - - describe('The Admittance class', function() { - afterEach(function(done) { - am.clearAll(); - return done(); - }); - describe('createAuthItem method', function() { - return it('should add an item to the auth collection', function() { - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - return am.getAuthItem('admin').name.should.equal('admin'); - }); - }); - describe('assign method', function() { - return it('should assign an item to a user id', function() { - am.checkAccess('admin', 1).should.equal(false); - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.assign('admin', 1, '', 'N;'); - return am.checkAccess('admin', 1).should.equal(true); - }); - }); - describe('addItemChild method', function() { - return it('should add an item child to an item', function() { - am.checkAccess('admin', 1).should.equal(false); - am.checkAccess('retard', 1).should.equal(false); - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.createAuthItem('retard', 2, 'Retarded user', '', 'N;'); - am.addItemChild('admin', 'retard'); - am.assign('admin', 1, '', 'N;'); - am.checkAccess('admin', 1).should.equal(true); - return am.checkAccess('retard', 1).should.equal(true); - }); - }); - describe('hasItemChild method', function() { - return it('should return true if item has a child', function() { - am.hasItemChild('admin', 'retard').should.equal(false); - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.createAuthItem('retard', 2, 'Retarded user', '', 'N;'); - am.addItemChild('admin', 'retard'); - return am.hasItemChild('admin', 'retard').should.equal(true); - }); - }); - describe('isAssigned method', function() { - return it('should return true if user has a given item assigned', function() { - am.isAssigned('admin', 1).should.equal(false); - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.assign('admin', 1, '', 'N;'); - return am.isAssigned('admin', 1).should.equal(true); - }); - }); - describe('getAuthAssignment method', function() { - return it('should return auth assignment for a given user by itemname', function() { - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.assign('admin', 1, '', 'N;'); - return am.getAuthAssignment('admin', 1).itemName.should.equal('admin'); - }); - }); - describe('getAuthAssignments method', function() { - return it('should return auth assignments for a given user', function() { - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.createAuthItem('monkey', 2, 'Admin user', '', 'N;'); - am.assign('admin', 1, '', 'N;'); - am.assign('monkey', 1, '', 'N;'); - am.getAuthAssignments(1).should.be.an('object'); - am.getAuthAssignments(1)['admin']['itemName'].should.equal('admin'); - return am.getAuthAssignments(1)['monkey']['itemName'].should.equal('monkey'); - }); - }); - describe('getAuthItem method', function() { - return it('should return auth item for a given auth item name', function() { - am.createAuthItem('admin', 2, 'Admin user', '', 'N;'); - am.getAuthItem('admin').should.be.an('object'); - return am.getAuthItem('admin').name.should.equal('admin'); - }); - }); - return describe('clearAll method', function() { - return it('should clear all items from memory', function() {}); - }); - }); - - /* - FileAdaptor Tests - */ - - - describe('The FileAdaptor class', function() { - beforeEach(function(done) { - am = new Admittance(new FileAdaptor('tests/rights.json')); - return done(); - }); - afterEach(function(done) { - am.clearAll(); - fs.readFile('tests/rights-src.json', 'utf8', function(err, data) { - return fs.writeFile('tests/rights.json', data, function() {}); - }); - return done(); - }); - describe('load method', function() { - return it('should load existing rights file', function(done) { - return am.on('load', function() { - am.getAuthItem('admin').should.be.an('object'); - am.getAuthItem('admin').name.should.equal('admin'); - return done(); - }); - }); - }); - return describe('save method', function() { - return it('should save rights to file', function(done) { - return am.on('load', function() { - am.createAuthItem('my-test', 2, 'this is a test'); - return am.save(function() { - var aam; - aam = new Admittance(new FileAdaptor('tests/rights.json')); - aam.getAuthItem('my-test').should.be.an('object'); - return done(); - }); - }); - }); - }); - }); - -}).call(this); From f426552e90e2a025f46e143e32341228ec764b2d Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 21:53:44 +0100 Subject: [PATCH 02/13] Add basic example file to work toward --- example.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 example.js diff --git a/example.js b/example.js new file mode 100644 index 0000000..c5ec60f --- /dev/null +++ b/example.js @@ -0,0 +1,15 @@ +'use strict'; + +var fs = require('fs') + , admittance = require('admittance') + +//read from the text file where we store pairs of user ids and permissions +var storeR = fs.createReadStream(__dirname + '/my-store.txt') + +//read in permissions +storeR.pipe(admittance) + +//do a permissions check +if (admittance(userid).is('admin')) { + //yay, user is admin! +} \ No newline at end of file From d3a576930a34a3eac3e30dad58ec3e9d6a3f35a1 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 22:13:40 +0100 Subject: [PATCH 03/13] clean up .gitignore file --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 651c20b..5c7b556 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ node_modules -lib-cov *.seed *.log *.csv @@ -7,7 +6,6 @@ lib-cov *.out *.pid *.gz -pids logs results npm-debug.log From 0eab55809cd22dc71ca6a15b64719bc85bb2a7ad Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 22:15:15 +0100 Subject: [PATCH 04/13] Add jshint config and fix jshint errors --- .jshintignore | 1 + .jshintrc | 9 +++++++++ example.js | 2 ++ 3 files changed, 12 insertions(+) create mode 100644 .jshintignore create mode 100644 .jshintrc diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.jshintignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..fcb3fc1 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,9 @@ +{ + "laxcomma": true, + "globals": { + "require": false, + "__dirname": false + }, + "asi": true, + "node": true +} \ No newline at end of file diff --git a/example.js b/example.js index c5ec60f..f393b95 100644 --- a/example.js +++ b/example.js @@ -9,6 +9,8 @@ var storeR = fs.createReadStream(__dirname + '/my-store.txt') //read in permissions storeR.pipe(admittance) +var userid = 1; + //do a permissions check if (admittance(userid).is('admin')) { //yay, user is admin! From 5c9176684af3b8fd6696e1c0969cf4d6db0b5f67 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 22:15:50 +0100 Subject: [PATCH 05/13] update package.json for version 2 --- package.json | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index ffd812a..242c750 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "admittance", - "version": "0.0.3", - "description": "Role based access control implementation for node", + "version": "2.0.0", + "description": "A Simple role based access control implementation for node", "main": "index.js", "scripts": { - "test": "mocha tests/test.coffee --compilers coffee:coffee-script", + "test": "", "jshint": "node_modules/.bin/jshint ." }, "repository": "git@github.com:digitalsadhu/admittance.git", @@ -17,14 +17,10 @@ "auth" ], "author": "Richard Walker", - "license": "BSD", - "dependencies": { - "underscore": "1.4.4", + "license": "MIT", + "devDependencies": { "mocha": "1.12.0", "chai": "1.7.2", - "coffee-script": "1.6.3" - }, - "devDependencies": { "jshint": "~2.4.4" } } From 932e9596e31e110ac04fd73b6091c72dcee1c019 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 22:17:07 +0100 Subject: [PATCH 06/13] Add editorconfig file --- .editorconfig | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..04ba039 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] + +# Change these settings to your own preference +indent_style = space +indent_size = 2 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From a8ff54c662fcc699e4a39f58ba09f962cc90d9ef Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:09:05 +0100 Subject: [PATCH 07/13] Update .jshint config --- .jshintrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.jshintrc b/.jshintrc index fcb3fc1..4b0b647 100644 --- a/.jshintrc +++ b/.jshintrc @@ -2,7 +2,9 @@ "laxcomma": true, "globals": { "require": false, - "__dirname": false + "__dirname": false, + "describe": false, + "it": false }, "asi": true, "node": true From fda54a3580ffe6f9355ee6ff77517a3eafa9c10f Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:09:31 +0100 Subject: [PATCH 08/13] Update example file --- example.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/example.js b/example.js index f393b95..570918c 100644 --- a/example.js +++ b/example.js @@ -1,14 +1,10 @@ 'use strict'; -var fs = require('fs') - , admittance = require('admittance') - -//read from the text file where we store pairs of user ids and permissions -var storeR = fs.createReadStream(__dirname + '/my-store.txt') - -//read in permissions -storeR.pipe(admittance) +var permissionData = require('permissions.json') + , admittance = require('.admittance.js') +admittance.load(permissionData); + var userid = 1; //do a permissions check From 7bcb96a78650d6bfcf7e2c15f1471bdd64282d05 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:09:46 +0100 Subject: [PATCH 09/13] Update package.json scripts for npm test --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 242c750..a0933a0 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "A Simple role based access control implementation for node", "main": "index.js", "scripts": { - "test": "", + "test": "node_modules/.bin/mocha --reporter spec test/**/*", "jshint": "node_modules/.bin/jshint ." }, "repository": "git@github.com:digitalsadhu/admittance.git", From 452f079230e10fe6853df94146f53a5629dc6131 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:10:04 +0100 Subject: [PATCH 10/13] Add basic README file --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..47bf208 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Admittance (Version 2) + From 6f95a6c5fc7714479fe07171999588d97147e8fd Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:10:27 +0100 Subject: [PATCH 11/13] Add tests for module --- test/admittance.spec.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/admittance.spec.js diff --git a/test/admittance.spec.js b/test/admittance.spec.js new file mode 100644 index 0000000..4272436 --- /dev/null +++ b/test/admittance.spec.js @@ -0,0 +1,30 @@ +'use strict'; + +var expect = require('chai').expect + , admittance = require('../admittance.js') + +//do a permissions check +describe('admittance', function () { + + it('should return true when a user has a given permission', function () { + admittance.load({1:'admin'}); + var userid = 1; + expect(admittance(userid).is('admin')).to.equal(true); + }) + + it('should return false when a user does not have a given permission', function () { + admittance.load({1: 'admin'}); + var userid = 1; + expect(admittance(userid).is('monkey')).to.equal(false); + }) + + it('should return true when a user has several permissions assigned', function () { + admittance.load({1: ['admin', 'subscriber']}); + var userid = 1; + expect(admittance(userid).is('admin')).to.equal(true); + expect(admittance(userid).is('subscriber')).to.equal(true); + expect(admittance(userid).is('monkey')).to.equal(false); + }) + +}) + From e64a55ccb013f53ea790d490bc8a9b01088fccce Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:10:41 +0100 Subject: [PATCH 12/13] Add example/mock permissions json doc --- permissions.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 permissions.json diff --git a/permissions.json b/permissions.json new file mode 100644 index 0000000..7e0ee31 --- /dev/null +++ b/permissions.json @@ -0,0 +1,5 @@ +{ + "1": ["admin", "subscriber"], + "2": "admin", + "3": "subscriber" +} From 6df4fee7c805085b09d5913ef567c0e245d8c9ff Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Thu, 6 Mar 2014 23:11:01 +0100 Subject: [PATCH 13/13] Add admittance module --- admittance.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 admittance.js diff --git a/admittance.js b/admittance.js new file mode 100644 index 0000000..34f3e4c --- /dev/null +++ b/admittance.js @@ -0,0 +1,23 @@ +'use strict'; + +var util = require('util') + +var permissions = {} + +var admittance = function (userid) { + return { + is: function (permission) { + + if (util.isArray(permissions[userid])) + if (permissions[userid].indexOf(permission) !== -1) return true + + return permissions[userid] === permission + } + } +} + +admittance.load = function (permissionData) { + permissions = permissionData +} + +module.exports = admittance