From d5559dbdb02c2be2cb20b48fd75b9c97408237f2 Mon Sep 17 00:00:00 2001 From: Richard Walker Date: Sun, 7 Jul 2013 21:55:14 +0200 Subject: [PATCH] implements save method with test --- README.md | 42 ++++++++++++- admittance.coffee | 4 +- admittance.js | 3 +- file-adaptor.coffee | 2 +- file-adaptor.js | 2 +- tests/rights-src.json | 53 ++++++++++++++++ tests/rights.json | 54 +---------------- tests/test.coffee | 14 ++++- tests/test.js | 138 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 250 insertions(+), 62 deletions(-) create mode 100644 tests/rights-src.json create mode 100644 tests/test.js diff --git a/README.md b/README.md index d1c20ad..4e5db6e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 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 some several key features are not yet implemented... ehh hmm, persisting permissions for example... Anyway, don't use it yet. Do contribute though! Accepting pull requests! +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. @@ -64,20 +64,56 @@ 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 -### saveAuthAssignment -### saveAuthItem + +Persists any changes ## Events diff --git a/admittance.coffee b/admittance.coffee index 5d62990..deadaad 100644 --- a/admittance.coffee +++ b/admittance.coffee @@ -182,8 +182,8 @@ class Admittance extends EventEmitter assignments[userId][itemName] = null save: (cb) -> - @adaptor.save @items, @assignments, @children, -> - # @emit "save" + @adaptor.save items, assignments, children, () -> + _this.emit "save" cb() # saveAuthAssignment: (assignment, cb) -> diff --git a/admittance.js b/admittance.js index 286eb0f..e1303c6 100644 --- a/admittance.js +++ b/admittance.js @@ -249,7 +249,8 @@ }; Admittance.prototype.save = function(cb) { - return this.adaptor.save(this.items, this.assignments, this.children, function() { + return this.adaptor.save(items, assignments, children, function() { + _this.emit("save"); return cb(); }); }; diff --git a/file-adaptor.coffee b/file-adaptor.coffee index 8d97eb8..c9e1e87 100644 --- a/file-adaptor.coffee +++ b/file-adaptor.coffee @@ -23,7 +23,7 @@ class FileAdaptor data = JSON.stringify json #when save is done call callback - fs.writeFile @fileName, 'utf8', data, (err, data) -> + fs.writeFile @fileName, data, (err, data) -> if err then cb err else cb() # saveAuthItem: (item, oldName, cb) -> diff --git a/file-adaptor.js b/file-adaptor.js index 806d4f9..f33ae87 100644 --- a/file-adaptor.js +++ b/file-adaptor.js @@ -32,7 +32,7 @@ children: children }; data = JSON.stringify(json); - return fs.writeFile(this.fileName, 'utf8', data, function(err, data) { + return fs.writeFile(this.fileName, data, function(err, data) { if (err) { return cb(err); } else { diff --git a/tests/rights-src.json b/tests/rights-src.json new file mode 100644 index 0000000..339cbf4 --- /dev/null +++ b/tests/rights-src.json @@ -0,0 +1,53 @@ +{ + "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 index 339cbf4..95229a3 100644 --- a/tests/rights.json +++ b/tests/rights.json @@ -1,53 +1 @@ -{ - "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 +{"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 index ea8ea4b..c2cd1ec 100644 --- a/tests/test.coffee +++ b/tests/test.coffee @@ -4,6 +4,7 @@ chai.should() AdmittanceModule = require '../index' Admittance = AdmittanceModule.Admittance FileAdaptor = AdmittanceModule.FileAdaptor +fs = require 'fs' am = new Admittance(new FileAdaptor('tests/rights.json')) @@ -99,9 +100,11 @@ describe 'The FileAdaptor class', -> afterEach (done) -> am.clearAll() + fs.readFile 'tests/rights-src.json', 'utf8', (err, data) -> + fs.writeFile 'tests/rights.json', data, () -> done() - describe 'load method', (done) -> + describe 'load method', () -> it 'should load existing rights file', (done) -> am.on 'load', () -> @@ -110,5 +113,14 @@ describe 'The FileAdaptor class', -> 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 new file mode 100644 index 0000000..4ba1fd9 --- /dev/null +++ b/tests/test.js @@ -0,0 +1,138 @@ +// 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);