diff --git a/coffee/db_interface.coffee b/coffee/db_interface.coffee index ca72ecf..8d52317 100644 --- a/coffee/db_interface.coffee +++ b/coffee/db_interface.coffee @@ -534,7 +534,7 @@ exports.deleteRule = ( ruleId ) => @db.smembers "rule:#{ ruleId }:users", ( err, obj ) => delLinkedUserRule = ( userId ) => @db.srem "user:#{ userId }:rules", ruleId, - replyHandler "Deleting rule key '#{ ruleId }'' in linked user '#{ userId }'" + replyHandler "Deleting rule key '#{ ruleId }' in linked user '#{ userId }'" delLinkedUserRule( id ) for id in obj @db.del "rule:#{ ruleId }:users", replyHandler "Deleting rule '#{ ruleId }' users" @@ -656,43 +656,26 @@ exports.getAllActivatedRuleIdsPerUser = ( cb ) => log.print 'DB', "Fetching all active rules" @db.smembers 'users', ( err, obj ) => result = {} - console.log 'checking length' if obj.length is 0 - console.log 'length cehcked is 0' cb null, result else - console.log 'length cehcked' semaphore = obj.length fFetchActiveUserRules = ( userId ) => @db.smembers "user:#{ user }:active-rules", ( err, obj ) => - console.log obj - console.log obj.length - if obj.length is 0 - console.log 'is 0' - else + if obj.length > 0 result[userId] = obj if --semaphore is 0 cb null, result fFetchActiveUserRules(user) for user in obj - -### -Fetch all active rules and pass them to cb(err, obj). -@public getAllActivatedRules( *cb* ) -@param {function} cb ### -exports.getAllActivatedRules = ( cb ) => - log.print 'DB', "Fetching all active rules" - fCb = ( err, obj ) -> - console.log 'fetched something' - console.log err - console.log obj - @db.smembers 'users', ( err, obj ) => - getSetRecords "user:#{ user }:active-rules", exports.getRule, fCb for user in obj +## Users +### ### Store a user object (needs to be a flat structure). +The password should be hashed before it is passed to this function. @public storeUser( *objUser* ) @param {Object} objUser @@ -704,12 +687,71 @@ exports.storeUser = ( objUser ) => if objUser and objUser.username and objUser.password @db.sadd 'users', objUser.username, replyHandler "storing user key '#{ objUser.username }'" - objUser.password = hash objUser.password + objUser.password = objUser.password @db.hmset "user:#{ objUser.username }", objUser, replyHandler "storing user properties '#{ objUser.username }'" else log.error 'DB', new Error 'username or password was missing' +### +Fetch all user IDs and pass them to cb(err, obj). + +@public getUserIds( *cb* ) +@param {function} cb +### +exports.getUserIds = ( cb ) => + log.print 'DB', "getUserIds" + @db.smembers "users", cb + +### +Fetch a user by id and pass it to cb(err, obj). + +@public getUser( *userId, cb* ) +@param {String} userId +@param {function} cb +### +exports.getUser = ( userId, cb ) => + log.print 'DB', "getUser: '#{ userId }'" + @db.hgetall "user:#{ userId }", cb + +### +Deletes a user and all his associated linked and active rules. + +@public deleteUser( *userId* ) +@param {String} userId +### +exports.deleteUser = ( userId ) => + log.print 'DB', "deleteUser: '#{ userId }'" + @db.srem "users", userId, replyHandler "Deleting user key '#{ userId }'" + @db.del "user:#{ userId }", replyHandler "Deleting user '#{ userId }'" + + # We also need to delete all linked rules + @db.smembers "user:#{ userId }:rules", ( err, obj ) => + delLinkedRuleUser = ( ruleId ) => + @db.srem "rule:#{ ruleId }:users", userId, + replyHandler "Deleting user key '#{ userId }' in linked rule '#{ ruleId }'" + delLinkedRuleUser( id ) for id in obj + @db.del "user:#{ userId }:rules", + replyHandler "Deleting user '#{ userId }' rules" + + # We also need to delete all active rules + @db.smembers "user:#{ userId }:active-rules", ( err, obj ) => + delActivatedRuleUser = ( ruleId ) => + @db.srem "rule:#{ ruleId }:active-users", userId, + replyHandler "Deleting user key '#{ userId }' in active rule '#{ ruleId }'" + delActivatedRuleUser( id ) for id in obj + @db.del "user:#{ userId }:active-rules", + replyHandler "Deleting user '#{ userId }' rules" + + # We also need to delete all associated roles + @db.smembers "user:#{ userId }:roles", ( err, obj ) => + delActivatedRoleUser = ( roleId ) => + @db.srem "role:#{ roleId }:users", userId, + replyHandler "Deleting user key '#{ userId }' in role '#{ roleId }'" + delActivatedRoleUser( id ) for id in obj + @db.del "user:#{ userId }:roles", + replyHandler "Deleting user '#{ userId }' roles" + ### Associate a role with a user. @@ -773,35 +815,6 @@ exports.loginUser = ( userId, password, cb ) => cb new Error 'User not found!' @db.hgetall "user:#{ userId }", fCheck password -### -Deletes a user and all his associated linked and active rules. - -@public deleteUser( *userId* ) -@param {String} userId -### -exports.deleteUser = ( userId ) => - log.print 'DB', "deleteUser: '#{ userId }'" - @db.srem "users", userId, replyHandler "Deleting user key '#{ userId }'" - @db.del "user:#{ userId }", replyHandler "Deleting user '#{ userId }'" - - # We also need to delete all linked rules - @db.smembers "user:#{ userId }:rules", ( err, obj ) => - delLinkedRuleUser = ( ruleId ) => - @db.srem "rule:#{ ruleId }:users", userId, - replyHandler "Deleting user key '#{ userId }' in linked rule '#{ ruleId }'" - delLinkedRuleUser( id ) for id in obj - @db.del "user:#{ userId }:rules", - replyHandler "Deleting user '#{ userId }' rules" - - # We also need to delete all active rules - @db.smembers "user:#{ userId }:rules", ( err, obj ) => - delActivatedRuleUser = ( ruleId ) => - @db.srem "rule:#{ ruleId }:active-users", userId, - replyHandler "Deleting user key '#{ userId }' in active rule '#{ ruleId }'" - delActivatedRuleUser( id ) for id in obj - @db.del "user:#{ userId }:active-rules", replyHandler "Deleting user '#{ userId }' rules" - - #TODO implement functions required for user sessions? ### diff --git a/js-coffee/db_interface.js b/js-coffee/db_interface.js index 4c43d13..a01fefc 100644 --- a/js-coffee/db_interface.js +++ b/js-coffee/db_interface.js @@ -676,7 +676,7 @@ DB Interface _this.db.smembers("rule:" + ruleId + ":users", function(err, obj) { var delLinkedUserRule, id, _i, _len, _results; delLinkedUserRule = function(userId) { - return _this.db.srem("user:" + userId + ":rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "'' in linked user '" + userId + "'")); + return _this.db.srem("user:" + userId + ":rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "' in linked user '" + userId + "'")); }; _results = []; for (_i = 0, _len = obj.length; _i < _len; _i++) { @@ -830,20 +830,13 @@ DB Interface return _this.db.smembers('users', function(err, obj) { var fFetchActiveUserRules, result, semaphore, user, _i, _len, _results; result = {}; - console.log('checking length'); if (obj.length === 0) { - console.log('length cehcked is 0'); return cb(null, result); } else { - console.log('length cehcked'); semaphore = obj.length; fFetchActiveUserRules = function(userId) { return _this.db.smembers("user:" + user + ":active-rules", function(err, obj) { - console.log(obj); - console.log(obj.length); - if (obj.length === 0) { - console.log('is 0'); - } else { + if (obj.length > 0) { result[userId] = obj; } if (--semaphore === 0) { @@ -862,34 +855,13 @@ DB Interface }; /* - Fetch all active rules and pass them to cb(err, obj). - - @public getAllActivatedRules( *cb* ) - @param {function} cb + ## Users */ - exports.getAllActivatedRules = function(cb) { - var fCb; - log.print('DB', "Fetching all active rules"); - fCb = function(err, obj) { - console.log('fetched something'); - console.log(err); - return console.log(obj); - }; - return _this.db.smembers('users', function(err, obj) { - var user, _i, _len, _results; - _results = []; - for (_i = 0, _len = obj.length; _i < _len; _i++) { - user = obj[_i]; - _results.push(getSetRecords("user:" + user + ":active-rules", exports.getRule, fCb)); - } - return _results; - }); - }; - /* Store a user object (needs to be a flat structure). + The password should be hashed before it is passed to this function. @public storeUser( *objUser* ) @param {Object} objUser @@ -900,13 +872,93 @@ DB Interface log.print('DB', "storeUser: '" + objUser.username + "'"); if (objUser && objUser.username && objUser.password) { _this.db.sadd('users', objUser.username, replyHandler("storing user key '" + objUser.username + "'")); - objUser.password = hash(objUser.password); + objUser.password = objUser.password; return _this.db.hmset("user:" + objUser.username, objUser, replyHandler("storing user properties '" + objUser.username + "'")); } else { return log.error('DB', new Error('username or password was missing')); } }; + /* + Fetch all user IDs and pass them to cb(err, obj). + + @public getUserIds( *cb* ) + @param {function} cb + */ + + + exports.getUserIds = function(cb) { + log.print('DB', "getUserIds"); + return _this.db.smembers("users", cb); + }; + + /* + Fetch a user by id and pass it to cb(err, obj). + + @public getUser( *userId, cb* ) + @param {String} userId + @param {function} cb + */ + + + exports.getUser = function(userId, cb) { + log.print('DB', "getUser: '" + userId + "'"); + return _this.db.hgetall("user:" + userId, cb); + }; + + /* + Deletes a user and all his associated linked and active rules. + + @public deleteUser( *userId* ) + @param {String} userId + */ + + + exports.deleteUser = function(userId) { + log.print('DB', "deleteUser: '" + userId + "'"); + _this.db.srem("users", userId, replyHandler("Deleting user key '" + userId + "'")); + _this.db.del("user:" + userId, replyHandler("Deleting user '" + userId + "'")); + _this.db.smembers("user:" + userId + ":rules", function(err, obj) { + var delLinkedRuleUser, id, _i, _len, _results; + delLinkedRuleUser = function(ruleId) { + return _this.db.srem("rule:" + ruleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in linked rule '" + ruleId + "'")); + }; + _results = []; + for (_i = 0, _len = obj.length; _i < _len; _i++) { + id = obj[_i]; + _results.push(delLinkedRuleUser(id)); + } + return _results; + }); + _this.db.del("user:" + userId + ":rules", replyHandler("Deleting user '" + userId + "' rules")); + _this.db.smembers("user:" + userId + ":active-rules", function(err, obj) { + var delActivatedRuleUser, id, _i, _len, _results; + delActivatedRuleUser = function(ruleId) { + return _this.db.srem("rule:" + ruleId + ":active-users", userId, replyHandler("Deleting user key '" + userId + "' in active rule '" + ruleId + "'")); + }; + _results = []; + for (_i = 0, _len = obj.length; _i < _len; _i++) { + id = obj[_i]; + _results.push(delActivatedRuleUser(id)); + } + return _results; + }); + _this.db.del("user:" + userId + ":active-rules", replyHandler("Deleting user '" + userId + "' rules")); + _this.db.smembers("user:" + userId + ":roles", function(err, obj) { + var delActivatedRoleUser, id, _i, _len, _results; + delActivatedRoleUser = function(roleId) { + return _this.db.srem("role:" + roleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in role '" + roleId + "'")); + }; + _results = []; + for (_i = 0, _len = obj.length; _i < _len; _i++) { + id = obj[_i]; + _results.push(delActivatedRoleUser(id)); + } + return _results; + }); + return _this.db.del("user:" + userId + ":roles", replyHandler("Deleting user '" + userId + "' roles")); + }; + /* Associate a role with a user. @@ -984,46 +1036,6 @@ DB Interface return _this.db.hgetall("user:" + userId, fCheck(password)); }; - /* - Deletes a user and all his associated linked and active rules. - - @public deleteUser( *userId* ) - @param {String} userId - */ - - - exports.deleteUser = function(userId) { - log.print('DB', "deleteUser: '" + userId + "'"); - _this.db.srem("users", userId, replyHandler("Deleting user key '" + userId + "'")); - _this.db.del("user:" + userId, replyHandler("Deleting user '" + userId + "'")); - _this.db.smembers("user:" + userId + ":rules", function(err, obj) { - var delLinkedRuleUser, id, _i, _len, _results; - delLinkedRuleUser = function(ruleId) { - return _this.db.srem("rule:" + ruleId + ":users", userId, replyHandler("Deleting user key '" + userId + "' in linked rule '" + ruleId + "'")); - }; - _results = []; - for (_i = 0, _len = obj.length; _i < _len; _i++) { - id = obj[_i]; - _results.push(delLinkedRuleUser(id)); - } - return _results; - }); - _this.db.del("user:" + userId + ":rules", replyHandler("Deleting user '" + userId + "' rules")); - _this.db.smembers("user:" + userId + ":rules", function(err, obj) { - var delActivatedRuleUser, id, _i, _len, _results; - delActivatedRuleUser = function(ruleId) { - return _this.db.srem("rule:" + ruleId + ":active-users", userId, replyHandler("Deleting user key '" + userId + "' in active rule '" + ruleId + "'")); - }; - _results = []; - for (_i = 0, _len = obj.length; _i < _len; _i++) { - id = obj[_i]; - _results.push(delActivatedRuleUser(id)); - } - return _results; - }); - return _this.db.del("user:" + userId + ":active-rules", replyHandler("Deleting user '" + userId + "' rules")); - }; - /* Shuts down the db link. diff --git a/testing/test_db_interface.coffee b/testing/test_db_interface.coffee index 00a5198..3eaf1d4 100644 --- a/testing/test_db_interface.coffee +++ b/testing/test_db_interface.coffee @@ -3,8 +3,16 @@ exports.setUp = ( cb ) => @db = require '../js-coffee/db_interface' @db logType: 2 cb() + +exports.tearDown = ( cb ) => + @db.shutDown() + cb() -exports.availability = + +### +# Test AVAILABILITY +### +exports.Availability = testRequire: ( test ) => test.expect 1 @@ -48,7 +56,11 @@ exports.availability = test.strictEqual obj, null, 'There was an event in the queue!?' test.done() -exports.events = + +### +# Test EVENT QUEUE +### +exports.EventQueue = setUp: ( cb ) => @evt1 = eventid: '1' @@ -120,7 +132,11 @@ exports.events = 'Wrong event in queue!' forkEnds() -exports.action_invoker = + +### +# Test ACTION INVOKER +### +exports.ActionInvoker = testCreateAndRead: ( test ) => test.expect 3 @@ -220,7 +236,10 @@ exports.action_invoker = @db.getActionInvoker action2name, fCheckInvoker action2name, action2 -exports.action_invoker_params = +### +# Test ACTION INVOKER PARAMS +### +exports.ActionInvokerParams = testCreateAndRead: ( test ) => test.expect 2 @@ -284,7 +303,10 @@ exports.action_invoker_params = test.done() -exports.event_poller = +### +# Test EVENT POLLER +### +exports.EventPoller = testCreateAndRead: ( test ) => test.expect 3 @@ -384,7 +406,10 @@ exports.event_poller = @db.getEventPoller event2name, fCheckPoller event2name, event2 -exports.event_poller_params = +### +# Test EVENT POLLER PARAMS +### +exports.EventPollerParams = testCreateAndRead: ( test ) => test.expect 2 @@ -448,9 +473,12 @@ exports.event_poller_params = test.done() -exports.rules = +### +# Test RULES +### +exports.Rules = setUp: ( cb ) => - @db logType: 1 + # @db logType: 1 @userId = 'tester-1' @ruleId = 'test-rule_1' @rule = @@ -562,7 +590,7 @@ exports.rules = test.done() testActivate: ( test ) => - test.expect 3 + test.expect 4 usr = username: "tester-1" @@ -583,10 +611,14 @@ exports.rules = # Ensure the rule is showing up in all active rules @db.getAllActivatedRuleIdsPerUser ( err, obj ) => - test.ok obj[@userId], - "User not found in activated set" - test.ok @ruleId in obj[@userId], - "Rule #{ @ruleId } not in activated rules set" + test.notStrictEqual obj[@userId], undefined, + "User #{ @userId } not in activated rules set" + if obj[@userId] + test.ok @ruleId in obj[@userId], + "Rule #{ @ruleId } not in activated rules set" + else + test.ok true, + "Dummy so we meet the expected num of tests" test.done() testDeactivate: ( test ) => @@ -608,8 +640,12 @@ exports.rules = # Ensure the rule is showing up in all active rules @db.getAllActivatedRuleIdsPerUser ( err, obj ) => - test.ok @ruleId not in obj[@userId], - "Rule #{ @ruleId } still in activated rules set" + if obj[@userId] + test.ok @ruleId not in obj[@userId], + "Rule #{ @ruleId } still in activated rules set" + else + test.ok true, + "We are fine since there are no entries for this user anymore" test.done() testUnlinkAndDeactivateAfterDeletion: ( test ) => @@ -641,13 +677,123 @@ exports.rules = setTimeout fWaitForDeletion, 100 -# exports.users = -# test: ( test ) => -# test.expect 0 -# test.done() -# TODO on delete, remove all rules for the user if he's deleted +### +# Test USER +### +exports.User = + setUp: ( cb ) => + @db logType: 1 + @oUser = + username: "tester-1" + password: "password" + cb() + tearDown: ( cb ) => + @db.deleteUser @oUser.username + cb() + + testCreateInvalid: ( test ) => + test.expect 4 + + oUserInvOne = + username: "tester-1-invalid" + oUserInvTwo = + password: "password" + + # try to store invalid users, ensure they weren't + @db.storeUser oUserInvOne + @db.storeUser oUserInvTwo + + @db.getUser oUserInvOne.username, ( err, obj ) => + test.strictEqual obj, null, + 'User One was stored!?' + + @db.getUser oUserInvTwo.username, ( err, obj ) => + test.strictEqual obj, null, + 'User Two was stored!?' + + @db.getUserIds ( err, obj ) => + test.ok oUserInvOne.username not in obj, + 'User key was stored!?' + test.ok oUserInvTwo.username not in obj, + 'User key was stored!?' + test.done() + + testDelete: ( test ) => + test.expect 2 + + # Store the user + @db.storeUser @oUser + + @db.getUser @oUser.username, ( err, obj ) => + test.deepEqual obj, @oUser, + "User #{ @oUser.username } is not what we expect!" + + @db.getUserIds ( err, obj ) => + test.ok @oUser.username in obj, + 'User key was not stored!?' + test.done() + + testUpdate: ( test ) => + test.expect 2 + + oUserOne = + username: "tester-1-update" + password: "password" + + # Store the user + @db.storeUser oUserOne + oUserOne.password = "password-update" + @db.storeUser oUserOne + + @db.getUser oUserOne.username, ( err, obj ) => + test.deepEqual obj, oUserOne, + "User #{ @oUser.username } is not what we expect!" + + @db.getUserIds ( err, obj ) => + test.ok oUserOne.username in obj, + 'User key was not stored!?' + @db.deleteUser oUserOne.username + test.done() + + testDelete: ( test ) => + test.expect 2 + + # Wait until the user and his rules and roles are stored + fWaitForPersistence = () => + @db.deleteUser @oUser.username + setTimeout fWaitForDeletion, 200 + + # Wait until the user and his rules and roles are deleted + fWaitForDeletion = () => + @db.getUserIds ( err, obj ) => + test.ok @oUser.username not in obj, + 'User key still in set!' + + @db.getUser @oUser.username, ( err, obj ) => + test.strictEqual obj, null, + 'User key still exists!' + test.done() + + # Store the user and make some links + @db.storeUser @oUser + @db.linkRule 'rule-1', @oUser.username + @db.linkRule 'rule-2', @oUser.username + @db.linkRule 'rule-3', @oUser.username + @db.activateRule 'rule-1', @oUser.username + @db.storeUserRole @oUser.username, 'tester' + setTimeout fWaitForPersistence, 100 -exports.tearDown = ( cb ) => - @db.shutDown() - cb() \ No newline at end of file +### +# Test ROLES +### +# exports.Roles = + # setUp: ( cb ) => + # @db logType: 1 + # @oUser = + # username: "tester-1" + # password: "password" + # cb() + # tearDown: ( cb ) => + # @db.deleteUser @oUser.username + # cb()