Updated tests in DB interface

This commit is contained in:
Dominic Bosch 2014-02-10 22:28:10 +01:00
parent 5a13beadd0
commit 8fbe21094b
22 changed files with 2083 additions and 482 deletions

View file

@ -3,18 +3,18 @@
DB Interface
============
> Handles the connection to the database and provides functionalities for
> event/action modules, rules and the encrypted storing of authentication tokens.
> event pollers, action invokers, rules and the encrypted storing of authentication tokens.
> General functionality as a wrapper for the module holds initialization,
> encryption/decryption, the retrieval of modules and shut down.
>
> The general structure for linked data is that the key is stored in a set.
> By fetching all set entries we can then fetch all elements, which is
> automated in this function.
> For example modules of the same group, e.g. action modules are registered in an
> For example, modules of the same group, e.g. action invokers are registered in an
> unordered set in the database, from where they can be retrieved again. For example
> a new action module has its ID (e.g 'probinder') first registered in the set
> 'action_modules' and then stored in the db with the key 'action\_module\_' + ID
> (e.g. action\_module\_probinder).
> a new action invoker has its ID (e.g 'probinder') first registered in the set
> 'action-invokers' and then stored in the db with the key 'action-invoker:' + ID
> (e.g. action-invoker:probinder).
>
###
@ -50,6 +50,8 @@ exports = module.exports = ( args ) =>
@db.on 'error', ( err ) ->
err.addInfo = 'message from DB'
log.error 'DB', err
@ep = new IndexedModules( 'event-poller', @db )
@ai = new IndexedModules( 'action-invoker', @db )
else
log.error 'DB', 'Initialization failed because of missing config file!'
@ -83,7 +85,7 @@ Abstracts logging for simple action replies from the DB.
replyHandler = ( action ) ->
( err, reply ) ->
if err
err.addInfo = "during \"#{ action }\""
err.addInfo = "during '#{ action }'"
log.error 'DB', err
else
log.print 'DB', "#{ action }: #{ reply }"
@ -96,14 +98,14 @@ Push an event into the event queue.
###
exports.pushEvent = ( oEvent ) =>
if oEvent
log.print 'DB', "Event pushed into the queue: #{ oEvent.eventid }"
log.print 'DB', "Event pushed into the queue: '#{ oEvent.eventid }'"
@db.rpush 'event_queue', JSON.stringify( oEvent )
else
log.error 'DB', 'Why would you give me an empty event...'
###
Pop an event from the event queue and pass it to the callback(err, obj) function.
Pop an event from the event queue and pass it to cb(err, obj).
@public popEvent( *cb* )
@param {function} cb
@ -146,10 +148,8 @@ Encrypts a string using the crypto key from the config file, based on aes-256-cb
###
encrypt = ( plainText ) =>
if !plainText? then return null
try
enciph = crypto.createCipher 'aes-256-cbc', @crypto_key
et = enciph.update plainText, 'utf8', 'base64'
et + enciph.final 'base64'
try
crypto.AES.encrypt plainText, @crypto_key
catch err
err.addInfo = 'during encryption'
log.error 'DB', err
@ -164,203 +164,309 @@ Decrypts an encrypted string and hands it back on success or null.
decrypt = ( crypticText ) =>
if !crypticText? then return null;
try
deciph = crypto.createDecipher 'aes-256-cbc', @crypto_key
dt = deciph.update crypticText, 'base64', 'utf8'
dt + deciph.final 'utf8'
dec = crypto.AES.decrypt crypticText, @crypto_key
dec.toString(crypto.enc.Utf8)
catch err
err.addInfo = 'during decryption'
log.error 'DB', err
null
###
Fetches all linked data set keys from a linking set, fetches the single data objects
via the provided function and returns the results to the callback(err, obj) function.
Fetches all linked data set keys from a linking set, fetches the single
data objects via the provided function and returns the results to cb(err, obj).
@private getSetRecords( *set, fSingle, cb* )
@param {String} set the set name how it is stored in the DB
@param {function} fSingle a function to retrieve a single data element per set entry
@param {function} cb the callback(err, obj) function that receives all the retrieved data or an error
@param {function} fSingle a function to retrieve a single data element
per set entry
@param {function} cb the callback(err, obj) function that receives all
the retrieved data or an error
###
getSetRecords = ( set, fSingle, cb ) =>
log.print 'DB', "Fetching set records: #{ set }"
log.print 'DB', "Fetching set records: '#{ set }'"
# Fetch all members of the set
@db.smembers set, ( err, arrReply ) ->
if err
err.addInfo = "fetching #{ set }"
# If an error happens we return it to the callback function
err.addInfo = "fetching '#{ set }'"
log.error 'DB', err
cb err
else if arrReply.length == 0
# If the set was empty we return null to the callback
cb()
else
# We need to fetch all the entries from the set and use a semaphore
# since the fetching from the DB will happen asynchronously
semaphore = arrReply.length
objReplies = {}
setTimeout ->
# We use a timeout function to cancel the operation
# in case the DB does not respond
if semaphore > 0
cb new Error "Timeout fetching #{ set }"
cb new Error "Timeout fetching '#{ set }'"
, 2000
fCallback = ( prop ) ->
# The callback function is required to preprocess the result before
# handing it to the callback. This especially includes decrementing
# the semaphore
( err, data ) ->
--semaphore
if err
err.addInfo = "fetching single element: #{ prop }"
err.addInfo = "fetching single element: '#{ prop }'"
log.error 'DB', err
else if not data
log.error 'DB', new Error "Empty key in DB: #{ prop }"
# There was no data behind the key
log.error 'DB', new Error "Empty key in DB: '#{ prop }'"
else
# We found a valid record and add it to the reply object
objReplies[ prop ] = data
if semaphore == 0
# If all fetch calls returned we finally pass the result
# to the callback
cb null, objReplies
# Since we retrieved an array of keys, we now execute the fSingle function
# on each of them, to retrieve the ata behind the key. Our fCallback function
# is used to preprocess the answer to determine correct execution
fSingle reply, fCallback( reply ) for reply in arrReply
class IndexedModules
constructor: ( @setname, @db ) ->
log.print 'DB', "Instantiated indexed modules for '#{ @setname }'"
storeModule: ( mId, data ) =>
log.print 'DB', "storeModule(#{ @setname }): #{ mId }"
@db.sadd "#{ @setname }s", mId,
replyHandler "Storing '#{ @setname }' key '#{ mId }'"
@db.set "#{ @setname }:#{ mId }", data,
replyHandler "Storing '#{ @setname }:#{ mId }'"
getModule: ( mId, cb ) =>
log.print 'DB', "getModule('#{ @setname }): #{ mId }'"
@db.get "#{ @setname }:#{ mId }", cb
getModuleIds: ( cb ) =>
log.print 'DB', "getModuleIds(#{ @setname })"
@db.smembers "#{ @setname }s", cb
getModules: ( cb ) =>
log.print 'DB', "getModules(#{ @setname })"
getSetRecords "#{ @setname }s", @getModule, cb
deleteModule: ( mId ) =>
log.print 'DB', "deleteModule(#{ @setname }): #{ mId }"
@db.srem "#{ @setname }s", mId,
replyHandler "Deleting '#{ @setname }' key '#{ mId }'"
@db.del "#{ @setname }:#{ mId }",
replyHandler "Deleting '#{ @setname }:#{ mId }'"
storeParameters: ( mId, userId, data ) =>
log.print 'DB', "storeParameters(#{ @setname }): '#{ mId }:#{ userId }'"
@db.sadd "#{ @setname }-params", "#{ mId }:#{ userId }",
replyHandler "Storing '#{ @setname }' module parameters key '#{ mId }'"
@db.set "#{ @setname }-params:#{ mId }:#{ userId }", encrypt(data),
replyHandler "Storing '#{ @setname }' module parameters '#{ mId }:#{ userId }'"
getParameters: ( mId, userId, cb ) =>
log.print 'DB', "getParameters(#{ @setname }): '#{ mId }:#{ userId }'"
@db.get "#{ @setname }-params:#{ mId }:#{ userId }", ( err, data ) ->
cb err, decrypt data
getParametersIds: ( cb ) =>
log.print 'DB', "getParametersIds(#{ @setname })"
@db.smembers "#{ @setname }-params", cb
deleteParameters: ( mId, userId ) =>
log.print 'DB', "deleteParameters(#{ @setname }): '#{ mId }:#{ userId }'"
@db.srem "#{ @setname }-params", "#{ mId }:#{ userId }",
replyHandler "Deleting '#{ @setname }-params' key '#{ mId }:#{ userId }'"
@db.del "#{ @setname }-params:#{ mId }:#{ userId }",
replyHandler "Deleting '#{ @setname }-params:#{ mId }:#{ userId }'"
###
## Action Modules
#TODO Rename Action Modules into something like Action Caller
## Action Invokers
###
###
Store a string representation of an action module in the DB.
Store a string representation of an action invoker in the DB.
@public storeActionModule ( *amId, data* )
@param {String} amId
@public storeActionInvoker ( *aiId, data* )
@param {String} aiId
@param {String} data
###
exports.storeActionModule = ( amId, data ) =>
log.print 'DB', "storeActionModule: #{ amId }"
@db.sadd 'action-modules', amId, replyHandler "storing action module key #{ amId }"
@db.set "action-module:#{ amId }", data, replyHandler "storing action module #{ amId }"
exports.storeActionInvoker = ( aiId, data ) =>
@ai.storeModule( aiId, data )
###
Query the DB for an action module and pass it to the callback(err, obj) function.
Query the DB for an action invoker and pass it to cb(err, obj).
@public getActionModule( *amId, cb* )
@param {String} amId
@public getActionInvoker( *aiId, cb* )
@param {String} aiId
@param {function} cb
###
exports.getActionModule = ( amId, cb ) =>
log.print 'DB', "getActionModule: #{ amId }"
@db.get "action-module:#{ amId }", cb
exports.getSetMembers = ( setId, cb ) =>
@db.smembers setId, cb
exports.getActionInvoker = ( aiId, cb ) =>
@ai.getModule aiId, cb
###
Fetch all action module IDs and hand them to the callback(err, obj) function.
Fetch all action invoker IDs and hand them to cb(err, obj).
@public getActionModuleIds( *cb* )
@public getActionInvokerIds( *cb* )
@param {function} cb
###
exports.getActionModuleIds = ( cb ) =>
@db.smembers 'action-modules', cb
exports.getActionInvokerIds = ( cb ) =>
@ai.getModuleIds cb
###
Fetch all action modules and hand them to the callback(err, obj) function.
Fetch all action invokers and hand them to cb(err, obj).
@public getActionModules( *cb* )
@public getActionInvokers( *cb* )
@param {function} cb
###
exports.getActionModules = ( cb ) ->
getSetRecords 'action-modules', exports.getActionModule, cb
exports.getActionInvokers = ( cb ) =>
@ai.getModules cb
###
Fetch all action modules and hand them to the callback(err, obj) function.
Fetch all action invokers and hand them to cb(err, obj).
@public getActionModules( *cb* )
@public getActionInvokers( *cb* )
@param {function} cb
###
exports.deleteActionModule = ( amId ) =>
@db.srem 'action-modules', amId, replyHandler "deleting action module key #{ amId }"
@db.del "action-module:#{ amId }", replyHandler "deleting action module #{ amId }"
exports.deleteActionInvoker = ( aiId ) =>
@ai.deleteModule aiId
###
Store user-specific action module parameters .
Store user-specific action invoker parameters .
@public storeActionParams( *userId, amId, data* )
@public storeActionParams( *userId, aiId, data* )
@param {String} userId
@param {String} amId
@param {String} aiId
@param {String} data
###
exports.storeActionParams = ( userId, amId, data ) =>
log.print 'DB', "storeActionParams: #{ amId }:#{ userId }"
@db.set "action-params:#{ amId }:#{ userId }", hash(data),
replyHandler "storing action params #{ amId }:#{ userId }"
exports.storeActionParams = ( aiId, userId, data ) =>
@ai.storeParameters aiId, userId, data
###
Query the DB for user-specific action module parameters,
and pass it to the callback(err, obj) function.
and pass it to cb(err, obj).
@public getActionParams( *userId, amId, cb* )
@public getActionParams( *userId, aiId, cb* )
@param {String} userId
@param {String} amId
@param {String} aiId
@param {function} cb
###
exports.getActionParams = ( userId, amId, cb ) =>
log.print 'DB', "getActionParams: #{ amId }:#{ userId }"
@db.get "action-params:#{ amId }:#{ userId }", ( err, data ) ->
cb err, decrypt data
exports.getActionParams = ( aiId, userId, cb ) =>
@ai.getParameters aiId, userId, cb
###
Fetch all action params IDs and hand them to cb(err, obj).
@public getActionParamsIds( *cb* )
@param {function} cb
###
exports.getActionParamsIds = ( cb ) =>
@ai.getParametersIds cb
###
Fetch all action modules and hand them to cb(err, obj).
@public deleteActionParams( *cb* )
@param {function} cb
###
exports.deleteActionParams = ( aiId, userId ) =>
@ai.deleteParameters aiId, userId
###
## Event Modules
#TODO rename event modules to event puller or something like that
## Event Pollers
###
###
Store a string representation of an event module in the DB.
Store a string representation of an event poller in the DB.
@public storeEventModule( *emId, data* )
@param {String} emId
@public storeEventPoller ( *epId, data* )
@param {String} epId
@param {String} data
###
exports.storeEventModule = ( emId, data ) =>
log.print 'DB', "storeEventModule: #{ emId }"
@db.sadd 'event-modules', emId, replyHandler "storing event module key #{ emId }"
@db.set 'event-module:#{ emId }', data, replyHandler "storing event module #{ emId }"
exports.storeEventPoller = ( epId, data ) =>
@ep.storeModule( epId, data )
###
Query the DB for an event module and pass it to the callback(err, obj) function.
Query the DB for an event poller and pass it to cb(err, obj).
@public getEventModule( *emId, cb* )
@param {String} emId
@public getEventPoller( *epId, cb* )
@param {String} epId
@param {function} cb
###
exports.getEventModule = ( emId, cb ) =>
log.print 'DB', "getEventModule: #{ emId }"
@db.get "event-module:#{ emId }", cb
exports.getEventPoller = ( epId, cb ) =>
@ep.getModule epId, cb
###
Fetch all event modules and pass them to the callback(err, obj) function.
Fetch all event poller IDs and hand them to cb(err, obj).
@public getEventModules( *cb* )
@public getEventPollerIds( *cb* )
@param {function} cb
###
exports.getEventModules = ( cb ) ->
getSetRecords 'event-modules', exports.getEventModule, cb
exports.getEventPollerIds = ( cb ) =>
@ep.getModuleIds cb
###
Store a string representation of user-specific parameters for an event module.
Fetch all event pollers and hand them to cb(err, obj).
@public storeEventParams( *userId, emId, data* )
@public getEventPollers( *cb* )
@param {function} cb
###
exports.getEventPollers = ( cb ) =>
@ep.getModules cb
###
Fetch all event pollers and hand them to cb(err, obj).
@public getEventPollers( *cb* )
@param {function} cb
###
exports.deleteEventPoller = ( epId ) =>
@ep.deleteModule epId
###
Store user-specific event poller parameters .
@public storeEventParams( *userId, epId, data* )
@param {String} userId
@param {String} emId
@param {Object} data
@param {String} epId
@param {String} data
###
# TODO is used, remove unused ones
exports.storeEventParams = ( userId, emId, data ) =>
log.print 'DB', "storeEventParams: #{ emId }:#{ userId }"
# TODO encryption based on user specific key?
@db.set "event-params:#{ emId }:#{ userId }", encrypt(data),
replyHandler "storing event auth #{ emId }:#{ userId }"
###
Query the DB for an action module authentication token, associated with a user.
exports.storeEventParams = ( epId, userId, data ) =>
@ep.storeParameters epId, userId, data
@public getEventAuth( *userId, emId, data* )
###
Query the DB for user-specific event module parameters,
and pass it to cb(err, obj).
@public getEventParams( *userId, epId, cb* )
@param {String} userId
@param {String} emId
@param {String} epId
@param {function} cb
###
exports.getEventAuth = ( userId, emId, cb ) =>
log.print 'DB', "getEventAuth: #{ emId }:#{ userId }"
@db.get "event-auth:#{ emId }:#{ userId }", ( err, data ) ->
cb err, decrypt data
exports.getEventParams = ( epId, userId, cb ) =>
@ep.getParameters epId, userId, cb
###
Fetch all event params IDs and hand them to cb(err, obj).
@public getEventParamsIds( *cb* )
@param {function} cb
###
exports.getEventParamsIds = ( cb ) =>
@ep.getParametersIds cb
###
Fetch all event modules and hand them to cb(err, obj).
@public deleteEventParams( *cb* )
@param {function} cb
###
exports.deleteEventParams = ( epId, userId ) =>
@ep.deleteParameters epId, userId
###
@ -368,33 +474,18 @@ exports.getEventAuth = ( userId, emId, cb ) =>
###
###
Store a string representation of a rule in the DB.
@public storeRule( *ruleId, userId, data* )
@param {String} ruleId
@param {String} userId
@param {String} data
###
exports.storeRule = ( ruleId, userId, data ) =>
log.print 'DB', "storeRule: #{ ruleId }"
@db.sadd 'rules', "#{ ruleId }:#{ userId }", replyHandler "storing rule key \"#{ ruleId }:#{ userId }\""
@db.sadd "user-set:#{ userId }:rules", ruleId, replyHandler "storing rule key to \"user:#{ userId }:rules\""
@db.sadd "rule-set:#{ ruleId }:users", user, replyHandler "storing user key to \"rule:#{ ruleId }:users\""
@db.set "rule:#{ ruleId }:#{ userId }", data, replyHandler "storing rule \"#{ ruleId }:#{ userId }\""
###
Query the DB for a rule and pass it to the callback(err, obj) function.
Query the DB for a rule and pass it to cb(err, obj).
@public getRule( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
###
exports.getRule = ( ruleId, cb ) =>
log.print 'DB', "getRule: #{ ruleId }"
log.print 'DB', "getRule: '#{ ruleId }'"
@db.get "rule:#{ ruleId }", cb
###
Fetch all rules from the database and pass them to the callback function.
Fetch all rules and pass them to cb(err, obj).
@public getRules( *cb* )
@param {function} cb
@ -403,6 +494,203 @@ exports.getRules = ( cb ) ->
log.print 'DB', 'Fetching all Rules'
getSetRecords 'rules', exports.getRule, cb
###
Fetch all rule IDs and hand it to cb(err, obj).
@public getRuleIds( *cb* )
@param {function} cb
###
exports.getRuleIds = ( cb ) =>
log.print 'DB', 'Fetching all Rule IDs'
@db.smembers 'rules', cb
###
Store a string representation of a rule in the DB.
@public storeRule( *ruleId, data* )
@param {String} ruleId
@param {String} data
###
exports.storeRule = ( ruleId, data ) =>
log.print 'DB', "storeRule: '#{ ruleId }'"
@db.sadd 'rules', "#{ ruleId }",
replyHandler "storing rule key '#{ ruleId }'"
@db.set "rule:#{ ruleId }", data,
replyHandler "storing rule '#{ ruleId }'"
###
Delete a string representation of a rule.
@public deleteRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
###
exports.deleteRule = ( ruleId ) =>
log.print 'DB', "deleteRule: '#{ ruleId }'"
@db.srem "rules", ruleId, replyHandler "Deleting rule key '#{ ruleId }'"
@db.del "rule:#{ ruleId }", replyHandler "Deleting rule '#{ ruleId }'"
# We also need to delete all references in linked and active users
@db.smembers "rule:#{ ruleId }:users", ( err, obj ) =>
delLinkedUserRule = ( userId ) =>
@db.srem "user:#{ userId }:rules", ruleId,
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"
@db.smembers "rule:#{ ruleId }:active-users", ( err, obj ) =>
delActiveUserRule = ( userId ) =>
@db.srem "user:#{ userId }:active-rules", ruleId,
replyHandler "Deleting rule key '#{ ruleId }' in active user '#{ userId }'"
delActiveUserRule( id ) for id in obj
@db.del "rule:#{ ruleId }:active-users",
replyHandler "Deleting rule '#{ ruleId }' active users"
###
Associate a rule to a user.
@public linkRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
###
exports.linkRule = ( ruleId, userId ) =>
log.print 'DB', "linkRule: '#{ ruleId }' for user '#{ userId }'"
@db.sadd "rule:#{ ruleId }:users", userId,
replyHandler "storing user '#{ userId }' for rule key '#{ ruleId }'"
@db.sadd "user:#{ userId }:rules", ruleId,
replyHandler "storing rule key '#{ ruleId }' for user '#{ userId }'"
###
Get rules linked to a user and hand it to cb(err, obj).
@public getUserLinkRule( *userId, cb* )
@param {String} userId
@param {function} cb
###
exports.getUserLinkedRules = ( userId, cb ) =>
log.print 'DB', "getUserLinkedRules: for user '#{ userId }'"
@db.smembers "user:#{ userId }:rules", cb
###
Get users linked to a rule and hand it to cb(err, obj).
@public getRuleLinkedUsers( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
###
exports.getRuleLinkedUsers = ( ruleId, cb ) =>
log.print 'DB', "getRuleLinkedUsers: for rule '#{ ruleId }'"
@db.smembers "rule:#{ ruleId }:users", cb
###
Delete an association of a rule to a user.
@public unlinkRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
###
exports.unlinkRule = ( ruleId, userId ) =>
log.print 'DB', "unlinkRule: '#{ ruleId }:#{ userId }'"
@db.srem "rule:#{ ruleId }:users", userId,
replyHandler "removing user '#{ userId }' for rule key '#{ ruleId }'"
@db.srem "user:#{ userId }:rules", ruleId,
replyHandler "removing rule key '#{ ruleId }' for user '#{ userId }'"
###
Activate a rule.
@public activateRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
###
exports.activateRule = ( ruleId, userId ) =>
log.print 'DB', "activateRule: '#{ ruleId }' for '#{ userId }'"
@db.sadd "rule:#{ ruleId }:active-users", userId,
replyHandler "storing activated user '#{ userId }' in rule '#{ ruleId }'"
@db.sadd "user:#{ userId }:active-rules", ruleId,
replyHandler "storing activated rule '#{ ruleId }' in user '#{ userId }'"
###
Get rules activated for a user and hand it to cb(err, obj).
@public getUserLinkRule( *userId, cb* )
@param {String} userId
@param {function} cb
###
exports.getUserActivatedRules = ( userId, cb ) =>
log.print 'DB', "getUserActivatedRules: for user '#{ userId }'"
@db.smembers "user:#{ userId }:active-rules", cb
###
Get users activated for a rule and hand it to cb(err, obj).
@public getRuleActivatedUsers ( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
###
exports.getRuleActivatedUsers = ( ruleId, cb ) =>
log.print 'DB', "getRuleLinkedUsers: for rule '#{ ruleId }'"
@db.smembers "rule:#{ ruleId }:active-users", cb
###
Deactivate a rule.
@public deactivateRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
###
exports.deactivateRule = ( ruleId, userId ) =>
log.print 'DB', "deactivateRule: '#{ ruleId }' for '#{ userId }'"
@db.srem "rule:#{ ruleId }:active-users", userId,
replyHandler "removing activated user '#{ userId }' in rule '#{ ruleId }'"
@db.srem "user:#{ userId }:active-rules", ruleId,
replyHandler "removing activated rule '#{ ruleId }' in user '#{ userId }'"
###
Fetch all active ruleIds and pass them to cb(err, obj).
@public getAllActivatedRuleIds( *cb* )
@param {function} cb
###
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
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
###
Store a user object (needs to be a flat structure).
@ -412,11 +700,13 @@ Store a user object (needs to be a flat structure).
exports.storeUser = ( objUser ) =>
#TODO Only store user if not already existing, or at least only then add a private key
#for his encryption. we would want to have one private key per user, right?
log.print 'DB', "storeUser: #{ objUser.username }"
log.print 'DB', "storeUser: '#{ objUser.username }'"
if objUser and objUser.username and objUser.password
@db.sadd 'users', objUser.username, replyHandler "storing user key #{ objUser.username }"
@db.sadd 'users', objUser.username,
replyHandler "storing user key '#{ objUser.username }'"
objUser.password = hash objUser.password
@db.hmset "user:#{ objUser.username }", objUser, replyHandler "storing user properties #{ objUser.username }"
@db.hmset "user:#{ objUser.username }", objUser,
replyHandler "storing user properties '#{ objUser.username }'"
else
log.error 'DB', new Error 'username or password was missing'
@ -428,29 +718,31 @@ Associate a role with a user.
@param {String} role
###
exports.storeUserRole = ( userId, role ) =>
log.print 'DB', "storeUserRole: #{ userId }:#{ role }"
@db.sadd 'roles', role, replyHandler "adding role #{ role } to role index set"
@db.sadd "user:#{ userId }:roles", role, replyHandler "adding role #{ role } to user #{ userId }"
@db.sadd "role:#{ role }:users", userId, replyHandler "adding user #{ userId } to role #{ role }"
log.print 'DB', "storeUserRole: '#{ userId }:#{ role }'"
@db.sadd 'roles', role, replyHandler "adding role '#{ role }' to role index set"
@db.sadd "user:#{ userId }:roles", role,
replyHandler "adding role '#{ role }' to user '#{ userId }'"
@db.sadd "role:#{ role }:users", userId,
replyHandler "adding user '#{ userId }' to role '#{ role }'"
###
Fetch all roles of a user and pass them to the callback(err, obj)
Fetch all roles of a user and pass them to cb(err, obj).
@public getUserRoles( *userId* )
@param {String} userId
###
exports.getUserRoles = ( userId ) =>
log.print 'DB', "getUserRole: #{ userId }"
log.print 'DB', "getUserRole: '#{ userId }'"
@db.get "user-roles:#{ userId }", cb
###
Fetch all users of a role and pass them to the callback(err, obj)
Fetch all users of a role and pass them to cb(err, obj).
@public getUserRoles( *role* )
@param {String} role
###
exports.getRoleUsers = ( role ) =>
log.print 'DB', "getRoleUsers: #{ role }"
log.print 'DB', "getRoleUsers: '#{ role }'"
@db.get "role-users:#{ role }", cb
###
@ -466,14 +758,14 @@ because we only store hashes of passwords for safety reasons.
###
#TODO verify and test whole function
exports.loginUser = ( userId, password, cb ) =>
log.print 'DB', "User \"#{ userId }\" tries to log in"
log.print 'DB', "User '#{ userId }' tries to log in"
fCheck = ( pw ) ->
( err, obj ) ->
if err
cb err
else if obj and obj.password
if pw == obj.password
log.print 'DB', "User \"#{ obj.username }\" logged in!"
log.print 'DB', "User '#{ obj.username }' logged in!"
cb null, obj
else
cb new Error 'Wrong credentials!'
@ -481,7 +773,36 @@ exports.loginUser = ( userId, password, cb ) =>
cb new Error 'User not found!'
@db.hgetall "user:#{ userId }", fCheck password
#TODO implement functions required for user sessions and the rule activation
###
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?
###
Shuts down the db link.

View file

@ -160,6 +160,16 @@ Resolves the path to a handler webpage and returns it as a string.
getHandlerFileAsString = ( name ) ->
fs.readFileSync getHandlerPath( name ), 'utf8'
###
Fetches an include file.
@private getIncludeFileAsString( *name* )
@param {String} name
###
getIncludeFileAsString = ( name ) ->
pth = path.resolve __dirname, '..', 'webpages', 'handlers', 'includes', name + '.html'
fs.readFileSync pth, 'utf8'
###
Renders a page depending on the user session and returns it.
@ -169,8 +179,8 @@ Renders a page depending on the user session and returns it.
###
renderPage = ( name, sess, msg ) ->
template = getHandlerFileAsString name
menubar = getHandlerFileAsString 'part_menubar'
requires = getHandlerFileAsString 'part_requires'
menubar = getIncludeFileAsString 'menubar'
requires = getIncludeFileAsString 'requires'
view =
user: sess.user,
head_requires: requires,
@ -190,10 +200,14 @@ objects.*
@param {String} pagename
###
sendLoginOrPage = ( pagename, req, resp ) ->
if req.session and req.session.user
resp.send renderPage pagename, req.session
else
resp.sendfile getHandlerPath 'login'
if !req.session
req.session = {}
if !req.session.user
pagename = 'login'
# resp.send renderPage pagename, req.session
# else
# resp.sendfile getHandlerPath 'login'
resp.send renderPage pagename, req.session
###
Present the module forge to the user.

View file

@ -4,25 +4,26 @@
DB Interface
============
> Handles the connection to the database and provides functionalities for
> event/action modules, rules and the encrypted storing of authentication tokens.
> event pollers, action invokers, rules and the encrypted storing of authentication tokens.
> General functionality as a wrapper for the module holds initialization,
> encryption/decryption, the retrieval of modules and shut down.
>
> The general structure for linked data is that the key is stored in a set.
> By fetching all set entries we can then fetch all elements, which is
> automated in this function.
> For example modules of the same group, e.g. action modules are registered in an
> For example, modules of the same group, e.g. action invokers are registered in an
> unordered set in the database, from where they can be retrieved again. For example
> a new action module has its ID (e.g 'probinder') first registered in the set
> 'action_modules' and then stored in the db with the key 'action\_module\_' + ID
> (e.g. action\_module\_probinder).
> a new action invoker has its ID (e.g 'probinder') first registered in the set
> 'action-invokers' and then stored in the db with the key 'action-invoker:' + ID
> (e.g. action-invoker:probinder).
>
*/
(function() {
var crypto, decrypt, encrypt, exports, getSetRecords, hash, log, redis, replyHandler,
_this = this;
var IndexedModules, crypto, decrypt, encrypt, exports, getSetRecords, hash, log, redis, replyHandler,
_this = this,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
log = require('./logging');
@ -54,10 +55,12 @@ DB Interface
_this.db = redis.createClient(config.getDBPort(), 'localhost', {
connect_timeout: 2000
});
return _this.db.on('error', function(err) {
_this.db.on('error', function(err) {
err.addInfo = 'message from DB';
return log.error('DB', err);
});
_this.ep = new IndexedModules('event-poller', _this.db);
return _this.ai = new IndexedModules('action-invoker', _this.db);
} else {
return log.error('DB', 'Initialization failed because of missing config file!');
}
@ -103,7 +106,7 @@ DB Interface
replyHandler = function(action) {
return function(err, reply) {
if (err) {
err.addInfo = "during \"" + action + "\"";
err.addInfo = "during '" + action + "'";
return log.error('DB', err);
} else {
return log.print('DB', "" + action + ": " + reply);
@ -121,7 +124,7 @@ DB Interface
exports.pushEvent = function(oEvent) {
if (oEvent) {
log.print('DB', "Event pushed into the queue: " + oEvent.eventid);
log.print('DB', "Event pushed into the queue: '" + oEvent.eventid + "'");
return _this.db.rpush('event_queue', JSON.stringify(oEvent));
} else {
return log.error('DB', 'Why would you give me an empty event...');
@ -129,7 +132,7 @@ DB Interface
};
/*
Pop an event from the event queue and pass it to the callback(err, obj) function.
Pop an event from the event queue and pass it to cb(err, obj).
@public popEvent( *cb* )
@param {function} cb
@ -191,14 +194,12 @@ DB Interface
encrypt = function(plainText) {
var enciph, err, et;
var err;
if (plainText == null) {
return null;
}
try {
enciph = crypto.createCipher('aes-256-cbc', _this.crypto_key);
et = enciph.update(plainText, 'utf8', 'base64');
return et + enciph.final('base64');
return crypto.AES.encrypt(plainText, _this.crypto_key);
} catch (_error) {
err = _error;
err.addInfo = 'during encryption';
@ -216,14 +217,13 @@ DB Interface
decrypt = function(crypticText) {
var deciph, dt, err;
var dec, err;
if (crypticText == null) {
return null;
}
try {
deciph = crypto.createDecipher('aes-256-cbc', _this.crypto_key);
dt = deciph.update(crypticText, 'base64', 'utf8');
return dt + deciph.final('utf8');
dec = crypto.AES.decrypt(crypticText, _this.crypto_key);
return dec.toString(crypto.enc.Utf8);
} catch (_error) {
err = _error;
err.addInfo = 'during decryption';
@ -233,23 +233,26 @@ DB Interface
};
/*
Fetches all linked data set keys from a linking set, fetches the single data objects
via the provided function and returns the results to the callback(err, obj) function.
Fetches all linked data set keys from a linking set, fetches the single
data objects via the provided function and returns the results to cb(err, obj).
@private getSetRecords( *set, fSingle, cb* )
@param {String} set the set name how it is stored in the DB
@param {function} fSingle a function to retrieve a single data element per set entry
@param {function} cb the callback(err, obj) function that receives all the retrieved data or an error
@param {function} fSingle a function to retrieve a single data element
per set entry
@param {function} cb the callback(err, obj) function that receives all
the retrieved data or an error
*/
getSetRecords = function(set, fSingle, cb) {
log.print('DB', "Fetching set records: " + set);
log.print('DB', "Fetching set records: '" + set + "'");
return _this.db.smembers(set, function(err, arrReply) {
var fCallback, objReplies, reply, semaphore, _i, _len, _results;
if (err) {
err.addInfo = "fetching " + set;
return log.error('DB', err);
err.addInfo = "fetching '" + set + "'";
log.error('DB', err);
return cb(err);
} else if (arrReply.length === 0) {
return cb();
} else {
@ -257,17 +260,17 @@ DB Interface
objReplies = {};
setTimeout(function() {
if (semaphore > 0) {
return cb(new Error("Timeout fetching " + set));
return cb(new Error("Timeout fetching '" + set + "'"));
}
}, 2000);
fCallback = function(prop) {
return function(err, data) {
--semaphore;
if (err) {
err.addInfo = "fetching single element: " + prop;
err.addInfo = "fetching single element: '" + prop + "'";
log.error('DB', err);
} else if (!data) {
log.error('DB', new Error("Empty key in DB: " + prop));
log.error('DB', new Error("Empty key in DB: '" + prop + "'"));
} else {
objReplies[prop] = data;
}
@ -286,192 +289,315 @@ DB Interface
});
};
IndexedModules = (function() {
function IndexedModules(setname, db) {
this.setname = setname;
this.db = db;
this.deleteParameters = __bind(this.deleteParameters, this);
this.getParametersIds = __bind(this.getParametersIds, this);
this.getParameters = __bind(this.getParameters, this);
this.storeParameters = __bind(this.storeParameters, this);
this.deleteModule = __bind(this.deleteModule, this);
this.getModules = __bind(this.getModules, this);
this.getModuleIds = __bind(this.getModuleIds, this);
this.getModule = __bind(this.getModule, this);
this.storeModule = __bind(this.storeModule, this);
log.print('DB', "Instantiated indexed modules for '" + this.setname + "'");
}
IndexedModules.prototype.storeModule = function(mId, data) {
log.print('DB', "storeModule(" + this.setname + "): " + mId);
this.db.sadd("" + this.setname + "s", mId, replyHandler("Storing '" + this.setname + "' key '" + mId + "'"));
return this.db.set("" + this.setname + ":" + mId, data, replyHandler("Storing '" + this.setname + ":" + mId + "'"));
};
IndexedModules.prototype.getModule = function(mId, cb) {
log.print('DB', "getModule('" + this.setname + "): " + mId + "'");
return this.db.get("" + this.setname + ":" + mId, cb);
};
IndexedModules.prototype.getModuleIds = function(cb) {
log.print('DB', "getModuleIds(" + this.setname + ")");
return this.db.smembers("" + this.setname + "s", cb);
};
IndexedModules.prototype.getModules = function(cb) {
log.print('DB', "getModules(" + this.setname + ")");
return getSetRecords("" + this.setname + "s", this.getModule, cb);
};
IndexedModules.prototype.deleteModule = function(mId) {
log.print('DB', "deleteModule(" + this.setname + "): " + mId);
this.db.srem("" + this.setname + "s", mId, replyHandler("Deleting '" + this.setname + "' key '" + mId + "'"));
return this.db.del("" + this.setname + ":" + mId, replyHandler("Deleting '" + this.setname + ":" + mId + "'"));
};
IndexedModules.prototype.storeParameters = function(mId, userId, data) {
log.print('DB', "storeParameters(" + this.setname + "): '" + mId + ":" + userId + "'");
this.db.sadd("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("Storing '" + this.setname + "' module parameters key '" + mId + "'"));
return this.db.set("" + this.setname + "-params:" + mId + ":" + userId, encrypt(data), replyHandler("Storing '" + this.setname + "' module parameters '" + mId + ":" + userId + "'"));
};
IndexedModules.prototype.getParameters = function(mId, userId, cb) {
log.print('DB', "getParameters(" + this.setname + "): '" + mId + ":" + userId + "'");
return this.db.get("" + this.setname + "-params:" + mId + ":" + userId, function(err, data) {
return cb(err, decrypt(data));
});
};
IndexedModules.prototype.getParametersIds = function(cb) {
log.print('DB', "getParametersIds(" + this.setname + ")");
return this.db.smembers("" + this.setname + "-params", cb);
};
IndexedModules.prototype.deleteParameters = function(mId, userId) {
log.print('DB', "deleteParameters(" + this.setname + "): '" + mId + ":" + userId + "'");
this.db.srem("" + this.setname + "-params", "" + mId + ":" + userId, replyHandler("Deleting '" + this.setname + "-params' key '" + mId + ":" + userId + "'"));
return this.db.del("" + this.setname + "-params:" + mId + ":" + userId, replyHandler("Deleting '" + this.setname + "-params:" + mId + ":" + userId + "'"));
};
return IndexedModules;
})();
/*
## Action Modules
#TODO Rename Action Modules into something like Action Caller
## Action Invokers
*/
/*
Store a string representation of an action module in the DB.
Store a string representation of an action invoker in the DB.
@public storeActionModule ( *amId, data* )
@param {String} amId
@public storeActionInvoker ( *aiId, data* )
@param {String} aiId
@param {String} data
*/
exports.storeActionModule = function(amId, data) {
log.print('DB', "storeActionModule: " + amId);
_this.db.sadd('action-modules', amId, replyHandler("storing action module key " + amId));
return _this.db.set("action-module:" + amId, data, replyHandler("storing action module " + amId));
exports.storeActionInvoker = function(aiId, data) {
return _this.ai.storeModule(aiId, data);
};
/*
Query the DB for an action module and pass it to the callback(err, obj) function.
Query the DB for an action invoker and pass it to cb(err, obj).
@public getActionModule( *amId, cb* )
@param {String} amId
@public getActionInvoker( *aiId, cb* )
@param {String} aiId
@param {function} cb
*/
exports.getActionModule = function(amId, cb) {
log.print('DB', "getActionModule: " + amId);
return _this.db.get("action-module:" + amId, cb);
};
exports.getSetMembers = function(setId, cb) {
return _this.db.smembers(setId, cb);
exports.getActionInvoker = function(aiId, cb) {
return _this.ai.getModule(aiId, cb);
};
/*
Fetch all action module IDs and hand them to the callback(err, obj) function.
Fetch all action invoker IDs and hand them to cb(err, obj).
@public getActionModuleIds( *cb* )
@public getActionInvokerIds( *cb* )
@param {function} cb
*/
exports.getActionModuleIds = function(cb) {
return _this.db.smembers('action-modules', cb);
exports.getActionInvokerIds = function(cb) {
return _this.ai.getModuleIds(cb);
};
/*
Fetch all action modules and hand them to the callback(err, obj) function.
Fetch all action invokers and hand them to cb(err, obj).
@public getActionModules( *cb* )
@public getActionInvokers( *cb* )
@param {function} cb
*/
exports.getActionModules = function(cb) {
return getSetRecords('action-modules', exports.getActionModule, cb);
exports.getActionInvokers = function(cb) {
return _this.ai.getModules(cb);
};
/*
Fetch all action modules and hand them to the callback(err, obj) function.
Fetch all action invokers and hand them to cb(err, obj).
@public getActionModules( *cb* )
@public getActionInvokers( *cb* )
@param {function} cb
*/
exports.deleteActionModule = function(amId) {
_this.db.srem('action-modules', amId, replyHandler("deleting action module key " + amId));
return _this.db.del("action-module:" + amId, replyHandler("deleting action module " + amId));
exports.deleteActionInvoker = function(aiId) {
return _this.ai.deleteModule(aiId);
};
/*
Store user-specific action module parameters .
Store user-specific action invoker parameters .
@public storeActionParams( *userId, amId, data* )
@public storeActionParams( *userId, aiId, data* )
@param {String} userId
@param {String} amId
@param {String} aiId
@param {String} data
*/
exports.storeActionParams = function(userId, amId, data) {
log.print('DB', "storeActionParams: " + amId + ":" + userId);
return _this.db.set("action-params:" + amId + ":" + userId, hash(data), replyHandler("storing action params " + amId + ":" + userId));
exports.storeActionParams = function(aiId, userId, data) {
return _this.ai.storeParameters(aiId, userId, data);
};
/*
Query the DB for user-specific action module parameters,
and pass it to the callback(err, obj) function.
and pass it to cb(err, obj).
@public getActionParams( *userId, amId, cb* )
@public getActionParams( *userId, aiId, cb* )
@param {String} userId
@param {String} amId
@param {String} aiId
@param {function} cb
*/
exports.getActionParams = function(userId, amId, cb) {
log.print('DB', "getActionParams: " + amId + ":" + userId);
return _this.db.get("action-params:" + amId + ":" + userId, function(err, data) {
return cb(err, decrypt(data));
});
exports.getActionParams = function(aiId, userId, cb) {
return _this.ai.getParameters(aiId, userId, cb);
};
/*
## Event Modules
#TODO rename event modules to event puller or something like that
Fetch all action params IDs and hand them to cb(err, obj).
@public getActionParamsIds( *cb* )
@param {function} cb
*/
exports.getActionParamsIds = function(cb) {
return _this.ai.getParametersIds(cb);
};
/*
Fetch all action modules and hand them to cb(err, obj).
@public deleteActionParams( *cb* )
@param {function} cb
*/
exports.deleteActionParams = function(aiId, userId) {
return _this.ai.deleteParameters(aiId, userId);
};
/*
## Event Pollers
*/
/*
Store a string representation of an event module in the DB.
Store a string representation of an event poller in the DB.
@public storeEventModule( *emId, data* )
@param {String} emId
@public storeEventPoller ( *epId, data* )
@param {String} epId
@param {String} data
*/
exports.storeEventModule = function(emId, data) {
log.print('DB', "storeEventModule: " + emId);
_this.db.sadd('event-modules', emId, replyHandler("storing event module key " + emId));
return _this.db.set('event-module:#{ emId }', data, replyHandler("storing event module " + emId));
exports.storeEventPoller = function(epId, data) {
return _this.ep.storeModule(epId, data);
};
/*
Query the DB for an event module and pass it to the callback(err, obj) function.
Query the DB for an event poller and pass it to cb(err, obj).
@public getEventModule( *emId, cb* )
@param {String} emId
@public getEventPoller( *epId, cb* )
@param {String} epId
@param {function} cb
*/
exports.getEventModule = function(emId, cb) {
log.print('DB', "getEventModule: " + emId);
return _this.db.get("event-module:" + emId, cb);
exports.getEventPoller = function(epId, cb) {
return _this.ep.getModule(epId, cb);
};
/*
Fetch all event modules and pass them to the callback(err, obj) function.
Fetch all event poller IDs and hand them to cb(err, obj).
@public getEventModules( *cb* )
@public getEventPollerIds( *cb* )
@param {function} cb
*/
exports.getEventModules = function(cb) {
return getSetRecords('event-modules', exports.getEventModule, cb);
exports.getEventPollerIds = function(cb) {
return _this.ep.getModuleIds(cb);
};
/*
Store a string representation of user-specific parameters for an event module.
Fetch all event pollers and hand them to cb(err, obj).
@public storeEventParams( *userId, emId, data* )
@public getEventPollers( *cb* )
@param {function} cb
*/
exports.getEventPollers = function(cb) {
return _this.ep.getModules(cb);
};
/*
Fetch all event pollers and hand them to cb(err, obj).
@public getEventPollers( *cb* )
@param {function} cb
*/
exports.deleteEventPoller = function(epId) {
return _this.ep.deleteModule(epId);
};
/*
Store user-specific event poller parameters .
@public storeEventParams( *userId, epId, data* )
@param {String} userId
@param {String} emId
@param {Object} data
@param {String} epId
@param {String} data
*/
exports.storeEventParams = function(userId, emId, data) {
log.print('DB', "storeEventParams: " + emId + ":" + userId);
return _this.db.set("event-params:" + emId + ":" + userId, encrypt(data), replyHandler("storing event auth " + emId + ":" + userId));
exports.storeEventParams = function(epId, userId, data) {
return _this.ep.storeParameters(epId, userId, data);
};
/*
Query the DB for an action module authentication token, associated with a user.
Query the DB for user-specific event module parameters,
and pass it to cb(err, obj).
@public getEventAuth( *userId, emId, data* )
@public getEventParams( *userId, epId, cb* )
@param {String} userId
@param {String} emId
@param {String} epId
@param {function} cb
*/
exports.getEventAuth = function(userId, emId, cb) {
log.print('DB', "getEventAuth: " + emId + ":" + userId);
return _this.db.get("event-auth:" + emId + ":" + userId, function(err, data) {
return cb(err, decrypt(data));
});
exports.getEventParams = function(epId, userId, cb) {
return _this.ep.getParameters(epId, userId, cb);
};
/*
Fetch all event params IDs and hand them to cb(err, obj).
@public getEventParamsIds( *cb* )
@param {function} cb
*/
exports.getEventParamsIds = function(cb) {
return _this.ep.getParametersIds(cb);
};
/*
Fetch all event modules and hand them to cb(err, obj).
@public deleteEventParams( *cb* )
@param {function} cb
*/
exports.deleteEventParams = function(epId, userId) {
return _this.ep.deleteParameters(epId, userId);
};
/*
@ -480,25 +606,7 @@ DB Interface
/*
Store a string representation of a rule in the DB.
@public storeRule( *ruleId, userId, data* )
@param {String} ruleId
@param {String} userId
@param {String} data
*/
exports.storeRule = function(ruleId, userId, data) {
log.print('DB', "storeRule: " + ruleId);
_this.db.sadd('rules', "" + ruleId + ":" + userId, replyHandler("storing rule key \"" + ruleId + ":" + userId + "\""));
_this.db.sadd("user-set:" + userId + ":rules", ruleId, replyHandler("storing rule key to \"user:" + userId + ":rules\""));
_this.db.sadd("rule-set:" + ruleId + ":users", user, replyHandler("storing user key to \"rule:" + ruleId + ":users\""));
return _this.db.set("rule:" + ruleId + ":" + userId, data, replyHandler("storing rule \"" + ruleId + ":" + userId + "\""));
};
/*
Query the DB for a rule and pass it to the callback(err, obj) function.
Query the DB for a rule and pass it to cb(err, obj).
@public getRule( *ruleId, cb* )
@param {String} ruleId
@ -507,12 +615,12 @@ DB Interface
exports.getRule = function(ruleId, cb) {
log.print('DB', "getRule: " + ruleId);
log.print('DB', "getRule: '" + ruleId + "'");
return _this.db.get("rule:" + ruleId, cb);
};
/*
Fetch all rules from the database and pass them to the callback function.
Fetch all rules and pass them to cb(err, obj).
@public getRules( *cb* )
@param {function} cb
@ -524,6 +632,262 @@ DB Interface
return getSetRecords('rules', exports.getRule, cb);
};
/*
Fetch all rule IDs and hand it to cb(err, obj).
@public getRuleIds( *cb* )
@param {function} cb
*/
exports.getRuleIds = function(cb) {
log.print('DB', 'Fetching all Rule IDs');
return _this.db.smembers('rules', cb);
};
/*
Store a string representation of a rule in the DB.
@public storeRule( *ruleId, data* )
@param {String} ruleId
@param {String} data
*/
exports.storeRule = function(ruleId, data) {
log.print('DB', "storeRule: '" + ruleId + "'");
_this.db.sadd('rules', "" + ruleId, replyHandler("storing rule key '" + ruleId + "'"));
return _this.db.set("rule:" + ruleId, data, replyHandler("storing rule '" + ruleId + "'"));
};
/*
Delete a string representation of a rule.
@public deleteRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
*/
exports.deleteRule = function(ruleId) {
log.print('DB', "deleteRule: '" + ruleId + "'");
_this.db.srem("rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "'"));
_this.db.del("rule:" + ruleId, replyHandler("Deleting rule '" + ruleId + "'"));
_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 + "'"));
};
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
id = obj[_i];
_results.push(delLinkedUserRule(id));
}
return _results;
});
_this.db.del("rule:" + ruleId + ":users", replyHandler("Deleting rule '" + ruleId + "' users"));
_this.db.smembers("rule:" + ruleId + ":active-users", function(err, obj) {
var delActiveUserRule, id, _i, _len, _results;
delActiveUserRule = function(userId) {
return _this.db.srem("user:" + userId + ":active-rules", ruleId, replyHandler("Deleting rule key '" + ruleId + "' in active user '" + userId + "'"));
};
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
id = obj[_i];
_results.push(delActiveUserRule(id));
}
return _results;
});
return _this.db.del("rule:" + ruleId + ":active-users", replyHandler("Deleting rule '" + ruleId + "' active users"));
};
/*
Associate a rule to a user.
@public linkRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
*/
exports.linkRule = function(ruleId, userId) {
log.print('DB', "linkRule: '" + ruleId + "' for user '" + userId + "'");
_this.db.sadd("rule:" + ruleId + ":users", userId, replyHandler("storing user '" + userId + "' for rule key '" + ruleId + "'"));
return _this.db.sadd("user:" + userId + ":rules", ruleId, replyHandler("storing rule key '" + ruleId + "' for user '" + userId + "'"));
};
/*
Get rules linked to a user and hand it to cb(err, obj).
@public getUserLinkRule( *userId, cb* )
@param {String} userId
@param {function} cb
*/
exports.getUserLinkedRules = function(userId, cb) {
log.print('DB', "getUserLinkedRules: for user '" + userId + "'");
return _this.db.smembers("user:" + userId + ":rules", cb);
};
/*
Get users linked to a rule and hand it to cb(err, obj).
@public getRuleLinkedUsers( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
*/
exports.getRuleLinkedUsers = function(ruleId, cb) {
log.print('DB', "getRuleLinkedUsers: for rule '" + ruleId + "'");
return _this.db.smembers("rule:" + ruleId + ":users", cb);
};
/*
Delete an association of a rule to a user.
@public unlinkRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
*/
exports.unlinkRule = function(ruleId, userId) {
log.print('DB', "unlinkRule: '" + ruleId + ":" + userId + "'");
_this.db.srem("rule:" + ruleId + ":users", userId, replyHandler("removing user '" + userId + "' for rule key '" + ruleId + "'"));
return _this.db.srem("user:" + userId + ":rules", ruleId, replyHandler("removing rule key '" + ruleId + "' for user '" + userId + "'"));
};
/*
Activate a rule.
@public activateRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
*/
exports.activateRule = function(ruleId, userId) {
log.print('DB', "activateRule: '" + ruleId + "' for '" + userId + "'");
_this.db.sadd("rule:" + ruleId + ":active-users", userId, replyHandler("storing activated user '" + userId + "' in rule '" + ruleId + "'"));
return _this.db.sadd("user:" + userId + ":active-rules", ruleId, replyHandler("storing activated rule '" + ruleId + "' in user '" + userId + "'"));
};
/*
Get rules activated for a user and hand it to cb(err, obj).
@public getUserLinkRule( *userId, cb* )
@param {String} userId
@param {function} cb
*/
exports.getUserActivatedRules = function(userId, cb) {
log.print('DB', "getUserActivatedRules: for user '" + userId + "'");
return _this.db.smembers("user:" + userId + ":active-rules", cb);
};
/*
Get users activated for a rule and hand it to cb(err, obj).
@public getRuleActivatedUsers ( *ruleId, cb* )
@param {String} ruleId
@param {function} cb
*/
exports.getRuleActivatedUsers = function(ruleId, cb) {
log.print('DB', "getRuleLinkedUsers: for rule '" + ruleId + "'");
return _this.db.smembers("rule:" + ruleId + ":active-users", cb);
};
/*
Deactivate a rule.
@public deactivateRule( *ruleId, userId* )
@param {String} ruleId
@param {String} userId
*/
exports.deactivateRule = function(ruleId, userId) {
log.print('DB', "deactivateRule: '" + ruleId + "' for '" + userId + "'");
_this.db.srem("rule:" + ruleId + ":active-users", userId, replyHandler("removing activated user '" + userId + "' in rule '" + ruleId + "'"));
return _this.db.srem("user:" + userId + ":active-rules", ruleId, replyHandler("removing activated rule '" + ruleId + "' in user '" + userId + "'"));
};
/*
Fetch all active ruleIds and pass them to cb(err, obj).
@public getAllActivatedRuleIds( *cb* )
@param {function} cb
*/
exports.getAllActivatedRuleIdsPerUser = function(cb) {
log.print('DB', "Fetching all active rules");
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 {
result[userId] = obj;
}
if (--semaphore === 0) {
return cb(null, result);
}
});
};
_results = [];
for (_i = 0, _len = obj.length; _i < _len; _i++) {
user = obj[_i];
_results.push(fFetchActiveUserRules(user));
}
return _results;
}
});
};
/*
Fetch all active rules and pass them to cb(err, obj).
@public getAllActivatedRules( *cb* )
@param {function} cb
*/
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).
@ -533,11 +897,11 @@ DB Interface
exports.storeUser = function(objUser) {
log.print('DB', "storeUser: " + objUser.username);
log.print('DB', "storeUser: '" + objUser.username + "'");
if (objUser && objUser.username && objUser.password) {
_this.db.sadd('users', objUser.username, replyHandler("storing user key " + objUser.username));
_this.db.sadd('users', objUser.username, replyHandler("storing user key '" + objUser.username + "'"));
objUser.password = hash(objUser.password);
return _this.db.hmset("user:" + objUser.username, objUser, replyHandler("storing user properties " + objUser.username));
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'));
}
@ -553,14 +917,14 @@ DB Interface
exports.storeUserRole = function(userId, role) {
log.print('DB', "storeUserRole: " + userId + ":" + role);
_this.db.sadd('roles', role, replyHandler("adding role " + role + " to role index set"));
_this.db.sadd("user:" + userId + ":roles", role, replyHandler("adding role " + role + " to user " + userId));
return _this.db.sadd("role:" + role + ":users", userId, replyHandler("adding user " + userId + " to role " + role));
log.print('DB', "storeUserRole: '" + userId + ":" + role + "'");
_this.db.sadd('roles', role, replyHandler("adding role '" + role + "' to role index set"));
_this.db.sadd("user:" + userId + ":roles", role, replyHandler("adding role '" + role + "' to user '" + userId + "'"));
return _this.db.sadd("role:" + role + ":users", userId, replyHandler("adding user '" + userId + "' to role '" + role + "'"));
};
/*
Fetch all roles of a user and pass them to the callback(err, obj)
Fetch all roles of a user and pass them to cb(err, obj).
@public getUserRoles( *userId* )
@param {String} userId
@ -568,12 +932,12 @@ DB Interface
exports.getUserRoles = function(userId) {
log.print('DB', "getUserRole: " + userId);
log.print('DB', "getUserRole: '" + userId + "'");
return _this.db.get("user-roles:" + userId, cb);
};
/*
Fetch all users of a role and pass them to the callback(err, obj)
Fetch all users of a role and pass them to cb(err, obj).
@public getUserRoles( *role* )
@param {String} role
@ -581,7 +945,7 @@ DB Interface
exports.getRoleUsers = function(role) {
log.print('DB', "getRoleUsers: " + role);
log.print('DB', "getRoleUsers: '" + role + "'");
return _this.db.get("role-users:" + role, cb);
};
@ -600,14 +964,14 @@ DB Interface
exports.loginUser = function(userId, password, cb) {
var fCheck;
log.print('DB', "User \"" + userId + "\" tries to log in");
log.print('DB', "User '" + userId + "' tries to log in");
fCheck = function(pw) {
return function(err, obj) {
if (err) {
return cb(err);
} else if (obj && obj.password) {
if (pw === obj.password) {
log.print('DB', "User \"" + obj.username + "\" logged in!");
log.print('DB', "User '" + obj.username + "' logged in!");
return cb(null, obj);
} else {
return cb(new Error('Wrong credentials!'));
@ -620,6 +984,46 @@ 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.

View file

@ -29,34 +29,34 @@ exports = module.exports = function(args) {
*/
exports.addDBLinkAndLoadActionsAndRules = function(db_link) {
db = db_link;
if(ml && db) db.getActionModules(function(err, obj) {
if(err) log.error('EN', 'retrieving Action Modules from DB!');
else {
if(!obj) {
log.print('EN', 'No Action Modules found in DB!');
loadRulesFromDB();
} else {
var m;
for(var el in obj) {
log.print('EN', 'Loading Action Module from DB: ' + el);
try{
m = ml.requireFromString(obj[el], el);
db.getActionModuleAuth(el, function(mod) {
return function(err, obj) {
if(obj && mod.loadCredentials) mod.loadCredentials(JSON.parse(obj));
};
}(m));
listActionModules[el] = m;
} catch(e) {
e.addInfo = 'error in action module "' + el + '"';
log.error('EN', e);
}
}
loadRulesFromDB();
}
}
});
else log.severe('EN', new Error('Module Loader or DB not defined!'));
// if(ml && db) db.getActionModules(function(err, obj) {
// if(err) log.error('EN', 'retrieving Action Modules from DB!');
// else {
// if(!obj) {
// log.print('EN', 'No Action Modules found in DB!');
// loadRulesFromDB();
// } else {
// var m;
// for(var el in obj) {
// log.print('EN', 'Loading Action Module from DB: ' + el);
// try{
// m = ml.requireFromString(obj[el], el);
// db.getActionModuleAuth(el, function(mod) {
// return function(err, obj) {
// if(obj && mod.loadCredentials) mod.loadCredentials(JSON.parse(obj));
// };
// }(m));
// listActionModules[el] = m;
// } catch(e) {
// e.addInfo = 'error in action module "' + el + '"';
// log.error('EN', e);
// }
// }
// loadRulesFromDB();
// }
// }
// });
// else log.severe('EN', new Error('Module Loader or DB not defined!'));
};
function loadRulesFromDB() {

View file

@ -8,7 +8,7 @@ Request Handler
(function() {
var answerHandler, crypto, db, exports, fs, getHandlerFileAsString, getHandlerPath, log, mm, mustache, objAdminCmds, objUserCmds, path, qs, renderPage, sendLoginOrPage,
var answerHandler, crypto, db, exports, fs, getHandlerFileAsString, getHandlerPath, getIncludeFileAsString, log, mm, mustache, objAdminCmds, objUserCmds, path, qs, renderPage, sendLoginOrPage,
_this = this;
log = require('./logging');
@ -189,6 +189,20 @@ Request Handler
return fs.readFileSync(getHandlerPath(name), 'utf8');
};
/*
Fetches an include file.
@private getIncludeFileAsString( *name* )
@param {String} name
*/
getIncludeFileAsString = function(name) {
var pth;
pth = path.resolve(__dirname, '..', 'webpages', 'handlers', 'includes', name + '.html');
return fs.readFileSync(pth, 'utf8');
};
/*
Renders a page depending on the user session and returns it.
@ -201,8 +215,8 @@ Request Handler
renderPage = function(name, sess, msg) {
var menubar, requires, template, view;
template = getHandlerFileAsString(name);
menubar = getHandlerFileAsString('part_menubar');
requires = getHandlerFileAsString('part_requires');
menubar = getIncludeFileAsString('menubar');
requires = getIncludeFileAsString('requires');
view = {
user: sess.user,
head_requires: requires,
@ -226,11 +240,13 @@ Request Handler
sendLoginOrPage = function(pagename, req, resp) {
if (req.session && req.session.user) {
return resp.send(renderPage(pagename, req.session));
} else {
return resp.sendfile(getHandlerPath('login'));
if (!req.session) {
req.session = {};
}
if (!req.session.user) {
pagename = 'login';
}
return resp.send(renderPage(pagename, req.session));
};
/*

View file

@ -31,7 +31,7 @@
exports.testDifferentConfigFile = function(test) {
test.expect(1);
_this.conf({
configPath: 'testing/jsonWrongConfig.json'
configPath: path.join('testing', 'files', 'jsonWrongConfig.json')
});
test.ok(_this.conf.isReady(), 'Different path not loaded!');
return test.done();

View file

@ -4,7 +4,6 @@
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
exports.setUp = function(cb) {
_this.log = require('../js-coffee/logging');
_this.db = require('../js-coffee/db_interface');
_this.db({
logType: 2
@ -47,11 +46,11 @@
},
testPurgeQueue: function(test) {
var evt;
test.expect(2);
evt = {
eventid: '1',
event: 'mail'
};
test.expect(2);
_this.db.pushEvent(evt);
_this.db.purgeEventQueue();
return _this.db.popEvent(function(err, obj) {
@ -128,68 +127,435 @@
}
};
exports.action_modules = {
testModule: function(test) {
var action1, action1name, fCheckModuleExists, fCheckModuleNotExists, fCheckModuleNotExistsInSet, fCheckSetEntry;
test.expect(4);
action1name = 'test-action-module_1';
action1 = 'unit-test action module 1 content';
fCheckSetEntry = function(err, obj) {
test.ok(__indexOf.call(obj, action1name) >= 0, 'Expected key not in action-modules set');
return _this.db.getActionModule(action1name, fCheckModuleExists);
};
fCheckModuleExists = function(err, obj) {
test.strictEqual(obj, action1, 'Retrieved Action Module is not what we expected');
_this.log.print('delete action module');
_this.db.deleteActionModule(action1name);
_this.log.print('tried to delete action module');
return _this.db.getActionModule(action1name, fCheckModuleNotExists);
};
fCheckModuleNotExists = function(err, obj) {
_this.log.print('got action module');
test.strictEqual(obj, null, 'Action module still exists');
_this.log.print('compared action module');
return _this.db.getActionModuleIds(fCheckModuleNotExistsInSet);
};
fCheckModuleNotExistsInSet = function(err, obj) {
test.ok(__indexOf.call(obj, action1name) < 0, 'Action module key still exists in set');
return test.done();
};
_this.db.storeActionModule(action1name, action1);
return _this.db.getActionModuleIds(fCheckSetEntry);
},
testFetchSeveralModules: function(test) {
var action1, action1name, action2, action2name, fCheckModule, fCheckSetEntries, forkEnds, semaphore;
semaphore = 2;
forkEnds = function() {
if (--semaphore === 0) {
return test.done();
}
};
exports.action_invoker = {
testCreateAndRead: function(test) {
var action, id;
test.expect(3);
action1name = 'test-action-module_1';
action2name = 'test-action-module_2';
action1 = 'unit-test action module 1 content';
action2 = 'unit-test action module 2 content';
fCheckModule = function(mod) {
var myTest;
id = 'test-action-invoker';
action = 'unit-test action invoker content';
_this.db.storeActionInvoker(id, action);
return _this.db.getActionInvokerIds(function(err, obj) {
test.ok(__indexOf.call(obj, id) >= 0, 'Expected key not in action-invokers set');
return _this.db.getActionInvoker(id, function(err, obj) {
test.strictEqual(obj, action, 'Retrieved Action Invoker is not what we expected');
return _this.db.getActionInvokers(function(err, obj) {
test.deepEqual(action, obj[id], 'Action Invoker ist not in result set');
_this.db.deleteActionInvoker(id);
return test.done();
});
});
});
},
testUpdate: function(test) {
var action, actionNew, id;
test.expect(2);
id = 'test-action-invoker';
action = 'unit-test action invoker content';
actionNew = 'unit-test action invoker new content';
_this.db.storeActionInvoker(id, action);
_this.db.storeActionInvoker(id, actionNew);
return _this.db.getActionInvoker(id, function(err, obj) {
test.strictEqual(obj, actionNew, 'Retrieved Action Invoker is not what we expected');
return _this.db.getActionInvokers(function(err, obj) {
test.deepEqual(actionNew, obj[id], 'Action Invoker ist not in result set');
_this.db.deleteActionInvoker(id);
return test.done();
});
});
},
testDelete: function(test) {
var action, id;
test.expect(2);
id = 'test-action-invoker';
action = 'unit-test action invoker content';
_this.db.storeActionInvoker(id, action);
_this.db.deleteActionInvoker(id);
return _this.db.getActionInvoker(id, function(err, obj) {
test.strictEqual(obj, null, 'Action Invoker still exists');
return _this.db.getActionInvokerIds(function(err, obj) {
test.ok(__indexOf.call(obj, id) < 0, 'Action Invoker key still exists in set');
return test.done();
});
});
},
testFetchSeveral: function(test) {
var action1, action1name, action2, action2name, fCheckInvoker, semaphore;
test.expect(3);
semaphore = 2;
action1name = 'test-action-invoker_1';
action2name = 'test-action-invoker_2';
action1 = 'unit-test action invoker 1 content';
action2 = 'unit-test action invoker 2 content';
fCheckInvoker = function(modname, mod) {
var forkEnds, myTest;
myTest = test;
console.log('check module');
forkEnds = function() {
if (--semaphore === 0) {
return myTest.done();
}
};
return function(err, obj) {
console.log('db answered');
myTest.strictEqual(mod, obj, "Module does not equal the expected one");
myTest.strictEqual(mod, obj, "Invoker " + modname + " does not equal the expected one");
_this.db.deleteActionInvoker(modname);
return forkEnds();
};
};
fCheckSetEntries = function(err, obj) {
test.ok(__indexOf.call(obj, action1name) >= 0 && __indexOf.call(obj, action2name) >= 0, 'Not all action module Ids in set');
console.log('setentries fetched');
this.db.getActionModule(action1name, fCheckModule(action1));
return this.db.getActionModule(action2name, fCheckModule(action2));
_this.db.storeActionInvoker(action1name, action1);
_this.db.storeActionInvoker(action2name, action2);
return _this.db.getActionInvokerIds(function(err, obj) {
test.ok(__indexOf.call(obj, action1name) >= 0 && __indexOf.call(obj, action2name) >= 0, 'Not all action invoker Ids in set');
_this.db.getActionInvoker(action1name, fCheckInvoker(action1name, action1));
return _this.db.getActionInvoker(action2name, fCheckInvoker(action2name, action2));
});
}
};
exports.action_invoker_params = {
testCreateAndRead: function(test) {
var actionId, params, userId;
test.expect(2);
userId = 'tester1';
actionId = 'test-action-invoker_1';
params = 'shouldn\'t this be an object?';
_this.db.storeActionParams(actionId, userId, params);
return _this.db.getActionParamsIds(function(err, obj) {
var _ref;
test.ok((_ref = actionId + ':' + userId, __indexOf.call(obj, _ref) >= 0), 'Expected key not in action-params set');
return _this.db.getActionParams(actionId, userId, function(err, obj) {
test.strictEqual(obj, params, 'Retrieved action params is not what we expected');
_this.db.deleteActionParams(actionId, userId);
return test.done();
});
});
},
testUpdate: function(test) {
var actionId, params, paramsNew, userId;
test.expect(1);
userId = 'tester1';
actionId = 'test-action-invoker_1';
params = 'shouldn\'t this be an object?';
paramsNew = 'shouldn\'t this be a new object?';
_this.db.storeActionParams(actionId, userId, params);
_this.db.storeActionParams(actionId, userId, paramsNew);
return _this.db.getActionParams(actionId, userId, function(err, obj) {
test.strictEqual(obj, paramsNew, 'Retrieved action params is not what we expected');
_this.db.deleteActionParams(actionId, userId);
return test.done();
});
},
testDelete: function(test) {
var actionId, params, userId;
test.expect(2);
userId = 'tester1';
actionId = 'test-action-invoker_1';
params = 'shouldn\'t this be an object?';
_this.db.storeActionParams(actionId, userId, params);
_this.db.deleteActionParams(actionId, userId);
return _this.db.getActionParams(actionId, userId, function(err, obj) {
test.strictEqual(obj, null, 'Action params still exists');
return _this.db.getActionParamsIds(function(err, obj) {
var _ref;
test.ok((_ref = actionId + ':' + userId, __indexOf.call(obj, _ref) < 0), 'Action Params key still exists in set');
return test.done();
});
});
}
};
exports.event_poller = {
testCreateAndRead: function(test) {
var event, id;
test.expect(3);
id = 'test-event-poller';
event = 'unit-test event poller content';
_this.db.storeEventPoller(id, event);
return _this.db.getEventPollerIds(function(err, obj) {
test.ok(__indexOf.call(obj, id) >= 0, 'Expected key not in event-pollers set');
return _this.db.getEventPoller(id, function(err, obj) {
test.strictEqual(obj, event, 'Retrieved Event Poller is not what we expected');
return _this.db.getEventPollers(function(err, obj) {
test.deepEqual(event, obj[id], 'Event Poller ist not in result set');
_this.db.deleteEventPoller(id);
return test.done();
});
});
});
},
testUpdate: function(test) {
var event, eventNew, id;
test.expect(2);
id = 'test-event-poller';
event = 'unit-test event poller content';
eventNew = 'unit-test event poller new content';
_this.db.storeEventPoller(id, event);
_this.db.storeEventPoller(id, eventNew);
return _this.db.getEventPoller(id, function(err, obj) {
test.strictEqual(obj, eventNew, 'Retrieved Event Poller is not what we expected');
return _this.db.getEventPollers(function(err, obj) {
test.deepEqual(eventNew, obj[id], 'Event Poller ist not in result set');
_this.db.deleteEventPoller(id);
return test.done();
});
});
},
testDelete: function(test) {
var event, id;
test.expect(2);
id = 'test-event-poller';
event = 'unit-test event poller content';
_this.db.storeEventPoller(id, event);
_this.db.deleteEventPoller(id);
return _this.db.getEventPoller(id, function(err, obj) {
test.strictEqual(obj, null, 'Event Poller still exists');
return _this.db.getEventPollerIds(function(err, obj) {
test.ok(__indexOf.call(obj, id) < 0, 'Event Poller key still exists in set');
return test.done();
});
});
},
testFetchSeveral: function(test) {
var event1, event1name, event2, event2name, fCheckPoller, semaphore;
test.expect(3);
semaphore = 2;
event1name = 'test-event-poller_1';
event2name = 'test-event-poller_2';
event1 = 'unit-test event poller 1 content';
event2 = 'unit-test event poller 2 content';
fCheckPoller = function(modname, mod) {
var forkEnds, myTest;
myTest = test;
forkEnds = function() {
if (--semaphore === 0) {
return myTest.done();
}
};
return function(err, obj) {
myTest.strictEqual(mod, obj, "Invoker " + modname + " does not equal the expected one");
_this.db.deleteEventPoller(modname);
return forkEnds();
};
};
_this.db.storeActionModule(action1name, action1);
_this.db.storeActionModule(action2name, action2);
return _this.db.getActionModuleIds(fCheckSetEntries);
_this.db.storeEventPoller(event1name, event1);
_this.db.storeEventPoller(event2name, event2);
return _this.db.getEventPollerIds(function(err, obj) {
test.ok(__indexOf.call(obj, event1name) >= 0 && __indexOf.call(obj, event2name) >= 0, 'Not all event poller Ids in set');
_this.db.getEventPoller(event1name, fCheckPoller(event1name, event1));
return _this.db.getEventPoller(event2name, fCheckPoller(event2name, event2));
});
}
};
exports.event_poller_params = {
testCreateAndRead: function(test) {
var eventId, params, userId;
test.expect(2);
userId = 'tester1';
eventId = 'test-event-poller_1';
params = 'shouldn\'t this be an object?';
_this.db.storeEventParams(eventId, userId, params);
return _this.db.getEventParamsIds(function(err, obj) {
var _ref;
test.ok((_ref = eventId + ':' + userId, __indexOf.call(obj, _ref) >= 0), 'Expected key not in event-params set');
return _this.db.getEventParams(eventId, userId, function(err, obj) {
test.strictEqual(obj, params, 'Retrieved event params is not what we expected');
_this.db.deleteEventParams(eventId, userId);
return test.done();
});
});
},
testUpdate: function(test) {
var eventId, params, paramsNew, userId;
test.expect(1);
userId = 'tester1';
eventId = 'test-event-poller_1';
params = 'shouldn\'t this be an object?';
paramsNew = 'shouldn\'t this be a new object?';
_this.db.storeEventParams(eventId, userId, params);
_this.db.storeEventParams(eventId, userId, paramsNew);
return _this.db.getEventParams(eventId, userId, function(err, obj) {
test.strictEqual(obj, paramsNew, 'Retrieved event params is not what we expected');
_this.db.deleteEventParams(eventId, userId);
return test.done();
});
},
testDelete: function(test) {
var eventId, params, userId;
test.expect(2);
userId = 'tester1';
eventId = 'test-event-poller_1';
params = 'shouldn\'t this be an object?';
_this.db.storeEventParams(eventId, userId, params);
_this.db.deleteEventParams(eventId, userId);
return _this.db.getEventParams(eventId, userId, function(err, obj) {
test.strictEqual(obj, null, 'Event params still exists');
return _this.db.getEventParamsIds(function(err, obj) {
var _ref;
test.ok((_ref = eventId + ':' + userId, __indexOf.call(obj, _ref) < 0), 'Event Params key still exists in set');
return test.done();
});
});
}
};
exports.rules = {
setUp: function(cb) {
_this.db({
logType: 1
});
_this.userId = 'tester-1';
_this.ruleId = 'test-rule_1';
_this.rule = {
"id": "rule_id",
"event": "custom",
"condition": {
"property": "yourValue"
},
"actions": []
};
_this.ruleNew = {
"id": "rule_new",
"event": "custom",
"condition": {
"property": "yourValue"
},
"actions": []
};
return cb();
},
tearDown: function(cb) {
_this.db.deleteRule(_this.ruleId);
return cb();
},
testCreateAndRead: function(test) {
test.expect(3);
_this.db.storeRule(_this.ruleId, JSON.stringify(_this.rule));
return _this.db.getRuleIds(function(err, obj) {
var _ref;
test.ok((_ref = _this.ruleId, __indexOf.call(obj, _ref) >= 0), 'Expected key not in rule key set');
return _this.db.getRule(_this.ruleId, function(err, obj) {
test.deepEqual(JSON.parse(obj), _this.rule, 'Retrieved rule is not what we expected');
return _this.db.getRules(function(err, obj) {
test.deepEqual(_this.rule, JSON.parse(obj[_this.ruleId]), 'Rule not in result set');
_this.db.deleteRule(_this.ruleId);
return test.done();
});
});
});
},
testUpdate: function(test) {
test.expect(1);
_this.db.storeRule(_this.ruleId, JSON.stringify(_this.rule));
_this.db.storeRule(_this.ruleId, JSON.stringify(_this.ruleNew));
return _this.db.getRule(_this.ruleId, function(err, obj) {
test.deepEqual(JSON.parse(obj), _this.ruleNew, 'Retrieved rule is not what we expected');
_this.db.deleteRule(_this.ruleId);
return test.done();
});
},
testDelete: function(test) {
test.expect(2);
_this.db.storeRule(_this.ruleId, JSON.stringify(_this.rule));
_this.db.deleteRule(_this.ruleId);
return _this.db.getRule(_this.ruleId, function(err, obj) {
test.strictEqual(obj, null, 'Rule still exists');
return _this.db.getRuleIds(function(err, obj) {
var _ref;
test.ok((_ref = _this.ruleId, __indexOf.call(obj, _ref) < 0), 'Rule key still exists in set');
return test.done();
});
});
},
testLink: function(test) {
test.expect(2);
_this.db.linkRule(_this.ruleId, _this.userId);
return _this.db.getRuleLinkedUsers(_this.ruleId, function(err, obj) {
var _ref;
test.ok((_ref = _this.userId, __indexOf.call(obj, _ref) >= 0), "Rule not linked to user " + _this.userId);
return _this.db.getUserLinkedRules(_this.userId, function(err, obj) {
var _ref1;
test.ok((_ref1 = _this.ruleId, __indexOf.call(obj, _ref1) >= 0), "User not linked to rule " + _this.ruleId);
return test.done();
});
});
},
testUnlink: function(test) {
test.expect(2);
_this.db.linkRule(_this.ruleId, _this.userId);
_this.db.unlinkRule(_this.ruleId, _this.userId);
return _this.db.getRuleLinkedUsers(_this.ruleId, function(err, obj) {
var _ref;
test.ok((_ref = _this.userId, __indexOf.call(obj, _ref) < 0), "Rule still linked to user " + _this.userId);
return _this.db.getUserLinkedRules(_this.userId, function(err, obj) {
var _ref1;
test.ok((_ref1 = _this.ruleId, __indexOf.call(obj, _ref1) < 0), "User still linked to rule " + _this.ruleId);
return test.done();
});
});
},
testActivate: function(test) {
var usr;
test.expect(3);
usr = {
username: "tester-1",
password: "tester-1"
};
_this.db.storeUser(usr);
_this.db.activateRule(_this.ruleId, _this.userId);
return _this.db.getRuleActivatedUsers(_this.ruleId, function(err, obj) {
var _ref;
test.ok((_ref = _this.userId, __indexOf.call(obj, _ref) >= 0), "Rule not activated for user " + _this.userId);
return _this.db.getUserActivatedRules(_this.userId, function(err, obj) {
var _ref1;
test.ok((_ref1 = _this.ruleId, __indexOf.call(obj, _ref1) >= 0), "User not activated for rule " + _this.ruleId);
return _this.db.getAllActivatedRuleIdsPerUser(function(err, obj) {
var _ref2;
test.ok(obj[_this.userId], "User not found in activated set");
test.ok((_ref2 = _this.ruleId, __indexOf.call(obj[_this.userId], _ref2) >= 0), "Rule " + _this.ruleId + " not in activated rules set");
return test.done();
});
});
});
},
testDeactivate: function(test) {
test.expect(3);
_this.db.activateRule(_this.ruleId, _this.userId);
_this.db.deactivateRule(_this.ruleId, _this.userId);
return _this.db.getRuleActivatedUsers(_this.ruleId, function(err, obj) {
var _ref;
test.ok((_ref = _this.userId, __indexOf.call(obj, _ref) < 0), "Rule still activated for user " + _this.userId);
return _this.db.getUserActivatedRules(_this.userId, function(err, obj) {
var _ref1;
test.ok((_ref1 = _this.ruleId, __indexOf.call(obj, _ref1) < 0), "User still activated for rule " + _this.ruleId);
return _this.db.getAllActivatedRuleIdsPerUser(function(err, obj) {
var _ref2;
test.ok((_ref2 = _this.ruleId, __indexOf.call(obj[_this.userId], _ref2) < 0), "Rule " + _this.ruleId + " still in activated rules set");
return test.done();
});
});
});
},
testUnlinkAndDeactivateAfterDeletion: function(test) {
var fWaitForDeletion, fWaitForTest;
test.expect(2);
_this.db.storeRule(_this.ruleId, JSON.stringify(_this.rule));
_this.db.linkRule(_this.ruleId, _this.userId);
_this.db.activateRule(_this.ruleId, _this.userId);
fWaitForTest = function() {
return _this.db.getUserLinkedRules(_this.userId, function(err, obj) {
var _ref;
test.ok((_ref = _this.ruleId, __indexOf.call(obj, _ref) < 0), "Rule " + _this.ruleId + " still linked to user " + _this.userId);
return _this.db.getUserActivatedRules(_this.userId, function(err, obj) {
var _ref1;
test.ok((_ref1 = _this.ruleId, __indexOf.call(obj, _ref1) < 0), "Rule " + _this.ruleId + " still activated for user " + _this.userId);
return test.done();
});
});
};
fWaitForDeletion = function() {
_this.db.deleteRule(_this.ruleId);
return setTimeout(fWaitForTest, 100);
};
return setTimeout(fWaitForDeletion, 100);
}
};

View file

@ -22,7 +22,7 @@ exports.testParameters = ( test ) =>
exports.testDifferentConfigFile = ( test ) =>
test.expect 1
@conf
configPath: 'testing/jsonWrongConfig.json'
configPath: path.join 'testing', 'files', 'jsonWrongConfig.json'
test.ok @conf.isReady(), 'Different path not loaded!'
test.done()

View file

@ -1,6 +1,5 @@
exports.setUp = ( cb ) =>
@log = require '../js-coffee/logging'
@db = require '../js-coffee/db_interface'
@db logType: 2
cb()
@ -8,17 +7,20 @@ exports.setUp = ( cb ) =>
exports.availability =
testRequire: ( test ) =>
test.expect 1
test.ok @db, 'DB interface loaded'
test.done()
testConnect: ( test ) =>
test.expect 1
@db.isConnected ( err ) ->
test.ifError err, 'Connection failed!'
test.done()
testNoConfig: ( test ) =>
test.expect 1
@db
configPath: 'nonexistingconf.file'
@db.isConnected ( err ) ->
@ -27,16 +29,18 @@ exports.availability =
testWrongConfig: ( test ) =>
test.expect 1
@db { configPath: 'testing/jsonWrongConfig.json' }
@db.isConnected ( err ) ->
test.ok err, 'Still connected!?'
test.done()
testPurgeQueue: ( test ) =>
test.expect 2
evt =
eventid: '1'
event: 'mail'
test.expect 2
@db.pushEvent evt
@db.purgeEventQueue()
@db.popEvent ( err, obj ) =>
@ -57,30 +61,41 @@ exports.events =
testEmptyPopping: ( test ) =>
test.expect 2
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during pop after purging!'
test.strictEqual obj, null, 'There was an event in the queue!?'
test.ifError err,
'Error during pop after purging!'
test.strictEqual obj, null,
'There was an event in the queue!?'
test.done()
testEmptyPushing: ( test ) =>
test.expect 2
@db.pushEvent null
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during non-empty pushing!'
test.strictEqual obj, null, 'There was an event in the queue!?'
test.ifError err,
'Error during non-empty pushing!'
test.strictEqual obj, null,
'There was an event in the queue!?'
test.done()
testNonEmptyPopping: ( test ) =>
test.expect 3
@db.pushEvent @evt1
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during non-empty popping!'
test.notStrictEqual obj, null, 'There was no event in the queue!'
test.deepEqual @evt1, obj, 'Wrong event in queue!'
test.ifError err,
'Error during non-empty popping!'
test.notStrictEqual obj, null,
'There was no event in the queue!'
test.deepEqual @evt1, obj,
'Wrong event in queue!'
test.done()
testMultiplePushAndPops: ( test ) =>
test.expect 6
semaphore = 2
forkEnds = () ->
test.done() if --semaphore is 0
@ -89,109 +104,548 @@ exports.events =
@db.pushEvent @evt2
# eventually it would be wise to not care about the order of events
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during multiple push and pop!'
test.notStrictEqual obj, null, 'There was no event in the queue!'
test.deepEqual @evt1, obj, 'Wrong event in queue!'
test.ifError err,
'Error during multiple push and pop!'
test.notStrictEqual obj, null,
'There was no event in the queue!'
test.deepEqual @evt1, obj,
'Wrong event in queue!'
forkEnds()
@db.popEvent ( err, obj ) =>
test.ifError err, 'Error during multiple push and pop!'
test.notStrictEqual obj, null, 'There was no event in the queue!'
test.deepEqual @evt2, obj, 'Wrong event in queue!'
test.ifError err,
'Error during multiple push and pop!'
test.notStrictEqual obj, null,
'There was no event in the queue!'
test.deepEqual @evt2, obj,
'Wrong event in queue!'
forkEnds()
exports.action_modules =
# setUp: ( cb ) =>
# @db logType: 1
# cb()
testModule: ( test ) =>
test.expect 4
action1name = 'test-action-module_1'
action1 = 'unit-test action module 1 content'
fCheckSetEntry = ( err , obj ) =>
test.ok action1name in obj, 'Expected key not in action-modules set'
@db.getActionModule action1name, fCheckModuleExists
fCheckModuleExists = ( err , obj ) =>
test.strictEqual obj, action1, 'Retrieved Action Module is not what we expected'
@log.print 'delete action module'
@db.deleteActionModule action1name
@log.print 'tried to delete action module'
@db.getActionModule action1name, fCheckModuleNotExists
fCheckModuleNotExists = ( err , obj ) =>
@log.print 'got action module'
test.strictEqual obj, null, 'Action module still exists'
@log.print 'compared action module'
@db.getActionModuleIds fCheckModuleNotExistsInSet
fCheckModuleNotExistsInSet = ( err , obj ) =>
test.ok action1name not in obj, 'Action module key still exists in set'
test.done()
@db.storeActionModule action1name, action1
@db.getActionModuleIds fCheckSetEntry
testFetchSeveralModules: ( test ) =>
semaphore = 2
exports.action_invoker =
testCreateAndRead: ( test ) =>
test.expect 3
action1name = 'test-action-module_1'
action2name = 'test-action-module_2'
action1 = 'unit-test action module 1 content'
action2 = 'unit-test action module 2 content'
fCheckModule = ( mod ) ->
id = 'test-action-invoker'
action = 'unit-test action invoker content'
# store an entry to start with
@db.storeActionInvoker id, action
# test that the ID shows up in the set
@db.getActionInvokerIds ( err , obj ) =>
test.ok id in obj,
'Expected key not in action-invokers set'
# the retrieved object really is the one we expected
@db.getActionInvoker id, ( err , obj ) =>
test.strictEqual obj, action,
'Retrieved Action Invoker is not what we expected'
# Ensure the action invoker is in the list of all existing ones
@db.getActionInvokers ( err , obj ) =>
test.deepEqual action, obj[id],
'Action Invoker ist not in result set'
@db.deleteActionInvoker id
test.done()
testUpdate: ( test ) =>
test.expect 2
id = 'test-action-invoker'
action = 'unit-test action invoker content'
actionNew = 'unit-test action invoker new content'
# store an entry to start with
@db.storeActionInvoker id, action
@db.storeActionInvoker id, actionNew
# the retrieved object really is the one we expected
@db.getActionInvoker id, ( err , obj ) =>
test.strictEqual obj, actionNew,
'Retrieved Action Invoker is not what we expected'
# Ensure the action invoker is in the list of all existing ones
@db.getActionInvokers ( err , obj ) =>
test.deepEqual actionNew, obj[id],
'Action Invoker ist not in result set'
@db.deleteActionInvoker id
test.done()
testDelete: ( test ) =>
test.expect 2
id = 'test-action-invoker'
action = 'unit-test action invoker content'
# store an entry to start with
@db.storeActionInvoker id, action
# Ensure the action invoker has been deleted
@db.deleteActionInvoker id
@db.getActionInvoker id, ( err , obj ) =>
test.strictEqual obj, null,
'Action Invoker still exists'
# Ensure the ID has been removed from the set
@db.getActionInvokerIds ( err , obj ) =>
test.ok id not in obj,
'Action Invoker key still exists in set'
test.done()
testFetchSeveral: ( test ) =>
test.expect 3
semaphore = 2
action1name = 'test-action-invoker_1'
action2name = 'test-action-invoker_2'
action1 = 'unit-test action invoker 1 content'
action2 = 'unit-test action invoker 2 content'
fCheckInvoker = ( modname, mod ) =>
myTest = test
sem = semaphore
forkEnds = () ->
console.log 'fork ends'
myTest.done() if --sem is 0
console.log 'check module'
( err, obj ) ->
console.log 'db answered'
myTest.strictEqual mod, obj, "Module does not equal the expected one"
myTest.done() if --semaphore is 0
( err, obj ) =>
myTest.strictEqual mod, obj,
"Invoker #{ modname } does not equal the expected one"
@db.deleteActionInvoker modname
forkEnds()
fCheckSetEntries = ( err, obj ) ->
test.ok action1name in obj and action2name in obj, 'Not all action module Ids in set'
console.log 'setentries fetched'
@db.getActionModule action1name, fCheckModule(action1)
@db.getActionModule action2name, fCheckModule(action2)
@db.storeActionModule action1name, action1
@db.storeActionModule action2name, action2
@db.getActionModuleIds fCheckSetEntries
@db.storeActionInvoker action1name, action1
@db.storeActionInvoker action2name, action2
@db.getActionInvokerIds ( err, obj ) =>
test.ok action1name in obj and action2name in obj,
'Not all action invoker Ids in set'
@db.getActionInvoker action1name, fCheckInvoker action1name, action1
@db.getActionInvoker action2name, fCheckInvoker action2name, action2
# testFetchModules: ( test ) =>
# test.expect 0
# test.done()
exports.action_invoker_params =
testCreateAndRead: ( test ) =>
test.expect 2
# testStoreParams: ( test ) =>
# test.expect 0
# test.done()
userId = 'tester1'
actionId = 'test-action-invoker_1'
params = 'shouldn\'t this be an object?'
# testFetchParams: ( test ) =>
# test.expect 0
# test.done()
# store an entry to start with
@db.storeActionParams actionId, userId, params
# test that the ID shows up in the set
@db.getActionParamsIds ( err, obj ) =>
test.ok actionId+':'+userId in obj,
'Expected key not in action-params set'
# the retrieved object really is the one we expected
@db.getActionParams actionId, userId, ( err, obj ) =>
test.strictEqual obj, params,
'Retrieved action params is not what we expected'
@db.deleteActionParams actionId, userId
test.done()
# exports.event_modules =
# test: ( test ) =>
# test.expect 0
# test.done()
testUpdate: ( test ) =>
test.expect 1
userId = 'tester1'
actionId = 'test-action-invoker_1'
params = 'shouldn\'t this be an object?'
paramsNew = 'shouldn\'t this be a new object?'
# store an entry to start with
@db.storeActionParams actionId, userId, params
@db.storeActionParams actionId, userId, paramsNew
# the retrieved object really is the one we expected
@db.getActionParams actionId, userId, ( err, obj ) =>
test.strictEqual obj, paramsNew,
'Retrieved action params is not what we expected'
@db.deleteActionParams actionId, userId
test.done()
testDelete: ( test ) =>
test.expect 2
userId = 'tester1'
actionId = 'test-action-invoker_1'
params = 'shouldn\'t this be an object?'
# store an entry to start with and delte it right away
@db.storeActionParams actionId, userId, params
@db.deleteActionParams actionId, userId
# Ensure the action params have been deleted
@db.getActionParams actionId, userId, ( err, obj ) =>
test.strictEqual obj, null,
'Action params still exists'
# Ensure the ID has been removed from the set
@db.getActionParamsIds ( err, obj ) =>
test.ok actionId+':'+userId not in obj,
'Action Params key still exists in set'
test.done()
# exports.rules =
# test: ( test ) =>
# test.expect 0
# test.done()
exports.event_poller =
testCreateAndRead: ( test ) =>
test.expect 3
id = 'test-event-poller'
event = 'unit-test event poller content'
# store an entry to start with
@db.storeEventPoller id, event
# test that the ID shows up in the set
@db.getEventPollerIds ( err , obj ) =>
test.ok id in obj,
'Expected key not in event-pollers set'
# the retrieved object really is the one we expected
@db.getEventPoller id, ( err , obj ) =>
test.strictEqual obj, event,
'Retrieved Event Poller is not what we expected'
# Ensure the event poller is in the list of all existing ones
@db.getEventPollers ( err , obj ) =>
test.deepEqual event, obj[id],
'Event Poller ist not in result set'
@db.deleteEventPoller id
test.done()
testUpdate: ( test ) =>
test.expect 2
id = 'test-event-poller'
event = 'unit-test event poller content'
eventNew = 'unit-test event poller new content'
# store an entry to start with
@db.storeEventPoller id, event
@db.storeEventPoller id, eventNew
# the retrieved object really is the one we expected
@db.getEventPoller id, ( err , obj ) =>
test.strictEqual obj, eventNew,
'Retrieved Event Poller is not what we expected'
# Ensure the event poller is in the list of all existing ones
@db.getEventPollers ( err , obj ) =>
test.deepEqual eventNew, obj[id],
'Event Poller ist not in result set'
@db.deleteEventPoller id
test.done()
testDelete: ( test ) =>
test.expect 2
id = 'test-event-poller'
event = 'unit-test event poller content'
# store an entry to start with
@db.storeEventPoller id, event
# Ensure the event poller has been deleted
@db.deleteEventPoller id
@db.getEventPoller id, ( err , obj ) =>
test.strictEqual obj, null,
'Event Poller still exists'
# Ensure the ID has been removed from the set
@db.getEventPollerIds ( err , obj ) =>
test.ok id not in obj,
'Event Poller key still exists in set'
test.done()
testFetchSeveral: ( test ) =>
test.expect 3
semaphore = 2
event1name = 'test-event-poller_1'
event2name = 'test-event-poller_2'
event1 = 'unit-test event poller 1 content'
event2 = 'unit-test event poller 2 content'
fCheckPoller = ( modname, mod ) =>
myTest = test
forkEnds = () ->
myTest.done() if --semaphore is 0
( err, obj ) =>
myTest.strictEqual mod, obj,
"Invoker #{ modname } does not equal the expected one"
@db.deleteEventPoller modname
forkEnds()
@db.storeEventPoller event1name, event1
@db.storeEventPoller event2name, event2
@db.getEventPollerIds ( err, obj ) =>
test.ok event1name in obj and event2name in obj,
'Not all event poller Ids in set'
@db.getEventPoller event1name, fCheckPoller event1name, event1
@db.getEventPoller event2name, fCheckPoller event2name, event2
exports.event_poller_params =
testCreateAndRead: ( test ) =>
test.expect 2
userId = 'tester1'
eventId = 'test-event-poller_1'
params = 'shouldn\'t this be an object?'
# store an entry to start with
@db.storeEventParams eventId, userId, params
# test that the ID shows up in the set
@db.getEventParamsIds ( err, obj ) =>
test.ok eventId+':'+userId in obj,
'Expected key not in event-params set'
# the retrieved object really is the one we expected
@db.getEventParams eventId, userId, ( err, obj ) =>
test.strictEqual obj, params,
'Retrieved event params is not what we expected'
@db.deleteEventParams eventId, userId
test.done()
testUpdate: ( test ) =>
test.expect 1
userId = 'tester1'
eventId = 'test-event-poller_1'
params = 'shouldn\'t this be an object?'
paramsNew = 'shouldn\'t this be a new object?'
# store an entry to start with
@db.storeEventParams eventId, userId, params
@db.storeEventParams eventId, userId, paramsNew
# the retrieved object really is the one we expected
@db.getEventParams eventId, userId, ( err, obj ) =>
test.strictEqual obj, paramsNew,
'Retrieved event params is not what we expected'
@db.deleteEventParams eventId, userId
test.done()
testDelete: ( test ) =>
test.expect 2
userId = 'tester1'
eventId = 'test-event-poller_1'
params = 'shouldn\'t this be an object?'
# store an entry to start with and delete it right away
@db.storeEventParams eventId, userId, params
@db.deleteEventParams eventId, userId
# Ensure the event params have been deleted
@db.getEventParams eventId, userId, ( err, obj ) =>
test.strictEqual obj, null,
'Event params still exists'
# Ensure the ID has been removed from the set
@db.getEventParamsIds ( err, obj ) =>
test.ok eventId+':'+userId not in obj,
'Event Params key still exists in set'
test.done()
exports.rules =
setUp: ( cb ) =>
@db logType: 1
@userId = 'tester-1'
@ruleId = 'test-rule_1'
@rule =
"id": "rule_id",
"event": "custom",
"condition":
"property": "yourValue",
"actions": []
@ruleNew =
"id": "rule_new",
"event": "custom",
"condition":
"property": "yourValue",
"actions": []
cb()
tearDown: ( cb ) =>
@db.deleteRule @ruleId
cb()
testCreateAndRead: ( test ) =>
test.expect 3
# store an entry to start with
@db.storeRule @ruleId, JSON.stringify(@rule)
# test that the ID shows up in the set
@db.getRuleIds ( err, obj ) =>
test.ok @ruleId in obj,
'Expected key not in rule key set'
# the retrieved object really is the one we expected
@db.getRule @ruleId, ( err, obj ) =>
test.deepEqual JSON.parse(obj), @rule,
'Retrieved rule is not what we expected'
# Ensure the rule is in the list of all existing ones
@db.getRules ( err , obj ) =>
test.deepEqual @rule, JSON.parse(obj[@ruleId]),
'Rule not in result set'
@db.deleteRule @ruleId
test.done()
testUpdate: ( test ) =>
test.expect 1
# store an entry to start with
@db.storeRule @ruleId, JSON.stringify(@rule)
@db.storeRule @ruleId, JSON.stringify(@ruleNew)
# the retrieved object really is the one we expected
@db.getRule @ruleId, ( err, obj ) =>
test.deepEqual JSON.parse(obj), @ruleNew,
'Retrieved rule is not what we expected'
@db.deleteRule @ruleId
test.done()
testDelete: ( test ) =>
test.expect 2
# store an entry to start with and delete it right away
@db.storeRule @ruleId, JSON.stringify(@rule)
@db.deleteRule @ruleId
# Ensure the event params have been deleted
@db.getRule @ruleId, ( err, obj ) =>
test.strictEqual obj, null,
'Rule still exists'
# Ensure the ID has been removed from the set
@db.getRuleIds ( err, obj ) =>
test.ok @ruleId not in obj,
'Rule key still exists in set'
test.done()
testLink: ( test ) =>
test.expect 2
# link a rule to the user
@db.linkRule @ruleId, @userId
# Ensure the user is linked to the rule
@db.getRuleLinkedUsers @ruleId, ( err, obj ) =>
test.ok @userId in obj,
"Rule not linked to user #{ @userId }"
# Ensure the rule is linked to the user
@db.getUserLinkedRules @userId, ( err, obj ) =>
test.ok @ruleId in obj,
"User not linked to rule #{ @ruleId }"
test.done()
testUnlink: ( test ) =>
test.expect 2
# link and unlink immediately afterwards
@db.linkRule @ruleId, @userId
@db.unlinkRule @ruleId, @userId
# Ensure the user is linked to the rule
@db.getRuleLinkedUsers @ruleId, ( err, obj ) =>
test.ok @userId not in obj,
"Rule still linked to user #{ @userId }"
# Ensure the rule is linked to the user
@db.getUserLinkedRules @userId, ( err, obj ) =>
test.ok @ruleId not in obj,
"User still linked to rule #{ @ruleId }"
test.done()
testActivate: ( test ) =>
test.expect 3
usr =
username: "tester-1"
password: "tester-1"
@db.storeUser usr
@db.activateRule @ruleId, @userId
# activate a rule for a user
# Ensure the user is activated to the rule
@db.getRuleActivatedUsers @ruleId, ( err, obj ) =>
test.ok @userId in obj,
"Rule not activated for user #{ @userId }"
# Ensure the rule is linked to the user
@db.getUserActivatedRules @userId, ( err, obj ) =>
test.ok @ruleId in obj,
"User not activated for rule #{ @ruleId }"
# 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.done()
testDeactivate: ( test ) =>
test.expect 3
# store an entry to start with and link it to te user
@db.activateRule @ruleId, @userId
@db.deactivateRule @ruleId, @userId
# Ensure the user is linked to the rule
@db.getRuleActivatedUsers @ruleId, ( err, obj ) =>
test.ok @userId not in obj,
"Rule still activated for user #{ @userId }"
# Ensure the rule is linked to the user
@db.getUserActivatedRules @userId, ( err, obj ) =>
test.ok @ruleId not in obj,
"User still activated for rule #{ @ruleId }"
# 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"
test.done()
testUnlinkAndDeactivateAfterDeletion: ( test ) =>
test.expect 2
# store an entry to start with and link it to te user
@db.storeRule @ruleId, JSON.stringify(@rule)
@db.linkRule @ruleId, @userId
@db.activateRule @ruleId, @userId
# We need to wait here and there since these calls are asynchronous
fWaitForTest = () =>
# Ensure the user is unlinked to the rule
@db.getUserLinkedRules @userId, ( err, obj ) =>
test.ok @ruleId not in obj,
"Rule #{ @ruleId } still linked to user #{ @userId }"
# Ensure the rule is deactivated for the user
@db.getUserActivatedRules @userId, ( err, obj ) =>
test.ok @ruleId not in obj,
"Rule #{ @ruleId } still activated for user #{ @userId }"
test.done()
fWaitForDeletion = () =>
@db.deleteRule @ruleId
setTimeout fWaitForTest, 100
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
exports.tearDown = ( cb ) =>

View file

@ -12,5 +12,6 @@
{{message}}
</p>
</div>
<div id="info"></div>
</body>
</html>

View file

@ -12,5 +12,6 @@
Error: {{message}}
</p>
</div>
<div id="info"></div>
</body>
</html>

View file

@ -73,6 +73,7 @@ exports.myOwnEventFunction = function( callback ) {
<button id="but_submit">save</button>
</p>
</div>
<div id="info"></div>
<script type="text/javascript">
$('#select_type').change(function(e) {

View file

@ -47,6 +47,7 @@
</form>
</p>
</div>
<div id="info"></div>
<script type="text/javascript">
$( "#form_rule" ).submit(function( event ) {

View file

@ -4,17 +4,17 @@
<div id="menubar_event">invoke events</div>
<div id="menubar_logout">logout</div>
<script>
$('#menubar_modules').click(function() {
$( '#menubar_modules' ).click( function() {
window.location.href = 'forge_modules';
});
$('#menubar_rules').click(function() {
$( '#menubar_rules' ).click( function() {
window.location.href = 'forge_rules';
});
$('#menubar_event').click(function() {
$( '#menubar_event' ).click( function() {
window.location.href = 'invoke_event';
});
$('#menubar_logout').click(function() {
$.post('/logout').done(function() {
$( '#menubar_logout' ).click( function() {
$.post( '/logout' ).done( function() {
window.location.href = document.URL;
});
});

View file

@ -0,0 +1,11 @@
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
<script type='text/javascript'>
var checkIncludes = function () {
if( window.$ === undefined ) {
document.getElementById('info').innerHTML = 'Not all required libraries have been loaded. Are you connected to the internet?';
}
};
window.addEventListener( "load" , checkIncludes, true );
</script>

View file

@ -2,9 +2,11 @@
<html>
<head>
<title>Login</title>
<link rel="stylesheet" type="text/css" href="style.css">
{{{head_requires}}}
<!-- <link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha3.js"></script>
-->
</head>
<body>
<div id="mainbody">
@ -15,9 +17,10 @@
</table>
<button id="but_submit">login</button>
</div>
<div id="info"></div>
<script>
$('#but_submit').click(function() {
var hashedPassword = (CryptoJS.SHA3($('#password').val(), { outputLength: 512 })).toString();
var hashedPassword = (CryptoJS.SHA3($('#password').val(), { outputLength: 512 })).toString();
$.post('/login', { username: $('#username').val(), password: hashedPassword })
.done(function(data) {
window.location.href = document.URL;

View file

@ -1,3 +0,0 @@
<link rel="stylesheet" type="text/css" href="style.css">
<script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script>

View file

@ -23,6 +23,7 @@
<button id="but_submit">invoke</button>
</p>
</div>
<div id="info"></div>
<script>
$('#but_submit').click(function() {

View file

@ -13,5 +13,6 @@
You only have these privileges: {{user.roles}}
</p>
</div>
<div id="info"></div>
</body>
</html>

View file

@ -13,5 +13,6 @@
Your roles are: {{user.roles}}
</p>
</div>
<div id="info"></div>
</body>
</html>

View file

@ -29,6 +29,14 @@ textarea {
cursor: pointer;
}
#info {
padding-left: 10px;
padding-top: 30px;
font-family: Tahoma, sans-serif;
font-size: 0.75em;
color: #F33;
}
#menubar div:hover {
background-color: #AAA;
}