mirror of
https://github.com/Hopiu/webapi-eca.git
synced 2026-03-16 22:10:31 +00:00
We are dirty again, replaced all indents with tabs, tried to fix all the lil things showing up as we test rule upload
This commit is contained in:
parent
f744d8d5f1
commit
18b36b84ac
45 changed files with 3771 additions and 3562 deletions
|
|
@ -31,10 +31,10 @@ Initializes the Components Manager and constructs a new Event Emitter.
|
|||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) =>
|
||||
@log = args.logger
|
||||
db args
|
||||
dynmod args
|
||||
module.exports
|
||||
@log = args.logger
|
||||
db args
|
||||
dynmod args
|
||||
module.exports
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -45,35 +45,35 @@ Add an event handler (eh) that listens for rules.
|
|||
###
|
||||
|
||||
exports.addRuleListener = ( eh ) =>
|
||||
eventEmitter.addListener 'rule', eh
|
||||
eventEmitter.addListener 'rule', eh
|
||||
|
||||
# Fetch all active rules per user
|
||||
db.getAllActivatedRuleIdsPerUser ( err, objUsers ) ->
|
||||
# Fetch all active rules per user
|
||||
db.getAllActivatedRuleIdsPerUser ( err, objUsers ) ->
|
||||
|
||||
# Go through all rules of each user
|
||||
fGoThroughUsers = ( user, rules ) ->
|
||||
# Go through all rules of each user
|
||||
fGoThroughUsers = ( user, rules ) ->
|
||||
|
||||
# Fetch the rules object for each rule in each user
|
||||
fFetchRule = ( userName ) ->
|
||||
( rule ) ->
|
||||
db.getRule rule, ( err, strRule ) =>
|
||||
try
|
||||
oRule = JSON.parse strRule
|
||||
db.resetLog userName, oRule.id
|
||||
db.appendLog userName, oRule.id, "INIT", "Rule '#{ oRule.id }' initialized"
|
||||
# Fetch the rules object for each rule in each user
|
||||
fFetchRule = ( userName ) ->
|
||||
( rule ) ->
|
||||
db.getRule rule, ( err, strRule ) =>
|
||||
try
|
||||
oRule = JSON.parse strRule
|
||||
db.resetLog userName, oRule.id
|
||||
db.appendLog userName, oRule.id, "INIT", "Rule '#{ oRule.id }' initialized"
|
||||
|
||||
eventEmitter.emit 'rule',
|
||||
event: 'init'
|
||||
user: userName
|
||||
rule: oRule
|
||||
catch err
|
||||
@log.warn "CM | There's an invalid rule in the system: #{ strRule }"
|
||||
eventEmitter.emit 'rule',
|
||||
event: 'init'
|
||||
user: userName
|
||||
rule: oRule
|
||||
catch err
|
||||
@log.warn "CM | There's an invalid rule in the system: #{ strRule }"
|
||||
|
||||
# Go through all rules for each user
|
||||
fFetchRule( user ) rule for rule in rules
|
||||
|
||||
# Go through each user
|
||||
fGoThroughUsers user, rules for user, rules of objUsers
|
||||
# Go through all rules for each user
|
||||
fFetchRule( user ) rule for rule in rules
|
||||
|
||||
# Go through each user
|
||||
fGoThroughUsers user, rules for user, rules of objUsers
|
||||
|
||||
###
|
||||
Processes a user request coming through the request-handler.
|
||||
|
|
@ -81,30 +81,30 @@ Processes a user request coming through the request-handler.
|
|||
- `user` is the user object as it comes from the DB.
|
||||
- `oReq` is the request object that contains:
|
||||
|
||||
- `command` as a string
|
||||
- `payload` an optional stringified JSON object
|
||||
- `command` as a string
|
||||
- `payload` an optional stringified JSON object
|
||||
The callback function `callback( obj )` will receive an object
|
||||
containing the HTTP response code and a corresponding message.
|
||||
|
||||
@public processRequest ( *user, oReq, callback* )
|
||||
###
|
||||
exports.processRequest = ( user, oReq, callback ) ->
|
||||
if not oReq.payload
|
||||
oReq.payload = '{}'
|
||||
try
|
||||
dat = JSON.parse oReq.payload
|
||||
catch err
|
||||
return callback
|
||||
code: 404
|
||||
message: 'You had a strange payload in your request!'
|
||||
if commandFunctions[oReq.command]
|
||||
if not oReq.payload
|
||||
oReq.payload = '{}'
|
||||
try
|
||||
dat = JSON.parse oReq.payload
|
||||
catch err
|
||||
return callback
|
||||
code: 404
|
||||
message: 'You had a strange payload in your request!'
|
||||
if commandFunctions[oReq.command]
|
||||
|
||||
# If the command function was registered we invoke it
|
||||
commandFunctions[oReq.command] user, dat, callback
|
||||
else
|
||||
callback
|
||||
code: 404
|
||||
message: 'What do you want from me?'
|
||||
# If the command function was registered we invoke it
|
||||
commandFunctions[oReq.command] user, dat, callback
|
||||
else
|
||||
callback
|
||||
code: 404
|
||||
message: 'What do you want from me?'
|
||||
|
||||
###
|
||||
Checks whether all required parameters are present in the payload.
|
||||
|
|
@ -114,13 +114,13 @@ Checks whether all required parameters are present in the payload.
|
|||
@param {Object} oPayload
|
||||
###
|
||||
hasRequiredParams = ( arrParams, oPayload ) ->
|
||||
answ =
|
||||
code: 400
|
||||
message: "Your request didn't contain all necessary fields! Requires: #{ arrParams.join() }"
|
||||
return answ for param in arrParams when not oPayload[param]
|
||||
answ.code = 200
|
||||
answ.message = 'All required properties found'
|
||||
answ
|
||||
answ =
|
||||
code: 400
|
||||
message: "Your request didn't contain all necessary fields! Requires: #{ arrParams.join() }"
|
||||
return answ for param in arrParams when not oPayload[param]
|
||||
answ.code = 200
|
||||
answ.message = 'All required properties found'
|
||||
answ
|
||||
|
||||
###
|
||||
Fetches all available modules and return them together with the available functions.
|
||||
|
|
@ -132,211 +132,225 @@ Fetches all available modules and return them together with the available functi
|
|||
@param {function} callback
|
||||
###
|
||||
getModules = ( user, oPayload, dbMod, callback ) ->
|
||||
dbMod.getAvailableModuleIds user.username, ( err, arrNames ) ->
|
||||
oRes = {}
|
||||
answReq = () ->
|
||||
callback
|
||||
code: 200
|
||||
message: JSON.stringify oRes
|
||||
sem = arrNames.length
|
||||
if sem is 0
|
||||
answReq()
|
||||
else
|
||||
fGetFunctions = ( id ) =>
|
||||
dbMod.getModule id, ( err, oModule ) =>
|
||||
if oModule
|
||||
oRes[id] = JSON.parse oModule.functions
|
||||
if --sem is 0
|
||||
answReq()
|
||||
fGetFunctions id for id in arrNames
|
||||
dbMod.getAvailableModuleIds user.username, ( err, arrNames ) ->
|
||||
oRes = {}
|
||||
answReq = () ->
|
||||
callback
|
||||
code: 200
|
||||
message: JSON.stringify oRes
|
||||
sem = arrNames.length
|
||||
if sem is 0
|
||||
answReq()
|
||||
else
|
||||
fGetFunctions = ( id ) =>
|
||||
dbMod.getModule id, ( err, oModule ) =>
|
||||
if oModule
|
||||
oRes[id] = JSON.parse oModule.functions
|
||||
if --sem is 0
|
||||
answReq()
|
||||
fGetFunctions id for id in arrNames
|
||||
|
||||
getModuleParams = ( user, oPayload, dbMod, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
dbMod.getModuleParams oPayload.id, ( err, oPayload ) ->
|
||||
answ.message = oPayload
|
||||
callback answ
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
dbMod.getModuleParams oPayload.id, ( err, oPayload ) ->
|
||||
answ.message = oPayload
|
||||
callback answ
|
||||
|
||||
|
||||
forgeModule = ( user, oPayload, dbMod, callback ) =>
|
||||
answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
i = 0
|
||||
dbMod.getModule oPayload.id, ( err, mod ) =>
|
||||
if mod
|
||||
answ.code = 409
|
||||
answ.message = 'Module name already existing: ' + oPayload.id
|
||||
callback answ
|
||||
else
|
||||
src = oPayload.data
|
||||
dynmod.compileString src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, ( cm ) =>
|
||||
answ = cm.answ
|
||||
if answ.code is 200
|
||||
funcs = []
|
||||
funcs.push name for name, id of cm.module
|
||||
@log.info "CM | Storing new module with functions #{ funcs.join( ', ' ) }"
|
||||
answ.message =
|
||||
" Module #{ oPayload.id } successfully stored! Found following function(s): #{ funcs }"
|
||||
oPayload.functions = JSON.stringify funcs
|
||||
oPayload.functionParameters = JSON.stringify cm.funcParams
|
||||
dbMod.storeModule user.username, oPayload
|
||||
if oPayload.public is 'true'
|
||||
dbMod.publish oPayload.id
|
||||
callback answ
|
||||
answ = hasRequiredParams [ 'id', 'params', 'lang', 'data' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
i = 0
|
||||
dbMod.getModule oPayload.id, ( err, mod ) =>
|
||||
if mod
|
||||
answ.code = 409
|
||||
answ.message = 'Module name already existing: ' + oPayload.id
|
||||
callback answ
|
||||
else
|
||||
src = oPayload.data
|
||||
dynmod.compileString src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, ( cm ) =>
|
||||
console.log cm
|
||||
answ = cm.answ
|
||||
if answ.code is 200
|
||||
funcs = []
|
||||
funcs.push name for name, id of cm.module
|
||||
@log.info "CM | Storing new module with functions #{ funcs.join( ', ' ) }"
|
||||
answ.message =
|
||||
" Module #{ oPayload.id } successfully stored! Found following function(s): #{ funcs }"
|
||||
oPayload.functions = JSON.stringify funcs
|
||||
oPayload.functionArgs = JSON.stringify cm.funcParams
|
||||
dbMod.storeModule user.username, oPayload
|
||||
if oPayload.public is 'true'
|
||||
dbMod.publish oPayload.id
|
||||
callback answ
|
||||
|
||||
commandFunctions =
|
||||
get_public_key: ( user, oPayload, callback ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: dynmod.getPublicKey()
|
||||
get_public_key: ( user, oPayload, callback ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: dynmod.getPublicKey()
|
||||
|
||||
# EVENT POLLERS
|
||||
# -------------
|
||||
get_event_pollers: ( user, oPayload, callback ) ->
|
||||
getModules user, oPayload, db.eventPollers, callback
|
||||
|
||||
get_full_event_poller: ( user, oPayload, callback ) ->
|
||||
db.eventPollers.getModule oPayload.id, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: JSON.stringify obj
|
||||
|
||||
get_event_poller_params: ( user, oPayload, callback ) ->
|
||||
getModuleParams user, oPayload, db.eventPollers, callback
|
||||
get_event_pollers: ( user, oPayload, callback ) ->
|
||||
getModules user, oPayload, db.eventPollers, callback
|
||||
|
||||
get_full_event_poller: ( user, oPayload, callback ) ->
|
||||
db.eventPollers.getModule oPayload.id, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: JSON.stringify obj
|
||||
|
||||
get_event_poller_params: ( user, oPayload, callback ) ->
|
||||
getModuleParams user, oPayload, db.eventPollers, callback
|
||||
|
||||
forge_event_poller: ( user, oPayload, callback ) ->
|
||||
forgeModule user, oPayload, db.eventPollers, callback
|
||||
forge_event_poller: ( user, oPayload, callback ) ->
|
||||
forgeModule user, oPayload, db.eventPollers, callback
|
||||
|
||||
delete_event_poller: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.eventPollers.deleteModule oPayload.id
|
||||
callback
|
||||
code: 200
|
||||
message: 'OK!'
|
||||
delete_event_poller: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.eventPollers.deleteModule oPayload.id
|
||||
callback
|
||||
code: 200
|
||||
message: 'OK!'
|
||||
|
||||
# ACTION INVOKERS
|
||||
# ---------------
|
||||
get_action_invokers: ( user, oPayload, callback ) ->
|
||||
getModules user, oPayload, db.actionInvokers, callback
|
||||
|
||||
get_full_action_invoker: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.actionInvokers.getModule oPayload.id, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: JSON.stringify obj
|
||||
get_action_invokers: ( user, oPayload, callback ) ->
|
||||
getModules user, oPayload, db.actionInvokers, callback
|
||||
|
||||
get_full_action_invoker: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.actionInvokers.getModule oPayload.id, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: JSON.stringify obj
|
||||
|
||||
get_action_invoker_params: ( user, oPayload, callback ) ->
|
||||
getModuleParams user, oPayload, db.actionInvokers, callback
|
||||
get_action_invoker_params: ( user, oPayload, callback ) ->
|
||||
getModuleParams user, oPayload, db.actionInvokers, callback
|
||||
|
||||
get_action_invoker_function_params: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.actionInvokers.getModuleField oPayload.id, 'functionParameters', ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: obj
|
||||
|
||||
forge_action_invoker: ( user, oPayload, callback ) ->
|
||||
forgeModule user, oPayload, db.actionInvokers, callback
|
||||
get_action_invoker_function_params: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.actionInvokers.getModuleField oPayload.id, 'functionArgs', ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: obj
|
||||
|
||||
forge_action_invoker: ( user, oPayload, callback ) ->
|
||||
forgeModule user, oPayload, db.actionInvokers, callback
|
||||
|
||||
delete_action_invoker: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.actionInvokers.deleteModule oPayload.id
|
||||
callback
|
||||
code: 200
|
||||
message: 'OK!'
|
||||
delete_action_invoker: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.actionInvokers.deleteModule oPayload.id
|
||||
callback
|
||||
code: 200
|
||||
message: 'OK!'
|
||||
|
||||
# RULES
|
||||
# -----
|
||||
get_rules: ( user, oPayload, callback ) ->
|
||||
db.getUserLinkedRules user.username, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: obj
|
||||
get_rules: ( user, oPayload, callback ) ->
|
||||
db.getUserLinkedRules user.username, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: obj
|
||||
|
||||
get_rule_log: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.getLog user.username, oPayload.id, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: obj
|
||||
get_rule_log: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.getLog user.username, oPayload.id, ( err, obj ) ->
|
||||
callback
|
||||
code: 200
|
||||
message: obj
|
||||
|
||||
# A rule needs to be in following format:
|
||||
|
||||
# - id
|
||||
# - event
|
||||
# - conditions
|
||||
# - actions
|
||||
forge_rule: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id', 'event', 'conditions', 'actions' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.getRule oPayload.id, ( err, oExisting ) ->
|
||||
if oExisting isnt null
|
||||
answ =
|
||||
code: 409
|
||||
message: 'Rule name already existing!'
|
||||
else
|
||||
rule =
|
||||
id: oPayload.id
|
||||
event: oPayload.event
|
||||
conditions: oPayload.conditions
|
||||
actions: oPayload.actions
|
||||
strRule = JSON.stringify rule
|
||||
db.storeRule rule.id, strRule
|
||||
db.linkRule rule.id, user.username
|
||||
db.activateRule rule.id, user.username
|
||||
if oPayload.event_params
|
||||
epModId = rule.event.split( ' -> ' )[0]
|
||||
db.eventPollers.storeUserParams epModId, user.username, oPayload.event_params
|
||||
oParams = oPayload.action_params
|
||||
db.actionInvokers.storeUserParams id, user.username, JSON.stringify params for id, params of oParams
|
||||
oParams = oPayload.action_functions
|
||||
for id, params of oParams
|
||||
arr = id.split ' -> '
|
||||
db.actionInvokers.storeUserArguments arr[ 0 ], arr[ 1 ], user.username, JSON.stringify params
|
||||
db.resetLog user.username, rule.id
|
||||
db.appendLog user.username, rule.id, "INIT", "Rule '#{ rule.id }' initialized"
|
||||
eventEmitter.emit 'rule',
|
||||
event: 'new'
|
||||
user: user.username
|
||||
rule: rule
|
||||
answ =
|
||||
code: 200
|
||||
message: "Rule '#{ rule.id }' stored and activated!"
|
||||
callback answ
|
||||
# A rule needs to be in following format:
|
||||
|
||||
# - id
|
||||
# - event
|
||||
# - conditions
|
||||
# - actions
|
||||
forge_rule: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id', 'event', 'conditions', 'actions' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.getRule oPayload.id, ( err, oExisting ) ->
|
||||
if oExisting isnt null
|
||||
answ =
|
||||
code: 409
|
||||
message: 'Rule name already existing!'
|
||||
else
|
||||
# This is how a rule is stored in the database
|
||||
rule =
|
||||
id: oPayload.id
|
||||
event: oPayload.event
|
||||
event_interval: oPayload.event_interval
|
||||
conditions: oPayload.conditions
|
||||
actions: oPayload.actions
|
||||
strRule = JSON.stringify rule
|
||||
# store the rule
|
||||
db.storeRule rule.id, strRule
|
||||
# link the rule to the user
|
||||
db.linkRule rule.id, user.username
|
||||
# activate the rule
|
||||
db.activateRule rule.id, user.username
|
||||
# if event module parameters were send, store them
|
||||
if oPayload.event_params
|
||||
epModId = rule.event.split( ' -> ' )[0]
|
||||
db.eventPollers.storeUserParams epModId, user.username, oPayload.event_params
|
||||
|
||||
# if action module params were send, store them
|
||||
oParams = oPayload.action_params
|
||||
db.actionInvokers.storeUserParams id, user.username, JSON.stringify params for id, params of oParams
|
||||
oParams = oPayload.action_functions
|
||||
# if action function arguments were send, store them
|
||||
for id, params of oParams
|
||||
arr = id.split ' -> '
|
||||
db.actionInvokers.storeUserArguments arr[ 0 ], arr[ 1 ], user.username, JSON.stringify params
|
||||
|
||||
# Initialize the rule log
|
||||
db.resetLog user.username, rule.id
|
||||
db.appendLog user.username, rule.id, "INIT", "Rule '#{ rule.id }' initialized"
|
||||
|
||||
# Inform everbody about the new rule
|
||||
eventEmitter.emit 'rule',
|
||||
event: 'new'
|
||||
user: user.username
|
||||
rule: rule
|
||||
answ =
|
||||
code: 200
|
||||
message: "Rule '#{ rule.id }' stored and activated!"
|
||||
callback answ
|
||||
|
||||
delete_rule: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.deleteRule oPayload.id
|
||||
eventEmitter.emit 'rule',
|
||||
event: 'del'
|
||||
user: user.username
|
||||
rule: null
|
||||
ruleId: oPayload.id
|
||||
callback
|
||||
code: 200
|
||||
message: 'OK!'
|
||||
delete_rule: ( user, oPayload, callback ) ->
|
||||
answ = hasRequiredParams [ 'id' ], oPayload
|
||||
if answ.code isnt 200
|
||||
callback answ
|
||||
else
|
||||
db.deleteRule oPayload.id
|
||||
eventEmitter.emit 'rule',
|
||||
event: 'del'
|
||||
user: user.username
|
||||
rule: null
|
||||
ruleId: oPayload.id
|
||||
callback
|
||||
code: 200
|
||||
message: 'OK!'
|
||||
|
|
|
|||
|
|
@ -24,14 +24,14 @@ be generated) and configPath for a custom configuration file path.
|
|||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) =>
|
||||
args = args ? {}
|
||||
if args.nolog
|
||||
@nolog = true
|
||||
if args.configPath
|
||||
loadConfigFile args.configPath
|
||||
else
|
||||
loadConfigFile path.join 'config', 'system.json'
|
||||
module.exports
|
||||
args = args ? {}
|
||||
if args.nolog
|
||||
@nolog = true
|
||||
if args.configPath
|
||||
loadConfigFile args.configPath
|
||||
else
|
||||
loadConfigFile path.join 'config', 'system.json'
|
||||
module.exports
|
||||
|
||||
###
|
||||
Tries to load a configuration file from the path relative to this module's parent folder.
|
||||
|
|
@ -41,26 +41,26 @@ Reads the config file synchronously from the file system and try to parse it.
|
|||
@param {String} configPath
|
||||
###
|
||||
loadConfigFile = ( configPath ) =>
|
||||
@config = null
|
||||
confProperties = [
|
||||
'log'
|
||||
'http-port'
|
||||
'db-port'
|
||||
]
|
||||
try
|
||||
@config = JSON.parse fs.readFileSync path.resolve __dirname, '..', configPath
|
||||
@isReady = true
|
||||
for prop in confProperties
|
||||
if !@config[prop]
|
||||
@isReady = false
|
||||
if not @isReady and not @nolog
|
||||
console.error "Missing property in config file, requires:\n" +
|
||||
" - #{ confProperties.join "\n - " }"
|
||||
catch e
|
||||
@isReady = false
|
||||
if not @nolog
|
||||
console.error "Failed loading config file: #{ e.message }"
|
||||
|
||||
@config = null
|
||||
confProperties = [
|
||||
'log'
|
||||
'http-port'
|
||||
'db-port'
|
||||
]
|
||||
try
|
||||
@config = JSON.parse fs.readFileSync path.resolve __dirname, '..', configPath
|
||||
@isReady = true
|
||||
for prop in confProperties
|
||||
if !@config[prop]
|
||||
@isReady = false
|
||||
if not @isReady and not @nolog
|
||||
console.error "Missing property in config file, requires:\n" +
|
||||
" - #{ confProperties.join "\n - " }"
|
||||
catch e
|
||||
@isReady = false
|
||||
if not @nolog
|
||||
console.error "Failed loading config file: #{ e.message }"
|
||||
|
||||
|
||||
###
|
||||
Fetch a property from the configuration
|
||||
|
|
@ -68,7 +68,7 @@ Fetch a property from the configuration
|
|||
@private fetchProp( *prop* )
|
||||
@param {String} prop
|
||||
###
|
||||
fetchProp = ( prop ) => @config?[prop]
|
||||
exports.fetchProp = ( prop ) => @config?[prop]
|
||||
|
||||
###
|
||||
***Returns*** true if the config file is ready, else false
|
||||
|
|
@ -82,25 +82,25 @@ exports.isReady = => @isReady
|
|||
|
||||
@public getHttpPort()
|
||||
###
|
||||
exports.getHttpPort = -> fetchProp 'http-port'
|
||||
exports.getHttpPort = -> exports.fetchProp 'http-port'
|
||||
|
||||
###
|
||||
***Returns*** the DB port*
|
||||
|
||||
@public getDBPort()
|
||||
###
|
||||
exports.getDbPort = -> fetchProp 'db-port'
|
||||
exports.getDbPort = -> exports.fetchProp 'db-port'
|
||||
|
||||
###
|
||||
***Returns*** the log conf object
|
||||
|
||||
@public getLogConf()
|
||||
###
|
||||
exports.getLogConf = -> fetchProp 'log'
|
||||
exports.getLogConf = -> exports.fetchProp 'log'
|
||||
|
||||
###
|
||||
***Returns*** the crypto key
|
||||
|
||||
@public getCryptoKey()
|
||||
###
|
||||
exports.getKeygenPassphrase = -> fetchProp 'keygen-passphrase'
|
||||
exports.getKeygenPassphrase = -> exports.fetchProp 'keygen-passphrase'
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@ needle = require 'needle'
|
|||
request = require 'request'
|
||||
|
||||
# - External Modules: [coffee-script](http://coffeescript.org/),
|
||||
# [cryptico](https://github.com/wwwtyro/cryptico)
|
||||
# [cryptico](https://github.com/wwwtyro/cryptico),
|
||||
# [crypto-js](https://www.npmjs.org/package/crypto-js) and
|
||||
# [import-io](https://www.npmjs.org/package/import-io)
|
||||
cs = require 'coffee-script'
|
||||
cryptico = require 'my-cryptico'
|
||||
cryptoJS = require 'crypto-js'
|
||||
importio = require( 'import-io' ).client
|
||||
|
||||
|
||||
|
||||
|
|
@ -33,34 +36,33 @@ Initializes the dynamic module handler.
|
|||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) =>
|
||||
@log = args.logger
|
||||
# FIXME this can't come through the arguments
|
||||
if not @strPublicKey and args[ 'keygen' ]
|
||||
db args
|
||||
passPhrase = args[ 'keygen' ]
|
||||
numBits = 1024
|
||||
@oPrivateRSAkey = cryptico.generateRSAKey passPhrase, numBits
|
||||
@strPublicKey = cryptico.publicKeyString @oPrivateRSAkey
|
||||
@log.info "DM | Public Key generated: #{ @strPublicKey }"
|
||||
@log = args.logger
|
||||
# FIXME this can't come through the arguments
|
||||
if not @strPublicKey and args[ 'keygen' ]
|
||||
db args
|
||||
passPhrase = args[ 'keygen' ]
|
||||
numBits = 1024
|
||||
@oPrivateRSAkey = cryptico.generateRSAKey passPhrase, numBits
|
||||
@strPublicKey = cryptico.publicKeyString @oPrivateRSAkey
|
||||
@log.info "DM | Public Key generated: #{ @strPublicKey }"
|
||||
|
||||
module.exports
|
||||
module.exports
|
||||
|
||||
|
||||
exports.getPublicKey = () =>
|
||||
@strPublicKey
|
||||
@strPublicKey
|
||||
|
||||
logFunction = ( uId, rId, mId ) ->
|
||||
( msg ) ->
|
||||
db.appendLog uId, rId, mId, msg
|
||||
( msg ) ->
|
||||
db.appendLog uId, rId, mId, msg
|
||||
|
||||
regexpComments = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
|
||||
getFunctionParamNames = ( fName, func, oFuncs ) ->
|
||||
fnStr = func.toString().replace regexpComments, ''
|
||||
result = fnStr.slice( fnStr.indexOf( '(' ) + 1, fnStr.indexOf( ')' ) ).match /([^\s,]+)/g
|
||||
if not result
|
||||
result = []
|
||||
oFuncs[fName] = result
|
||||
|
||||
fnStr = func.toString().replace regexpComments, ''
|
||||
result = fnStr.slice( fnStr.indexOf( '(' ) + 1, fnStr.indexOf( ')' ) ).match /([^\s,]+)/g
|
||||
if not result
|
||||
result = []
|
||||
oFuncs[fName] = result
|
||||
|
||||
###
|
||||
Try to run a JS module from a string, together with the
|
||||
|
|
@ -74,86 +76,101 @@ compile it first into JS.
|
|||
@param {String} lang
|
||||
###
|
||||
exports.compileString = ( src, userId, ruleId, modId, lang, dbMod, cb ) =>
|
||||
answ =
|
||||
code: 200
|
||||
message: 'Successfully compiled'
|
||||
if lang is 'CoffeeScript'
|
||||
try
|
||||
@log.info "DM | Compiling module '#{ modId }' for user '#{ userId }'"
|
||||
src = cs.compile src
|
||||
catch err
|
||||
cb
|
||||
code: 400
|
||||
message: 'Compilation of CoffeeScript failed at line ' +
|
||||
err.location.first_line
|
||||
return
|
||||
|
||||
if lang is 'CoffeeScript'
|
||||
try
|
||||
src = cs.compile src
|
||||
catch err
|
||||
answ.code = 400
|
||||
answ.message = 'Compilation of CoffeeScript failed at line ' +
|
||||
err.location.first_line
|
||||
|
||||
fTryToLoad = ( params ) =>
|
||||
if params
|
||||
try
|
||||
oDecrypted = cryptico.decrypt params, @oPrivateRSAkey
|
||||
params = JSON.parse oDecrypted.plaintext
|
||||
catch err
|
||||
@log.warn "DM | Error during parsing of user defined params for #{ userId }, #{ ruleId }, #{ modId }"
|
||||
@log.warn err
|
||||
params = {}
|
||||
else
|
||||
params = {}
|
||||
@log.info "DM | Trying to fetch user specific module '#{ modId }' paramters for user '#{ userId }'"
|
||||
# dbMod is only attached if the module really gets loaded and needs to fetch user information from the database
|
||||
if dbMod
|
||||
dbMod.getUserParams modId, userId, ( err, obj ) =>
|
||||
try
|
||||
oDecrypted = cryptico.decrypt obj, @oPrivateRSAkey
|
||||
obj = JSON.parse oDecrypted.plaintext
|
||||
@log.warn "DM | Loaded user defined params for #{ userId }, #{ ruleId }, #{ modId }"
|
||||
catch err
|
||||
@log.warn "DM | Error during parsing of user defined params for #{ userId }, #{ ruleId }, #{ modId }"
|
||||
@log.warn err
|
||||
fTryToLoadModule userId, ruleId, modId, src, dbMod, obj, cb
|
||||
else
|
||||
fTryToLoadModule userId, ruleId, modId, src, dbMod, null, cb
|
||||
|
||||
|
||||
logFunc = logFunction userId, ruleId, modId
|
||||
sandbox =
|
||||
id: userId + '.' + modId + '.vm'
|
||||
params: params
|
||||
needle: needle
|
||||
request: request
|
||||
cryptoJS: cryptoJS
|
||||
log: logFunc
|
||||
debug: console.log
|
||||
exports: {}
|
||||
fTryToLoadModule = ( userId, ruleId, modId, src, dbMod, params, cb ) =>
|
||||
if not params
|
||||
params = {}
|
||||
|
||||
#TODO child_process to run module!
|
||||
#Define max runtime per loop as 10 seconds, after that the child will be killed
|
||||
#it can still be active after that if there was a timing function or a callback used...
|
||||
#kill the child each time? how to determine whether there's still a token in the module?
|
||||
try
|
||||
vm.runInNewContext src, sandbox, sandbox.id
|
||||
# TODO We should investigate memory usage and garbage collection (global.gc())?
|
||||
# Start Node with the flags —nouse_idle_notification and —expose_gc, and then when you want to run the GC, just call global.gc().
|
||||
catch err
|
||||
answ.code = 400
|
||||
msg = err.message
|
||||
if not msg
|
||||
msg = 'Try to run the script locally to track the error! Sadly we cannot provide the line number'
|
||||
answ.message = 'Loading Module failed: ' + msg
|
||||
oFuncParams = {}
|
||||
for fName, func of sandbox.exports
|
||||
getFunctionParamNames fName, func, oFuncParams
|
||||
answ =
|
||||
code: 200
|
||||
message: 'Successfully compiled'
|
||||
|
||||
if dbMod
|
||||
oFuncArgs = {}
|
||||
console.log 'oFuncParams'
|
||||
console.log oFuncParams
|
||||
@log.info "DM | Running module '#{ modId }' for user '#{ userId }'"
|
||||
# The function used to provide logging mechanisms on a per rule basis
|
||||
logFunc = logFunction userId, ruleId, modId
|
||||
# The sandbox contains the objects that are accessible to the user. Eventually they need to be required from a vm themselves
|
||||
sandbox =
|
||||
id: "#{ userId }.#{ ruleId }.#{ modId }.vm"
|
||||
params: params
|
||||
needle: needle
|
||||
importio: importio
|
||||
request: request
|
||||
cryptoJS: cryptoJS
|
||||
log: logFunc
|
||||
debug: console.log
|
||||
exports: {}
|
||||
|
||||
for func of oFuncParams
|
||||
console.log 'fetching ' + func
|
||||
console.log typeof func
|
||||
dbMod.getUserArguments modId, func, userId, ( err, obj ) =>
|
||||
console.log err, obj
|
||||
try
|
||||
oDecrypted = cryptico.decrypt obj, @oPrivateRSAkey
|
||||
oFuncArgs[ func ] = JSON.parse oDecrypted.plaintext
|
||||
catch err
|
||||
@log.warn "DM | Error during parsing of user defined params for #{ userId }, #{ ruleId }, #{ modId }"
|
||||
@log.warn err
|
||||
cb
|
||||
answ: answ
|
||||
module: sandbox.exports
|
||||
funcParams: oFuncParams
|
||||
funcArgs: oFuncArgs
|
||||
logger: sandbox.log
|
||||
#TODO child_process to run module!
|
||||
#Define max runtime per function call as 10 seconds, after that the child will be killed
|
||||
#it can still be active after that if there was a timing function or a callback used...
|
||||
#kill the child each time? how to determine whether there's still a token in the module?
|
||||
try
|
||||
# Finally the module is run in a
|
||||
vm.runInNewContext src, sandbox, sandbox.id
|
||||
# TODO We should investigate memory usage and garbage collection (global.gc())?
|
||||
# Start Node with the flags —nouse_idle_notification and —expose_gc, and then when you want to run the GC, just call global.gc().
|
||||
catch err
|
||||
answ.code = 400
|
||||
msg = err.message
|
||||
if not msg
|
||||
msg = 'Try to run the script locally to track the error! Sadly we cannot provide the line number'
|
||||
answ.message = 'Loading Module failed: ' + msg
|
||||
|
||||
if dbMod
|
||||
dbMod.getUserParams modId, userId, ( err, obj ) ->
|
||||
fTryToLoad obj
|
||||
else
|
||||
fTryToLoad null
|
||||
@log.info "DM | Module '#{ modId }' ran successfully for user '#{ userId }' in rule '#{ ruleId }'"
|
||||
oFuncParams = {}
|
||||
oFuncArgs = {}
|
||||
for fName, func of sandbox.exports
|
||||
getFunctionParamNames fName, func, oFuncParams
|
||||
|
||||
if dbMod
|
||||
oFuncArgs = {}
|
||||
console.log 'oFuncParams'
|
||||
console.log oFuncParams
|
||||
|
||||
for func of oFuncParams
|
||||
console.log 'fetching ' + func
|
||||
console.log typeof func
|
||||
dbMod.getUserArguments modId, func, userId, ( err, obj ) =>
|
||||
console.log err, obj
|
||||
try
|
||||
oDecrypted = cryptico.decrypt obj, @oPrivateRSAkey
|
||||
oFuncArgs[ func ] = JSON.parse oDecrypted.plaintext
|
||||
catch err
|
||||
@log.warn "DM | Error during parsing of user defined params for #{ userId }, #{ ruleId }, #{ modId }"
|
||||
@log.warn err
|
||||
|
||||
console.log 'answering compile request string'
|
||||
console.log cb
|
||||
|
||||
cb
|
||||
answ: answ
|
||||
module: sandbox.exports
|
||||
funcParams: oFuncParams
|
||||
funcArgs: oFuncArgs
|
||||
logger: sandbox.log
|
||||
|
|
|
|||
|
|
@ -23,21 +23,21 @@ jsonQuery = require 'js-select'
|
|||
This is ging to have a structure like:
|
||||
An object of users with their active rules and the required action modules
|
||||
|
||||
"user-1":
|
||||
"rule-1":
|
||||
"rule": oRule-1
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"action-2": oAction-2
|
||||
"rule-2":
|
||||
"rule": oRule-2
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"user-2":
|
||||
"rule-3":
|
||||
"rule": oRule-3
|
||||
"actions":
|
||||
"action-3": oAction-3
|
||||
"user-1":
|
||||
"rule-1":
|
||||
"rule": oRule-1
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"action-2": oAction-2
|
||||
"rule-2":
|
||||
"rule": oRule-2
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"user-2":
|
||||
"rule-3":
|
||||
"rule": oRule-3
|
||||
"actions":
|
||||
"action-3": oAction-3
|
||||
###
|
||||
|
||||
#TODO how often do we allow rules to be processed?
|
||||
|
|
@ -55,12 +55,12 @@ Initializes the Engine and starts polling the event queue for new events.
|
|||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) =>
|
||||
if not isRunning
|
||||
@log = args.logger
|
||||
db args
|
||||
dynmod args
|
||||
setTimeout exports.startEngine, 10 # Very important, this forks a token for the poll task
|
||||
module.exports
|
||||
if not isRunning
|
||||
@log = args.logger
|
||||
db args
|
||||
dynmod args
|
||||
setTimeout exports.startEngine, 10 # Very important, this forks a token for the poll task
|
||||
module.exports
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -72,13 +72,13 @@ modules are loaded correctly
|
|||
#TODO we should change this to functions returning true or false rather than returning
|
||||
#the whole list
|
||||
exports.getListUserRules = () ->
|
||||
listUserRules
|
||||
listUserRules
|
||||
|
||||
# We need this so we can shut it down after the module unit tests
|
||||
exports.startEngine = () ->
|
||||
if not isRunning
|
||||
isRunning = true
|
||||
pollQueue()
|
||||
if not isRunning
|
||||
isRunning = true
|
||||
pollQueue()
|
||||
|
||||
###
|
||||
An event associated to rules happened and is captured here. Such events
|
||||
|
|
@ -88,23 +88,23 @@ are basically CRUD on rules.
|
|||
@param {Object} evt
|
||||
###
|
||||
exports.internalEvent = ( evt ) =>
|
||||
if not listUserRules[evt.user] and evt.event isnt 'del'
|
||||
listUserRules[evt.user] = {}
|
||||
if not listUserRules[evt.user] and evt.event isnt 'del'
|
||||
listUserRules[evt.user] = {}
|
||||
|
||||
oUser = listUserRules[evt.user]
|
||||
oRule = evt.rule
|
||||
if evt.event is 'new' or ( evt.event is 'init' and not oUser[oRule.id] )
|
||||
oUser[oRule.id] =
|
||||
rule: oRule
|
||||
actions: {}
|
||||
updateActionModules oRule.id
|
||||
oUser = listUserRules[evt.user]
|
||||
oRule = evt.rule
|
||||
if evt.event is 'new' or ( evt.event is 'init' and not oUser[oRule.id] )
|
||||
oUser[oRule.id] =
|
||||
rule: oRule
|
||||
actions: {}
|
||||
updateActionModules oRule.id
|
||||
|
||||
if evt.event is 'del' and oUser
|
||||
delete oUser[evt.ruleId]
|
||||
if evt.event is 'del' and oUser
|
||||
delete oUser[evt.ruleId]
|
||||
|
||||
# If a user is empty after all the updates above, we remove her from the list
|
||||
if JSON.stringify( oUser ) is "{}"
|
||||
delete listUserRules[evt.user]
|
||||
# If a user is empty after all the updates above, we remove her from the list
|
||||
if JSON.stringify( oUser ) is "{}"
|
||||
delete listUserRules[evt.user]
|
||||
|
||||
|
||||
|
||||
|
|
@ -115,65 +115,67 @@ invoker modules are loaded, updated or deleted.
|
|||
@private updateActionModules ( *updatedRuleId* )
|
||||
@param {Object} updatedRuleId
|
||||
###
|
||||
updateActionModules = ( updatedRuleId ) ->
|
||||
|
||||
# Remove all action invoker modules that are not required anymore
|
||||
fRemoveNotRequired = ( oUser ) ->
|
||||
updateActionModules = ( updatedRuleId ) =>
|
||||
|
||||
# Remove all action invoker modules that are not required anymore
|
||||
fRemoveNotRequired = ( oUser ) ->
|
||||
|
||||
# Check whether the action is still existing in the rule
|
||||
fRequired = ( actionName ) ->
|
||||
for action in oUser[updatedRuleId].rule.actions
|
||||
# Since the event is in the format 'module -> function' we need to split the string
|
||||
if (action.split ' -> ')[0] is actionName
|
||||
return true
|
||||
false
|
||||
# Check whether the action is still existing in the rule
|
||||
fRequired = ( actionName ) ->
|
||||
for action in oUser[updatedRuleId].rule.actions
|
||||
# Since the event is in the format 'module -> function' we need to split the string
|
||||
if (action.split ' -> ')[0] is actionName
|
||||
return true
|
||||
false
|
||||
|
||||
# Go thorugh all loaded action modules and check whether the action is still required
|
||||
for action of oUser[updatedRuleId].rule.actions
|
||||
delete oUser[updatedRuleId].actions[action] if not fRequired action
|
||||
# Go thorugh all loaded action modules and check whether the action is still required
|
||||
for action of oUser[updatedRuleId].rule.actions
|
||||
delete oUser[updatedRuleId].actions[action] if not fRequired action
|
||||
|
||||
fRemoveNotRequired oUser for name, oUser of listUserRules
|
||||
fRemoveNotRequired oUser for name, oUser of listUserRules
|
||||
|
||||
# Add action invoker modules that are not yet loaded
|
||||
fAddRequired = ( userName, oUser ) ->
|
||||
# Add action invoker modules that are not yet loaded
|
||||
fAddRequired = ( userName, oUser ) =>
|
||||
|
||||
# Check whether the action is existing in a rule and load if not
|
||||
fCheckRules = ( oMyRule ) ->
|
||||
# Check whether the action is existing in a rule and load if not
|
||||
fCheckRules = ( oMyRule ) =>
|
||||
|
||||
# Load the action invoker module if it was part of the updated rule or if it's new
|
||||
fAddIfNewOrNotExisting = ( actionName ) ->
|
||||
moduleName = (actionName.split ' -> ')[0]
|
||||
if not oMyRule.actions[moduleName] or oMyRule.rule.id is updatedRuleId
|
||||
db.actionInvokers.getModule moduleName, ( err, obj ) ->
|
||||
# we compile the module and pass:
|
||||
dynmod.compileString obj.data, # code
|
||||
userName, # userId
|
||||
oMyRule.rule.id, # ruleId
|
||||
moduleName, # moduleId
|
||||
obj.lang, # script language
|
||||
db.actionInvokers, # the DB interface
|
||||
( result ) ->
|
||||
if not result.answ is 200
|
||||
@log.error "EN | Compilation of code failed! #{ userName },
|
||||
#{ oMyRule.rule.id }, #{ moduleName }"
|
||||
oMyRule.actions[moduleName] = result.module
|
||||
# Load the action invoker module if it was part of the updated rule or if it's new
|
||||
fAddIfNewOrNotExisting = ( actionName ) =>
|
||||
moduleName = (actionName.split ' -> ')[0]
|
||||
if not oMyRule.actions[moduleName] or oMyRule.rule.id is updatedRuleId
|
||||
db.actionInvokers.getModule moduleName, ( err, obj ) =>
|
||||
if obj
|
||||
# we compile the module and pass:
|
||||
dynmod.compileString obj.data, # code
|
||||
userName, # userId
|
||||
oMyRule.rule.id, # ruleId
|
||||
moduleName, # moduleId
|
||||
obj.lang, # script language
|
||||
db.actionInvokers, # the DB interface
|
||||
( result ) =>
|
||||
if not result.answ is 200
|
||||
@log.error "EN | Compilation of code failed! #{ userName },
|
||||
#{ oMyRule.rule.id }, #{ moduleName }"
|
||||
oMyRule.actions[moduleName] = result.module
|
||||
else
|
||||
@log.warn 'EN | #{ moduleName } not found for #{ oMyRule.rule.id }!'
|
||||
|
||||
fAddIfNewOrNotExisting action for action in oMyRule.rule.actions
|
||||
fAddIfNewOrNotExisting action for action in oMyRule.rule.actions
|
||||
|
||||
# Go thorugh all rules and check whether the action is still required
|
||||
fCheckRules oRl for nmRl, oRl of oUser
|
||||
# Go thorugh all rules and check whether the action is still required
|
||||
fCheckRules oRl for nmRl, oRl of oUser
|
||||
|
||||
# load all required modules for all users
|
||||
fAddRequired userName, oUser for userName, oUser of listUserRules
|
||||
# load all required modules for all users
|
||||
fAddRequired userName, oUser for userName, oUser of listUserRules
|
||||
|
||||
semaphore = 0
|
||||
numExecutingFunctions = 1
|
||||
pollQueue = () ->
|
||||
if isRunning
|
||||
db.popEvent ( err, obj ) ->
|
||||
if not err and obj
|
||||
processEvent obj
|
||||
semaphore--
|
||||
setTimeout pollQueue, 20 * semaphore #FIXME right wayx to adapt to load?
|
||||
if isRunning
|
||||
db.popEvent ( err, obj ) ->
|
||||
if not err and obj
|
||||
processEvent obj
|
||||
setTimeout pollQueue, 20 * numExecutingFunctions #FIXME right way to adapt to load?
|
||||
|
||||
###
|
||||
Checks whether all conditions of the rule are met by the event.
|
||||
|
|
@ -183,13 +185,12 @@ Checks whether all conditions of the rule are met by the event.
|
|||
@param {Object} rule
|
||||
###
|
||||
validConditions = ( evt, rule ) ->
|
||||
if rule.conditions.length is 0
|
||||
return true
|
||||
for prop in rule.conditions
|
||||
return false if jsonQuery( evt, prop ).nodes().length is 0
|
||||
return true
|
||||
if rule.conditions.length is 0
|
||||
return true
|
||||
for prop in rule.conditions
|
||||
return false if jsonQuery( evt, prop ).nodes().length is 0
|
||||
return true
|
||||
|
||||
semaphore = 0
|
||||
###
|
||||
Handles retrieved events.
|
||||
|
||||
|
|
@ -197,30 +198,32 @@ Handles retrieved events.
|
|||
@param {Object} evt
|
||||
###
|
||||
processEvent = ( evt ) =>
|
||||
fSearchAndInvokeAction = ( node, arrPath, funcName, evt, depth ) ->
|
||||
if not node
|
||||
@log.error "EN | Didn't find property in user rule list: " + arrPath.join ', ' + " at depth " + depth
|
||||
return
|
||||
if depth is arrPath.length
|
||||
try
|
||||
semaphore++
|
||||
node[funcName] evt.payload
|
||||
catch err
|
||||
@log.info "EN | ERROR IN ACTION INVOKER: " + err.message
|
||||
node.logger err.message
|
||||
if semaphore-- % 100 is 0
|
||||
@log.warn "EN | The system is producing too many tokens! Currently: #{ semaphore }"
|
||||
else
|
||||
fSearchAndInvokeAction node[arrPath[depth]], arrPath, funcName, evt, depth + 1
|
||||
fSearchAndInvokeAction = ( node, arrPath, funcName, evt, depth ) =>
|
||||
if not node
|
||||
@log.error "EN | Didn't find property in user rule list: " + arrPath.join ', ' + " at depth " + depth
|
||||
return
|
||||
if depth is arrPath.length
|
||||
try
|
||||
numExecutingFunctions++
|
||||
@log.info "EN | #{ funcName } executes..."
|
||||
node[funcName] evt.payload
|
||||
@log.info "EN | #{ funcName } finished execution"
|
||||
catch err
|
||||
@log.info "EN | ERROR IN ACTION INVOKER: " + err.message
|
||||
node.logger err.message
|
||||
if numExecutingFunctions-- % 100 is 0
|
||||
@log.warn "EN | The system is producing too many tokens! Currently: #{ numExecutingFunctions }"
|
||||
else
|
||||
fSearchAndInvokeAction node[arrPath[depth]], arrPath, funcName, evt, depth + 1
|
||||
|
||||
@log.info 'EN | processing event: ' + evt.event + '(' + evt.eventid + ')'
|
||||
for userName, oUser of listUserRules
|
||||
for ruleName, oMyRule of oUser
|
||||
if evt.event is oMyRule.rule.event and validConditions evt, oMyRule.rule
|
||||
@log.info 'EN | EVENT FIRED: ' + evt.event + '(' + evt.eventid + ') for rule ' + ruleName
|
||||
for action in oMyRule.rule.actions
|
||||
arr = action.split ' -> '
|
||||
fSearchAndInvokeAction listUserRules, [ userName, ruleName, 'actions', arr[0]], arr[1], evt, 0
|
||||
@log.info 'EN | processing event: ' + evt.event + '(' + evt.eventid + ')'
|
||||
for userName, oUser of listUserRules
|
||||
for ruleName, oMyRule of oUser
|
||||
if evt.event is oMyRule.rule.event and validConditions evt, oMyRule.rule
|
||||
@log.info 'EN | EVENT FIRED: ' + evt.event + '(' + evt.eventid + ') for rule ' + ruleName
|
||||
for action in oMyRule.rule.actions
|
||||
arr = action.split ' -> '
|
||||
fSearchAndInvokeAction listUserRules, [ userName, ruleName, 'actions', arr[0]], arr[1], evt, 0
|
||||
|
||||
exports.shutDown = () ->
|
||||
isRunning = false
|
||||
isRunning = false
|
||||
|
|
@ -16,13 +16,13 @@ dynmod = require './dynamic-modules'
|
|||
|
||||
# If we do not receive all required arguments we shut down immediately
|
||||
if process.argv.length < 8
|
||||
console.error 'Not all arguments have been passed!'
|
||||
process.exit()
|
||||
console.error 'Not all arguments have been passed!'
|
||||
process.exit()
|
||||
|
||||
# Fetch all the command line arguments to the process to init the logger
|
||||
logconf =
|
||||
mode: process.argv[ 2 ]
|
||||
nolog: process.argv[ 6 ]
|
||||
mode: process.argv[ 2 ]
|
||||
nolog: process.argv[ 6 ]
|
||||
logconf[ 'io-level' ] = process.argv[ 3 ]
|
||||
logconf[ 'file-level' ] = process.argv[ 4 ]
|
||||
logconf[ 'file-path' ] = process.argv[ 5 ]
|
||||
|
|
@ -32,8 +32,8 @@ log.info 'EP | Event Poller starts up'
|
|||
# Initialize required modules (should be in cache already)
|
||||
db logger: log
|
||||
dynmod
|
||||
logger: log
|
||||
keygen: process.argv[ 7 ]
|
||||
logger: log
|
||||
keygen: process.argv[ 7 ]
|
||||
|
||||
# Initialize module local variables and
|
||||
listUserModules = {}
|
||||
|
|
@ -42,102 +42,111 @@ isRunning = true
|
|||
# Register disconnect action. Since no standalone mode is intended
|
||||
# the event poller will shut down
|
||||
process.on 'disconnect', () ->
|
||||
log.info 'EP | Shutting down Event Poller'
|
||||
isRunning = false
|
||||
# very important so the process doesnt linger on when the paren process is killed
|
||||
process.exit()
|
||||
log.info 'EP | Shutting down Event Poller'
|
||||
isRunning = false
|
||||
# very important so the process doesnt linger on when the paren process is killed
|
||||
process.exit()
|
||||
|
||||
# If the process receives a message it is concerning the rules
|
||||
process.on 'message', ( msg ) ->
|
||||
|
||||
# Let's split the event string to find module and function in an array
|
||||
# Let's split the event string to find module and function in an array
|
||||
|
||||
# A initialization notification or a new rule
|
||||
if msg.event is 'new' or msg.event is 'init'
|
||||
fLoadModule msg
|
||||
# We fetch the module also if the rule was updated
|
||||
# A initialization notification or a new rule
|
||||
if msg.event is 'new' or msg.event is 'init'
|
||||
fLoadModule msg
|
||||
# We fetch the module also if the rule was updated
|
||||
|
||||
# A rule was deleted
|
||||
if msg.event is 'del'
|
||||
delete listUserModules[msg.user][msg.ruleId]
|
||||
if JSON.stringify( listUserModules[msg.user] ) is "{}"
|
||||
delete listUserModules[msg.user]
|
||||
# A rule was deleted
|
||||
if msg.event is 'del'
|
||||
delete listUserModules[msg.user][msg.ruleId]
|
||||
if JSON.stringify( listUserModules[msg.user] ) is "{}"
|
||||
delete listUserModules[msg.user]
|
||||
|
||||
# Loads a module if required
|
||||
fLoadModule = ( msg ) ->
|
||||
arrName = msg.rule.event.split ' -> '
|
||||
fAnonymous = () ->
|
||||
db.eventPollers.getModule arrName[ 0 ], ( err, obj ) ->
|
||||
if not obj
|
||||
log.warn "EP | Strange... no module retrieved: #{ arrName[0] }"
|
||||
else
|
||||
# we compile the module and pass:
|
||||
dynmod.compileString obj.data, # code
|
||||
msg.user, # userId
|
||||
msg.rule.id, # ruleId
|
||||
arrName[0], # moduleId
|
||||
obj.lang, # script language
|
||||
db.eventPollers, # the DB interface
|
||||
( result ) ->
|
||||
if not result.answ is 200
|
||||
log.error "EP | Compilation of code failed! #{ msg.user },
|
||||
#{ msg.rule.id }, #{ arrName[0] }"
|
||||
arrName = msg.rule.event.split ' -> '
|
||||
fAnonymous = () ->
|
||||
db.eventPollers.getModule arrName[ 0 ], ( err, obj ) ->
|
||||
if not obj
|
||||
log.warn "EP | Strange... no module retrieved: #{ arrName[0] }"
|
||||
else
|
||||
# we compile the module and pass:
|
||||
dynmod.compileString obj.data, # code
|
||||
msg.user, # userId
|
||||
msg.rule.id, # ruleId
|
||||
arrName[0], # moduleId
|
||||
obj.lang, # script language
|
||||
db.eventPollers, # the DB interface
|
||||
( result ) ->
|
||||
if not result.answ is 200
|
||||
log.error "EP | Compilation of code failed! #{ msg.user },
|
||||
#{ msg.rule.id }, #{ arrName[0] }"
|
||||
|
||||
# If user is not yet stored, we open a new object
|
||||
if not listUserModules[msg.user]
|
||||
listUserModules[msg.user] = {}
|
||||
|
||||
# We open up a new object for the rule it
|
||||
listUserModules[msg.user][msg.rule.id] =
|
||||
id: msg.rule.event
|
||||
pollfunc: arrName[1]
|
||||
module: result.module
|
||||
logger: result.logger
|
||||
# If user is not yet stored, we open a new object
|
||||
if not listUserModules[msg.user]
|
||||
listUserModules[msg.user] = {}
|
||||
|
||||
iv = msg.rule.interval * 60 * 1000
|
||||
# We open up a new object for the rule it
|
||||
listUserModules[msg.user][msg.rule.id] =
|
||||
id: msg.rule.event
|
||||
pollfunc: arrName[1]
|
||||
interval: iv
|
||||
module: result.module
|
||||
logger: result.logger
|
||||
|
||||
log.info "EP | New event module loaded! #{ msg.user },
|
||||
#{ msg.rule.id }, #{ arrName[0] }"
|
||||
log.info "EP | New event module '#{ arrName[0] }' loaded for user #{ msg.user },
|
||||
in rule #{ msg.rule.id }, polling every #{ iv } minutes"
|
||||
setTimeout fCheckAndRun( msg.user, msg.rule.id ), iv
|
||||
|
||||
if msg.event is 'new' or
|
||||
not listUserModules[msg.user] or
|
||||
not listUserModules[msg.user][msg.rule.id]
|
||||
fAnonymous()
|
||||
if msg.event is 'new' or
|
||||
not listUserModules[msg.user] or
|
||||
not listUserModules[msg.user][msg.rule.id]
|
||||
fAnonymous()
|
||||
|
||||
fCheckAndRun = ( userId, ruleId ) ->
|
||||
() ->
|
||||
if isRunning and
|
||||
listUserModules[userId] and
|
||||
listUserModules[userId][ruleId]
|
||||
oRule = listUserModules[userId][ruleId]
|
||||
fCallFunction userId, ruleId, oRule
|
||||
setTimeout fCheckAndRun( userId, ruleId ), oRule.interval
|
||||
|
||||
# We have to register the poll function in belows anonymous function
|
||||
# because we're fast iterating through the listUserModules and references will
|
||||
# eventually not be what they are expected to be
|
||||
fCallFunction = ( userId, ruleId, oRule ) ->
|
||||
try
|
||||
oRule.module[oRule.pollfunc] ( obj ) ->
|
||||
db.pushEvent
|
||||
event: oRule.id
|
||||
eventid: "polled #{ oRule.id } #{ userId }_#{ ( new Date ).toISOString() }"
|
||||
payload: obj
|
||||
catch err
|
||||
log.info "EP | ERROR in module when polled: #{ oRule.id } #{ userId }: #{err.message}"
|
||||
oRule.logger err.message
|
||||
# ###
|
||||
# This function will loop infinitely every 10 seconds until isRunning is set to false
|
||||
|
||||
# @private pollLoop()
|
||||
# ###
|
||||
# pollLoop = () ->
|
||||
# # We only loop if we're running
|
||||
# if isRunning
|
||||
|
||||
# # Go through all users
|
||||
# for userName, oRules of listUserModules
|
||||
|
||||
# # Go through each of the users modules
|
||||
# for ruleName, myRule of oRules
|
||||
|
||||
# # Call the event poller module function
|
||||
# fCallFunction myRule, ruleName, userName
|
||||
|
||||
# setTimeout pollLoop, 10000
|
||||
|
||||
|
||||
###
|
||||
This function will loop infinitely every 10 seconds until isRunning is set to false
|
||||
|
||||
@private pollLoop()
|
||||
###
|
||||
pollLoop = () ->
|
||||
# We only loop if we're running
|
||||
if isRunning
|
||||
|
||||
# Go through all users
|
||||
for userName, oRules of listUserModules
|
||||
|
||||
# Go through each of the users modules
|
||||
for ruleName, myRule of oRules
|
||||
|
||||
# # This is the to be polled function
|
||||
# fPoll = myRule.module[myRule.pollfunc]
|
||||
|
||||
# We have to register the poll function in belows anonymous function
|
||||
# because we're fast iterating through the listUserModules and references will
|
||||
# eventually not be what they are expected to be
|
||||
fCallFunction = ( oRule, ruleId, userId ) ->
|
||||
try
|
||||
oRule.module[oRule.pollfunc] ( obj ) ->
|
||||
db.pushEvent
|
||||
event: oRule.id
|
||||
eventid: "polled #{ oRule.id } #{ userId }_#{ ( new Date ).toISOString() }"
|
||||
payload: obj
|
||||
catch err
|
||||
log.info "EP | ERROR in module when polled: #{ oRule.id } #{ userId }: #{err.message}"
|
||||
oRule.logger err.message
|
||||
|
||||
fCallFunction myRule, ruleName, userName
|
||||
setTimeout pollLoop, 10000
|
||||
|
||||
|
||||
# Finally if everything initialized we start polling for new events
|
||||
pollLoop()
|
||||
# # Finally if everything initialized we start polling for new events
|
||||
# pollLoop()
|
||||
|
|
@ -33,11 +33,37 @@ Initializes the HTTP listener and its request handler.
|
|||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) =>
|
||||
@log = args.logger
|
||||
@shutDownSystem = args[ 'shutdown-function' ]
|
||||
requestHandler args
|
||||
initRouting args[ 'http-port' ]
|
||||
module.exports
|
||||
@log = args.logger
|
||||
@arrWebhooks = args.webhooks
|
||||
@shutDownSystem = args[ 'shutdown-function' ]
|
||||
requestHandler args
|
||||
initRouting args[ 'http-port' ]
|
||||
module.exports
|
||||
|
||||
indexEvent = ( event, body, resp ) ->
|
||||
try
|
||||
obj = JSON.parse body
|
||||
timestamp = ( new Date ).toISOString()
|
||||
rand = ( Math.floor Math.random() * 10e9 ).toString( 16 ).toUpperCase()
|
||||
obj.event = event
|
||||
obj.eventid = "#{ obj.event }_#{ timestamp }_#{ rand }"
|
||||
db.pushEvent obj
|
||||
resp.send 200, "Thank you for the event: #{ obj.eventid }"
|
||||
catch err
|
||||
resp.send 400, 'Badly formed event!'
|
||||
|
||||
# Activate a webhook. the body will be JSON parsed, the name of the webhook will
|
||||
# be the event name given to the event object, a timestamp will be added
|
||||
activateWebHook = ( app, name ) =>
|
||||
@log.info "HL | Webhook activated for #{ name }"
|
||||
app.post "/webhooks/#{ name }", ( req, resp ) ->
|
||||
console.log 'something is coming through'
|
||||
body = ''
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
|
||||
req.on 'end', ->
|
||||
indexEvent name, body, resp
|
||||
|
||||
###
|
||||
Initializes the request routing and starts listening on the given port.
|
||||
|
|
@ -46,58 +72,60 @@ Initializes the request routing and starts listening on the given port.
|
|||
@private initRouting( *fShutDown* )
|
||||
###
|
||||
initRouting = ( port ) =>
|
||||
# Add cookie support for session handling.
|
||||
app.use express.cookieParser()
|
||||
#TODO The session secret approach needs to be fixed!
|
||||
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw"
|
||||
app.use express.session { secret: sess_sec }
|
||||
# Add cookie support for session handling.
|
||||
app.use express.cookieParser()
|
||||
#TODO The session secret approach needs to be fixed!
|
||||
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw"
|
||||
app.use express.session { secret: sess_sec }
|
||||
|
||||
#At the moment there's no redis session backbone (didn't work straight away)
|
||||
@log.info 'HL | no session backbone'
|
||||
#At the moment there's no redis session backbone (didn't work straight away)
|
||||
@log.info 'HL | no session backbone'
|
||||
|
||||
# **Accepted requests to paths:**
|
||||
# **Accepted requests to paths:**
|
||||
|
||||
# GET Requests
|
||||
# GET Requests
|
||||
|
||||
# - **`GET` to _"/"_:** Static redirect to the _"webpages/public"_ directory
|
||||
app.use '/', express.static path.resolve __dirname, '..', 'webpages', 'public'
|
||||
# - **`GET` to _"/admin"_:** Displays the admin console if user is admin
|
||||
app.get '/admin', requestHandler.handleAdmin
|
||||
# - **`GET` to _"/forge"_:** Displays different forge pages
|
||||
app.get '/forge', requestHandler.handleForge
|
||||
# - **`GET` to _"/"_:** Static redirect to the _"webpages/public"_ directory
|
||||
app.use '/', express.static path.resolve __dirname, '..', 'webpages', 'public'
|
||||
# - **`GET` to _"/admin"_:** Displays the admin console if user is admin
|
||||
app.get '/admin', requestHandler.handleAdmin
|
||||
# - **`GET` to _"/forge"_:** Displays different forge pages
|
||||
app.get '/forge', requestHandler.handleForge
|
||||
|
||||
# POST Requests
|
||||
# POST Requests
|
||||
|
||||
# - **`POST` to _"/event"_:** Events coming from remote systems are passed to the engine
|
||||
app.post '/event', requestHandler.handleEvent
|
||||
# - **`POST` to _"/login"_:** Credentials will be verified
|
||||
app.post '/login', requestHandler.handleLogin
|
||||
# - **`POST` to _"/logout"_:** User will be logged out
|
||||
app.post '/logout', requestHandler.handleLogout
|
||||
# - **`POST` to _"/usercommand"_:** User requests are possible for all users with an account
|
||||
app.post '/usercommand', requestHandler.handleUserCommand
|
||||
# - **`POST` to _"/admincommand"_:** Admin requests are only possible for admins
|
||||
app.post '/admincommand', requestHandler.handleAdminCommand
|
||||
# - **`POST` to _"/event"_:** Events coming from remote systems are passed to the engine
|
||||
app.post '/event', requestHandler.handleEvent
|
||||
# - **`POST` to _"/login"_:** Credentials will be verified
|
||||
app.post '/login', requestHandler.handleLogin
|
||||
# - **`POST` to _"/logout"_:** User will be logged out
|
||||
app.post '/logout', requestHandler.handleLogout
|
||||
# - **`POST` to _"/usercommand"_:** User requests are possible for all users with an account
|
||||
app.post '/usercommand', requestHandler.handleUserCommand
|
||||
# - **`POST` to _"/admincommand"_:** Admin requests are only possible for admins
|
||||
app.post '/admincommand', requestHandler.handleAdminCommand
|
||||
# - **`POST` to _"/webhooks/*"_:** Webhooks can be added in the config file
|
||||
activateWebHook app, hookName for hookName in @arrWebhooks
|
||||
|
||||
server = app.listen parseInt( port ) || 8111 # inbound event channel
|
||||
server = app.listen parseInt( port ) || 8111 # inbound event channel
|
||||
|
||||
server.on 'listening', () =>
|
||||
addr = server.address()
|
||||
if addr.port isnt port
|
||||
@shutDownSystem()
|
||||
server.on 'error', ( err ) =>
|
||||
###
|
||||
Error handling of the express port listener requires special attention,
|
||||
thus we have to catch the error, which is issued if the port is already in use.
|
||||
###
|
||||
switch err.errno
|
||||
when 'EADDRINUSE'
|
||||
@log.error err, 'HL | http-port already in use, shutting down!'
|
||||
when 'EACCES'
|
||||
@log.error err, 'HL | http-port not accessible, shutting down!'
|
||||
else
|
||||
@log.error err, 'HL | Error in server, shutting down!'
|
||||
@shutDownSystem()
|
||||
server.on 'listening', () =>
|
||||
addr = server.address()
|
||||
if addr.port isnt port
|
||||
@shutDownSystem()
|
||||
server.on 'error', ( err ) =>
|
||||
###
|
||||
Error handling of the express port listener requires special attention,
|
||||
thus we have to catch the error, which is issued if the port is already in use.
|
||||
###
|
||||
switch err.errno
|
||||
when 'EADDRINUSE'
|
||||
@log.error err, 'HL | http-port already in use, shutting down!'
|
||||
when 'EACCES'
|
||||
@log.error err, 'HL | http-port not accessible, shutting down!'
|
||||
else
|
||||
@log.error err, 'HL | Error in server, shutting down!'
|
||||
@shutDownSystem()
|
||||
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -25,61 +25,61 @@ Returns a bunyan logger according to the given arguments.
|
|||
@param {Object} args
|
||||
###
|
||||
exports.getLogger = ( args ) =>
|
||||
emptylog =
|
||||
trace: () ->
|
||||
debug: () ->
|
||||
info: () ->
|
||||
warn: () ->
|
||||
error: () ->
|
||||
fatal: () ->
|
||||
# `args` holds the configuration settings for the logging, see either CLI arguments
|
||||
# in [webapi-eca](webapi-eca.html) or the configuration parameters in [config](config.html).
|
||||
args = args ? {}
|
||||
# We need to check for string 'true' also since the cliArgs passed to
|
||||
# the event-poller will be strings
|
||||
if args.nolog is true or args.nolog is 'true'
|
||||
# if the user doesn't want to have a log at all (e.g. during tests), it can be omitted with
|
||||
# the nolog flag
|
||||
emptylog
|
||||
else
|
||||
try
|
||||
opt =
|
||||
name: "webapi-eca"
|
||||
# if we are in development mode, we also add information about where the call came from
|
||||
# this should be turned off in productive mode since it slows down the logging.
|
||||
if args['mode'] is 'development'
|
||||
opt.src = true
|
||||
# if there's a custom path defined for the log, we adopt the setting.
|
||||
if args['file-path']
|
||||
@logPath = path.resolve args['file-path']
|
||||
else
|
||||
@logPath = path.resolve __dirname, '..', 'logs', 'server.log'
|
||||
emptylog =
|
||||
trace: () ->
|
||||
debug: () ->
|
||||
info: () ->
|
||||
warn: () ->
|
||||
error: () ->
|
||||
fatal: () ->
|
||||
# `args` holds the configuration settings for the logging, see either CLI arguments
|
||||
# in [webapi-eca](webapi-eca.html) or the configuration parameters in [config](config.html).
|
||||
args = args ? {}
|
||||
# We need to check for string 'true' also since the cliArgs passed to
|
||||
# the event-poller will be strings
|
||||
if args.nolog is true or args.nolog is 'true'
|
||||
# if the user doesn't want to have a log at all (e.g. during tests), it can be omitted with
|
||||
# the nolog flag
|
||||
emptylog
|
||||
else
|
||||
try
|
||||
opt =
|
||||
name: "webapi-eca"
|
||||
# if we are in development mode, we also add information about where the call came from
|
||||
# this should be turned off in productive mode since it slows down the logging.
|
||||
if args['mode'] is 'development'
|
||||
opt.src = true
|
||||
# if there's a custom path defined for the log, we adopt the setting.
|
||||
if args['file-path']
|
||||
@logPath = path.resolve args['file-path']
|
||||
else
|
||||
@logPath = path.resolve __dirname, '..', 'logs', 'server.log'
|
||||
|
||||
# We try to write a temp file in the same folder to check if the log can be written
|
||||
try
|
||||
fs.writeFileSync @logPath + '.temp', 'temp'
|
||||
fs.unlinkSync @logPath + '.temp'
|
||||
catch e
|
||||
console.error "Log folder '#{ @logPath }' is not writable"
|
||||
return emptylog
|
||||
# We try to write a temp file in the same folder to check if the log can be written
|
||||
try
|
||||
fs.writeFileSync @logPath + '.temp', 'temp'
|
||||
fs.unlinkSync @logPath + '.temp'
|
||||
catch e
|
||||
console.error "Log folder '#{ @logPath }' is not writable"
|
||||
return emptylog
|
||||
|
||||
# We attach two streams, one for the I/O and one for the log file.
|
||||
# The log levels are defined per stream according to the CLI args or the configuration.
|
||||
opt.streams = [
|
||||
{
|
||||
level: args['io-level']
|
||||
stream: process.stdout
|
||||
},
|
||||
{
|
||||
level: args['file-level']
|
||||
path: @logPath
|
||||
}
|
||||
]
|
||||
# Finally we create the bunyan logger and return it
|
||||
bunyan.createLogger opt
|
||||
# We attach two streams, one for the I/O and one for the log file.
|
||||
# The log levels are defined per stream according to the CLI args or the configuration.
|
||||
opt.streams = [
|
||||
{
|
||||
level: args['io-level']
|
||||
stream: process.stdout
|
||||
},
|
||||
{
|
||||
level: args['file-level']
|
||||
path: @logPath
|
||||
}
|
||||
]
|
||||
# Finally we create the bunyan logger and return it
|
||||
bunyan.createLogger opt
|
||||
|
||||
# If something goes wrong we print the error and return an empty logger.
|
||||
catch e
|
||||
console.error e
|
||||
emptylog
|
||||
# If something goes wrong we print the error and return an empty logger.
|
||||
catch e
|
||||
console.error e
|
||||
emptylog
|
||||
|
||||
|
|
|
|||
|
|
@ -34,32 +34,34 @@ Initializes the DB connection with the given `db-port` property in the `args` ob
|
|||
@param {Object} args
|
||||
###
|
||||
exports = module.exports = ( args ) =>
|
||||
if not @db
|
||||
#TODO we need to have a secure concept here, private keys per user
|
||||
#FIXME get rid of crpto
|
||||
if not args[ 'db-port' ]
|
||||
args[ 'db-port' ] = 6379
|
||||
@log = args.logger
|
||||
exports.eventPollers = new IndexedModules 'event-poller', @log
|
||||
exports.actionInvokers = new IndexedModules 'action-invoker', @log
|
||||
exports.initPort args[ 'db-port' ]
|
||||
if not @db
|
||||
#TODO we need to have a secure concept here, private keys per user
|
||||
#FIXME get rid of crpto
|
||||
if not args[ 'db-port' ]
|
||||
args[ 'db-port' ] = 6379
|
||||
@log = args.logger
|
||||
exports.eventPollers = new IndexedModules 'event-poller', @log
|
||||
exports.actionInvokers = new IndexedModules 'action-invoker', @log
|
||||
exports.initPort args[ 'db-port' ]
|
||||
|
||||
exports.getLogger = () =>
|
||||
@log
|
||||
@log
|
||||
|
||||
exports.initPort = ( port ) =>
|
||||
@connRefused = false
|
||||
@db?.quit()
|
||||
@db = redis.createClient port,
|
||||
'localhost', { connect_timeout: 2000 }
|
||||
# Eventually we try to connect to the wrong port, redis will emit an error that we
|
||||
# need to catch and take into account when answering the isConnected function call
|
||||
@db.on 'error', ( err ) =>
|
||||
if err.message.indexOf( 'ECONNREFUSED' ) > -1
|
||||
@connRefused = true
|
||||
@log.error err, 'DB | Wrong port?'
|
||||
exports.eventPollers.setDB @db
|
||||
exports.actionInvokers.setDB @db
|
||||
@connRefused = false
|
||||
@db?.quit()
|
||||
@db = redis.createClient port,
|
||||
'localhost', { connect_timeout: 2000 }
|
||||
# Eventually we try to connect to the wrong port, redis will emit an error that we
|
||||
# need to catch and take into account when answering the isConnected function call
|
||||
@db.on 'error', ( err ) =>
|
||||
if err.message.indexOf( 'ECONNREFUSED' ) > -1
|
||||
@connRefused = true
|
||||
@log.warn 'DB | Wrong port?'
|
||||
else
|
||||
@log.error err
|
||||
exports.eventPollers.setDB @db
|
||||
exports.actionInvokers.setDB @db
|
||||
|
||||
###
|
||||
Checks whether the db is connected and passes either an error on failure after
|
||||
|
|
@ -69,26 +71,26 @@ ten attempts within five seconds, or nothing on success to the callback(err).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.isConnected = ( cb ) =>
|
||||
if not @db
|
||||
cb new Error 'DB | DB initialization did not occur or failed miserably!'
|
||||
else
|
||||
if @db.connected
|
||||
cb()
|
||||
else
|
||||
numAttempts = 0
|
||||
fCheckConnection = =>
|
||||
if @connRefused
|
||||
@db?.quit()
|
||||
cb new Error 'DB | Connection refused! Wrong port?'
|
||||
else
|
||||
if @db.connected
|
||||
@log.info 'DB | Successfully connected to DB!'
|
||||
cb()
|
||||
else if numAttempts++ < 10
|
||||
setTimeout fCheckConnection, 100
|
||||
else
|
||||
cb new Error 'DB | Connection to DB failed!'
|
||||
setTimeout fCheckConnection, 100
|
||||
if not @db
|
||||
cb new Error 'DB | DB initialization did not occur or failed miserably!'
|
||||
else
|
||||
if @db.connected
|
||||
cb()
|
||||
else
|
||||
numAttempts = 0
|
||||
fCheckConnection = =>
|
||||
if @connRefused
|
||||
@db?.quit()
|
||||
cb new Error 'DB | Connection refused! Wrong port?'
|
||||
else
|
||||
if @db.connected
|
||||
@log.info 'DB | Successfully connected to DB!'
|
||||
cb()
|
||||
else if numAttempts++ < 10
|
||||
setTimeout fCheckConnection, 100
|
||||
else
|
||||
cb new Error 'DB | Connection to DB failed!'
|
||||
setTimeout fCheckConnection, 100
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -98,11 +100,11 @@ Abstracts logging for simple action replies from the DB.
|
|||
@param {String} action
|
||||
###
|
||||
replyHandler = ( action ) =>
|
||||
( err, reply ) =>
|
||||
if err
|
||||
@log.warn err, "during '#{ action }'"
|
||||
else
|
||||
@log.info "DB | #{ action }: #{ reply }"
|
||||
( err, reply ) =>
|
||||
if err
|
||||
@log.warn err, "during '#{ action }'"
|
||||
else
|
||||
@log.info "DB | #{ action }: #{ reply }"
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -112,11 +114,11 @@ Push an event into the event queue.
|
|||
@param {Object} oEvent
|
||||
###
|
||||
exports.pushEvent = ( oEvent ) =>
|
||||
if oEvent
|
||||
@log.info "DB | Event pushed into the queue: '#{ oEvent.eventid }'"
|
||||
@db.rpush 'event_queue', JSON.stringify oEvent
|
||||
else
|
||||
@log.warn 'DB | Why would you give me an empty event...'
|
||||
if oEvent
|
||||
@log.info "DB | Event pushed into the queue: '#{ oEvent.eventid }'"
|
||||
@db.rpush 'event_queue', JSON.stringify oEvent
|
||||
else
|
||||
@log.warn 'DB | Why would you give me an empty event...'
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -126,10 +128,10 @@ Pop an event from the event queue and pass it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.popEvent = ( cb ) =>
|
||||
makeObj = ( pcb ) ->
|
||||
( err, obj ) ->
|
||||
pcb err, JSON.parse obj
|
||||
@db.lpop 'event_queue', makeObj cb
|
||||
makeObj = ( pcb ) ->
|
||||
( err, obj ) ->
|
||||
pcb err, JSON.parse obj
|
||||
@db.lpop 'event_queue', makeObj cb
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -138,7 +140,7 @@ Purge the event queue.
|
|||
@public purgeEventQueue()
|
||||
###
|
||||
exports.purgeEventQueue = () =>
|
||||
@db.del 'event_queue', replyHandler 'purging event queue'
|
||||
@db.del 'event_queue', replyHandler 'purging event queue'
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -148,202 +150,202 @@ 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
|
||||
per set entry
|
||||
@param {function} cb the callback(err, obj) function that receives all
|
||||
the retrieved data or an error
|
||||
the retrieved data or an error
|
||||
###
|
||||
getSetRecords = ( set, fSingle, cb ) =>
|
||||
@log.info "DB | Fetching set records: '#{ set }'"
|
||||
# Fetch all members of the set
|
||||
@db.smembers set, ( err, arrReply ) =>
|
||||
if err
|
||||
# If an error happens we return it to the callback function
|
||||
@log.warn err, "DB | fetching '#{ set }'"
|
||||
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 }'"
|
||||
, 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
|
||||
@log.warn err, "DB | fetching single element: '#{ prop }'"
|
||||
else if not data
|
||||
# There was no data behind the key
|
||||
@log.warn 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
|
||||
@log.info "DB | Fetching set records: '#{ set }'"
|
||||
# Fetch all members of the set
|
||||
@db.smembers set, ( err, arrReply ) =>
|
||||
if err
|
||||
# If an error happens we return it to the callback function
|
||||
@log.warn err, "DB | fetching '#{ set }'"
|
||||
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 }'"
|
||||
, 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
|
||||
@log.warn err, "DB | fetching single element: '#{ prop }'"
|
||||
else if not data
|
||||
# There was no data behind the key
|
||||
@log.warn 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, @log ) ->
|
||||
@log.info "DB | (IdxedMods) Instantiated indexed modules for '#{ @setname }'"
|
||||
constructor: ( @setname, @log ) ->
|
||||
@log.info "DB | (IdxedMods) Instantiated indexed modules for '#{ @setname }'"
|
||||
|
||||
setDB: ( @db ) ->
|
||||
@log.info "DB | (IdxedMods) Registered new DB connection for '#{ @setname }'"
|
||||
setDB: ( @db ) ->
|
||||
@log.info "DB | (IdxedMods) Registered new DB connection for '#{ @setname }'"
|
||||
|
||||
###
|
||||
Stores a module and links it to the user.
|
||||
|
||||
@private storeModule( *userId, oModule* )
|
||||
@param {String} userId
|
||||
@param {object} oModule
|
||||
###
|
||||
storeModule: ( userId, oModule ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.storeModule( #{ userId }, oModule )"
|
||||
@db.sadd "#{ @setname }s", oModule.id,
|
||||
replyHandler "sadd '#{ oModule.id }' to '#{ @setname }'"
|
||||
@db.hmset "#{ @setname }:#{ oModule.id }", oModule,
|
||||
replyHandler "hmset properties in hash '#{ @setname }:#{ oModule.id }'"
|
||||
@linkModule oModule.id, userId
|
||||
###
|
||||
Stores a module and links it to the user.
|
||||
|
||||
@private storeModule( *userId, oModule* )
|
||||
@param {String} userId
|
||||
@param {object} oModule
|
||||
###
|
||||
storeModule: ( userId, oModule ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.storeModule( #{ userId }, oModule )"
|
||||
@db.sadd "#{ @setname }s", oModule.id,
|
||||
replyHandler "sadd '#{ oModule.id }' to '#{ @setname }'"
|
||||
@db.hmset "#{ @setname }:#{ oModule.id }", oModule,
|
||||
replyHandler "hmset properties in hash '#{ @setname }:#{ oModule.id }'"
|
||||
@linkModule oModule.id, userId
|
||||
|
||||
#TODO add testing
|
||||
linkModule: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.linkModule( #{ mId }, #{ userId } )"
|
||||
@db.sadd "#{ @setname }:#{ mId }:users", userId,
|
||||
replyHandler "sadd #{ userId } to '#{ @setname }:#{ mId }:users'"
|
||||
@db.sadd "user:#{ userId }:#{ @setname }s", mId,
|
||||
replyHandler "sadd #{ mId } to 'user:#{ userId }:#{ @setname }s'"
|
||||
#TODO add testing
|
||||
linkModule: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.linkModule( #{ mId }, #{ userId } )"
|
||||
@db.sadd "#{ @setname }:#{ mId }:users", userId,
|
||||
replyHandler "sadd #{ userId } to '#{ @setname }:#{ mId }:users'"
|
||||
@db.sadd "user:#{ userId }:#{ @setname }s", mId,
|
||||
replyHandler "sadd #{ mId } to 'user:#{ userId }:#{ @setname }s'"
|
||||
|
||||
#TODO add testing
|
||||
unlinkModule: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.unlinkModule( #{ mId }, #{ userId } )"
|
||||
@db.srem "#{ @setname }:#{ mId }:users", userId,
|
||||
replyHandler "srem #{ userId } from '#{ @setname }:#{ mId }:users'"
|
||||
@db.srem "user:#{ userId }:#{ @setname }s", mId,
|
||||
replyHandler "srem #{ mId } from 'user:#{ userId }:#{ @setname }s'"
|
||||
#TODO add testing
|
||||
unlinkModule: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.unlinkModule( #{ mId }, #{ userId } )"
|
||||
@db.srem "#{ @setname }:#{ mId }:users", userId,
|
||||
replyHandler "srem #{ userId } from '#{ @setname }:#{ mId }:users'"
|
||||
@db.srem "user:#{ userId }:#{ @setname }s", mId,
|
||||
replyHandler "srem #{ mId } from 'user:#{ userId }:#{ @setname }s'"
|
||||
|
||||
#TODO add testing
|
||||
publish: ( mId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.publish( #{ mId } )"
|
||||
@db.sadd "public-#{ @setname }s", mId,
|
||||
replyHandler "sadd '#{ mId }' to 'public-#{ @setname }s'"
|
||||
#TODO add testing
|
||||
publish: ( mId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.publish( #{ mId } )"
|
||||
@db.sadd "public-#{ @setname }s", mId,
|
||||
replyHandler "sadd '#{ mId }' to 'public-#{ @setname }s'"
|
||||
|
||||
#TODO add testing
|
||||
unpublish: ( mId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.unpublish( #{ mId } )"
|
||||
@db.srem "public-#{ @setname }s", mId,
|
||||
replyHandler "srem '#{ mId }' from 'public-#{ @setname }s'"
|
||||
#TODO add testing
|
||||
unpublish: ( mId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.unpublish( #{ mId } )"
|
||||
@db.srem "public-#{ @setname }s", mId,
|
||||
replyHandler "srem '#{ mId }' from 'public-#{ @setname }s'"
|
||||
|
||||
getModule: ( mId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModule( #{ mId } )"
|
||||
@db.hgetall "#{ @setname }:#{ mId }", cb
|
||||
getModule: ( mId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModule( #{ mId } )"
|
||||
@db.hgetall "#{ @setname }:#{ mId }", cb
|
||||
|
||||
getModuleField: ( mId, field, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModule( #{ mId } )"
|
||||
@db.hget "#{ @setname }:#{ mId }", field, cb
|
||||
getModuleField: ( mId, field, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModule( #{ mId } )"
|
||||
@db.hget "#{ @setname }:#{ mId }", field, cb
|
||||
|
||||
#TODO add testing
|
||||
getModuleParams: ( mId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModuleParams( #{ mId } )"
|
||||
@db.hget "#{ @setname }:#{ mId }", "params", cb
|
||||
#TODO add testing
|
||||
getModuleParams: ( mId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModuleParams( #{ mId } )"
|
||||
@db.hget "#{ @setname }:#{ mId }", "params", cb
|
||||
|
||||
#TODO add testing
|
||||
getAvailableModuleIds: ( userId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getPublicModuleIds( #{ userId } )"
|
||||
@db.sunion "public-#{ @setname }s", "user:#{ userId }:#{ @setname }s", cb
|
||||
#TODO add testing
|
||||
getAvailableModuleIds: ( userId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getPublicModuleIds( #{ userId } )"
|
||||
@db.sunion "public-#{ @setname }s", "user:#{ userId }:#{ @setname }s", cb
|
||||
|
||||
getModuleIds: ( cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModuleIds()"
|
||||
@db.smembers "#{ @setname }s", cb
|
||||
getModuleIds: ( cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModuleIds()"
|
||||
@db.smembers "#{ @setname }s", cb
|
||||
|
||||
getModules: ( cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModules()"
|
||||
getSetRecords "#{ @setname }s", @getModule, cb
|
||||
getModules: ( cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getModules()"
|
||||
getSetRecords "#{ @setname }s", @getModule, cb
|
||||
|
||||
deleteModule: ( mId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.deleteModule( #{ mId } )"
|
||||
@db.srem "#{ @setname }s", mId,
|
||||
replyHandler "srem '#{ mId }' from #{ @setname }s"
|
||||
@db.del "#{ @setname }:#{ mId }",
|
||||
replyHandler "del of '#{ @setname }:#{ mId }'"
|
||||
@unpublish mId
|
||||
@db.smembers "#{ @setname }:#{ mId }:users", ( err, obj ) =>
|
||||
@unlinkModule mId, userId for userId in obj
|
||||
@deleteUserParams mId, userId for userId in obj
|
||||
@deleteUserArguments mId, userId for userId in obj
|
||||
deleteModule: ( mId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.deleteModule( #{ mId } )"
|
||||
@db.srem "#{ @setname }s", mId,
|
||||
replyHandler "srem '#{ mId }' from #{ @setname }s"
|
||||
@db.del "#{ @setname }:#{ mId }",
|
||||
replyHandler "del of '#{ @setname }:#{ mId }'"
|
||||
@unpublish mId
|
||||
@db.smembers "#{ @setname }:#{ mId }:users", ( err, obj ) =>
|
||||
@unlinkModule mId, userId for userId in obj
|
||||
@deleteUserParams mId, userId for userId in obj
|
||||
@deleteUserArguments mId, userId for userId in obj
|
||||
|
||||
###
|
||||
Stores user params for a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserParams( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
###
|
||||
storeUserParams: ( mId, userId, encData ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.storeUserParams( #{ mId }, #{ userId }, encData )"
|
||||
@db.sadd "#{ @setname }-params", "#{ mId }:#{ userId }",
|
||||
replyHandler "sadd '#{ mId }:#{ userId }' to '#{ @setname }-params'"
|
||||
@db.set "#{ @setname }-params:#{ mId }:#{ userId }", encData,
|
||||
replyHandler "set user params in '#{ @setname }-params:#{ mId }:#{ userId }'"
|
||||
###
|
||||
Stores user params for a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserParams( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
###
|
||||
storeUserParams: ( mId, userId, encData ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.storeUserParams( #{ mId }, #{ userId }, encData )"
|
||||
@db.sadd "#{ @setname }-params", "#{ mId }:#{ userId }",
|
||||
replyHandler "sadd '#{ mId }:#{ userId }' to '#{ @setname }-params'"
|
||||
@db.set "#{ @setname }-params:#{ mId }:#{ userId }", encData,
|
||||
replyHandler "set user params in '#{ @setname }-params:#{ mId }:#{ userId }'"
|
||||
|
||||
getUserParams: ( mId, userId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getUserParams( #{ mId }, #{ userId } )"
|
||||
@db.get "#{ @setname }-params:#{ mId }:#{ userId }", cb
|
||||
getUserParams: ( mId, userId, cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getUserParams( #{ mId }, #{ userId } )"
|
||||
@db.get "#{ @setname }-params:#{ mId }:#{ userId }", cb
|
||||
|
||||
getUserParamsIds: ( cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getUserParamsIds()"
|
||||
@db.smembers "#{ @setname }-params", cb
|
||||
getUserParamsIds: ( cb ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getUserParamsIds()"
|
||||
@db.smembers "#{ @setname }-params", cb
|
||||
|
||||
deleteUserParams: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.deleteUserParams(#{ mId }, #{ userId } )"
|
||||
@db.srem "#{ @setname }-params", "#{ mId }:#{ userId }",
|
||||
replyHandler "srem '#{ mId }:#{ userId }' from '#{ @setname }-params'"
|
||||
@db.del "#{ @setname }-params:#{ mId }:#{ userId }",
|
||||
replyHandler "del '#{ @setname }-params:#{ mId }:#{ userId }'"
|
||||
deleteUserParams: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.deleteUserParams(#{ mId }, #{ userId } )"
|
||||
@db.srem "#{ @setname }-params", "#{ mId }:#{ userId }",
|
||||
replyHandler "srem '#{ mId }:#{ userId }' from '#{ @setname }-params'"
|
||||
@db.del "#{ @setname }-params:#{ mId }:#{ userId }",
|
||||
replyHandler "del '#{ @setname }-params:#{ mId }:#{ userId }'"
|
||||
|
||||
###
|
||||
Stores user arguments for a function within a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserArguments( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
###
|
||||
storeUserArguments: ( mId, funcId, userId, encData ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.storeUserArguments( #{ mId }, #{ funcId }, #{ userId }, encData )"
|
||||
@db.sadd "#{ @setname }:#{ mId }:#{ userId }:functions", funcId,
|
||||
replyHandler "sadd '#{ funcId }' to '#{ @setname }:#{ mId }:#{ userId }:functions'"
|
||||
@db.set "#{ @setname }:#{ mId }:#{ userId }:function:#{ funcId }", encData,
|
||||
replyHandler "set user params in '#{ @setname }:#{ mId }:#{ userId }:function:#{ func }'"
|
||||
###
|
||||
Stores user arguments for a function within a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserArguments( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
###
|
||||
storeUserArguments: ( mId, funcId, userId, encData ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.storeUserArguments( #{ mId }, #{ funcId }, #{ userId }, encData )"
|
||||
@db.sadd "#{ @setname }:#{ mId }:#{ userId }:functions", funcId,
|
||||
replyHandler "sadd '#{ funcId }' to '#{ @setname }:#{ mId }:#{ userId }:functions'"
|
||||
@db.set "#{ @setname }:#{ mId }:#{ userId }:function:#{ funcId }", encData,
|
||||
replyHandler "set user params in '#{ @setname }:#{ mId }:#{ userId }:function:#{ func }'"
|
||||
|
||||
getUserArguments: ( mId, funcId, userId, cb ) =>
|
||||
console.log 'calling ffunct'
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getUserArguments( #{ mId }, #{ funcId }, #{ userId } )"
|
||||
@db.get "#{ @setname }:#{ mId }:#{ userId }:function:#{ funcId }", cb
|
||||
getUserArguments: ( mId, funcId, userId, cb ) =>
|
||||
console.log 'calling ffunct'
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.getUserArguments( #{ mId }, #{ funcId }, #{ userId } )"
|
||||
@db.get "#{ @setname }:#{ mId }:#{ userId }:function:#{ funcId }", cb
|
||||
|
||||
deleteUserArguments: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.deleteUserArguments(#{ mId }, #{ userId } )"
|
||||
@db.smembers "#{ @setname }:#{ mId }:#{ userId }:functions", ( err, obj ) =>
|
||||
for func in obj
|
||||
@db.del "#{ @setname }:#{ mId }:#{ userId }:function:#{ func }",
|
||||
replyHandler "del '#{ @setname }:#{ mId }:#{ userId }:function:#{ func }'"
|
||||
deleteUserArguments: ( mId, userId ) =>
|
||||
@log.info "DB | (IdxedMods) #{ @setname }.deleteUserArguments(#{ mId }, #{ userId } )"
|
||||
@db.smembers "#{ @setname }:#{ mId }:#{ userId }:functions", ( err, obj ) =>
|
||||
for func in obj
|
||||
@db.del "#{ @setname }:#{ mId }:#{ userId }:function:#{ func }",
|
||||
replyHandler "del '#{ @setname }:#{ mId }:#{ userId }:function:#{ func }'"
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -360,8 +362,8 @@ Appends a log entry.
|
|||
@param {String} message
|
||||
###
|
||||
exports.appendLog = ( userId, ruleId, moduleId, message ) =>
|
||||
@db.append "#{ userId }:#{ ruleId }:log",
|
||||
"[#{ ( new Date ).toISOString() }] {#{ moduleId }} #{ message }\n"
|
||||
@db.append "#{ userId }:#{ ruleId }:log",
|
||||
"[#{ ( new Date ).toISOString() }] {#{ moduleId }} #{ message }\n"
|
||||
|
||||
###
|
||||
Retrieves a log entry.
|
||||
|
|
@ -372,7 +374,7 @@ Retrieves a log entry.
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getLog = ( userId, ruleId, cb ) =>
|
||||
@db.get "#{ userId }:#{ ruleId }:log", cb
|
||||
@db.get "#{ userId }:#{ ruleId }:log", cb
|
||||
|
||||
###
|
||||
Resets a log entry.
|
||||
|
|
@ -382,8 +384,8 @@ Resets a log entry.
|
|||
@param {String} ruleId
|
||||
###
|
||||
exports.resetLog = ( userId, ruleId ) =>
|
||||
@db.del "#{ userId }:#{ ruleId }:log",
|
||||
replyHandler "del '#{ userId }:#{ ruleId }:log'"
|
||||
@db.del "#{ userId }:#{ ruleId }:log",
|
||||
replyHandler "del '#{ userId }:#{ ruleId }:log'"
|
||||
|
||||
###
|
||||
Query the DB for a rule and pass it to cb(err, obj).
|
||||
|
|
@ -393,8 +395,8 @@ Query the DB for a rule and pass it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getRule = ( ruleId, cb ) =>
|
||||
@log.info "DB | get: 'rule:#{ ruleId }'"
|
||||
@db.get "rule:#{ ruleId }", cb
|
||||
@log.info "DB | get: 'rule:#{ ruleId }'"
|
||||
@db.get "rule:#{ ruleId }", cb
|
||||
|
||||
###
|
||||
Fetch all rules and pass them to cb(err, obj).
|
||||
|
|
@ -403,8 +405,8 @@ Fetch all rules and pass them to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getRules = ( cb ) =>
|
||||
@log.info "DB | Fetching all Rules: getSetRecords 'rules'"
|
||||
getSetRecords 'rules', exports.getRule, cb
|
||||
@log.info "DB | Fetching all Rules: getSetRecords 'rules'"
|
||||
getSetRecords 'rules', exports.getRule, cb
|
||||
|
||||
###
|
||||
Fetch all rule IDs and hand it to cb(err, obj).
|
||||
|
|
@ -413,8 +415,8 @@ Fetch all rule IDs and hand it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getRuleIds = ( cb ) =>
|
||||
@log.info "DB | Fetching all Rule IDs: 'rules'"
|
||||
@db.smembers 'rules', cb
|
||||
@log.info "DB | Fetching all Rule IDs: 'rules'"
|
||||
@db.smembers 'rules', cb
|
||||
|
||||
###
|
||||
Store a string representation of a rule in the DB.
|
||||
|
|
@ -424,11 +426,11 @@ Store a string representation of a rule in the DB.
|
|||
@param {String} data
|
||||
###
|
||||
exports.storeRule = ( ruleId, data ) =>
|
||||
@log.info "DB | storeRule: '#{ ruleId }'"
|
||||
@db.sadd 'rules', "#{ ruleId }",
|
||||
replyHandler "sadd rules: '#{ ruleId }'"
|
||||
@db.set "rule:#{ ruleId }", data,
|
||||
replyHandler "set 'rule:#{ ruleId }': data"
|
||||
@log.info "DB | storeRule: '#{ ruleId }'"
|
||||
@db.sadd 'rules', "#{ ruleId }",
|
||||
replyHandler "sadd rules: '#{ ruleId }'"
|
||||
@db.set "rule:#{ ruleId }", data,
|
||||
replyHandler "set 'rule:#{ ruleId }': data"
|
||||
|
||||
###
|
||||
Delete a string representation of a rule.
|
||||
|
|
@ -438,26 +440,26 @@ Delete a string representation of a rule.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.deleteRule = ( ruleId ) =>
|
||||
@log.info "DB | deleteRule: '#{ ruleId }'"
|
||||
@db.srem "rules", ruleId, replyHandler "srem 'rules': '#{ ruleId }'"
|
||||
@db.del "rule:#{ ruleId }", replyHandler "del: 'rule:#{ ruleId }'"
|
||||
@log.info "DB | deleteRule: '#{ ruleId }'"
|
||||
@db.srem "rules", ruleId, replyHandler "srem 'rules': '#{ ruleId }'"
|
||||
@db.del "rule:#{ ruleId }", replyHandler "del: 'rule:#{ ruleId }'"
|
||||
|
||||
# We also need to delete all references in linked and active users
|
||||
@db.smembers "rule:#{ ruleId }:users", ( err, obj ) =>
|
||||
delLinkedUserRule = ( userId ) =>
|
||||
exports.resetLog userId, ruleId
|
||||
@db.srem "user:#{ userId }:rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:rules': '#{ ruleId }'"
|
||||
delLinkedUserRule id for id in obj
|
||||
@db.del "rule:#{ ruleId }:users", replyHandler "del 'rule:#{ ruleId }:users'"
|
||||
# We also need to delete all references in linked and active users
|
||||
@db.smembers "rule:#{ ruleId }:users", ( err, obj ) =>
|
||||
delLinkedUserRule = ( userId ) =>
|
||||
exports.resetLog userId, ruleId
|
||||
@db.srem "user:#{ userId }:rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:rules': '#{ ruleId }'"
|
||||
delLinkedUserRule id for id in obj
|
||||
@db.del "rule:#{ ruleId }:users", replyHandler "del 'rule:#{ ruleId }:users'"
|
||||
|
||||
@db.smembers "rule:#{ ruleId }:active-users", ( err, obj ) =>
|
||||
delActiveUserRule = ( userId ) =>
|
||||
@db.srem "user:#{ userId }:active-rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:active-rules': '#{ ruleId }'"
|
||||
delActiveUserRule id for id in obj
|
||||
@db.del "rule:#{ ruleId }:active-users",
|
||||
replyHandler "del 'rule:#{ ruleId }:active-users'"
|
||||
@db.smembers "rule:#{ ruleId }:active-users", ( err, obj ) =>
|
||||
delActiveUserRule = ( userId ) =>
|
||||
@db.srem "user:#{ userId }:active-rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:active-rules': '#{ ruleId }'"
|
||||
delActiveUserRule id for id in obj
|
||||
@db.del "rule:#{ ruleId }:active-users",
|
||||
replyHandler "del 'rule:#{ ruleId }:active-users'"
|
||||
|
||||
###
|
||||
Associate a rule to a user.
|
||||
|
|
@ -467,11 +469,11 @@ Associate a rule to a user.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.linkRule = ( ruleId, userId ) =>
|
||||
@log.info "DB | linkRule: '#{ ruleId }' to user '#{ userId }'"
|
||||
@db.sadd "rule:#{ ruleId }:users", userId,
|
||||
replyHandler "sadd 'rule:#{ ruleId }:users': '#{ userId }'"
|
||||
@db.sadd "user:#{ userId }:rules", ruleId,
|
||||
replyHandler "sadd 'user:#{ userId }:rules': '#{ ruleId }'"
|
||||
@log.info "DB | linkRule: '#{ ruleId }' to user '#{ userId }'"
|
||||
@db.sadd "rule:#{ ruleId }:users", userId,
|
||||
replyHandler "sadd 'rule:#{ ruleId }:users': '#{ userId }'"
|
||||
@db.sadd "user:#{ userId }:rules", ruleId,
|
||||
replyHandler "sadd 'user:#{ userId }:rules': '#{ ruleId }'"
|
||||
|
||||
###
|
||||
Get rules linked to a user and hand it to cb(err, obj).
|
||||
|
|
@ -481,8 +483,8 @@ Get rules linked to a user and hand it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getUserLinkedRules = ( userId, cb ) =>
|
||||
@log.info "DB | getUserLinkedRules: 'user:#{ userId }:rules'"
|
||||
@db.smembers "user:#{ userId }:rules", cb
|
||||
@log.info "DB | getUserLinkedRules: 'user:#{ userId }:rules'"
|
||||
@db.smembers "user:#{ userId }:rules", cb
|
||||
|
||||
###
|
||||
Get users linked to a rule and hand it to cb(err, obj).
|
||||
|
|
@ -492,8 +494,8 @@ Get users linked to a rule and hand it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getRuleLinkedUsers = ( ruleId, cb ) =>
|
||||
@log.info "DB | getRuleLinkedUsers: 'rule:#{ ruleId }:users'"
|
||||
@db.smembers "rule:#{ ruleId }:users", cb
|
||||
@log.info "DB | getRuleLinkedUsers: 'rule:#{ ruleId }:users'"
|
||||
@db.smembers "rule:#{ ruleId }:users", cb
|
||||
|
||||
###
|
||||
Delete an association of a rule to a user.
|
||||
|
|
@ -503,11 +505,11 @@ Delete an association of a rule to a user.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.unlinkRule = ( ruleId, userId ) =>
|
||||
@log.info "DB | unlinkRule: '#{ ruleId }:#{ userId }'"
|
||||
@db.srem "rule:#{ ruleId }:users", userId,
|
||||
replyHandler "srem 'rule:#{ ruleId }:users': '#{ userId }'"
|
||||
@db.srem "user:#{ userId }:rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:rules': '#{ ruleId }'"
|
||||
@log.info "DB | unlinkRule: '#{ ruleId }:#{ userId }'"
|
||||
@db.srem "rule:#{ ruleId }:users", userId,
|
||||
replyHandler "srem 'rule:#{ ruleId }:users': '#{ userId }'"
|
||||
@db.srem "user:#{ userId }:rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:rules': '#{ ruleId }'"
|
||||
|
||||
###
|
||||
Activate a rule.
|
||||
|
|
@ -517,11 +519,11 @@ Activate a rule.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.activateRule = ( ruleId, userId ) =>
|
||||
@log.info "DB | activateRule: '#{ ruleId }' for '#{ userId }'"
|
||||
@db.sadd "rule:#{ ruleId }:active-users", userId,
|
||||
replyHandler "sadd 'rule:#{ ruleId }:active-users': '#{ userId }'"
|
||||
@db.sadd "user:#{ userId }:active-rules", ruleId,
|
||||
replyHandler "sadd 'user:#{ userId }:active-rules': '#{ ruleId }'"
|
||||
@log.info "DB | activateRule: '#{ ruleId }' for '#{ userId }'"
|
||||
@db.sadd "rule:#{ ruleId }:active-users", userId,
|
||||
replyHandler "sadd 'rule:#{ ruleId }:active-users': '#{ userId }'"
|
||||
@db.sadd "user:#{ userId }:active-rules", ruleId,
|
||||
replyHandler "sadd 'user:#{ userId }:active-rules': '#{ ruleId }'"
|
||||
|
||||
###
|
||||
Get rules activated for a user and hand it to cb(err, obj).
|
||||
|
|
@ -531,8 +533,8 @@ Get rules activated for a user and hand it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getUserActivatedRules = ( userId, cb ) =>
|
||||
@log.info "DB | getUserActivatedRules: smembers 'user:#{ userId }:active-rules'"
|
||||
@db.smembers "user:#{ userId }:active-rules", cb
|
||||
@log.info "DB | getUserActivatedRules: smembers 'user:#{ userId }:active-rules'"
|
||||
@db.smembers "user:#{ userId }:active-rules", cb
|
||||
|
||||
###
|
||||
Get users activated for a rule and hand it to cb(err, obj).
|
||||
|
|
@ -542,8 +544,8 @@ Get users activated for a rule and hand it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getRuleActivatedUsers = ( ruleId, cb ) =>
|
||||
@log.info "DB | getRuleActivatedUsers: smembers 'rule:#{ ruleId }:active-users'"
|
||||
@db.smembers "rule:#{ ruleId }:active-users", cb
|
||||
@log.info "DB | getRuleActivatedUsers: smembers 'rule:#{ ruleId }:active-users'"
|
||||
@db.smembers "rule:#{ ruleId }:active-users", cb
|
||||
|
||||
###
|
||||
Deactivate a rule.
|
||||
|
|
@ -553,11 +555,11 @@ Deactivate a rule.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.deactivateRule = ( ruleId, userId ) =>
|
||||
@log.info "DB | deactivateRule: '#{ ruleId }' for '#{ userId }'"
|
||||
@db.srem "rule:#{ ruleId }:active-users", userId,
|
||||
replyHandler "srem 'rule:#{ ruleId }:active-users': '#{ userId }'"
|
||||
@db.srem "user:#{ userId }:active-rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:active-rules' '#{ ruleId }'"
|
||||
@log.info "DB | deactivateRule: '#{ ruleId }' for '#{ userId }'"
|
||||
@db.srem "rule:#{ ruleId }:active-users", userId,
|
||||
replyHandler "srem 'rule:#{ ruleId }:active-users': '#{ userId }'"
|
||||
@db.srem "user:#{ userId }:active-rules", ruleId,
|
||||
replyHandler "srem 'user:#{ userId }:active-rules' '#{ ruleId }'"
|
||||
|
||||
###
|
||||
Fetch all active ruleIds and pass them to cb(err, obj).
|
||||
|
|
@ -566,20 +568,20 @@ Fetch all active ruleIds and pass them to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getAllActivatedRuleIdsPerUser = ( cb ) =>
|
||||
@log.info "DB | Fetching all active rules"
|
||||
@db.smembers 'users', ( err, obj ) =>
|
||||
result = {}
|
||||
if obj.length is 0
|
||||
cb null, result
|
||||
else
|
||||
semaphore = obj.length
|
||||
fFetchActiveUserRules = ( userId ) =>
|
||||
@db.smembers "user:#{ user }:active-rules", ( err, obj ) =>
|
||||
if obj.length > 0
|
||||
result[userId] = obj
|
||||
if --semaphore is 0
|
||||
cb null, result
|
||||
fFetchActiveUserRules user for user in obj
|
||||
@log.info "DB | Fetching all active rules"
|
||||
@db.smembers 'users', ( err, obj ) =>
|
||||
result = {}
|
||||
if obj.length is 0
|
||||
cb null, result
|
||||
else
|
||||
semaphore = obj.length
|
||||
fFetchActiveUserRules = ( userId ) =>
|
||||
@db.smembers "user:#{ user }:active-rules", ( err, obj ) =>
|
||||
if obj.length > 0
|
||||
result[userId] = obj
|
||||
if --semaphore is 0
|
||||
cb null, result
|
||||
fFetchActiveUserRules user for user in obj
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -594,15 +596,15 @@ The password should be hashed before it is passed to this function.
|
|||
@param {Object} objUser
|
||||
###
|
||||
exports.storeUser = ( objUser ) =>
|
||||
@log.info "DB | storeUser: '#{ objUser.username }'"
|
||||
if objUser and objUser.username and objUser.password
|
||||
@db.sadd 'users', objUser.username,
|
||||
replyHandler "storing user key '#{ objUser.username }'"
|
||||
objUser.password = objUser.password
|
||||
@db.hmset "user:#{ objUser.username }", objUser,
|
||||
replyHandler "storing user properties '#{ objUser.username }'"
|
||||
else
|
||||
@log.warn new Error 'DB | username or password was missing'
|
||||
@log.info "DB | storeUser: '#{ objUser.username }'"
|
||||
if objUser and objUser.username and objUser.password
|
||||
@db.sadd 'users', objUser.username,
|
||||
replyHandler "storing user key '#{ objUser.username }'"
|
||||
objUser.password = objUser.password
|
||||
@db.hmset "user:#{ objUser.username }", objUser,
|
||||
replyHandler "storing user properties '#{ objUser.username }'"
|
||||
else
|
||||
@log.warn new Error 'DB | username or password was missing'
|
||||
|
||||
###
|
||||
Fetch all user IDs and pass them to cb(err, obj).
|
||||
|
|
@ -611,9 +613,9 @@ Fetch all user IDs and pass them to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getUserIds = ( cb ) =>
|
||||
@log.info "DB | getUserIds"
|
||||
@db.smembers "users", cb
|
||||
|
||||
@log.info "DB | getUserIds"
|
||||
@db.smembers "users", cb
|
||||
|
||||
###
|
||||
Fetch a user by id and pass it to cb(err, obj).
|
||||
|
||||
|
|
@ -622,9 +624,9 @@ Fetch a user by id and pass it to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getUser = ( userId, cb ) =>
|
||||
@log.info "DB | getUser: '#{ userId }'"
|
||||
@db.hgetall "user:#{ userId }", cb
|
||||
|
||||
@log.info "DB | getUser: '#{ userId }'"
|
||||
@db.hgetall "user:#{ userId }", cb
|
||||
|
||||
###
|
||||
Deletes a user and all his associated linked and active rules.
|
||||
|
||||
|
|
@ -632,36 +634,36 @@ Deletes a user and all his associated linked and active rules.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.deleteUser = ( userId ) =>
|
||||
@log.info "DB | deleteUser: '#{ userId }'"
|
||||
@db.srem "users", userId, replyHandler "Deleting user key '#{ userId }'"
|
||||
@db.del "user:#{ userId }", replyHandler "Deleting user '#{ userId }'"
|
||||
@log.info "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 linked rules
|
||||
@db.smembers "user:#{ userId }:rules", ( err, obj ) =>
|
||||
delLinkedRuleUser = ( ruleId ) =>
|
||||
@db.srem "rule:#{ ruleId }:users", userId,
|
||||
replyHandler "Deleting user key '#{ userId }' in linked rule '#{ ruleId }'"
|
||||
delLinkedRuleUser id for id in obj
|
||||
@db.del "user:#{ userId }:rules",
|
||||
replyHandler "Deleting user '#{ userId }' rules"
|
||||
|
||||
# We also need to delete all active rules
|
||||
@db.smembers "user:#{ userId }:active-rules", ( err, obj ) =>
|
||||
delActivatedRuleUser = ( ruleId ) =>
|
||||
@db.srem "rule:#{ ruleId }:active-users", userId,
|
||||
replyHandler "Deleting user key '#{ userId }' in active rule '#{ ruleId }'"
|
||||
delActivatedRuleUser id for id in obj
|
||||
@db.del "user:#{ userId }:active-rules",
|
||||
replyHandler "Deleting user '#{ userId }' rules"
|
||||
# We also need to delete all active rules
|
||||
@db.smembers "user:#{ userId }:active-rules", ( err, obj ) =>
|
||||
delActivatedRuleUser = ( ruleId ) =>
|
||||
@db.srem "rule:#{ ruleId }:active-users", userId,
|
||||
replyHandler "Deleting user key '#{ userId }' in active rule '#{ ruleId }'"
|
||||
delActivatedRuleUser id for id in obj
|
||||
@db.del "user:#{ userId }:active-rules",
|
||||
replyHandler "Deleting user '#{ userId }' rules"
|
||||
|
||||
# We also need to delete all associated roles
|
||||
@db.smembers "user:#{ userId }:roles", ( err, obj ) =>
|
||||
delRoleUser = ( roleId ) =>
|
||||
@db.srem "role:#{ roleId }:users", userId,
|
||||
replyHandler "Deleting user key '#{ userId }' in role '#{ roleId }'"
|
||||
delRoleUser id for id in obj
|
||||
@db.del "user:#{ userId }:roles",
|
||||
replyHandler "Deleting user '#{ userId }' roles"
|
||||
# We also need to delete all associated roles
|
||||
@db.smembers "user:#{ userId }:roles", ( err, obj ) =>
|
||||
delRoleUser = ( roleId ) =>
|
||||
@db.srem "role:#{ roleId }:users", userId,
|
||||
replyHandler "Deleting user key '#{ userId }' in role '#{ roleId }'"
|
||||
delRoleUser id for id in obj
|
||||
@db.del "user:#{ userId }:roles",
|
||||
replyHandler "Deleting user '#{ userId }' roles"
|
||||
|
||||
###
|
||||
Checks the credentials and on success returns the user object to the
|
||||
|
|
@ -675,20 +677,20 @@ because we only store hashes of passwords for security6 reasons.
|
|||
@param {function} cb
|
||||
###
|
||||
exports.loginUser = ( userId, password, cb ) =>
|
||||
@log.info "DB | User '#{ userId }' tries to log in"
|
||||
fCheck = ( pw ) =>
|
||||
( err, obj ) =>
|
||||
if err
|
||||
cb err, null
|
||||
else if obj and obj.password
|
||||
if pw is obj.password
|
||||
@log.info "DB | User '#{ obj.username }' logged in!"
|
||||
cb null, obj
|
||||
else
|
||||
cb (new Error 'Wrong credentials!'), null
|
||||
else
|
||||
cb (new Error 'User not found!'), null
|
||||
@db.hgetall "user:#{ userId }", fCheck password
|
||||
@log.info "DB | User '#{ userId }' tries to log in"
|
||||
fCheck = ( pw ) =>
|
||||
( err, obj ) =>
|
||||
if err
|
||||
cb err, null
|
||||
else if obj and obj.password
|
||||
if pw is obj.password
|
||||
@log.info "DB | User '#{ obj.username }' logged in!"
|
||||
cb null, obj
|
||||
else
|
||||
cb (new Error 'Wrong credentials!'), null
|
||||
else
|
||||
cb (new Error 'User not found!'), null
|
||||
@db.hgetall "user:#{ userId }", fCheck password
|
||||
|
||||
#TODO implement functions required for user sessions?
|
||||
|
||||
|
|
@ -705,12 +707,12 @@ Associate a role with a user.
|
|||
@param {String} role
|
||||
###
|
||||
exports.storeUserRole = ( userId, role ) =>
|
||||
@log.info "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.info "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 cb(err, obj).
|
||||
|
|
@ -720,9 +722,9 @@ Fetch all roles of a user and pass them to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getUserRoles = ( userId, cb ) =>
|
||||
@log.info "DB | getUserRoles: '#{ userId }'"
|
||||
@db.smembers "user:#{ userId }:roles", cb
|
||||
|
||||
@log.info "DB | getUserRoles: '#{ userId }'"
|
||||
@db.smembers "user:#{ userId }:roles", cb
|
||||
|
||||
###
|
||||
Fetch all users of a role and pass them to cb(err, obj).
|
||||
|
||||
|
|
@ -731,8 +733,8 @@ Fetch all users of a role and pass them to cb(err, obj).
|
|||
@param {function} cb
|
||||
###
|
||||
exports.getRoleUsers = ( role, cb ) =>
|
||||
@log.info "DB | getRoleUsers: '#{ role }'"
|
||||
@db.smembers "role:#{ role }:users", cb
|
||||
@log.info "DB | getRoleUsers: '#{ role }'"
|
||||
@db.smembers "role:#{ role }:users", cb
|
||||
|
||||
###
|
||||
Remove a role from a user.
|
||||
|
|
@ -742,11 +744,11 @@ Remove a role from a user.
|
|||
@param {String} userId
|
||||
###
|
||||
exports.removeUserRole = ( userId, role ) =>
|
||||
@log.info "DB | removeRoleFromUser: role '#{ role }', user '#{ userId }'"
|
||||
@db.srem "user:#{ userId }:roles", role,
|
||||
replyHandler "Removing role '#{ role }' from user '#{ userId }'"
|
||||
@db.srem "role:#{ role }:users", userId,
|
||||
replyHandler "Removing user '#{ userId }' from role '#{ role }'"
|
||||
@log.info "DB | removeRoleFromUser: role '#{ role }', user '#{ userId }'"
|
||||
@db.srem "user:#{ userId }:roles", role,
|
||||
replyHandler "Removing role '#{ role }' from user '#{ userId }'"
|
||||
@db.srem "role:#{ role }:users", userId,
|
||||
replyHandler "Removing user '#{ userId }' from role '#{ role }'"
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -755,5 +757,5 @@ Shuts down the db link.
|
|||
@public shutDown()
|
||||
###
|
||||
exports.shutDown = () =>
|
||||
@db?.quit()
|
||||
# @db?.end()
|
||||
@db?.quit()
|
||||
# @db?.end()
|
||||
|
|
|
|||
|
|
@ -25,32 +25,32 @@ qs = require 'querystring'
|
|||
# [crypto-js](https://github.com/evanvosberg/crypto-js)
|
||||
mustache = require 'mustache'
|
||||
crypto = require 'crypto-js'
|
||||
|
||||
|
||||
# Prepare the user command handlers which are invoked via HTTP requests.
|
||||
dirHandlers = path.resolve __dirname, '..', 'webpages', 'handlers'
|
||||
exports = module.exports = ( args ) =>
|
||||
@log = args.logger
|
||||
@log = args.logger
|
||||
|
||||
# Register the request service
|
||||
@userRequestHandler = args[ 'request-service' ]
|
||||
# Register the request service
|
||||
@userRequestHandler = args[ 'request-service' ]
|
||||
|
||||
# Register the shutdown handler to the admin command.
|
||||
@objAdminCmds =
|
||||
shutdown: ( obj, cb ) ->
|
||||
data =
|
||||
code: 200
|
||||
message: 'Shutting down... BYE!'
|
||||
setTimeout args[ 'shutdown-function' ], 500
|
||||
cb null, data
|
||||
db args
|
||||
# Register the shutdown handler to the admin command.
|
||||
@objAdminCmds =
|
||||
shutdown: ( obj, cb ) ->
|
||||
data =
|
||||
code: 200
|
||||
message: 'Shutting down... BYE!'
|
||||
setTimeout args[ 'shutdown-function' ], 500
|
||||
cb null, data
|
||||
db args
|
||||
|
||||
# Load the standard users from the user config file
|
||||
users = JSON.parse fs.readFileSync path.resolve __dirname, '..', 'config', 'users.json'
|
||||
fStoreUser = ( username, oUser ) ->
|
||||
oUser.username = username
|
||||
db.storeUser oUser
|
||||
fStoreUser user, oUser for user, oUser of users
|
||||
module.exports
|
||||
# Load the standard users from the user config file
|
||||
users = JSON.parse fs.readFileSync path.resolve __dirname, '..', 'config', 'users.json'
|
||||
fStoreUser = ( username, oUser ) ->
|
||||
oUser.username = username
|
||||
db.storeUser oUser
|
||||
fStoreUser user, oUser for user, oUser of users
|
||||
module.exports
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -65,32 +65,32 @@ objects.*
|
|||
@public handleEvent( *req, resp* )
|
||||
###
|
||||
exports.handleEvent = ( req, resp ) ->
|
||||
body = ''
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
body = ''
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
|
||||
req.on 'end', ->
|
||||
#if req.session and req.session.user
|
||||
try
|
||||
obj = JSON.parse body
|
||||
console.log 'got foreign event!'
|
||||
console.log obj
|
||||
catch err
|
||||
resp.send 400, 'Badly formed event!'
|
||||
# If required event properties are present we process the event #
|
||||
if obj and obj.event and not err
|
||||
timestamp = ( new Date ).toISOString()
|
||||
rand = ( Math.floor Math.random() * 10e9 ).toString( 16 ).toUpperCase()
|
||||
obj.eventid = "#{ obj.event }_#{ timestamp }_#{ rand }"
|
||||
answ =
|
||||
code: 200
|
||||
message: "Thank you for the event: #{ obj.eventid }"
|
||||
resp.send answ.code, answ
|
||||
db.pushEvent obj
|
||||
else
|
||||
resp.send 400, 'Your event was missing important parameters!'
|
||||
# else
|
||||
# resp.send 401, 'Please login!'
|
||||
req.on 'end', ->
|
||||
#if req.session and req.session.user
|
||||
try
|
||||
obj = JSON.parse body
|
||||
console.log 'got foreign event!'
|
||||
console.log obj
|
||||
catch err
|
||||
resp.send 400, 'Badly formed event!'
|
||||
# If required event properties are present we process the event #
|
||||
if obj and obj.event and not err
|
||||
timestamp = ( new Date ).toISOString()
|
||||
rand = ( Math.floor Math.random() * 10e9 ).toString( 16 ).toUpperCase()
|
||||
obj.eventid = "#{ obj.event }_#{ timestamp }_#{ rand }"
|
||||
answ =
|
||||
code: 200
|
||||
message: "Thank you for the event: #{ obj.eventid }"
|
||||
resp.send answ.code, answ
|
||||
db.pushEvent obj
|
||||
else
|
||||
resp.send 400, 'Your event was missing important parameters!'
|
||||
# else
|
||||
# resp.send 401, 'Please login!'
|
||||
|
||||
|
||||
|
||||
|
|
@ -105,21 +105,21 @@ objects.*
|
|||
@public handleLogin( *req, resp* )
|
||||
###
|
||||
exports.handleLogin = ( req, resp ) =>
|
||||
body = ''
|
||||
req.on 'data', ( data ) -> body += data
|
||||
req.on 'end', =>
|
||||
obj = JSON.parse body
|
||||
db.loginUser obj.username, obj.password, ( err, usr ) =>
|
||||
if err
|
||||
# Tapping on fingers, at least in log...
|
||||
@log.warn "RH | AUTH-UH-OH ( #{ obj.username } ): #{ err.message }"
|
||||
else
|
||||
# no error, so we can associate the user object from the DB to the session
|
||||
req.session.user = usr
|
||||
if req.session.user
|
||||
resp.send 'OK!'
|
||||
else
|
||||
resp.send 401, 'NO!'
|
||||
body = ''
|
||||
req.on 'data', ( data ) -> body += data
|
||||
req.on 'end', =>
|
||||
obj = JSON.parse body
|
||||
db.loginUser obj.username, obj.password, ( err, usr ) =>
|
||||
if err
|
||||
# Tapping on fingers, at least in log...
|
||||
@log.warn "RH | AUTH-UH-OH ( #{ obj.username } ): #{ err.message }"
|
||||
else
|
||||
# no error, so we can associate the user object from the DB to the session
|
||||
req.session.user = usr
|
||||
if req.session.user
|
||||
resp.send 'OK!'
|
||||
else
|
||||
resp.send 401, 'NO!'
|
||||
|
||||
###
|
||||
A post request retrieved on this handler causes the user object to be
|
||||
|
|
@ -133,9 +133,9 @@ objects.*
|
|||
@public handleLogout( *req, resp* )
|
||||
###
|
||||
exports.handleLogout = ( req, resp ) ->
|
||||
if req.session
|
||||
req.session.user = null
|
||||
resp.send 'Bye!'
|
||||
if req.session
|
||||
req.session.user = null
|
||||
resp.send 'Bye!'
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -145,7 +145,7 @@ Resolves the path to a handler webpage.
|
|||
@param {String} name
|
||||
###
|
||||
getHandlerPath = ( name ) ->
|
||||
path.join dirHandlers, name + '.html'
|
||||
path.join dirHandlers, name + '.html'
|
||||
|
||||
###
|
||||
Fetches a template.
|
||||
|
|
@ -154,9 +154,9 @@ Fetches a template.
|
|||
@param {String} name
|
||||
###
|
||||
getTemplate = ( name ) ->
|
||||
pth = path.join dirHandlers, 'templates', name + '.html'
|
||||
fs.readFileSync pth, 'utf8'
|
||||
|
||||
pth = path.join dirHandlers, 'templates', name + '.html'
|
||||
fs.readFileSync pth, 'utf8'
|
||||
|
||||
###
|
||||
Fetches a script.
|
||||
|
||||
|
|
@ -164,9 +164,9 @@ Fetches a script.
|
|||
@param {String} name
|
||||
###
|
||||
getScript = ( name ) ->
|
||||
pth = path.join dirHandlers, 'js', name + '.js'
|
||||
fs.readFileSync pth, 'utf8'
|
||||
|
||||
pth = path.join dirHandlers, 'js', name + '.js'
|
||||
fs.readFileSync pth, 'utf8'
|
||||
|
||||
###
|
||||
Fetches remote scripts snippets.
|
||||
|
||||
|
|
@ -174,9 +174,9 @@ Fetches remote scripts snippets.
|
|||
@param {String} name
|
||||
###
|
||||
getRemoteScripts = ( name ) ->
|
||||
pth = path.join dirHandlers, 'remote-scripts', name + '.html'
|
||||
fs.readFileSync pth, 'utf8'
|
||||
|
||||
pth = path.join dirHandlers, 'remote-scripts', name + '.html'
|
||||
fs.readFileSync pth, 'utf8'
|
||||
|
||||
###
|
||||
Renders a page, with helps of mustache, depending on the user session and returns it.
|
||||
|
||||
|
|
@ -186,46 +186,46 @@ Renders a page, with helps of mustache, depending on the user session and return
|
|||
@param {Object} msg
|
||||
###
|
||||
renderPage = ( name, req, resp, msg ) ->
|
||||
# Grab the skeleton
|
||||
pathSkel = path.join dirHandlers, 'skeleton.html'
|
||||
skeleton = fs.readFileSync pathSkel, 'utf8'
|
||||
code = 200
|
||||
data =
|
||||
message: msg
|
||||
user: req.session.user
|
||||
# Grab the skeleton
|
||||
pathSkel = path.join dirHandlers, 'skeleton.html'
|
||||
skeleton = fs.readFileSync pathSkel, 'utf8'
|
||||
code = 200
|
||||
data =
|
||||
message: msg
|
||||
user: req.session.user
|
||||
|
||||
# Try to grab the script belonging to this page. But don't bother if it's not existing
|
||||
try
|
||||
script = getScript name
|
||||
# Try to grab the remote scripts belonging to this page. But don't bother if it's not existing
|
||||
try
|
||||
remote_scripts = getRemoteScripts name
|
||||
# Try to grab the script belonging to this page. But don't bother if it's not existing
|
||||
try
|
||||
script = getScript name
|
||||
# Try to grab the remote scripts belonging to this page. But don't bother if it's not existing
|
||||
try
|
||||
remote_scripts = getRemoteScripts name
|
||||
|
||||
# Now try to find the page the user requested.
|
||||
try
|
||||
content = getTemplate name
|
||||
catch err
|
||||
# If the page doesn't exist we return the error page, load the error script into it
|
||||
# and render the error page with some additional data
|
||||
content = getTemplate 'error'
|
||||
script = getScript 'error'
|
||||
code = 404
|
||||
data.message = 'Invalid Page!'
|
||||
# Now try to find the page the user requested.
|
||||
try
|
||||
content = getTemplate name
|
||||
catch err
|
||||
# If the page doesn't exist we return the error page, load the error script into it
|
||||
# and render the error page with some additional data
|
||||
content = getTemplate 'error'
|
||||
script = getScript 'error'
|
||||
code = 404
|
||||
data.message = 'Invalid Page!'
|
||||
|
||||
if req.session.user
|
||||
menubar = getTemplate 'menubar'
|
||||
if req.session.user
|
||||
menubar = getTemplate 'menubar'
|
||||
|
||||
pageElements =
|
||||
content: content
|
||||
script: script
|
||||
remote_scripts: remote_scripts
|
||||
menubar: menubar
|
||||
pageElements =
|
||||
content: content
|
||||
script: script
|
||||
remote_scripts: remote_scripts
|
||||
menubar: menubar
|
||||
|
||||
# First we render the page by including all page elements into the skeleton
|
||||
page = mustache.render skeleton, pageElements
|
||||
# First we render the page by including all page elements into the skeleton
|
||||
page = mustache.render skeleton, pageElements
|
||||
|
||||
# Then we complete the rendering by adding the data, and send the result to the user
|
||||
resp.send code, mustache.render page, data
|
||||
# Then we complete the rendering by adding the data, and send the result to the user
|
||||
resp.send code, mustache.render page, data
|
||||
|
||||
###
|
||||
Present the desired forge page to the user.
|
||||
|
|
@ -238,10 +238,10 @@ objects.*
|
|||
@public handleForge( *req, resp* )
|
||||
###
|
||||
exports.handleForge = ( req, resp ) ->
|
||||
page = req.query.page
|
||||
if not req.session.user
|
||||
page = 'login'
|
||||
renderPage page, req, resp
|
||||
page = req.query.page
|
||||
if not req.session.user
|
||||
page = 'login'
|
||||
renderPage page, req, resp
|
||||
|
||||
###
|
||||
Handles the user command requests.
|
||||
|
|
@ -254,18 +254,18 @@ objects.*
|
|||
@public handleUser( *req, resp* )
|
||||
###
|
||||
exports.handleUserCommand = ( req, resp ) =>
|
||||
if req.session and req.session.user
|
||||
body = ''
|
||||
#Append data to body while receiving fragments
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
req.on 'end', =>
|
||||
obj = qs.parse body
|
||||
# Let the user request handler service answer the request
|
||||
@userRequestHandler req.session.user, obj, ( obj ) ->
|
||||
resp.send obj.code, obj
|
||||
else
|
||||
resp.send 401, 'Login first!'
|
||||
if req.session and req.session.user
|
||||
body = ''
|
||||
#Append data to body while receiving fragments
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
req.on 'end', =>
|
||||
obj = qs.parse body
|
||||
# Let the user request handler service answer the request
|
||||
@userRequestHandler req.session.user, obj, ( obj ) ->
|
||||
resp.send obj.code, obj
|
||||
else
|
||||
resp.send 401, 'Login first!'
|
||||
|
||||
|
||||
###
|
||||
|
|
@ -279,15 +279,15 @@ objects.*
|
|||
@public handleForge( *req, resp* )
|
||||
###
|
||||
exports.handleAdmin = ( req, resp ) ->
|
||||
if not req.session.user
|
||||
page = 'login'
|
||||
#TODO isAdmin should come from the db role
|
||||
else if req.session.user.isAdmin isnt "true"
|
||||
page = 'login'
|
||||
msg = 'You need to be admin!'
|
||||
else
|
||||
page = 'admin'
|
||||
renderPage page, req, resp, msg
|
||||
if not req.session.user
|
||||
page = 'login'
|
||||
#TODO isAdmin should come from the db role
|
||||
else if req.session.user.isAdmin isnt "true"
|
||||
page = 'login'
|
||||
msg = 'You need to be admin!'
|
||||
else
|
||||
page = 'admin'
|
||||
renderPage page, req, resp, msg
|
||||
|
||||
###
|
||||
Handles the admin command requests.
|
||||
|
|
@ -300,20 +300,20 @@ objects.*
|
|||
@public handleAdminCommand( *req, resp* )
|
||||
###
|
||||
exports.handleAdminCommand = ( req, resp ) =>
|
||||
if req.session and
|
||||
req.session.user and
|
||||
req.session.user.isAdmin is "true"
|
||||
body = ''
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
req.on 'end', =>
|
||||
obj = qs.parse body
|
||||
@log.info 'RH | Received admin request: ' + obj.command
|
||||
if obj.command and @objAdminCmds[obj.command]
|
||||
@objAdminCmds[obj.command] obj, ( err, obj ) ->
|
||||
resp.send obj.code, obj
|
||||
else
|
||||
resp.send 404, 'Command unknown!'
|
||||
else
|
||||
resp.send 401, 'You need to be logged in as admin!'
|
||||
|
||||
if req.session and
|
||||
req.session.user and
|
||||
req.session.user.isAdmin is "true"
|
||||
body = ''
|
||||
req.on 'data', ( data ) ->
|
||||
body += data
|
||||
req.on 'end', =>
|
||||
obj = qs.parse body
|
||||
@log.info 'RH | Received admin request: ' + obj.command
|
||||
if obj.command and @objAdminCmds[obj.command]
|
||||
@objAdminCmds[obj.command] obj, ( err, obj ) ->
|
||||
resp.send obj.code, obj
|
||||
else
|
||||
resp.send 404, 'Command unknown!'
|
||||
else
|
||||
resp.send 401, 'You need to be logged in as admin!'
|
||||
|
||||
|
|
|
|||
|
|
@ -51,69 +51,69 @@ Let's prepare the optimist CLI optional arguments `[opt]`:
|
|||
usage = 'This runs your webapi-based ECA engine'
|
||||
opt =
|
||||
# `-h`, `--help`: Display the help
|
||||
'h':
|
||||
alias : 'help',
|
||||
describe: 'Display this'
|
||||
'h':
|
||||
alias : 'help',
|
||||
describe: 'Display this'
|
||||
# `-c`, `--config-path`: Specify a path to a custom configuration file, other than "config/config.json"
|
||||
'c':
|
||||
alias : 'config-path',
|
||||
describe: 'Specify a path to a custom configuration file, other than "config/config.json"'
|
||||
'c':
|
||||
alias : 'config-path',
|
||||
describe: 'Specify a path to a custom configuration file, other than "config/config.json"'
|
||||
# `-w`, `--http-port`: Specify a HTTP port for the web server
|
||||
'w':
|
||||
alias : 'http-port',
|
||||
describe: 'Specify a HTTP port for the web server'
|
||||
'w':
|
||||
alias : 'http-port',
|
||||
describe: 'Specify a HTTP port for the web server'
|
||||
# `-d`, `--db-port`: Specify a port for the redis DB
|
||||
'd':
|
||||
alias : 'db-port',
|
||||
describe: 'Specify a port for the redis DB'
|
||||
'd':
|
||||
alias : 'db-port',
|
||||
describe: 'Specify a port for the redis DB'
|
||||
# `-m`, `--log-mode`: Specify a log mode: [development|productive]
|
||||
'm':
|
||||
alias : 'log-mode',
|
||||
describe: 'Specify a log mode: [development|productive]'
|
||||
'm':
|
||||
alias : 'log-mode',
|
||||
describe: 'Specify a log mode: [development|productive]'
|
||||
# `-i`, `--log-io-level`: Specify the log level for the I/O. in development expensive origin
|
||||
# lookups are made and added to the log entries
|
||||
'i':
|
||||
alias : 'log-io-level',
|
||||
describe: 'Specify the log level for the I/O'
|
||||
'i':
|
||||
alias : 'log-io-level',
|
||||
describe: 'Specify the log level for the I/O'
|
||||
# `-f`, `--log-file-level`: Specify the log level for the log file
|
||||
'f':
|
||||
alias : 'log-file-level',
|
||||
describe: 'Specify the log level for the log file'
|
||||
'f':
|
||||
alias : 'log-file-level',
|
||||
describe: 'Specify the log level for the log file'
|
||||
# `-p`, `--log-file-path`: Specify the path to the log file within the "logs" folder
|
||||
'p':
|
||||
alias : 'log-file-path',
|
||||
describe: 'Specify the path to the log file within the "logs" folder'
|
||||
'p':
|
||||
alias : 'log-file-path',
|
||||
describe: 'Specify the path to the log file within the "logs" folder'
|
||||
# `-n`, `--nolog`: Set this true if no output shall be generated
|
||||
'n':
|
||||
alias : 'nolog',
|
||||
describe: 'Set this if no output shall be generated'
|
||||
'n':
|
||||
alias : 'nolog',
|
||||
describe: 'Set this if no output shall be generated'
|
||||
|
||||
# now fetch the CLI arguments and exit if the help has been called.
|
||||
argv = optimist.usage( usage ).options( opt ).argv
|
||||
if argv.help
|
||||
console.log optimist.help()
|
||||
process.exit()
|
||||
console.log optimist.help()
|
||||
process.exit()
|
||||
|
||||
conf argv.c
|
||||
# > Check whether the config file is ready, which is required to start the server.
|
||||
if !conf.isReady()
|
||||
console.error 'FAIL: Config file not ready! Shutting down...'
|
||||
process.exit()
|
||||
console.error 'FAIL: Config file not ready! Shutting down...'
|
||||
process.exit()
|
||||
|
||||
logconf = conf.getLogConf()
|
||||
|
||||
if argv.m
|
||||
logconf[ 'mode' ] = argv.m
|
||||
logconf[ 'mode' ] = argv.m
|
||||
if argv.i
|
||||
logconf[ 'io-level' ] = argv.i
|
||||
logconf[ 'io-level' ] = argv.i
|
||||
if argv.f
|
||||
logconf[ 'file-level' ] = argv.f
|
||||
logconf[ 'file-level' ] = argv.f
|
||||
if argv.p
|
||||
logconf[ 'file-path' ] = argv.p
|
||||
logconf[ 'file-path' ] = argv.p
|
||||
if argv.n
|
||||
logconf[ 'nolog' ] = true
|
||||
logconf[ 'nolog' ] = true
|
||||
try
|
||||
fs.unlinkSync path.resolve __dirname, '..', 'logs', logconf[ 'file-path' ]
|
||||
fs.unlinkSync path.resolve __dirname, '..', 'logs', logconf[ 'file-path' ]
|
||||
@log = logger.getLogger logconf
|
||||
@log.info 'RS | STARTING SERVER'
|
||||
|
||||
|
|
@ -124,80 +124,81 @@ This function is invoked right after the module is loaded and starts the server.
|
|||
###
|
||||
init = =>
|
||||
|
||||
args =
|
||||
logger: @log
|
||||
logconf: logconf
|
||||
# > Fetch the `http-port` argument
|
||||
args[ 'http-port' ] = parseInt argv.w || conf.getHttpPort()
|
||||
args[ 'db-port' ] = parseInt argv.d || conf.getDbPort()
|
||||
args =
|
||||
logger: @log
|
||||
logconf: logconf
|
||||
# > Fetch the `http-port` argument
|
||||
args[ 'http-port' ] = parseInt argv.w || conf.getHttpPort()
|
||||
args[ 'db-port' ] = parseInt argv.d || conf.getDbPort()
|
||||
|
||||
#FIXME this has to come from user input for security reasons:
|
||||
args[ 'keygen' ] = conf.getKeygenPassphrase()
|
||||
|
||||
@log.info 'RS | Initialzing DB'
|
||||
db args
|
||||
# > We only proceed with the initialization if the DB is ready
|
||||
#TODO eventually we shouldn't let each module load its own persistence
|
||||
#module, but hand this one through them via the args...
|
||||
db.isConnected ( err ) =>
|
||||
if err
|
||||
@log.error 'RS | No DB connection, shutting down system!'
|
||||
shutDown()
|
||||
#FIXME this has to come from user input for security reasons:
|
||||
args[ 'keygen' ] = conf.getKeygenPassphrase()
|
||||
args[ 'webhooks' ] = conf.fetchProp 'webhooks'
|
||||
|
||||
@log.info 'RS | Initialzing DB'
|
||||
db args
|
||||
# > We only proceed with the initialization if the DB is ready
|
||||
#TODO eventually we shouldn't let each module load its own persistence
|
||||
#module, but hand this one through them via the args...
|
||||
db.isConnected ( err ) =>
|
||||
if err
|
||||
@log.error 'RS | No DB connection, shutting down system!'
|
||||
shutDown()
|
||||
|
||||
else
|
||||
# > Initialize all required modules with the args object.
|
||||
@log.info 'RS | Initialzing engine'
|
||||
#TODO We could in the future make the engine a child process as well
|
||||
engine args
|
||||
|
||||
# Start the event poller. The module manager will emit events for it
|
||||
@log.info 'RS | Forking a child process for the event poller'
|
||||
# Grab all required log config fields
|
||||
|
||||
cliArgs = [
|
||||
# - the log mode: [development|productive], in development expensive origin
|
||||
# lookups are made and added to the log entries
|
||||
args.logconf[ 'mode' ]
|
||||
# - the I/O log level, refer to logging.coffee for the different levels
|
||||
args.logconf[ 'io-level' ]
|
||||
# - the file log level, refer to logging.coffee for the different levels
|
||||
args.logconf[ 'file-level' ]
|
||||
# - the optional path to the log file
|
||||
args.logconf[ 'file-path' ]
|
||||
# - whether a log file shall be written at all [true|false]
|
||||
args.logconf[ 'nolog' ]
|
||||
# - The keygen phrase, this has to be handled differently in the future!
|
||||
args[ 'keygen' ]
|
||||
]
|
||||
poller = cp.fork path.resolve( __dirname, nameEP ), cliArgs
|
||||
else
|
||||
# > Initialize all required modules with the args object.
|
||||
@log.info 'RS | Initialzing engine'
|
||||
#TODO We could in the future make the engine a child process as well
|
||||
engine args
|
||||
|
||||
# Start the event poller. The module manager will emit events for it
|
||||
@log.info 'RS | Forking a child process for the event poller'
|
||||
# Grab all required log config fields
|
||||
|
||||
cliArgs = [
|
||||
# - the log mode: [development|productive], in development expensive origin
|
||||
# lookups are made and added to the log entries
|
||||
args.logconf[ 'mode' ]
|
||||
# - the I/O log level, refer to logging.coffee for the different levels
|
||||
args.logconf[ 'io-level' ]
|
||||
# - the file log level, refer to logging.coffee for the different levels
|
||||
args.logconf[ 'file-level' ]
|
||||
# - the optional path to the log file
|
||||
args.logconf[ 'file-path' ]
|
||||
# - whether a log file shall be written at all [true|false]
|
||||
args.logconf[ 'nolog' ]
|
||||
# - The keygen phrase, this has to be handled differently in the future!
|
||||
args[ 'keygen' ]
|
||||
]
|
||||
poller = cp.fork path.resolve( __dirname, nameEP ), cliArgs
|
||||
|
||||
# after the engine and the event poller have been initialized we can
|
||||
# initialize the module manager and register event listener functions
|
||||
# from engine and event poller
|
||||
@log.info 'RS | Initialzing module manager'
|
||||
cm args
|
||||
cm.addRuleListener engine.internalEvent
|
||||
cm.addRuleListener ( evt ) -> poller.send evt
|
||||
# after the engine and the event poller have been initialized we can
|
||||
# initialize the module manager and register event listener functions
|
||||
# from engine and event poller
|
||||
@log.info 'RS | Initialzing module manager'
|
||||
cm args
|
||||
cm.addRuleListener engine.internalEvent
|
||||
cm.addRuleListener ( evt ) -> poller.send evt
|
||||
|
||||
@log.info 'RS | Initialzing http listener'
|
||||
# The request handler passes certain requests to the module manager
|
||||
args[ 'request-service' ] = cm.processRequest
|
||||
# We give the HTTP listener the ability to shutdown the whole system
|
||||
args[ 'shutdown-function' ] = shutDown
|
||||
http args
|
||||
|
||||
@log.info 'RS | Initialzing http listener'
|
||||
# The request handler passes certain requests to the module manager
|
||||
args[ 'request-service' ] = cm.processRequest
|
||||
# We give the HTTP listener the ability to shutdown the whole system
|
||||
args[ 'shutdown-function' ] = shutDown
|
||||
http args
|
||||
|
||||
###
|
||||
Shuts down the server.
|
||||
|
||||
@private shutDown()
|
||||
###
|
||||
shutDown = () =>
|
||||
@log.warn 'RS | Received shut down command!'
|
||||
db?.shutDown()
|
||||
engine.shutDown()
|
||||
# We need to call process.exit() since the express server in the http-listener
|
||||
# can't be stopped gracefully. Why would you stop this system anyways!??
|
||||
process.exit()
|
||||
@log.warn 'RS | Received shut down command!'
|
||||
db?.shutDown()
|
||||
engine.shutDown()
|
||||
# We need to call process.exit() since the express server in the http-listener
|
||||
# can't be stopped gracefully. Why would you stop this system anyways!??
|
||||
process.exit()
|
||||
|
||||
###
|
||||
## Process Commands
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@
|
|||
"file-level": "info",
|
||||
"file-path": "logs/server.log"
|
||||
},
|
||||
"webhooks": [
|
||||
"github"
|
||||
],
|
||||
"keygen-passphrase": "[TODO this has to come from prompt when server is started!]"
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
###
|
||||
ProBinder ACTION INVOKER
|
||||
------------------------
|
||||
|
|
@ -6,8 +8,6 @@ Global variables
|
|||
This module requires user-specific parameters:
|
||||
- username
|
||||
- password
|
||||
- companyId: company where to post the binder entries
|
||||
- contextId: context where to post the binder entries
|
||||
###
|
||||
urlService = 'https://probinder.com/service/'
|
||||
credentials =
|
||||
|
|
@ -44,50 +44,45 @@ callService = ( args ) ->
|
|||
if not args.callback
|
||||
args.callback = standardCallback 'call'
|
||||
url = urlService + args.service + '/' + args.method
|
||||
needlereq 'post', url, args.data, credentials, args.callback
|
||||
needle.request 'post', url, args.data, credentials, args.callback
|
||||
|
||||
|
||||
###
|
||||
Does everything to post something in a binder
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.content the content to be posted
|
||||
@param {String} companyId the comany associated to the binder
|
||||
@param {String} contextId the binder id
|
||||
@param {String} content the content to be posted
|
||||
###
|
||||
exports.newContent = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'newContent'
|
||||
exports.newContent = ( companyId, contextId, content ) ->
|
||||
if arguments[ 4 ]
|
||||
callback = arguments[ 4 ]
|
||||
else
|
||||
callback = standardCallback 'newContent'
|
||||
callService
|
||||
service: '27'
|
||||
method: 'save'
|
||||
data:
|
||||
companyId: params.companyId
|
||||
context: params.contextId
|
||||
text: args.content
|
||||
callback: args.callback
|
||||
companyId: companyId
|
||||
context: contextId
|
||||
text: content
|
||||
callback: callback
|
||||
|
||||
###
|
||||
Does everything to post a file info in a binder tabe
|
||||
Does everything to post a file info in a binder tab
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.service the content service
|
||||
@param {String} args.id the content id
|
||||
@param {String} fromService the content service which grabs the content
|
||||
@param {String} fromId the content id from which the information is grabbed
|
||||
###
|
||||
exports.makeFileEntry = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'makeFileEntry'
|
||||
exports.makeFileEntry = ( fromService, fromId, toCompany, toContext ) ->
|
||||
getContent
|
||||
serviceid: args.service
|
||||
contentid: args.id
|
||||
serviceid: fromService
|
||||
contentid: fromId
|
||||
callback: ( err, resp, body ) ->
|
||||
callService
|
||||
service: '27'
|
||||
method: 'save'
|
||||
data:
|
||||
companyId: params.companyId
|
||||
context: params.contextId
|
||||
text: "New file (#{ body.title }) in tab \"#{ body.context[0].name }\",
|
||||
find it <a href=\"https://probinder.com/file/#{ body.fileIds[0] }\">here</a>!'"
|
||||
callback: args.callback
|
||||
content = "New file (#{ body.title }) in tab \"#{ body.context[0].name }\",
|
||||
find it here!'"
|
||||
exports.newContent toCompanyId, toContextId, content, standardCallback 'makeFileEntry'
|
||||
|
||||
|
||||
###
|
||||
Calls the content get service with the content id and the service id provided.
|
||||
|
|
@ -112,15 +107,12 @@ getContent = ( args ) ->
|
|||
###
|
||||
Sets the content as read.
|
||||
|
||||
@param {Object} args the object containing the content
|
||||
@param {String} args.content the content to be posted
|
||||
@param {Object} id the content id to be set to read.
|
||||
###
|
||||
exports.setRead = ( args ) ->
|
||||
if not args.callback
|
||||
args.callback = standardCallback 'setRead'
|
||||
exports.setRead = ( id ) ->
|
||||
callService
|
||||
service: '2'
|
||||
method: 'setread'
|
||||
data:
|
||||
id: args.id
|
||||
callback: args.callback
|
||||
id: id
|
||||
callback: standardCallback 'setRead'
|
||||
|
|
|
|||
|
|
@ -18,26 +18,7 @@ cs = require 'coffee-script'
|
|||
needle = require 'needle'
|
||||
crypto = require 'crypto-js'
|
||||
request = require 'request'
|
||||
|
||||
issueApiCall = ( method, url, data, options, cb ) ->
|
||||
try
|
||||
needle.request method, url, data, options, ( err, resp, body ) =>
|
||||
try
|
||||
cb err, resp, body
|
||||
catch err
|
||||
console.log 'Error during needle request! ' + err.message
|
||||
catch err
|
||||
console.log 'Error before needle request! ' + err.message
|
||||
|
||||
issueRequest = ( options, cb ) ->
|
||||
try
|
||||
request options, ( err, resp, body ) =>
|
||||
try
|
||||
cb err, resp, body
|
||||
catch err
|
||||
console.log 'Error during request! ' + err.message
|
||||
catch err
|
||||
console.log 'Error before request! ' + err.message
|
||||
importio = require( 'import-io' ).client
|
||||
|
||||
params = JSON.parse fs.readFileSync 'params.json', 'utf8'
|
||||
code = fs.readFileSync process.argv[ 2 ], 'utf8'
|
||||
|
|
@ -46,9 +27,10 @@ src = cs.compile code
|
|||
sandbox =
|
||||
id: 'test.vm'
|
||||
params: params.userparams
|
||||
needlereq: issueApiCall
|
||||
request: issueRequest
|
||||
needle: needle
|
||||
request: request
|
||||
cryptoJS: crypto
|
||||
importio: importio
|
||||
log: console.log
|
||||
debug: console.log
|
||||
exports: {}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ compilation and running of module code
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var code, crypto, cs, fs, issueApiCall, issueRequest, needle, params, request, sandbox, src, vm;
|
||||
var code, crypto, cs, fs, importio, needle, params, request, sandbox, src, vm;
|
||||
|
||||
if (!process.argv[2]) {
|
||||
console.log('Please provide a path to a coffee file');
|
||||
|
|
@ -28,43 +28,7 @@ compilation and running of module code
|
|||
|
||||
request = require('request');
|
||||
|
||||
issueApiCall = function(method, url, data, options, cb) {
|
||||
var err;
|
||||
try {
|
||||
return needle.request(method, url, data, options, (function(_this) {
|
||||
return function(err, resp, body) {
|
||||
try {
|
||||
return cb(err, resp, body);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return console.log('Error during needle request! ' + err.message);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return console.log('Error before needle request! ' + err.message);
|
||||
}
|
||||
};
|
||||
|
||||
issueRequest = function(options, cb) {
|
||||
var err;
|
||||
try {
|
||||
return request(options, (function(_this) {
|
||||
return function(err, resp, body) {
|
||||
try {
|
||||
return cb(err, resp, body);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return console.log('Error during request! ' + err.message);
|
||||
}
|
||||
};
|
||||
})(this));
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return console.log('Error before request! ' + err.message);
|
||||
}
|
||||
};
|
||||
importio = require('import-io').client;
|
||||
|
||||
params = JSON.parse(fs.readFileSync('params.json', 'utf8'));
|
||||
|
||||
|
|
@ -75,9 +39,10 @@ compilation and running of module code
|
|||
sandbox = {
|
||||
id: 'test.vm',
|
||||
params: params.userparams,
|
||||
needlereq: issueApiCall,
|
||||
request: issueRequest,
|
||||
needle: needle,
|
||||
request: request,
|
||||
cryptoJS: crypto,
|
||||
importio: importio,
|
||||
log: console.log,
|
||||
debug: console.log,
|
||||
exports: {}
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ Components Manager
|
|||
- `user` is the user object as it comes from the DB.
|
||||
- `oReq` is the request object that contains:
|
||||
|
||||
- `command` as a string
|
||||
- `payload` an optional stringified JSON object
|
||||
- `command` as a string
|
||||
- `payload` an optional stringified JSON object
|
||||
The callback function `callback( obj )` will receive an object
|
||||
containing the HTTP response code and a corresponding message.
|
||||
|
||||
|
|
@ -239,6 +239,7 @@ Components Manager
|
|||
src = oPayload.data;
|
||||
return dynmod.compileString(src, user.username, 'dummyRule', oPayload.id, oPayload.lang, null, function(cm) {
|
||||
var funcs, id, name, _ref;
|
||||
console.log(cm);
|
||||
answ = cm.answ;
|
||||
if (answ.code === 200) {
|
||||
funcs = [];
|
||||
|
|
@ -250,7 +251,7 @@ Components Manager
|
|||
_this.log.info("CM | Storing new module with functions " + (funcs.join(', ')));
|
||||
answ.message = " Module " + oPayload.id + " successfully stored! Found following function(s): " + funcs;
|
||||
oPayload.functions = JSON.stringify(funcs);
|
||||
oPayload.functionParameters = JSON.stringify(cm.funcParams);
|
||||
oPayload.functionArgs = JSON.stringify(cm.funcParams);
|
||||
dbMod.storeModule(user.username, oPayload);
|
||||
if (oPayload["public"] === 'true') {
|
||||
dbMod.publish(oPayload.id);
|
||||
|
|
@ -327,7 +328,7 @@ Components Manager
|
|||
if (answ.code !== 200) {
|
||||
return callback(answ);
|
||||
} else {
|
||||
return db.actionInvokers.getModuleField(oPayload.id, 'functionParameters', function(err, obj) {
|
||||
return db.actionInvokers.getModuleField(oPayload.id, 'functionArgs', function(err, obj) {
|
||||
return callback({
|
||||
code: 200,
|
||||
message: obj
|
||||
|
|
@ -390,6 +391,7 @@ Components Manager
|
|||
rule = {
|
||||
id: oPayload.id,
|
||||
event: oPayload.event,
|
||||
event_interval: oPayload.event_interval,
|
||||
conditions: oPayload.conditions,
|
||||
actions: oPayload.actions
|
||||
};
|
||||
|
|
|
|||
12
js/config.js
12
js/config.js
|
|
@ -8,7 +8,7 @@ Configuration
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var exports, fetchProp, fs, loadConfigFile, path;
|
||||
var exports, fs, loadConfigFile, path;
|
||||
|
||||
fs = require('fs');
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ Configuration
|
|||
@param {String} prop
|
||||
*/
|
||||
|
||||
fetchProp = (function(_this) {
|
||||
exports.fetchProp = (function(_this) {
|
||||
return function(prop) {
|
||||
var _ref;
|
||||
return (_ref = _this.config) != null ? _ref[prop] : void 0;
|
||||
|
|
@ -113,7 +113,7 @@ Configuration
|
|||
*/
|
||||
|
||||
exports.getHttpPort = function() {
|
||||
return fetchProp('http-port');
|
||||
return exports.fetchProp('http-port');
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ Configuration
|
|||
*/
|
||||
|
||||
exports.getDbPort = function() {
|
||||
return fetchProp('db-port');
|
||||
return exports.fetchProp('db-port');
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -135,7 +135,7 @@ Configuration
|
|||
*/
|
||||
|
||||
exports.getLogConf = function() {
|
||||
return fetchProp('log');
|
||||
return exports.fetchProp('log');
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ Configuration
|
|||
*/
|
||||
|
||||
exports.getKeygenPassphrase = function() {
|
||||
return fetchProp('keygen-passphrase');
|
||||
return exports.fetchProp('keygen-passphrase');
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Dynamic Modules
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var cryptico, cryptoJS, cs, db, exports, getFunctionParamNames, logFunction, needle, regexpComments, request, vm;
|
||||
var cryptico, cryptoJS, cs, db, exports, fTryToLoadModule, getFunctionParamNames, importio, logFunction, needle, regexpComments, request, vm;
|
||||
|
||||
db = require('./persistence');
|
||||
|
||||
|
|
@ -25,6 +25,8 @@ Dynamic Modules
|
|||
|
||||
cryptoJS = require('crypto-js');
|
||||
|
||||
importio = require('import-io').client;
|
||||
|
||||
|
||||
/*
|
||||
Module call
|
||||
|
|
@ -89,99 +91,114 @@ Dynamic Modules
|
|||
|
||||
exports.compileString = (function(_this) {
|
||||
return function(src, userId, ruleId, modId, lang, dbMod, cb) {
|
||||
var answ, err, fTryToLoad;
|
||||
answ = {
|
||||
code: 200,
|
||||
message: 'Successfully compiled'
|
||||
};
|
||||
var err;
|
||||
if (lang === 'CoffeeScript') {
|
||||
try {
|
||||
_this.log.info("DM | Compiling module '" + modId + "' for user '" + userId + "'");
|
||||
src = cs.compile(src);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
answ.message = 'Compilation of CoffeeScript failed at line ' + err.location.first_line;
|
||||
cb({
|
||||
code: 400,
|
||||
message: 'Compilation of CoffeeScript failed at line ' + err.location.first_line
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
fTryToLoad = function(params) {
|
||||
var fName, func, logFunc, msg, oDecrypted, oFuncArgs, oFuncParams, sandbox, _ref;
|
||||
if (params) {
|
||||
_this.log.info("DM | Trying to fetch user specific module '" + modId + "' paramters for user '" + userId + "'");
|
||||
if (dbMod) {
|
||||
return dbMod.getUserParams(modId, userId, function(err, obj) {
|
||||
var oDecrypted;
|
||||
try {
|
||||
oDecrypted = cryptico.decrypt(params, _this.oPrivateRSAkey);
|
||||
params = JSON.parse(oDecrypted.plaintext);
|
||||
oDecrypted = cryptico.decrypt(obj, _this.oPrivateRSAkey);
|
||||
obj = JSON.parse(oDecrypted.plaintext);
|
||||
_this.log.warn("DM | Loaded user defined params for " + userId + ", " + ruleId + ", " + modId);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
_this.log.warn("DM | Error during parsing of user defined params for " + userId + ", " + ruleId + ", " + modId);
|
||||
_this.log.warn(err);
|
||||
params = {};
|
||||
}
|
||||
} else {
|
||||
params = {};
|
||||
}
|
||||
logFunc = logFunction(userId, ruleId, modId);
|
||||
sandbox = {
|
||||
id: userId + '.' + modId + '.vm',
|
||||
params: params,
|
||||
needle: needle,
|
||||
request: request,
|
||||
cryptoJS: cryptoJS,
|
||||
log: logFunc,
|
||||
debug: console.log,
|
||||
exports: {}
|
||||
};
|
||||
try {
|
||||
vm.runInNewContext(src, sandbox, sandbox.id);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
msg = err.message;
|
||||
if (!msg) {
|
||||
msg = 'Try to run the script locally to track the error! Sadly we cannot provide the line number';
|
||||
}
|
||||
answ.message = 'Loading Module failed: ' + msg;
|
||||
}
|
||||
oFuncParams = {};
|
||||
_ref = sandbox.exports;
|
||||
for (fName in _ref) {
|
||||
func = _ref[fName];
|
||||
getFunctionParamNames(fName, func, oFuncParams);
|
||||
}
|
||||
if (dbMod) {
|
||||
oFuncArgs = {};
|
||||
console.log('oFuncParams');
|
||||
console.log(oFuncParams);
|
||||
for (func in oFuncParams) {
|
||||
console.log('fetching ' + func);
|
||||
console.log(typeof func);
|
||||
dbMod.getUserArguments(modId, func, userId, function(err, obj) {
|
||||
console.log(err, obj);
|
||||
try {
|
||||
oDecrypted = cryptico.decrypt(obj, _this.oPrivateRSAkey);
|
||||
return oFuncArgs[func] = JSON.parse(oDecrypted.plaintext);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
_this.log.warn("DM | Error during parsing of user defined params for " + userId + ", " + ruleId + ", " + modId);
|
||||
return _this.log.warn(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return cb({
|
||||
answ: answ,
|
||||
module: sandbox.exports,
|
||||
funcParams: oFuncParams,
|
||||
funcArgs: oFuncArgs,
|
||||
logger: sandbox.log
|
||||
});
|
||||
};
|
||||
if (dbMod) {
|
||||
return dbMod.getUserParams(modId, userId, function(err, obj) {
|
||||
return fTryToLoad(obj);
|
||||
return fTryToLoadModule(userId, ruleId, modId, src, dbMod, obj, cb);
|
||||
});
|
||||
} else {
|
||||
return fTryToLoad(null);
|
||||
return fTryToLoadModule(userId, ruleId, modId, src, dbMod, null, cb);
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
|
||||
fTryToLoadModule = (function(_this) {
|
||||
return function(userId, ruleId, modId, src, dbMod, params, cb) {
|
||||
var answ, err, fName, func, logFunc, msg, oFuncArgs, oFuncParams, sandbox, _ref;
|
||||
if (!params) {
|
||||
params = {};
|
||||
answ = {
|
||||
code: 200,
|
||||
message: 'Successfully compiled'
|
||||
};
|
||||
}
|
||||
_this.log.info("DM | Running module '" + modId + "' for user '" + userId + "'");
|
||||
logFunc = logFunction(userId, ruleId, modId);
|
||||
sandbox = {
|
||||
id: "" + userId + "." + ruleId + "." + modId + ".vm",
|
||||
params: params,
|
||||
needle: needle,
|
||||
importio: importio,
|
||||
request: request,
|
||||
cryptoJS: cryptoJS,
|
||||
log: logFunc,
|
||||
debug: console.log,
|
||||
exports: {}
|
||||
};
|
||||
try {
|
||||
vm.runInNewContext(src, sandbox, sandbox.id);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
answ.code = 400;
|
||||
msg = err.message;
|
||||
if (!msg) {
|
||||
msg = 'Try to run the script locally to track the error! Sadly we cannot provide the line number';
|
||||
}
|
||||
answ.message = 'Loading Module failed: ' + msg;
|
||||
}
|
||||
_this.log.info("DM | Module '" + modId + "' ran successfully for user '" + userId + "' in rule '" + ruleId + "'");
|
||||
oFuncParams = {};
|
||||
oFuncArgs = {};
|
||||
_ref = sandbox.exports;
|
||||
for (fName in _ref) {
|
||||
func = _ref[fName];
|
||||
getFunctionParamNames(fName, func, oFuncParams);
|
||||
}
|
||||
if (dbMod) {
|
||||
oFuncArgs = {};
|
||||
console.log('oFuncParams');
|
||||
console.log(oFuncParams);
|
||||
for (func in oFuncParams) {
|
||||
console.log('fetching ' + func);
|
||||
console.log(typeof func);
|
||||
dbMod.getUserArguments(modId, func, userId, function(err, obj) {
|
||||
var oDecrypted;
|
||||
console.log(err, obj);
|
||||
try {
|
||||
oDecrypted = cryptico.decrypt(obj, _this.oPrivateRSAkey);
|
||||
return oFuncArgs[func] = JSON.parse(oDecrypted.plaintext);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
_this.log.warn("DM | Error during parsing of user defined params for " + userId + ", " + ruleId + ", " + modId);
|
||||
return _this.log.warn(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
console.log('answering compile request string');
|
||||
console.log(cb);
|
||||
return cb({
|
||||
answ: answ,
|
||||
module: sandbox.exports,
|
||||
funcParams: oFuncParams,
|
||||
funcArgs: oFuncArgs,
|
||||
logger: sandbox.log
|
||||
});
|
||||
};
|
||||
})(this);
|
||||
|
||||
}).call(this);
|
||||
|
|
|
|||
177
js/engine.js
177
js/engine.js
|
|
@ -10,7 +10,7 @@ Engine
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var db, dynmod, exports, isRunning, jsonQuery, listUserRules, pollQueue, processEvent, semaphore, updateActionModules, validConditions;
|
||||
var db, dynmod, exports, isRunning, jsonQuery, listUserRules, numExecutingFunctions, pollQueue, processEvent, updateActionModules, validConditions;
|
||||
|
||||
db = require('./persistence');
|
||||
|
||||
|
|
@ -23,21 +23,21 @@ Engine
|
|||
This is ging to have a structure like:
|
||||
An object of users with their active rules and the required action modules
|
||||
|
||||
"user-1":
|
||||
"rule-1":
|
||||
"rule": oRule-1
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"action-2": oAction-2
|
||||
"rule-2":
|
||||
"rule": oRule-2
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"user-2":
|
||||
"rule-3":
|
||||
"rule": oRule-3
|
||||
"actions":
|
||||
"action-3": oAction-3
|
||||
"user-1":
|
||||
"rule-1":
|
||||
"rule": oRule-1
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"action-2": oAction-2
|
||||
"rule-2":
|
||||
"rule": oRule-2
|
||||
"actions":
|
||||
"action-1": oAction-1
|
||||
"user-2":
|
||||
"rule-3":
|
||||
"rule": oRule-3
|
||||
"actions":
|
||||
"action-3": oAction-3
|
||||
*/
|
||||
|
||||
listUserRules = {};
|
||||
|
|
@ -126,87 +126,92 @@ Engine
|
|||
@param {Object} updatedRuleId
|
||||
*/
|
||||
|
||||
updateActionModules = function(updatedRuleId) {
|
||||
var fAddRequired, fRemoveNotRequired, name, oUser, userName, _results;
|
||||
fRemoveNotRequired = function(oUser) {
|
||||
var action, fRequired, _results;
|
||||
fRequired = function(actionName) {
|
||||
var action, _i, _len, _ref;
|
||||
_ref = oUser[updatedRuleId].rule.actions;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
action = _ref[_i];
|
||||
if ((action.split(' -> '))[0] === actionName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
_results = [];
|
||||
for (action in oUser[updatedRuleId].rule.actions) {
|
||||
if (!fRequired(action)) {
|
||||
_results.push(delete oUser[updatedRuleId].actions[action]);
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
for (name in listUserRules) {
|
||||
oUser = listUserRules[name];
|
||||
fRemoveNotRequired(oUser);
|
||||
}
|
||||
fAddRequired = function(userName, oUser) {
|
||||
var fCheckRules, nmRl, oRl, _results;
|
||||
fCheckRules = function(oMyRule) {
|
||||
var action, fAddIfNewOrNotExisting, _i, _len, _ref, _results;
|
||||
fAddIfNewOrNotExisting = function(actionName) {
|
||||
var moduleName;
|
||||
moduleName = (actionName.split(' -> '))[0];
|
||||
if (!oMyRule.actions[moduleName] || oMyRule.rule.id === updatedRuleId) {
|
||||
return db.actionInvokers.getModule(moduleName, function(err, obj) {
|
||||
return dynmod.compileString(obj.data, userName, oMyRule.rule.id, moduleName, obj.lang, db.actionInvokers, function(result) {
|
||||
if (!result.answ === 200) {
|
||||
this.log.error("EN | Compilation of code failed! " + userName + ", " + oMyRule.rule.id + ", " + moduleName);
|
||||
}
|
||||
return oMyRule.actions[moduleName] = result.module;
|
||||
});
|
||||
});
|
||||
updateActionModules = (function(_this) {
|
||||
return function(updatedRuleId) {
|
||||
var fAddRequired, fRemoveNotRequired, name, oUser, userName, _results;
|
||||
fRemoveNotRequired = function(oUser) {
|
||||
var action, fRequired, _results;
|
||||
fRequired = function(actionName) {
|
||||
var action, _i, _len, _ref;
|
||||
_ref = oUser[updatedRuleId].rule.actions;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
action = _ref[_i];
|
||||
if ((action.split(' -> '))[0] === actionName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
_ref = oMyRule.rule.actions;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
action = _ref[_i];
|
||||
_results.push(fAddIfNewOrNotExisting(action));
|
||||
for (action in oUser[updatedRuleId].rule.actions) {
|
||||
if (!fRequired(action)) {
|
||||
_results.push(delete oUser[updatedRuleId].actions[action]);
|
||||
} else {
|
||||
_results.push(void 0);
|
||||
}
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
for (name in listUserRules) {
|
||||
oUser = listUserRules[name];
|
||||
fRemoveNotRequired(oUser);
|
||||
}
|
||||
fAddRequired = function(userName, oUser) {
|
||||
var fCheckRules, nmRl, oRl, _results;
|
||||
fCheckRules = function(oMyRule) {
|
||||
var action, fAddIfNewOrNotExisting, _i, _len, _ref, _results;
|
||||
fAddIfNewOrNotExisting = function(actionName) {
|
||||
var moduleName;
|
||||
moduleName = (actionName.split(' -> '))[0];
|
||||
if (!oMyRule.actions[moduleName] || oMyRule.rule.id === updatedRuleId) {
|
||||
return db.actionInvokers.getModule(moduleName, function(err, obj) {
|
||||
if (obj) {
|
||||
return dynmod.compileString(obj.data, userName, oMyRule.rule.id, moduleName, obj.lang, db.actionInvokers, function(result) {
|
||||
if (!result.answ === 200) {
|
||||
_this.log.error("EN | Compilation of code failed! " + userName + ", " + oMyRule.rule.id + ", " + moduleName);
|
||||
}
|
||||
return oMyRule.actions[moduleName] = result.module;
|
||||
});
|
||||
} else {
|
||||
return _this.log.warn('EN | #{ moduleName } not found for #{ oMyRule.rule.id }!');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
_ref = oMyRule.rule.actions;
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
action = _ref[_i];
|
||||
_results.push(fAddIfNewOrNotExisting(action));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
_results = [];
|
||||
for (nmRl in oUser) {
|
||||
oRl = oUser[nmRl];
|
||||
_results.push(fCheckRules(oRl));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
_results = [];
|
||||
for (nmRl in oUser) {
|
||||
oRl = oUser[nmRl];
|
||||
_results.push(fCheckRules(oRl));
|
||||
for (userName in listUserRules) {
|
||||
oUser = listUserRules[userName];
|
||||
_results.push(fAddRequired(userName, oUser));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
_results = [];
|
||||
for (userName in listUserRules) {
|
||||
oUser = listUserRules[userName];
|
||||
_results.push(fAddRequired(userName, oUser));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
})(this);
|
||||
|
||||
semaphore = 0;
|
||||
numExecutingFunctions = 1;
|
||||
|
||||
pollQueue = function() {
|
||||
if (isRunning) {
|
||||
db.popEvent(function(err, obj) {
|
||||
if (!err && obj) {
|
||||
processEvent(obj);
|
||||
return processEvent(obj);
|
||||
}
|
||||
return semaphore--;
|
||||
});
|
||||
return setTimeout(pollQueue, 20 * semaphore);
|
||||
return setTimeout(pollQueue, 20 * numExecutingFunctions);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -234,8 +239,6 @@ Engine
|
|||
return true;
|
||||
};
|
||||
|
||||
semaphore = 0;
|
||||
|
||||
|
||||
/*
|
||||
Handles retrieved events.
|
||||
|
|
@ -250,20 +253,22 @@ Engine
|
|||
fSearchAndInvokeAction = function(node, arrPath, funcName, evt, depth) {
|
||||
var err;
|
||||
if (!node) {
|
||||
this.log.error("EN | Didn't find property in user rule list: " + arrPath.join(', ' + " at depth " + depth));
|
||||
_this.log.error("EN | Didn't find property in user rule list: " + arrPath.join(', ' + " at depth " + depth));
|
||||
return;
|
||||
}
|
||||
if (depth === arrPath.length) {
|
||||
try {
|
||||
semaphore++;
|
||||
numExecutingFunctions++;
|
||||
_this.log.info("EN | " + funcName + " executes...");
|
||||
node[funcName](evt.payload);
|
||||
_this.log.info("EN | " + funcName + " finished execution");
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
this.log.info("EN | ERROR IN ACTION INVOKER: " + err.message);
|
||||
_this.log.info("EN | ERROR IN ACTION INVOKER: " + err.message);
|
||||
node.logger(err.message);
|
||||
}
|
||||
if (semaphore-- % 100 === 0) {
|
||||
return this.log.warn("EN | The system is producing too many tokens! Currently: " + semaphore);
|
||||
if (numExecutingFunctions-- % 100 === 0) {
|
||||
return _this.log.warn("EN | The system is producing too many tokens! Currently: " + numExecutingFunctions);
|
||||
}
|
||||
} else {
|
||||
return fSearchAndInvokeAction(node[arrPath[depth]], arrPath, funcName, evt, depth + 1);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Dynamic Modules
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var db, dynmod, fLoadModule, isRunning, listUserModules, log, logconf, logger, pollLoop;
|
||||
var db, dynmod, fCallFunction, fCheckAndRun, fLoadModule, isRunning, listUserModules, log, logconf, logger;
|
||||
|
||||
logger = require('./logging');
|
||||
|
||||
|
|
@ -77,19 +77,23 @@ Dynamic Modules
|
|||
return log.warn("EP | Strange... no module retrieved: " + arrName[0]);
|
||||
} else {
|
||||
return dynmod.compileString(obj.data, msg.user, msg.rule.id, arrName[0], obj.lang, db.eventPollers, function(result) {
|
||||
var iv;
|
||||
if (!result.answ === 200) {
|
||||
log.error("EP | Compilation of code failed! " + msg.user + ", " + msg.rule.id + ", " + arrName[0]);
|
||||
}
|
||||
if (!listUserModules[msg.user]) {
|
||||
listUserModules[msg.user] = {};
|
||||
}
|
||||
iv = msg.rule.interval * 60 * 1000;
|
||||
listUserModules[msg.user][msg.rule.id] = {
|
||||
id: msg.rule.event,
|
||||
pollfunc: arrName[1],
|
||||
interval: iv,
|
||||
module: result.module,
|
||||
logger: result.logger
|
||||
};
|
||||
return log.info("EP | New event module loaded! " + msg.user + ", " + msg.rule.id + ", " + arrName[0]);
|
||||
log.info("EP | New event module '" + arrName[0] + "' loaded for user " + msg.user + ", in rule " + msg.rule.id + ", polling every " + iv + " minutes");
|
||||
return setTimeout(fCheckAndRun(msg.user, msg.rule.id), iv);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -99,43 +103,32 @@ Dynamic Modules
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
This function will loop infinitely every 10 seconds until isRunning is set to false
|
||||
|
||||
@private pollLoop()
|
||||
*/
|
||||
|
||||
pollLoop = function() {
|
||||
var fCallFunction, myRule, oRules, ruleName, userName;
|
||||
if (isRunning) {
|
||||
for (userName in listUserModules) {
|
||||
oRules = listUserModules[userName];
|
||||
for (ruleName in oRules) {
|
||||
myRule = oRules[ruleName];
|
||||
fCallFunction = function(oRule, ruleId, userId) {
|
||||
var err;
|
||||
try {
|
||||
return oRule.module[oRule.pollfunc](function(obj) {
|
||||
return db.pushEvent({
|
||||
event: oRule.id,
|
||||
eventid: "polled " + oRule.id + " " + userId + "_" + ((new Date).toISOString()),
|
||||
payload: obj
|
||||
});
|
||||
});
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
log.info("EP | ERROR in module when polled: " + oRule.id + " " + userId + ": " + err.message);
|
||||
return oRule.logger(err.message);
|
||||
}
|
||||
};
|
||||
fCallFunction(myRule, ruleName, userName);
|
||||
}
|
||||
fCheckAndRun = function(userId, ruleId) {
|
||||
return function() {
|
||||
var oRule;
|
||||
if (isRunning && listUserModules[userId] && listUserModules[userId][ruleId]) {
|
||||
oRule = listUserModules[userId][ruleId];
|
||||
fCallFunction(userId, ruleId, oRule);
|
||||
return setTimeout(fCheckAndRun(userId, ruleId), oRule.interval);
|
||||
}
|
||||
return setTimeout(pollLoop, 10000);
|
||||
};
|
||||
};
|
||||
|
||||
fCallFunction = function(userId, ruleId, oRule) {
|
||||
var err;
|
||||
try {
|
||||
return oRule.module[oRule.pollfunc](function(obj) {
|
||||
return db.pushEvent({
|
||||
event: oRule.id,
|
||||
eventid: "polled " + oRule.id + " " + userId + "_" + ((new Date).toISOString()),
|
||||
payload: obj
|
||||
});
|
||||
});
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
log.info("EP | ERROR in module when polled: " + oRule.id + " " + userId + ": " + err.message);
|
||||
return oRule.logger(err.message);
|
||||
}
|
||||
};
|
||||
|
||||
pollLoop();
|
||||
|
||||
}).call(this);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ HTTP Listener
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var app, exports, express, initRouting, path, qs, requestHandler;
|
||||
var activateWebHook, app, exports, express, indexEvent, initRouting, path, qs, requestHandler;
|
||||
|
||||
requestHandler = require('./request-handler');
|
||||
|
||||
|
|
@ -34,6 +34,7 @@ HTTP Listener
|
|||
exports = module.exports = (function(_this) {
|
||||
return function(args) {
|
||||
_this.log = args.logger;
|
||||
_this.arrWebhooks = args.webhooks;
|
||||
_this.shutDownSystem = args['shutdown-function'];
|
||||
requestHandler(args);
|
||||
initRouting(args['http-port']);
|
||||
|
|
@ -41,6 +42,39 @@ HTTP Listener
|
|||
};
|
||||
})(this);
|
||||
|
||||
indexEvent = function(event, body, resp) {
|
||||
var err, obj, rand, timestamp;
|
||||
try {
|
||||
obj = JSON.parse(body);
|
||||
timestamp = (new Date).toISOString();
|
||||
rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase();
|
||||
obj.event = event;
|
||||
obj.eventid = "" + obj.event + "_" + timestamp + "_" + rand;
|
||||
db.pushEvent(obj);
|
||||
return resp.send(200, "Thank you for the event: " + obj.eventid);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return resp.send(400, 'Badly formed event!');
|
||||
}
|
||||
};
|
||||
|
||||
activateWebHook = (function(_this) {
|
||||
return function(app, name) {
|
||||
_this.log.info("HL | Webhook activated for " + name);
|
||||
return app.post("/webhooks/" + name, function(req, resp) {
|
||||
var body;
|
||||
console.log('something is coming through');
|
||||
body = '';
|
||||
req.on('data', function(data) {
|
||||
return body += data;
|
||||
});
|
||||
return req.on('end', function() {
|
||||
return indexEvent(name, body, resp);
|
||||
});
|
||||
});
|
||||
};
|
||||
})(this);
|
||||
|
||||
|
||||
/*
|
||||
Initializes the request routing and starts listening on the given port.
|
||||
|
|
@ -51,7 +85,7 @@ HTTP Listener
|
|||
|
||||
initRouting = (function(_this) {
|
||||
return function(port) {
|
||||
var server, sess_sec;
|
||||
var hookName, server, sess_sec, _i, _len, _ref;
|
||||
app.use(express.cookieParser());
|
||||
sess_sec = "149u*y8C:@kmN/520Gt\\v'+KFBnQ!\\r<>5X/xRI`sT<Iw";
|
||||
app.use(express.session({
|
||||
|
|
@ -66,6 +100,11 @@ HTTP Listener
|
|||
app.post('/logout', requestHandler.handleLogout);
|
||||
app.post('/usercommand', requestHandler.handleUserCommand);
|
||||
app.post('/admincommand', requestHandler.handleAdminCommand);
|
||||
_ref = _this.arrWebhooks;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
hookName = _ref[_i];
|
||||
activateWebHook(app, hookName);
|
||||
}
|
||||
server = app.listen(parseInt(port) || 8111);
|
||||
server.on('listening', function() {
|
||||
var addr;
|
||||
|
|
@ -77,8 +116,8 @@ HTTP Listener
|
|||
return server.on('error', function(err) {
|
||||
|
||||
/*
|
||||
Error handling of the express port listener requires special attention,
|
||||
thus we have to catch the error, which is issued if the port is already in use.
|
||||
Error handling of the express port listener requires special attention,
|
||||
thus we have to catch the error, which is issued if the port is already in use.
|
||||
*/
|
||||
switch (err.errno) {
|
||||
case 'EADDRINUSE':
|
||||
|
|
|
|||
|
|
@ -69,7 +69,9 @@ Persistence
|
|||
_this.db.on('error', function(err) {
|
||||
if (err.message.indexOf('ECONNREFUSED') > -1) {
|
||||
_this.connRefused = true;
|
||||
return _this.log.error(err, 'DB | Wrong port?');
|
||||
return _this.log.warn('DB | Wrong port?');
|
||||
} else {
|
||||
return _this.log.error(err);
|
||||
}
|
||||
});
|
||||
exports.eventPollers.setDB(_this.db);
|
||||
|
|
@ -200,9 +202,9 @@ Persistence
|
|||
@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
|
||||
per set entry
|
||||
@param {function} cb the callback(err, obj) function that receives all
|
||||
the retrieved data or an error
|
||||
the retrieved data or an error
|
||||
*/
|
||||
|
||||
getSetRecords = (function(_this) {
|
||||
|
|
@ -282,11 +284,11 @@ Persistence
|
|||
|
||||
|
||||
/*
|
||||
Stores a module and links it to the user.
|
||||
|
||||
@private storeModule( *userId, oModule* )
|
||||
@param {String} userId
|
||||
@param {object} oModule
|
||||
Stores a module and links it to the user.
|
||||
|
||||
@private storeModule( *userId, oModule* )
|
||||
@param {String} userId
|
||||
@param {object} oModule
|
||||
*/
|
||||
|
||||
IndexedModules.prototype.storeModule = function(userId, oModule) {
|
||||
|
|
@ -376,13 +378,13 @@ Persistence
|
|||
|
||||
|
||||
/*
|
||||
Stores user params for a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserParams( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
Stores user params for a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserParams( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
*/
|
||||
|
||||
IndexedModules.prototype.storeUserParams = function(mId, userId, encData) {
|
||||
|
|
@ -409,13 +411,13 @@ Persistence
|
|||
|
||||
|
||||
/*
|
||||
Stores user arguments for a function within a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserArguments( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
Stores user arguments for a function within a module. They are expected to be RSA encrypted with helps of
|
||||
the provided cryptico JS library and will only be decrypted right before the module is loaded!
|
||||
|
||||
@private storeUserArguments( *mId, userId, encData* )
|
||||
@param {String} mId
|
||||
@param {String} userId
|
||||
@param {object} encData
|
||||
*/
|
||||
|
||||
IndexedModules.prototype.storeUserArguments = function(mId, funcId, userId, encData) {
|
||||
|
|
|
|||
|
|
@ -78,28 +78,26 @@ Request Handler
|
|||
});
|
||||
return req.on('end', function() {
|
||||
var answ, err, obj, rand, timestamp;
|
||||
if (req.session && req.session.user) {
|
||||
try {
|
||||
obj = JSON.parse(body);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
resp.send(400, 'Badly formed event!');
|
||||
}
|
||||
if (obj && obj.event && !err) {
|
||||
timestamp = (new Date).toISOString();
|
||||
rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase();
|
||||
obj.eventid = "" + obj.event + "_" + timestamp + "_" + rand;
|
||||
answ = {
|
||||
code: 200,
|
||||
message: "Thank you for the event: " + obj.eventid
|
||||
};
|
||||
resp.send(answ.code, answ);
|
||||
return db.pushEvent(obj);
|
||||
} else {
|
||||
return resp.send(400, 'Your event was missing important parameters!');
|
||||
}
|
||||
try {
|
||||
obj = JSON.parse(body);
|
||||
console.log('got foreign event!');
|
||||
console.log(obj);
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
resp.send(400, 'Badly formed event!');
|
||||
}
|
||||
if (obj && obj.event && !err) {
|
||||
timestamp = (new Date).toISOString();
|
||||
rand = (Math.floor(Math.random() * 10e9)).toString(16).toUpperCase();
|
||||
obj.eventid = "" + obj.event + "_" + timestamp + "_" + rand;
|
||||
answ = {
|
||||
code: 200,
|
||||
message: "Thank you for the event: " + obj.eventid
|
||||
};
|
||||
resp.send(answ.code, answ);
|
||||
return db.pushEvent(obj);
|
||||
} else {
|
||||
return resp.send(401, 'Please login!');
|
||||
return resp.send(400, 'Your event was missing important parameters!');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
42
js/sandbox.js
Normal file
42
js/sandbox.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Generated by CoffeeScript 1.7.1
|
||||
(function() {
|
||||
var app, express, fHandleEvent, fHandleEventGet;
|
||||
|
||||
express = require('express');
|
||||
|
||||
app = express();
|
||||
|
||||
app.post('/event', fHandleEvent);
|
||||
|
||||
app.get('/event', fHandleEventGet);
|
||||
|
||||
app.listen(8111);
|
||||
|
||||
fHandleEvent = function(req, resp) {
|
||||
var body;
|
||||
console.log('received something with POST!');
|
||||
body = '';
|
||||
req.on('data', function(data) {
|
||||
return body += data;
|
||||
});
|
||||
req.on('end', function() {
|
||||
var err, obj;
|
||||
console.log('got foreign event!');
|
||||
console.log(body);
|
||||
try {
|
||||
obj = JSON.parse(body);
|
||||
return console.log('successfully parsed');
|
||||
} catch (_error) {
|
||||
err = _error;
|
||||
return console.log(err);
|
||||
}
|
||||
});
|
||||
return resp.send(200, 'Cheers!');
|
||||
};
|
||||
|
||||
fHandleEventGet = function(req, resp) {
|
||||
console.log('received something with GET!');
|
||||
return resp.send(200, 'Cheers!');
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
|
@ -146,6 +146,7 @@ WebAPI-ECA Engine
|
|||
args['http-port'] = parseInt(argv.w || conf.getHttpPort());
|
||||
args['db-port'] = parseInt(argv.d || conf.getDbPort());
|
||||
args['keygen'] = conf.getKeygenPassphrase();
|
||||
args['webhooks'] = conf.fetchProp('webhooks');
|
||||
_this.log.info('RS | Initialzing DB');
|
||||
db(args);
|
||||
return db.isConnected(function(err) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"crypto-js": "3.1.2",
|
||||
"express": "3.4.8",
|
||||
"groc": "0.6.1",
|
||||
"import-io": "1.0.x",
|
||||
"js-select": "0.6.0",
|
||||
"mustache": "0.8.1",
|
||||
"needle": "0.6.3",
|
||||
|
|
|
|||
|
|
@ -35,15 +35,17 @@
|
|||
"data":"# Send a mail through emailyak\nexports.otherEvent = ( evt ) ->\n\turl = 'https://api.emailyak.com/v1/' + params.apikey + '/json/send/email/'\n\tpayload =\n\t FromAddress : \"testsender@mscliveweb.simpleyak.com\",\n\t ToAddress: \"dominic.bosch@gmail.com\",\n\t Subject: \"TestMAIL\",\n\t TextBody: \"Hello\"\n\t\n\tneedle.post url, payload, ( err, resp, body ) ->\n\t\tif err\n\t\t\tlog err\n\t\tif resp.statusCode isnt 200\n\t\t\tlog 'Request not successful:'\n\t\t\tlog body\n",
|
||||
"public":"false",
|
||||
"params":"[\"apikey\",\"andmore\"]",
|
||||
"functions":"[\"otherEvent\"]"
|
||||
"functions":"[\"otherEvent\"]",
|
||||
"functionArgs":"{\"otherEvent\":[\"evt\"]}"
|
||||
},
|
||||
"aiThree": {
|
||||
"id":"aiThree",
|
||||
"lang":"CoffeeScript",
|
||||
"data":"exports.printUserParamToLog = ( evt ) ->\n\tlog params.password",
|
||||
"data":"exports.printUserParamToLog = ( evt ) ->\n\tdebug 'wow'n\tlog 'wow'\n\tlog params.password",
|
||||
"public":"false",
|
||||
"params":"[\"password\"]",
|
||||
"functions":"[\"printUserParamToLog\"]"
|
||||
"functions":"[\"printUserParamToLog\"]",
|
||||
"functionArgs":"{\"printUserParamToLog\":[\"evt\"]}"
|
||||
}
|
||||
},
|
||||
"userparams": {
|
||||
|
|
@ -76,36 +78,18 @@
|
|||
},
|
||||
"rules": {
|
||||
"ruleOne": {
|
||||
"id": "ruleOne_id",
|
||||
"event": "custom-test-1",
|
||||
"conditions": [],
|
||||
"actions": []
|
||||
},
|
||||
"ruleTwo": {
|
||||
"id": "ruleTwo_id",
|
||||
"event": "custom-test-2",
|
||||
"conditions": [],
|
||||
"actions": []
|
||||
},
|
||||
"ruleThree": {
|
||||
"id": "ruleThree_id",
|
||||
"event": "custom-test-3",
|
||||
"conditions": [],
|
||||
"actions": []
|
||||
},
|
||||
"ruleReal": {
|
||||
"id": "ruleReal",
|
||||
"event": "epOne -> newMail",
|
||||
"event": "test_1",
|
||||
"conditions": [".more:val(\"really nested\")"],
|
||||
"actions": ["aiOne -> printToLog"]
|
||||
},
|
||||
"ruleRealTwo": {
|
||||
"ruleTwo": {
|
||||
"id": "ruleRealTwo",
|
||||
"event": "epOne -> newMail",
|
||||
"event": "test_2",
|
||||
"conditions": [],
|
||||
"actions": ["aiTwo -> otherEvent"]
|
||||
},
|
||||
"ruleRealThree": {
|
||||
"ruleThree": {
|
||||
"id": "ruleRealThree",
|
||||
"event": "epOne -> newMail",
|
||||
"conditions": [],
|
||||
|
|
|
|||
|
|
@ -1,24 +1,36 @@
|
|||
fs = require 'fs'
|
||||
path = require 'path'
|
||||
|
||||
cryptico = require 'my-cryptico'
|
||||
|
||||
passPhrase = 'UNIT TESTING PASSWORD'
|
||||
numBits = 1024
|
||||
oPrivateRSAkey = cryptico.generateRSAKey passPhrase, numBits
|
||||
strPublicKey = cryptico.publicKeyString oPrivateRSAkey
|
||||
|
||||
try
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
catch err
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
|
||||
logger = require path.join '..', 'js', 'logging'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
log = logger.getLogger()
|
||||
# nolog: true
|
||||
opts =
|
||||
logger: log
|
||||
logger: log
|
||||
|
||||
engine = require path.join '..', 'js', 'engine'
|
||||
engine opts
|
||||
|
||||
cm = require path.join '..', 'js', 'components-manager'
|
||||
cm opts
|
||||
|
||||
cm.addRuleListener engine.internalEvent
|
||||
|
||||
db = require path.join '..', 'js', 'persistence'
|
||||
db opts
|
||||
|
||||
|
|
@ -29,139 +41,182 @@ oRuleThree = objects.rules.ruleThree
|
|||
oEpOne = objects.eps.epOne
|
||||
oEpTwo = objects.eps.epTwo
|
||||
oAiTwo = objects.ais.aiTwo
|
||||
oAiThree = objects.ais.aiThree
|
||||
|
||||
exports.tearDown = ( cb ) ->
|
||||
db.deleteRule oRuleOne.id
|
||||
db.deleteRule oRuleTwo.id
|
||||
db.deleteRule oRuleThree.id
|
||||
setTimeout cb, 100
|
||||
db.deleteRule oRuleOne.id
|
||||
db.deleteRule oRuleTwo.id
|
||||
db.deleteRule oRuleThree.id
|
||||
setTimeout cb, 100
|
||||
|
||||
exports.requestProcessing =
|
||||
testEmptyPayload: ( test ) =>
|
||||
test.expect 1
|
||||
testEmptyPayload: ( test ) =>
|
||||
test.expect 1
|
||||
|
||||
request =
|
||||
command: 'get_event_pollers'
|
||||
request =
|
||||
command: 'get_event_pollers'
|
||||
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, 'Empty payload did not return 200'
|
||||
test.done()
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, 'Empty payload did not return 200'
|
||||
test.done()
|
||||
|
||||
testCorruptPayload: ( test ) =>
|
||||
test.expect 1
|
||||
testCorruptPayload: ( test ) =>
|
||||
test.expect 1
|
||||
|
||||
request =
|
||||
command: 'get_event_pollers'
|
||||
payload: 'no-json'
|
||||
request =
|
||||
command: 'get_event_pollers'
|
||||
payload: 'no-json'
|
||||
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 404, answ.code, 'Corrupt payload did not return 404'
|
||||
test.done()
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 404, answ.code, 'Corrupt payload did not return 404'
|
||||
test.done()
|
||||
|
||||
exports.testListener = ( test ) =>
|
||||
test.expect 3
|
||||
test.expect 3
|
||||
|
||||
strRuleOne = JSON.stringify oRuleOne
|
||||
strRuleTwo = JSON.stringify oRuleTwo
|
||||
strRuleThree = JSON.stringify oRuleThree
|
||||
strRuleOne = JSON.stringify oRuleOne
|
||||
strRuleTwo = JSON.stringify oRuleTwo
|
||||
strRuleThree = JSON.stringify oRuleThree
|
||||
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleOne.id, strRuleOne
|
||||
db.linkRule oRuleOne.id, oUser.username
|
||||
db.activateRule oRuleOne.id, oUser.username
|
||||
|
||||
db.storeRule oRuleTwo.id, strRuleTwo
|
||||
db.linkRule oRuleTwo.id, oUser.username
|
||||
db.activateRule oRuleTwo.id, oUser.username
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleOne.id, strRuleOne
|
||||
db.linkRule oRuleOne.id, oUser.username
|
||||
db.activateRule oRuleOne.id, oUser.username
|
||||
|
||||
db.storeRule oRuleTwo.id, strRuleTwo
|
||||
db.linkRule oRuleTwo.id, oUser.username
|
||||
db.activateRule oRuleTwo.id, oUser.username
|
||||
|
||||
request =
|
||||
command: 'forge_rule'
|
||||
payload: strRuleThree
|
||||
request =
|
||||
command: 'forge_rule'
|
||||
payload: strRuleThree
|
||||
|
||||
cm.addRuleListener ( evt ) =>
|
||||
strEvt = JSON.stringify evt.rule
|
||||
if evt.event is 'init'
|
||||
if strEvt is strRuleOne or strEvt is strRuleTwo
|
||||
test.ok true, 'Dummy true to fill expected tests!'
|
||||
cm.addRuleListener ( evt ) =>
|
||||
strEvt = JSON.stringify evt.rule
|
||||
if evt.event is 'init'
|
||||
if strEvt is strRuleOne or strEvt is strRuleTwo
|
||||
test.ok true, 'Dummy true to fill expected tests!'
|
||||
|
||||
if strEvt is strRuleThree
|
||||
test.ok false, 'Init Rule found test rule number two??'
|
||||
if strEvt is strRuleThree
|
||||
test.ok false, 'Init Rule found test rule number two??'
|
||||
|
||||
if evt.event is 'new'
|
||||
if strEvt is strRuleOne or strEvt is strRuleTwo
|
||||
test.ok false, 'New Rule got test rule number one??'
|
||||
if evt.event is 'new'
|
||||
if strEvt is strRuleOne or strEvt is strRuleTwo
|
||||
test.ok false, 'New Rule got test rule number one??'
|
||||
|
||||
if strEvt is strRuleThree
|
||||
test.ok true, 'Dummy true to fill expected tests!'
|
||||
if strEvt is strRuleThree
|
||||
test.ok true, 'Dummy true to fill expected tests!'
|
||||
|
||||
|
||||
|
||||
fWaitForInit = ->
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
if answ.code isnt 200
|
||||
test.ok false, 'testListener failed: ' + answ.message
|
||||
test.done()
|
||||
setTimeout test.done, 500
|
||||
fWaitForInit = ->
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
if answ.code isnt 200
|
||||
test.ok false, 'testListener failed: ' + answ.message
|
||||
test.done()
|
||||
setTimeout test.done, 500
|
||||
|
||||
setTimeout fWaitForInit, 200
|
||||
setTimeout fWaitForInit, 200
|
||||
|
||||
exports.moduleHandling =
|
||||
tearDown: ( cb ) ->
|
||||
db.eventPollers.deleteModule oEpOne.id
|
||||
db.eventPollers.deleteModule oEpTwo.id
|
||||
db.actionInvokers.deleteModule oAiTwo.id
|
||||
setTimeout cb, 100
|
||||
tearDown: ( cb ) ->
|
||||
db.eventPollers.deleteModule oEpOne.id
|
||||
db.eventPollers.deleteModule oEpTwo.id
|
||||
db.actionInvokers.deleteModule oAiTwo.id
|
||||
setTimeout cb, 100
|
||||
|
||||
testGetModules: ( test ) ->
|
||||
test.expect 2
|
||||
testGetModules: ( test ) ->
|
||||
test.expect 2
|
||||
|
||||
db.eventPollers.storeModule oUser.username, oEpOne
|
||||
db.eventPollers.storeModule oUser.username, oEpTwo
|
||||
request =
|
||||
command: 'get_event_pollers'
|
||||
db.eventPollers.storeModule oUser.username, oEpOne
|
||||
db.eventPollers.storeModule oUser.username, oEpTwo
|
||||
request =
|
||||
command: 'get_event_pollers'
|
||||
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, 'GetModules failed...'
|
||||
oExpected = {}
|
||||
oExpected[oEpOne.id] = JSON.parse oEpOne.functions
|
||||
oExpected[oEpTwo.id] = JSON.parse oEpTwo.functions
|
||||
test.deepEqual oExpected, JSON.parse(answ.message),
|
||||
'GetModules retrieved modules is not what we expected'
|
||||
test.done()
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, 'GetModules failed...'
|
||||
oExpected = {}
|
||||
oExpected[oEpOne.id] = JSON.parse oEpOne.functions
|
||||
oExpected[oEpTwo.id] = JSON.parse oEpTwo.functions
|
||||
test.deepEqual oExpected, JSON.parse(answ.message),
|
||||
'GetModules retrieved modules is not what we expected'
|
||||
test.done()
|
||||
|
||||
testGetModuleParams: ( test ) ->
|
||||
test.expect 2
|
||||
testGetModuleParams: ( test ) ->
|
||||
test.expect 2
|
||||
|
||||
db.eventPollers.storeModule oUser.username, oEpOne
|
||||
db.eventPollers.storeModule oUser.username, oEpOne
|
||||
|
||||
request =
|
||||
command: 'get_event_poller_params'
|
||||
payload:
|
||||
id: oEpOne.id
|
||||
request.payload = JSON.stringify request.payload
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code,
|
||||
'Required Module Parameters did not return 200'
|
||||
test.strictEqual oEpOne.params, answ.message,
|
||||
'Required Module Parameters did not match'
|
||||
test.done()
|
||||
request =
|
||||
command: 'get_event_poller_params'
|
||||
payload:
|
||||
id: oEpOne.id
|
||||
request.payload = JSON.stringify request.payload
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code,
|
||||
'Required Module Parameters did not return 200'
|
||||
test.strictEqual oEpOne.params, answ.message,
|
||||
'Required Module Parameters did not match'
|
||||
test.done()
|
||||
|
||||
testForgeModule: ( test ) ->
|
||||
test.expect 2
|
||||
testForgeModule: ( test ) ->
|
||||
test.expect 2
|
||||
|
||||
oTmp = {}
|
||||
for key, val of oAiTwo
|
||||
oTmp[key] = val if key isnt 'functions' and key isnt 'functionParameters'
|
||||
oTmp = {}
|
||||
for key, val of oAiTwo
|
||||
oTmp[key] = val if key isnt 'functions' and key isnt 'functionParameters'
|
||||
|
||||
request =
|
||||
command: 'forge_action_invoker'
|
||||
payload: JSON.stringify oTmp
|
||||
request =
|
||||
command: 'forge_action_invoker'
|
||||
payload: JSON.stringify oTmp
|
||||
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, 'Forging Module did not return 200'
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, 'Forging Module did not return 200'
|
||||
|
||||
db.actionInvokers.getModule oAiTwo.id, ( err, obj ) ->
|
||||
test.deepEqual obj, oAiTwo, 'Forged Module is not what we expected'
|
||||
test.done()
|
||||
|
||||
|
||||
exports.testForgeRule = ( test ) ->
|
||||
test.expect 1
|
||||
|
||||
db.storeUser oUser
|
||||
db.actionInvokers.storeModule oUser.username, oAiThree
|
||||
|
||||
pw = 'This password should come out cleartext'
|
||||
userparams = JSON.stringify password: pw
|
||||
oEncrypted = cryptico.encrypt userparams, strPublicKey
|
||||
|
||||
db.actionInvokers.storeUserParams oAiThree.id, oUser.username, oEncrypted.cipher
|
||||
|
||||
request =
|
||||
command: 'forge_rule'
|
||||
payload: JSON.stringify oRuleThree
|
||||
|
||||
cm.processRequest oUser, request, ( answ ) =>
|
||||
test.strictEqual 200, answ.code, "Forging Rule returned #{ answ.code }: #{ answ.message }"
|
||||
|
||||
fWaitForPersistence = () ->
|
||||
evt = objects.events.eventReal
|
||||
evt.eventid = 'event_testid'
|
||||
db.pushEvent evt
|
||||
console.log 'pushed'
|
||||
|
||||
fWaitAgain = () ->
|
||||
console.log 'waited'
|
||||
db.getLog oUser.username, oRuleThree.id, ( err, data ) ->
|
||||
console.log data
|
||||
try
|
||||
logged = data.split( '] ' )[1]
|
||||
logged = logged.split( "\n" )[0]
|
||||
test.strictEqual logged, "{#{ oAiThree.id }} " + pw, 'Did not log the right thing'
|
||||
catch e
|
||||
test.ok false, 'Parsing log failed'
|
||||
|
||||
setTimeout test.done, 200
|
||||
|
||||
setTimeout fWaitAgain, 200
|
||||
|
||||
setTimeout fWaitForPersistence, 200
|
||||
|
||||
db.actionInvokers.getModule oAiTwo.id, ( err, obj ) ->
|
||||
console.log obj
|
||||
console.log oAiTwo
|
||||
test.deepEqual obj, oAiTwo, 'Forged Module is not what we expected'
|
||||
test.done()
|
||||
|
|
|
|||
|
|
@ -1,43 +1,43 @@
|
|||
path = require 'path'
|
||||
logger = require path.join '..', 'js', 'logging'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
nolog: true
|
||||
conf = require path.join '..', 'js', 'config'
|
||||
conf
|
||||
logger: log
|
||||
logger: log
|
||||
|
||||
exports.testRequire = ( test ) ->
|
||||
test.expect 1
|
||||
test.ok conf.isReady(), 'File does not exist!'
|
||||
test.done()
|
||||
test.expect 1
|
||||
test.ok conf.isReady(), 'File does not exist!'
|
||||
test.done()
|
||||
|
||||
exports.testParameters = ( test ) ->
|
||||
reqProp = [
|
||||
'mode'
|
||||
'io-level'
|
||||
'file-level'
|
||||
]
|
||||
test.expect 3 + reqProp.length
|
||||
test.ok conf.getHttpPort(), 'HTTP port does not exist!'
|
||||
test.ok conf.getDbPort(), 'DB port does not exist!'
|
||||
logconf = conf.getLogConf()
|
||||
test.ok logconf, 'Log config does not exist!'
|
||||
for prop in reqProp
|
||||
test.ok logconf[prop], "Log conf property #{ prop } does not exist!"
|
||||
test.done()
|
||||
reqProp = [
|
||||
'mode'
|
||||
'io-level'
|
||||
'file-level'
|
||||
]
|
||||
test.expect 3 + reqProp.length
|
||||
test.ok conf.getHttpPort(), 'HTTP port does not exist!'
|
||||
test.ok conf.getDbPort(), 'DB port does not exist!'
|
||||
logconf = conf.getLogConf()
|
||||
test.ok logconf, 'Log config does not exist!'
|
||||
for prop in reqProp
|
||||
test.ok logconf[prop], "Log conf property #{ prop } does not exist!"
|
||||
test.done()
|
||||
|
||||
exports.testDifferentConfigFile = ( test ) ->
|
||||
test.expect 1
|
||||
conf
|
||||
# nolog: true
|
||||
configPath: path.join 'testing', 'files', 'jsonTestConfig.json'
|
||||
test.ok conf.isReady(), 'Different path not loaded!'
|
||||
test.done()
|
||||
test.expect 1
|
||||
conf
|
||||
# nolog: true
|
||||
configPath: path.join 'testing', 'files', 'jsonTestConfig.json'
|
||||
test.ok conf.isReady(), 'Different path not loaded!'
|
||||
test.done()
|
||||
|
||||
exports.testNoConfigFile = ( test ) ->
|
||||
test.expect 1
|
||||
conf
|
||||
nolog: true
|
||||
configPath: 'wrongpath.file'
|
||||
test.strictEqual conf.isReady(), false, 'Wrong path still loaded!'
|
||||
test.done()
|
||||
test.expect 1
|
||||
conf
|
||||
nolog: true
|
||||
configPath: 'wrongpath.file'
|
||||
test.strictEqual conf.isReady(), false, 'Wrong path still loaded!'
|
||||
test.done()
|
||||
|
|
|
|||
|
|
@ -8,20 +8,20 @@ oPrivateRSAkey = cryptico.generateRSAKey passPhrase, numBits
|
|||
strPublicKey = cryptico.publicKeyString oPrivateRSAkey
|
||||
|
||||
try
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
catch err
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
|
||||
logger = require path.join '..', 'js', 'logging'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
nolog: true
|
||||
opts =
|
||||
logger: log
|
||||
keygen: passPhrase
|
||||
logger: log
|
||||
keygen: passPhrase
|
||||
|
||||
db = require path.join '..', 'js', 'persistence'
|
||||
db opts
|
||||
|
|
@ -33,78 +33,30 @@ dm = require path.join '..', 'js', 'dynamic-modules'
|
|||
dm opts
|
||||
|
||||
oUser = objects.users.userOne
|
||||
oRuleReal = objects.rules.ruleRealThree
|
||||
oRule = objects.rules.ruleThree
|
||||
oAi = objects.ais.aiThree
|
||||
|
||||
exports.tearDown = ( cb ) ->
|
||||
db.storeUser oUser
|
||||
db.deleteRule oRuleReal.id
|
||||
db.actionInvokers.deleteModule oAi.id
|
||||
setTimeout cb, 200
|
||||
db.storeUser oUser
|
||||
db.deleteRule oRule.id
|
||||
db.actionInvokers.deleteModule oAi.id
|
||||
setTimeout cb, 200
|
||||
|
||||
exports.testCompile = ( test ) ->
|
||||
test.expect 5
|
||||
test.expect 5
|
||||
|
||||
paramOne = 'First Test'
|
||||
code = "exports.testFunc = () ->\n\t'#{ paramOne }'"
|
||||
dm.compileString code, 'userOne', 'ruleOne', 'moduleOne', 'CoffeeScript', null, ( result ) ->
|
||||
test.strictEqual 200, result.answ.code
|
||||
moduleOne = result.module
|
||||
test.strictEqual paramOne, moduleOne.testFunc(), "Other result expected"
|
||||
|
||||
paramTwo = 'Second Test'
|
||||
code = "exports.testFunc = () ->\n\t'#{ paramTwo }'"
|
||||
dm.compileString code, 'userOne', 'ruleOne', 'moduleOne', 'CoffeeScript', null, ( result ) ->
|
||||
test.strictEqual 200, result.answ.code
|
||||
moduleTwo = result.module
|
||||
test.strictEqual paramTwo, moduleTwo.testFunc(), "Other result expected"
|
||||
test.notStrictEqual paramOne, moduleTwo.testFunc(), "Other result expected"
|
||||
setTimeout test.done, 200
|
||||
|
||||
|
||||
exports.testCorrectUserParams = ( test ) ->
|
||||
test.expect 1
|
||||
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
db.linkRule oRuleReal.id, oUser.username
|
||||
db.activateRule oRuleReal.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAi
|
||||
|
||||
pw = 'This password should come out cleartext'
|
||||
userparams = JSON.stringify password: pw
|
||||
oEncrypted = cryptico.encrypt userparams, strPublicKey
|
||||
|
||||
db.actionInvokers.storeUserParams oAi.id, oUser.username, oEncrypted.cipher
|
||||
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
|
||||
fWaitForPersistence = () ->
|
||||
evt = objects.events.eventReal
|
||||
evt.eventid = 'event_testid'
|
||||
db.pushEvent evt
|
||||
|
||||
fWaitAgain = () ->
|
||||
db.getLog oUser.username, oRuleReal.id, ( err, data ) ->
|
||||
try
|
||||
logged = data.split( '] ' )[1]
|
||||
logged = logged.split( "\n" )[0]
|
||||
test.strictEqual logged, "{#{ oAi.id }} " + pw, 'Did not log the right thing'
|
||||
catch e
|
||||
test.ok false, 'Parsing log failed'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: null
|
||||
ruleId: oRuleReal.id
|
||||
engine.shutDown()
|
||||
setTimeout test.done, 200
|
||||
|
||||
setTimeout fWaitAgain, 200
|
||||
|
||||
setTimeout fWaitForPersistence, 200
|
||||
paramOne = 'First Test'
|
||||
code = "exports.testFunc = () ->\n\t'#{ paramOne }'"
|
||||
dm.compileString code, 'userOne', 'ruleOne', 'moduleOne', 'CoffeeScript', null, ( result ) ->
|
||||
test.strictEqual 200, result.answ.code
|
||||
moduleOne = result.module
|
||||
test.strictEqual paramOne, moduleOne.testFunc(), "Other result expected"
|
||||
|
||||
paramTwo = 'Second Test'
|
||||
code = "exports.testFunc = () ->\n\t'#{ paramTwo }'"
|
||||
dm.compileString code, 'userOne', 'ruleOne', 'moduleOne', 'CoffeeScript', null, ( result ) ->
|
||||
test.strictEqual 200, result.answ.code
|
||||
moduleTwo = result.module
|
||||
test.strictEqual paramTwo, moduleTwo.testFunc(), "Other result expected"
|
||||
test.notStrictEqual paramOne, moduleTwo.testFunc(), "Other result expected"
|
||||
setTimeout test.done, 200
|
||||
|
|
|
|||
|
|
@ -2,19 +2,19 @@ fs = require 'fs'
|
|||
path = require 'path'
|
||||
|
||||
try
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
catch err
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
|
||||
logger = require path.join '..', 'js', 'logging'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
nolog: true
|
||||
opts =
|
||||
logger: log
|
||||
logger: log
|
||||
|
||||
engine = require path.join '..', 'js', 'engine'
|
||||
engine opts
|
||||
|
|
@ -25,93 +25,93 @@ db opts
|
|||
listRules = engine.getListUserRules()
|
||||
|
||||
oUser = objects.users.userOne
|
||||
oRuleReal = objects.rules.ruleReal
|
||||
oRuleRealTwo = objects.rules.ruleRealTwo
|
||||
oRuleOne = objects.rules.ruleOne
|
||||
oRuleTwo = objects.rules.ruleTwo
|
||||
oAiOne = objects.ais.aiOne
|
||||
oAiTwo = objects.ais.aiTwo
|
||||
|
||||
exports.setUp = ( cb ) ->
|
||||
engine.startEngine()
|
||||
cb()
|
||||
|
||||
engine.startEngine()
|
||||
cb()
|
||||
|
||||
exports.tearDown = ( cb ) ->
|
||||
db.deleteRule oRuleReal.id
|
||||
db.actionInvokers.deleteModule oAiOne.id
|
||||
db.actionInvokers.deleteModule oAiTwo.id
|
||||
# TODO if user is deleted all his modules should be unlinked and deleted
|
||||
db.deleteUser oUser.username
|
||||
db.deleteRule oRuleOne.id
|
||||
db.actionInvokers.deleteModule oAiOne.id
|
||||
db.actionInvokers.deleteModule oAiTwo.id
|
||||
# TODO if user is deleted all his modules should be unlinked and deleted
|
||||
db.deleteUser oUser.username
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleOne
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleRealTwo
|
||||
engine.shutDown()
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: oRuleTwo
|
||||
engine.shutDown()
|
||||
|
||||
setTimeout cb, 200
|
||||
setTimeout cb, 200
|
||||
|
||||
exports.ruleEvents =
|
||||
testInitAddDeleteMultiple: ( test ) ->
|
||||
test.expect 2 + 2 * oRuleReal.actions.length + oRuleRealTwo.actions.length
|
||||
testInitAddDeleteMultiple: ( test ) ->
|
||||
test.expect 2 + 2 * oRuleOne.actions.length + oRuleTwo.actions.length
|
||||
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
db.linkRule oRuleReal.id, oUser.username
|
||||
db.activateRule oRuleReal.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
db.actionInvokers.storeModule oUser.username, oAiTwo
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleOne.id, JSON.stringify oRuleOne
|
||||
db.linkRule oRuleOne.id, oUser.username
|
||||
db.activateRule oRuleOne.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
db.actionInvokers.storeModule oUser.username, oAiTwo
|
||||
|
||||
test.strictEqual listRules[oUser.username], undefined, 'Initial user object exists!?'
|
||||
test.strictEqual listRules[oUser.username], undefined, 'Initial user object exists!?'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleOne
|
||||
|
||||
fWaitForPersistence = () ->
|
||||
fWaitForPersistence = () ->
|
||||
|
||||
for act in oRuleReal.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username][oRuleReal.id].actions[mod], 'Missing action!'
|
||||
|
||||
for act in oRuleOne.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username][oRuleOne.id].actions[mod], 'Missing action!'
|
||||
|
||||
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleRealTwo
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleTwo
|
||||
|
||||
fWaitAgainForPersistence = () ->
|
||||
fWaitAgainForPersistence = () ->
|
||||
|
||||
for act in oRuleRealTwo.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username][oRuleRealTwo.id].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: null
|
||||
ruleId: oRuleRealTwo.id
|
||||
for act in oRuleTwo.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username][oRuleTwo.id].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: null
|
||||
ruleId: oRuleTwo.id
|
||||
|
||||
for act in oRuleReal.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username][oRuleReal.id].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: null
|
||||
ruleId: oRuleReal.id
|
||||
for act in oRuleOne.actions
|
||||
mod = ( act.split ' -> ' )[0]
|
||||
test.ok listRules[oUser.username][oRuleOne.id].actions[mod], 'Missing action!'
|
||||
|
||||
engine.internalEvent
|
||||
event: 'del'
|
||||
user: oUser.username
|
||||
rule: null
|
||||
ruleId: oRuleOne.id
|
||||
|
||||
test.strictEqual listRules[oUser.username], undefined, 'Final user object exists!?'
|
||||
test.done()
|
||||
test.strictEqual listRules[oUser.username], undefined, 'Final user object exists!?'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitAgainForPersistence, 200
|
||||
setTimeout fWaitAgainForPersistence, 200
|
||||
|
||||
setTimeout fWaitForPersistence, 200
|
||||
setTimeout fWaitForPersistence, 200
|
||||
|
||||
# #TODO
|
||||
# testUpdate: ( test ) ->
|
||||
|
|
@ -120,9 +120,9 @@ exports.ruleEvents =
|
|||
# test.done()
|
||||
|
||||
# db.storeUser oUser
|
||||
# db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
# db.linkRule oRuleReal.id, oUser.username
|
||||
# db.activateRule oRuleReal.id, oUser.username
|
||||
# db.storeRule oRuleOne.id, JSON.stringify oRuleOne
|
||||
# db.linkRule oRuleOne.id, oUser.username
|
||||
# db.activateRule oRuleOne.id, oUser.username
|
||||
# db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ exports.ruleEvents =
|
|||
# engine.internalEvent
|
||||
# event: 'init'
|
||||
# user: oUser.username
|
||||
# rule: oRuleReal
|
||||
# rule: oRuleOne
|
||||
|
||||
# fCheckRules = () ->
|
||||
# db.getAllActivatedRuleIdsPerUser ( err, obj ) ->
|
||||
|
|
@ -143,35 +143,35 @@ exports.ruleEvents =
|
|||
# setTimeout fCheckRules, 500
|
||||
|
||||
exports.engine =
|
||||
testMatchingEvent: ( test ) ->
|
||||
test.expect 1
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleReal.id, JSON.stringify oRuleReal
|
||||
db.linkRule oRuleReal.id, oUser.username
|
||||
db.activateRule oRuleReal.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
testMatchingEvent: ( test ) ->
|
||||
test.expect 1
|
||||
db.storeUser oUser
|
||||
db.storeRule oRuleOne.id, JSON.stringify oRuleOne
|
||||
db.linkRule oRuleOne.id, oUser.username
|
||||
db.activateRule oRuleOne.id, oUser.username
|
||||
db.actionInvokers.storeModule oUser.username, oAiOne
|
||||
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleReal
|
||||
engine.internalEvent
|
||||
event: 'new'
|
||||
user: oUser.username
|
||||
rule: oRuleOne
|
||||
|
||||
fWaitForPersistence = () ->
|
||||
evt = objects.events.eventReal
|
||||
evt.eventid = 'event_testid'
|
||||
db.pushEvent evt
|
||||
fWaitForPersistence = () ->
|
||||
evt = objects.events.eventReal
|
||||
evt.eventid = 'event_testid'
|
||||
db.pushEvent evt
|
||||
|
||||
fWaitAgain = () ->
|
||||
db.getLog oUser.username, oRuleReal.id, ( err, data ) ->
|
||||
try
|
||||
fWaitAgain = () ->
|
||||
db.getLog oUser.username, oRuleOne.id, ( err, data ) ->
|
||||
try
|
||||
|
||||
logged = data.split( '] ' )[1]
|
||||
logged = logged.split( "\n" )[0]
|
||||
test.strictEqual logged, "{#{ oAiOne.id }} " + evt.payload.property, 'Did not log the right thing'
|
||||
catch e
|
||||
test.ok false, 'Parsing log failed'
|
||||
test.done()
|
||||
logged = data.split( '] ' )[1]
|
||||
logged = logged.split( "\n" )[0]
|
||||
test.strictEqual logged, "{#{ oAiOne.id }} " + evt.payload.property, 'Did not log the right thing'
|
||||
catch e
|
||||
test.ok false, 'Parsing log failed'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitAgain, 200
|
||||
setTimeout fWaitAgain, 200
|
||||
|
||||
setTimeout fWaitForPersistence, 200
|
||||
setTimeout fWaitForPersistence, 200
|
||||
|
|
|
|||
|
|
@ -4,97 +4,97 @@ stdPath = path.resolve __dirname, '..', 'logs', 'server.log'
|
|||
logger = require path.join '..', 'js', 'logging'
|
||||
|
||||
getLog = ( strPath, cb ) ->
|
||||
fWait = ->
|
||||
# cb fs.readFileSync path, 'utf-8'
|
||||
str = fs.readFileSync path.resolve( strPath ), 'utf-8'
|
||||
arrStr = str.split "\n"
|
||||
fConvertRow = ( row ) ->
|
||||
try
|
||||
JSON.parse row
|
||||
arrStr[i] = fConvertRow row for row, i in arrStr
|
||||
cb arrStr.slice 0, arrStr.length - 1
|
||||
setTimeout fWait, 100
|
||||
fWait = ->
|
||||
# cb fs.readFileSync path, 'utf-8'
|
||||
str = fs.readFileSync path.resolve( strPath ), 'utf-8'
|
||||
arrStr = str.split "\n"
|
||||
fConvertRow = ( row ) ->
|
||||
try
|
||||
JSON.parse row
|
||||
arrStr[i] = fConvertRow row for row, i in arrStr
|
||||
cb arrStr.slice 0, arrStr.length - 1
|
||||
setTimeout fWait, 100
|
||||
|
||||
exports.setUp = ( cb ) ->
|
||||
try
|
||||
fs.unlinkSync stdPath
|
||||
cb()
|
||||
try
|
||||
fs.unlinkSync stdPath
|
||||
cb()
|
||||
|
||||
exports.testCreate = ( test ) ->
|
||||
test.expect 2
|
||||
arrLogs = [
|
||||
'TL | testInitIO - info'
|
||||
'TL | testInitIO - warn'
|
||||
'TL | testInitIO - error'
|
||||
]
|
||||
args = {}
|
||||
args[ 'io-level' ] = 'error'
|
||||
log = logger.getLogger args
|
||||
log.info arrLogs[0]
|
||||
log.warn arrLogs[1]
|
||||
log.error arrLogs[2]
|
||||
test.ok fs.existsSync( stdPath ), 'Log file does not exist!'
|
||||
getLog stdPath, ( arr ) ->
|
||||
allCorrect = true
|
||||
for o,i in arr
|
||||
if o.msg is not arrLogs[i]
|
||||
allCorrect = false
|
||||
test.ok allCorrect, 'Log file does not contain the correct entries!'
|
||||
test.done()
|
||||
test.expect 2
|
||||
arrLogs = [
|
||||
'TL | testInitIO - info'
|
||||
'TL | testInitIO - warn'
|
||||
'TL | testInitIO - error'
|
||||
]
|
||||
args = {}
|
||||
args[ 'io-level' ] = 'error'
|
||||
log = logger.getLogger args
|
||||
log.info arrLogs[0]
|
||||
log.warn arrLogs[1]
|
||||
log.error arrLogs[2]
|
||||
test.ok fs.existsSync( stdPath ), 'Log file does not exist!'
|
||||
getLog stdPath, ( arr ) ->
|
||||
allCorrect = true
|
||||
for o,i in arr
|
||||
if o.msg is not arrLogs[i]
|
||||
allCorrect = false
|
||||
test.ok allCorrect, 'Log file does not contain the correct entries!'
|
||||
test.done()
|
||||
|
||||
exports.testNoLog = ( test ) ->
|
||||
test.expect 1
|
||||
test.expect 1
|
||||
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
log.info 'TL | test 1'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
log.info 'TL | test 1'
|
||||
|
||||
fWait = () ->
|
||||
test.ok !fs.existsSync( stdPath ), 'Log file does still exist!'
|
||||
test.done()
|
||||
fWait = () ->
|
||||
test.ok !fs.existsSync( stdPath ), 'Log file does still exist!'
|
||||
test.done()
|
||||
|
||||
setTimeout fWait, 100
|
||||
setTimeout fWait, 100
|
||||
|
||||
exports.testCustomPath = ( test ) ->
|
||||
test.expect 2
|
||||
test.expect 2
|
||||
|
||||
strInfo = 'TL | custom path test 1'
|
||||
strPath = 'testing/files/test.log'
|
||||
args = {}
|
||||
args[ 'file-path' ] = strPath
|
||||
args[ 'io-level' ] = 'error'
|
||||
strInfo = 'TL | custom path test 1'
|
||||
strPath = 'testing/files/test.log'
|
||||
args = {}
|
||||
args[ 'file-path' ] = strPath
|
||||
args[ 'io-level' ] = 'error'
|
||||
|
||||
log = logger.getLogger args
|
||||
log.info strInfo
|
||||
log = logger.getLogger args
|
||||
log.info strInfo
|
||||
|
||||
fWait = () ->
|
||||
test.ok fs.existsSync( strPath ), 'Custom log file does not exist!'
|
||||
getLog strPath, ( arr ) ->
|
||||
test.ok arr[0].msg is strInfo, 'Custom log file not correct!'
|
||||
try
|
||||
fs.unlinkSync strPath
|
||||
test.done()
|
||||
fWait = () ->
|
||||
test.ok fs.existsSync( strPath ), 'Custom log file does not exist!'
|
||||
getLog strPath, ( arr ) ->
|
||||
test.ok arr[0].msg is strInfo, 'Custom log file not correct!'
|
||||
try
|
||||
fs.unlinkSync strPath
|
||||
test.done()
|
||||
|
||||
setTimeout fWait, 100
|
||||
setTimeout fWait, 100
|
||||
|
||||
exports.testWrongPath = ( test ) ->
|
||||
empty = [
|
||||
'trace'
|
||||
'debug'
|
||||
'info'
|
||||
'warn'
|
||||
'error'
|
||||
'fatal'
|
||||
]
|
||||
test.expect empty.length
|
||||
empty = [
|
||||
'trace'
|
||||
'debug'
|
||||
'info'
|
||||
'warn'
|
||||
'error'
|
||||
'fatal'
|
||||
]
|
||||
test.expect empty.length
|
||||
|
||||
strInfo = 'TL | custom path test 1'
|
||||
strPath = 'strange/path/to/test.log'
|
||||
args = {}
|
||||
args[ 'file-path' ] = strPath
|
||||
args[ 'io-level' ] = 'error'
|
||||
log = logger.getLogger args
|
||||
test.ok prop in empty, "#{ prop } shouldn't be here" for prop of log
|
||||
test.done()
|
||||
strInfo = 'TL | custom path test 1'
|
||||
strPath = 'strange/path/to/test.log'
|
||||
args = {}
|
||||
args[ 'file-path' ] = strPath
|
||||
args[ 'io-level' ] = 'error'
|
||||
log = logger.getLogger args
|
||||
test.ok prop in empty, "#{ prop } shouldn't be here" for prop of log
|
||||
test.done()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -6,241 +6,241 @@ cp = require 'child_process'
|
|||
|
||||
|
||||
try
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
data = fs.readFileSync path.resolve( 'testing', 'files', 'testObjects.json' ), 'utf8'
|
||||
try
|
||||
objects = JSON.parse data
|
||||
catch err
|
||||
console.log 'Error parsing standard objects file: ' + err.message
|
||||
catch err
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
console.log 'Error fetching standard objects file: ' + err.message
|
||||
logger = require path.join '..', 'js', 'logging'
|
||||
log = logger.getLogger
|
||||
nolog: true
|
||||
nolog: true
|
||||
opts =
|
||||
logger: log
|
||||
logger: log
|
||||
opts[ 'db-port' ] = 6379
|
||||
db = require path.join '..', 'js', 'persistence'
|
||||
db opts
|
||||
|
||||
rh = require path.join '..', 'js', 'request-handler'
|
||||
opts[ 'request-service' ] = ( usr, obj, cb ) ->
|
||||
test.ok false, 'testEvent should not cause a service request call'
|
||||
test.ok false, 'testEvent should not cause a service request call'
|
||||
opts[ 'shutdown-function' ] = () ->
|
||||
test.ok false, 'testEvent should not cause a system shutdown'
|
||||
test.ok false, 'testEvent should not cause a system shutdown'
|
||||
rh opts
|
||||
|
||||
createRequest = ( query, origUrl ) ->
|
||||
req = new events.EventEmitter()
|
||||
req.query = query
|
||||
req.originalUrl = origUrl
|
||||
req.session = {}
|
||||
req
|
||||
req = new events.EventEmitter()
|
||||
req.query = query
|
||||
req.originalUrl = origUrl
|
||||
req.session = {}
|
||||
req
|
||||
|
||||
createLoggedInRequest = ( query, origUrl ) ->
|
||||
req = createRequest query, origUrl
|
||||
req.session =
|
||||
user: objects.users.userOne
|
||||
req
|
||||
req = createRequest query, origUrl
|
||||
req.session =
|
||||
user: objects.users.userOne
|
||||
req
|
||||
|
||||
createAdminRequest = ( query, origUrl ) ->
|
||||
req = createRequest()
|
||||
req.session =
|
||||
user: objects.users.userAdmin
|
||||
req
|
||||
req = createRequest()
|
||||
req.session =
|
||||
user: objects.users.userAdmin
|
||||
req
|
||||
|
||||
postRequestData = ( req, data ) ->
|
||||
req.emit 'data', data
|
||||
req.emit 'end'
|
||||
req.emit 'data', data
|
||||
req.emit 'end'
|
||||
|
||||
# cb want's to get a response like { code, msg }
|
||||
createResponse = ( cb ) ->
|
||||
resp =
|
||||
send: ( code, msg ) ->
|
||||
if msg
|
||||
code = parseInt code
|
||||
else
|
||||
msg = code
|
||||
code = 200
|
||||
cb code, msg
|
||||
resp =
|
||||
send: ( code, msg ) ->
|
||||
if msg
|
||||
code = parseInt code
|
||||
else
|
||||
msg = code
|
||||
code = 200
|
||||
cb code, msg
|
||||
|
||||
exports.session =
|
||||
setUp: ( cb ) =>
|
||||
@oUsr = objects.users.userOne
|
||||
db.storeUser @oUsr
|
||||
cb()
|
||||
setUp: ( cb ) =>
|
||||
@oUsr = objects.users.userOne
|
||||
db.storeUser @oUsr
|
||||
cb()
|
||||
|
||||
tearDown: ( cb ) =>
|
||||
db.deleteUser @oUsr.username
|
||||
cb()
|
||||
tearDown: ( cb ) =>
|
||||
db.deleteUser @oUsr.username
|
||||
cb()
|
||||
|
||||
testLoginAndOut: ( test ) =>
|
||||
test.expect 6
|
||||
testLoginAndOut: ( test ) =>
|
||||
test.expect 6
|
||||
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) =>
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) =>
|
||||
|
||||
# Check Login
|
||||
test.strictEqual code, 200, 'Login failed'
|
||||
test.deepEqual req.session.user, @oUsr, 'Session user not what we expected'
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) =>
|
||||
# Check Login
|
||||
test.strictEqual code, 200, 'Login failed'
|
||||
test.deepEqual req.session.user, @oUsr, 'Session user not what we expected'
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) =>
|
||||
|
||||
# Check Login again
|
||||
test.strictEqual code, 200, 'Login again did nothing different'
|
||||
test.deepEqual req.session.user, @oUsr, 'Session user not what we expected after relogin'
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
# Check Login again
|
||||
test.strictEqual code, 200, 'Login again did nothing different'
|
||||
test.deepEqual req.session.user, @oUsr, 'Session user not what we expected after relogin'
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
|
||||
# Check logout
|
||||
test.strictEqual code, 200, 'Logout failed'
|
||||
test.strictEqual req.session.user, null, 'User not removed from session'
|
||||
test.done()
|
||||
rh.handleLogout req, resp # set the handler to listening
|
||||
rh.handleLogin req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify @oUsr # emit the data post event
|
||||
# Check logout
|
||||
test.strictEqual code, 200, 'Logout failed'
|
||||
test.strictEqual req.session.user, null, 'User not removed from session'
|
||||
test.done()
|
||||
rh.handleLogout req, resp # set the handler to listening
|
||||
rh.handleLogin req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify @oUsr # emit the data post event
|
||||
|
||||
rh.handleLogin req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify @oUsr # emit the data post event
|
||||
rh.handleLogin req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify @oUsr # emit the data post event
|
||||
|
||||
|
||||
testWrongLogin: ( test ) =>
|
||||
test.expect 2
|
||||
testWrongLogin: ( test ) =>
|
||||
test.expect 2
|
||||
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) =>
|
||||
test.strictEqual code, 401, 'Login did not fail?'
|
||||
test.strictEqual req.session.user, undefined, 'User in session?'
|
||||
test.done()
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) =>
|
||||
test.strictEqual code, 401, 'Login did not fail?'
|
||||
test.strictEqual req.session.user, undefined, 'User in session?'
|
||||
test.done()
|
||||
|
||||
usr =
|
||||
username: @oUsr.username
|
||||
password: 'wrongpassword'
|
||||
rh.handleLogin req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify usr # emit the data post event
|
||||
usr =
|
||||
username: @oUsr.username
|
||||
password: 'wrongpassword'
|
||||
rh.handleLogin req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify usr # emit the data post event
|
||||
|
||||
exports.events =
|
||||
setUp: ( cb ) ->
|
||||
db.purgeEventQueue()
|
||||
cb()
|
||||
setUp: ( cb ) ->
|
||||
db.purgeEventQueue()
|
||||
cb()
|
||||
|
||||
# This test seems to hang sometimes... maybe it's also happening somewhere else...
|
||||
testCorrectEvent: ( test ) ->
|
||||
test.expect 2
|
||||
testCorrectEvent: ( test ) ->
|
||||
test.expect 2
|
||||
|
||||
oEvt = objects.events.eventOne
|
||||
oEvt = objects.events.eventOne
|
||||
|
||||
semaphore = 2
|
||||
fPopEvent = () ->
|
||||
fCb = ( err, obj ) ->
|
||||
oEvt.eventid = obj.eventid # because the event id is generated by the system
|
||||
test.deepEqual obj, oEvt, 'Caught event is not what we expected'
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
db.popEvent fCb
|
||||
semaphore = 2
|
||||
fPopEvent = () ->
|
||||
fCb = ( err, obj ) ->
|
||||
oEvt.eventid = obj.eventid # because the event id is generated by the system
|
||||
test.deepEqual obj, oEvt, 'Caught event is not what we expected'
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
db.popEvent fCb
|
||||
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 200
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 200
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
|
||||
rh.handleEvent req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify oEvt # emit the data post event
|
||||
setTimeout fPopEvent, 200 # try to fetch the db entry
|
||||
rh.handleEvent req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify oEvt # emit the data post event
|
||||
setTimeout fPopEvent, 200 # try to fetch the db entry
|
||||
|
||||
testIncorrectEvent: ( test ) ->
|
||||
test.expect 2
|
||||
testIncorrectEvent: ( test ) ->
|
||||
test.expect 2
|
||||
|
||||
oEvt =
|
||||
data: 'event misses event type property'
|
||||
oEvt =
|
||||
data: 'event misses event type property'
|
||||
|
||||
semaphore = 2
|
||||
fPopEvent = () ->
|
||||
fCb = ( err, obj ) ->
|
||||
test.deepEqual obj, null, 'We caught an event!?'
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
db.popEvent fCb
|
||||
semaphore = 2
|
||||
fPopEvent = () ->
|
||||
fCb = ( err, obj ) ->
|
||||
test.deepEqual obj, null, 'We caught an event!?'
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
db.popEvent fCb
|
||||
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 400
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 400
|
||||
if --semaphore is 0
|
||||
test.done()
|
||||
|
||||
rh.handleEvent req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify oEvt # emit the data post event
|
||||
setTimeout fPopEvent, 200 # try to fetch the db entry
|
||||
rh.handleEvent req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify oEvt # emit the data post event
|
||||
setTimeout fPopEvent, 200 # try to fetch the db entry
|
||||
|
||||
exports.testLoginOrPage = ( test ) ->
|
||||
test.expect 3
|
||||
test.expect 3
|
||||
|
||||
req = createRequest()
|
||||
req.query =
|
||||
page: 'forge_event'
|
||||
resp = createResponse ( code, msg ) ->
|
||||
|
||||
# Ensure we have to login first
|
||||
test.ok msg.indexOf( 'document.title = \'Login\'' ) > 0, 'Didn\'t get login page?'
|
||||
req = createLoggedInRequest()
|
||||
req.query =
|
||||
page: 'forge_event'
|
||||
resp = createResponse ( code, msg ) ->
|
||||
req = createRequest()
|
||||
req.query =
|
||||
page: 'forge_event'
|
||||
resp = createResponse ( code, msg ) ->
|
||||
|
||||
# Ensure we have to login first
|
||||
test.ok msg.indexOf( 'document.title = \'Login\'' ) > 0, 'Didn\'t get login page?'
|
||||
req = createLoggedInRequest()
|
||||
req.query =
|
||||
page: 'forge_event'
|
||||
resp = createResponse ( code, msg ) ->
|
||||
|
||||
# After being logged in we should get the expected page
|
||||
test.ok msg.indexOf( 'document.title = \'Event Forge!\'' ) > 0, 'Didn\' get forge page?'
|
||||
req = createLoggedInRequest()
|
||||
req.query =
|
||||
page: 'wrongpage'
|
||||
resp = createResponse ( code, msg ) ->
|
||||
# After being logged in we should get the expected page
|
||||
test.ok msg.indexOf( 'document.title = \'Event Forge!\'' ) > 0, 'Didn\' get forge page?'
|
||||
req = createLoggedInRequest()
|
||||
req.query =
|
||||
page: 'wrongpage'
|
||||
resp = createResponse ( code, msg ) ->
|
||||
|
||||
# A wrong page request should give back an error page
|
||||
test.ok msg.indexOf( 'document.title = \'Error!\'' ) > 0, 'Didn\' get forge page?'
|
||||
test.done()
|
||||
# A wrong page request should give back an error page
|
||||
test.ok msg.indexOf( 'document.title = \'Error!\'' ) > 0, 'Didn\' get forge page?'
|
||||
test.done()
|
||||
|
||||
rh.handleForge req, resp # set the handler to listening
|
||||
rh.handleForge req, resp # set the handler to listening
|
||||
rh.handleForge req, resp # set the handler to listening
|
||||
rh.handleForge req, resp # set the handler to listening
|
||||
rh.handleForge req, resp # set the handler to listening
|
||||
rh.handleForge req, resp # set the handler to listening
|
||||
|
||||
|
||||
exports.testUserCommandsNoLogin = ( test ) ->
|
||||
test.expect 1
|
||||
test.expect 1
|
||||
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 401, 'Login did not fail?'
|
||||
test.done()
|
||||
rh.handleUserCommand req, resp # set the handler to listening
|
||||
req = createRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 401, 'Login did not fail?'
|
||||
test.done()
|
||||
rh.handleUserCommand req, resp # set the handler to listening
|
||||
|
||||
|
||||
exports.testUserCommands = ( test ) ->
|
||||
test.expect 3
|
||||
test.expect 3
|
||||
|
||||
oReqData =
|
||||
command: 'get_something'
|
||||
# store_action
|
||||
# store_event
|
||||
# store_rule
|
||||
# get_eventmodules
|
||||
# get_actionmodules
|
||||
oReqData =
|
||||
command: 'get_something'
|
||||
# store_action
|
||||
# store_event
|
||||
# store_rule
|
||||
# get_eventmodules
|
||||
# get_actionmodules
|
||||
|
||||
oRespData =
|
||||
code: 200
|
||||
some: 'very'
|
||||
important: 'data'
|
||||
oRespData =
|
||||
code: 200
|
||||
some: 'very'
|
||||
important: 'data'
|
||||
|
||||
args =
|
||||
logger: log
|
||||
args[ 'request-service' ] = ( usr, obj, cb ) ->
|
||||
test.ok true, 'Yay we got the request!'
|
||||
cb oRespData
|
||||
rh args
|
||||
args =
|
||||
logger: log
|
||||
args[ 'request-service' ] = ( usr, obj, cb ) ->
|
||||
test.ok true, 'Yay we got the request!'
|
||||
cb oRespData
|
||||
rh args
|
||||
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 200, 'Service wasn\'t happy with our request'
|
||||
test.deepEqual msg, oRespData, 'Service didn\'t return expected'
|
||||
test.done()
|
||||
rh.handleUserCommand req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify oReqData # emit the data post event
|
||||
|
||||
req = createLoggedInRequest()
|
||||
resp = createResponse ( code, msg ) ->
|
||||
test.strictEqual code, 200, 'Service wasn\'t happy with our request'
|
||||
test.deepEqual msg, oRespData, 'Service didn\'t return expected'
|
||||
test.done()
|
||||
rh.handleUserCommand req, resp # set the handler to listening
|
||||
postRequestData req, JSON.stringify oReqData # emit the data post event
|
||||
|
||||
|
|
|
|||
|
|
@ -6,125 +6,125 @@ path = require 'path'
|
|||
# TODO test wrong/invalid config file
|
||||
|
||||
exports.testShutDown = ( test ) ->
|
||||
test.expect 1
|
||||
test.expect 1
|
||||
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-w', '8640' ] # [ '-i' , 'warn' ]
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-w', '8640' ] # [ '-i' , 'warn' ]
|
||||
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
|
||||
fWaitForStartup = () ->
|
||||
engine.send 'die'
|
||||
setTimeout fWaitForDeath, 5000
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
if isRunning
|
||||
test.ok false, '"testShutDown" Engine didn\'t shut down!'
|
||||
engine.kill()
|
||||
setTimeout test.done, 100
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
|
||||
fWaitForStartup = () ->
|
||||
engine.send 'die'
|
||||
setTimeout fWaitForDeath, 5000
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
if isRunning
|
||||
test.ok false, '"testShutDown" Engine didn\'t shut down!'
|
||||
engine.kill()
|
||||
setTimeout test.done, 100
|
||||
|
||||
setTimeout fWaitForStartup, 1000
|
||||
setTimeout fWaitForStartup, 1000
|
||||
|
||||
exports.testKill = ( test ) ->
|
||||
test.expect 1
|
||||
test.expect 1
|
||||
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-w', '8641' ] # [ '-i' , 'warn' ]
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-w', '8641' ] # [ '-i' , 'warn' ]
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
|
||||
fWaitForStartup = () ->
|
||||
engine.kill()
|
||||
setTimeout fWaitForDeath, 1000
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
test.ok engine.killed, '"testKill" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
fWaitForStartup = () ->
|
||||
engine.kill()
|
||||
setTimeout fWaitForDeath, 1000
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
test.ok engine.killed, '"testKill" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitForStartup, 1000
|
||||
setTimeout fWaitForStartup, 1000
|
||||
|
||||
exports.testHttpPortAlreadyUsed = ( test ) =>
|
||||
test.expect 1
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
|
||||
# Strange! why can't we make these variables local without
|
||||
# the tests failing in one of the next tests...
|
||||
@engine_one = cp.fork pth, [ '-n', '-w', '8642' ] # [ '-i' , 'warn' ]
|
||||
@engine_one.on 'error', ( err ) ->
|
||||
console.log err
|
||||
test.expect 1
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
|
||||
# Strange! why can't we make these variables local without
|
||||
# the tests failing in one of the next tests...
|
||||
@engine_one = cp.fork pth, [ '-n', '-w', '8642' ] # [ '-i' , 'warn' ]
|
||||
@engine_one.on 'error', ( err ) ->
|
||||
console.log err
|
||||
|
||||
fWaitForFirstStartup = () =>
|
||||
@engine_two = cp.fork pth, [ '-n', '-w', '8642' ] # [ '-i' , 'warn' ]
|
||||
@engine_two.on 'error', ( err ) ->
|
||||
console.log err
|
||||
fWaitForFirstStartup = () =>
|
||||
@engine_two = cp.fork pth, [ '-n', '-w', '8642' ] # [ '-i' , 'warn' ]
|
||||
@engine_two.on 'error', ( err ) ->
|
||||
console.log err
|
||||
|
||||
@engine_two.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitForDeath, 12000
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () =>
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortAlreadyUsed" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
@engine_two.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitForDeath, 12000
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () =>
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortAlreadyUsed" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
|
||||
@engine_one.kill()
|
||||
@engine_two.kill()
|
||||
@engine_one.kill()
|
||||
@engine_two.kill()
|
||||
|
||||
setTimeout fWaitForFirstStartup, 1000
|
||||
setTimeout fWaitForFirstStartup, 1000
|
||||
|
||||
exports.testHttpPortInvalid = ( test ) ->
|
||||
test.expect 1
|
||||
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-w', '1' ] # [ '-i' , 'warn' ]
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
test.expect 1
|
||||
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-w', '1' ] # [ '-i' , 'warn' ]
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
# engine.kill()
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
# engine.kill()
|
||||
|
||||
setTimeout fWaitForDeath, 12000
|
||||
setTimeout fWaitForDeath, 12000
|
||||
|
||||
exports.testDbPortInvalid = ( test ) ->
|
||||
test.expect 1
|
||||
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-d', '10'] # [ '-i' , 'warn' ]
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
test.expect 1
|
||||
|
||||
isRunning = true
|
||||
pth = path.resolve 'js', 'webapi-eca'
|
||||
engine = cp.fork pth, [ '-n', '-d', '10'] # [ '-i' , 'warn' ]
|
||||
engine.on 'error', ( err ) ->
|
||||
console.log err
|
||||
engine.on 'exit', ( code, signal ) ->
|
||||
test.ok true, 'Engine stopped'
|
||||
isRunning = false
|
||||
test.done()
|
||||
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
engine.kill()
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
# Garbage collect eventually still running process
|
||||
fWaitForDeath = () ->
|
||||
engine.kill()
|
||||
if isRunning
|
||||
test.ok false, '"testHttpPortInvalid" Engine didn\'t shut down!'
|
||||
test.done()
|
||||
|
||||
setTimeout fWaitForDeath, 12000
|
||||
setTimeout fWaitForDeath, 12000
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Administrate'
|
||||
$( '#pagetitle' ).text 'Hi {{{user.username}}}, issue your commands please:'
|
||||
$( '#but_submit' ).click () ->
|
||||
data =
|
||||
command: $( '#inp_command' ).val()
|
||||
$.post( 'admincommand', data )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
err.responseText = 'No Response from Server!'
|
||||
$( '#info' ).text 'Error: ' + err.responseText
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
if err.status is 401
|
||||
window.location.href = 'admin'
|
||||
setTimeout fDelayed, 500
|
||||
document.title = 'Administrate'
|
||||
$( '#pagetitle' ).text 'Hi {{{user.username}}}, issue your commands please:'
|
||||
$( '#but_submit' ).click () ->
|
||||
data =
|
||||
command: $( '#inp_command' ).val()
|
||||
$.post( 'admincommand', data )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
err.responseText = 'No Response from Server!'
|
||||
$( '#info' ).text 'Error: ' + err.responseText
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
if err.status is 401
|
||||
window.location.href = 'admin'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
|
|
|||
|
|
@ -1,111 +1,111 @@
|
|||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Edit Modules'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, edit your Modules!"
|
||||
document.title = 'Edit Modules'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, edit your Modules!"
|
||||
|
||||
moduleType = $( '#module_type' ).val()
|
||||
$( '#module_type' ).change () ->
|
||||
moduleType = $( this ).val()
|
||||
console.log moduleType
|
||||
fFetchModules()
|
||||
moduleType = $( '#module_type' ).val()
|
||||
$( '#module_type' ).change () ->
|
||||
moduleType = $( this ).val()
|
||||
console.log moduleType
|
||||
fFetchModules()
|
||||
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.setReadOnly true
|
||||
editor.setShowPrintMargin false
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.setReadOnly true
|
||||
editor.setShowPrintMargin false
|
||||
|
||||
fErrHandler = ( errMsg ) ->
|
||||
( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=edit_modules'
|
||||
else
|
||||
$( '#moduleName' ).html "<h2> </h2>"
|
||||
$( '#moduleLanguage' ).html "<b> </b>"
|
||||
editor.setValue ""
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text errMsg + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
fErrHandler = ( errMsg ) ->
|
||||
( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=edit_modules'
|
||||
else
|
||||
$( '#moduleName' ).html "<h2> </h2>"
|
||||
$( '#moduleLanguage' ).html "<b> </b>"
|
||||
editor.setValue ""
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text errMsg + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
fFetchModules = () ->
|
||||
if moduleType is 'Event Poller'
|
||||
cmd = 'get_event_pollers'
|
||||
else
|
||||
cmd = 'get_action_invokers'
|
||||
$.post( '/usercommand', command: cmd )
|
||||
.done fUpdateModuleList
|
||||
.fail fErrHandler 'Did not retrieve rules! '
|
||||
fFetchModules = () ->
|
||||
if moduleType is 'Event Poller'
|
||||
cmd = 'get_event_pollers'
|
||||
else
|
||||
cmd = 'get_action_invokers'
|
||||
$.post( '/usercommand', command: cmd )
|
||||
.done fUpdateModuleList
|
||||
.fail fErrHandler 'Did not retrieve rules! '
|
||||
|
||||
fUpdateModuleList = ( data ) ->
|
||||
$( '#tableModules tr' ).remove()
|
||||
oMods = JSON.parse data.message
|
||||
for modName of oMods
|
||||
tr = $ '<tr>'
|
||||
inp = $( '<div>' ).text modName
|
||||
img = $( '<img>' ).attr( 'class', 'del' )
|
||||
.attr( 'title', 'Delete Module' ).attr 'src', 'red_cross_small.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
img = $( '<img>' ).attr( 'class', 'log' )
|
||||
.attr( 'title', 'Edit Module' ).attr 'src', 'edit.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
$( '#tableModules' ).append tr
|
||||
fUpdateModuleList = ( data ) ->
|
||||
$( '#tableModules tr' ).remove()
|
||||
oMods = JSON.parse data.message
|
||||
for modName of oMods
|
||||
tr = $ '<tr>'
|
||||
inp = $( '<div>' ).text modName
|
||||
img = $( '<img>' ).attr( 'class', 'del' )
|
||||
.attr( 'title', 'Delete Module' ).attr 'src', 'red_cross_small.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
img = $( '<img>' ).attr( 'class', 'log' )
|
||||
.attr( 'title', 'Edit Module' ).attr 'src', 'edit.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
$( '#tableModules' ).append tr
|
||||
|
||||
fFetchModules()
|
||||
fFetchModules()
|
||||
|
||||
$( '#tableModules' ).on 'click', 'img.del', () ->
|
||||
modName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
if confirm "Do you really want to delete the Module '#{ modName }'?
|
||||
The module might still be active in some of your rules!"
|
||||
$( '#moduleName' ).html "<h2> </h2>"
|
||||
$( '#moduleLanguage' ).html "<b> </b>"
|
||||
editor.setValue ""
|
||||
if moduleType is 'Event Poller'
|
||||
cmd = 'delete_event_poller'
|
||||
else
|
||||
cmd = 'delete_action_invoker'
|
||||
data =
|
||||
command: cmd
|
||||
payload:
|
||||
id: modName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done fFetchModules
|
||||
.fail fErrHandler 'Could not delete module! '
|
||||
$( '#tableModules' ).on 'click', 'img.del', () ->
|
||||
modName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
if confirm "Do you really want to delete the Module '#{ modName }'?
|
||||
The module might still be active in some of your rules!"
|
||||
$( '#moduleName' ).html "<h2> </h2>"
|
||||
$( '#moduleLanguage' ).html "<b> </b>"
|
||||
editor.setValue ""
|
||||
if moduleType is 'Event Poller'
|
||||
cmd = 'delete_event_poller'
|
||||
else
|
||||
cmd = 'delete_action_invoker'
|
||||
data =
|
||||
command: cmd
|
||||
payload:
|
||||
id: modName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done fFetchModules
|
||||
.fail fErrHandler 'Could not delete module! '
|
||||
|
||||
$( '#tableModules' ).on 'click', 'img.log', () ->
|
||||
modName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
if moduleType is 'Event Poller'
|
||||
cmd = 'get_full_event_poller'
|
||||
else
|
||||
cmd = 'get_full_action_invoker'
|
||||
data =
|
||||
command: cmd
|
||||
payload:
|
||||
id: modName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done ( data ) ->
|
||||
try
|
||||
oMod = JSON.parse data.message
|
||||
catch err
|
||||
fErrHandler err.message
|
||||
if oMod.lang is 'CoffeeScript'
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
else
|
||||
editor.getSession().setMode "ace/mode/javascript"
|
||||
editor.setValue oMod.data
|
||||
editor.gotoLine 1, 1
|
||||
editor.scrollToRow 1
|
||||
$( '#moduleName' ).html "<h2>#{ oMod.id }</h2>"
|
||||
$( '#moduleLanguage' ).html "<b>#{ oMod.lang }</b>"
|
||||
$( '#tableModules' ).on 'click', 'img.log', () ->
|
||||
modName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
if moduleType is 'Event Poller'
|
||||
cmd = 'get_full_event_poller'
|
||||
else
|
||||
cmd = 'get_full_action_invoker'
|
||||
data =
|
||||
command: cmd
|
||||
payload:
|
||||
id: modName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done ( data ) ->
|
||||
try
|
||||
oMod = JSON.parse data.message
|
||||
catch err
|
||||
fErrHandler err.message
|
||||
if oMod.lang is 'CoffeeScript'
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
else
|
||||
editor.getSession().setMode "ace/mode/javascript"
|
||||
editor.setValue oMod.data
|
||||
editor.gotoLine 1, 1
|
||||
editor.scrollToRow 1
|
||||
$( '#moduleName' ).html "<h2>#{ oMod.id }</h2>"
|
||||
$( '#moduleLanguage' ).html "<b>#{ oMod.lang }</b>"
|
||||
|
||||
.fail fErrHandler 'Could not get module! '
|
||||
.fail fErrHandler 'Could not get module! '
|
||||
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
|
|
|||
|
|
@ -12,112 +12,112 @@
|
|||
|
||||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Edit Rules'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, edit your Rules!"
|
||||
document.title = 'Edit Rules'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, edit your Rules!"
|
||||
|
||||
fErrHandler = ( errMsg ) ->
|
||||
( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=edit_rules'
|
||||
else
|
||||
$( '#log_col' ).text ""
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text errMsg + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
fErrHandler = ( errMsg ) ->
|
||||
( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=edit_rules'
|
||||
else
|
||||
$( '#log_col' ).text ""
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text errMsg + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
fFetchRules = () ->
|
||||
$.post( '/usercommand', command: 'get_rules' )
|
||||
.done fUpdateRuleList
|
||||
.fail fErrHandler 'Did not retrieve rules! '
|
||||
fFetchRules = () ->
|
||||
$.post( '/usercommand', command: 'get_rules' )
|
||||
.done fUpdateRuleList
|
||||
.fail fErrHandler 'Did not retrieve rules! '
|
||||
|
||||
fUpdateRuleList = ( data ) ->
|
||||
$( '#tableRules tr' ).remove()
|
||||
for ruleName in data.message
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'class', 'del' )
|
||||
.attr( 'title', 'Delete Rule' ).attr 'src', 'red_cross_small.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
img = $( '<img>' ).attr( 'class', 'edit' )
|
||||
.attr( 'title', 'Edit Rule' ).attr 'src', 'edit.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
img = $( '<img>' ).attr( 'class', 'log' )
|
||||
.attr( 'title', 'Show Rule Log' ).attr 'src', 'logicon.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
inp = $( '<div>' ).text ruleName
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
$( '#tableRules' ).append tr
|
||||
fUpdateRuleList = ( data ) ->
|
||||
$( '#tableRules tr' ).remove()
|
||||
for ruleName in data.message
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'class', 'del' )
|
||||
.attr( 'title', 'Delete Rule' ).attr 'src', 'red_cross_small.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
img = $( '<img>' ).attr( 'class', 'edit' )
|
||||
.attr( 'title', 'Edit Rule' ).attr 'src', 'edit.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
img = $( '<img>' ).attr( 'class', 'log' )
|
||||
.attr( 'title', 'Show Rule Log' ).attr 'src', 'logicon.png'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
inp = $( '<div>' ).text ruleName
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
$( '#tableRules' ).append tr
|
||||
|
||||
fFetchRules()
|
||||
fFetchRules()
|
||||
|
||||
$( '#tableRules' ).on 'click', 'img.del', () ->
|
||||
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
if confirm "Do you really want to delete the rule '#{ ruleName }'?"
|
||||
$( '#log_col' ).text ""
|
||||
data =
|
||||
command: 'delete_rule'
|
||||
payload:
|
||||
id: ruleName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done fFetchRules
|
||||
.fail fErrHandler 'Could not delete rule! '
|
||||
$( '#tableRules' ).on 'click', 'img.del', () ->
|
||||
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
if confirm "Do you really want to delete the rule '#{ ruleName }'?"
|
||||
$( '#log_col' ).text ""
|
||||
data =
|
||||
command: 'delete_rule'
|
||||
payload:
|
||||
id: ruleName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done fFetchRules
|
||||
.fail fErrHandler 'Could not delete rule! '
|
||||
|
||||
$( '#tableRules' ).on 'click', 'img.edit', () ->
|
||||
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
window.location.href = 'forge?page=forge_rule&id=' + encodeURIComponent ruleName
|
||||
$( '#tableRules' ).on 'click', 'img.edit', () ->
|
||||
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
window.location.href = 'forge?page=forge_rule&id=' + encodeURIComponent ruleName
|
||||
|
||||
$( '#tableRules' ).on 'click', 'img.log', () ->
|
||||
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
data =
|
||||
command: 'get_rule_log'
|
||||
payload:
|
||||
id: ruleName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done ( data ) ->
|
||||
log = data.message.replace new RegExp("\n", 'g'), "<br>"
|
||||
$( '#log_col' ).html "<h3>#{ ruleName } Log:</h3>#{ log }"
|
||||
.fail fErrHandler 'Could not get rule log! '
|
||||
$( '#tableRules' ).on 'click', 'img.log', () ->
|
||||
ruleName = $( 'div', $( this ).closest( 'tr' )).text()
|
||||
data =
|
||||
command: 'get_rule_log'
|
||||
payload:
|
||||
id: ruleName
|
||||
data.payload = JSON.stringify data.payload
|
||||
$.post( '/usercommand', data )
|
||||
.done ( data ) ->
|
||||
log = data.message.replace new RegExp("\n", 'g'), "<br>"
|
||||
$( '#log_col' ).html "<h3>#{ ruleName } Log:</h3>#{ log }"
|
||||
.fail fErrHandler 'Could not get rule log! '
|
||||
|
||||
# Add parameter list functionality
|
||||
fChangeInputVisibility = () ->
|
||||
$( '#tableParams tr' ).each ( id ) ->
|
||||
if $( this ).is ':last-child' or $( this ).is ':only-child'
|
||||
$( 'img', this ).hide()
|
||||
$( 'input[type=checkbox]', this ).hide()
|
||||
else
|
||||
$( 'img', this ).show()
|
||||
$( 'input[type=checkbox]', this ).show()
|
||||
# Add parameter list functionality
|
||||
fChangeInputVisibility = () ->
|
||||
$( '#tableParams tr' ).each ( id ) ->
|
||||
if $( this ).is ':last-child' or $( this ).is ':only-child'
|
||||
$( 'img', this ).hide()
|
||||
$( 'input[type=checkbox]', this ).hide()
|
||||
else
|
||||
$( 'img', this ).show()
|
||||
$( 'input[type=checkbox]', this ).show()
|
||||
|
||||
$( '#tableParams' ).on 'click', 'img', () ->
|
||||
par = $( this ).closest 'tr'
|
||||
if not par.is ':last-child'
|
||||
par.remove()
|
||||
fChangeInputVisibility()
|
||||
$( '#tableParams' ).on 'click', 'img', () ->
|
||||
par = $( this ).closest 'tr'
|
||||
if not par.is ':last-child'
|
||||
par.remove()
|
||||
fChangeInputVisibility()
|
||||
|
||||
$( '#tableParams' ).on 'keyup', 'input', ( e ) ->
|
||||
code = e.keyCode or e.which
|
||||
if code isnt 9
|
||||
par = $( this ).closest 'tr'
|
||||
if par.is ':last-child'
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
|
||||
cb = $( '<input>' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
|
||||
inp = $( '<input>' ).attr( 'type', 'text' ).attr 'class', 'textinput'
|
||||
tr.append $( '<td>' ).append img
|
||||
tr.append $( '<td>' ).append cb
|
||||
tr.append $( '<td>' ).append inp
|
||||
par.parent().append tr
|
||||
fChangeInputVisibility()
|
||||
else if $( this ).val() is '' and not par.is ':only-child'
|
||||
par.remove()
|
||||
$( '#tableParams' ).on 'keyup', 'input', ( e ) ->
|
||||
code = e.keyCode or e.which
|
||||
if code isnt 9
|
||||
par = $( this ).closest 'tr'
|
||||
if par.is ':last-child'
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
|
||||
cb = $( '<input>' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
|
||||
inp = $( '<input>' ).attr( 'type', 'text' ).attr 'class', 'textinput'
|
||||
tr.append $( '<td>' ).append img
|
||||
tr.append $( '<td>' ).append cb
|
||||
tr.append $( '<td>' ).append inp
|
||||
par.parent().append tr
|
||||
fChangeInputVisibility()
|
||||
else if $( this ).val() is '' and not par.is ':only-child'
|
||||
par.remove()
|
||||
|
||||
fChangeInputVisibility()
|
||||
fChangeInputVisibility()
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
|
|
|||
|
|
@ -1,95 +1,95 @@
|
|||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Forge Action Invoker'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, forge your custom action invoker!"
|
||||
document.title = 'Forge Action Invoker'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, forge your custom action invoker!"
|
||||
|
||||
# Setup the ACE editor
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
editor.setShowPrintMargin false
|
||||
editor.session.setUseSoftTabs false
|
||||
|
||||
$( '#editor_mode' ).change ( el ) ->
|
||||
if $( this ).val() is 'CoffeeScript'
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
else
|
||||
editor.getSession().setMode "ace/mode/javascript"
|
||||
|
||||
# Add parameter list functionality
|
||||
fChangeInputVisibility = () ->
|
||||
$( '#tableParams tr' ).each ( id ) ->
|
||||
if $( this ).is ':last-child' or $( this ).is ':only-child'
|
||||
$( 'img', this ).hide()
|
||||
$( 'input[type=checkbox]', this ).hide()
|
||||
else
|
||||
$( 'img', this ).show()
|
||||
$( 'input[type=checkbox]', this ).show()
|
||||
# Setup the ACE editor
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
editor.setShowPrintMargin false
|
||||
editor.session.setUseSoftTabs false
|
||||
|
||||
$( '#editor_mode' ).change ( el ) ->
|
||||
if $( this ).val() is 'CoffeeScript'
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
else
|
||||
editor.getSession().setMode "ace/mode/javascript"
|
||||
|
||||
# Add parameter list functionality
|
||||
fChangeInputVisibility = () ->
|
||||
$( '#tableParams tr' ).each ( id ) ->
|
||||
if $( this ).is ':last-child' or $( this ).is ':only-child'
|
||||
$( 'img', this ).hide()
|
||||
$( 'input[type=checkbox]', this ).hide()
|
||||
else
|
||||
$( 'img', this ).show()
|
||||
$( 'input[type=checkbox]', this ).show()
|
||||
|
||||
$( '#tableParams' ).on 'click', 'img', () ->
|
||||
par = $( this ).closest 'tr'
|
||||
if not par.is ':last-child'
|
||||
par.remove()
|
||||
fChangeInputVisibility()
|
||||
$( '#tableParams' ).on 'click', 'img', () ->
|
||||
par = $( this ).closest 'tr'
|
||||
if not par.is ':last-child'
|
||||
par.remove()
|
||||
fChangeInputVisibility()
|
||||
|
||||
$( '#tableParams' ).on 'keyup', 'input', ( e ) ->
|
||||
code = e.keyCode or e.which
|
||||
if code isnt 9
|
||||
par = $( this ).closest( 'tr' )
|
||||
if par.is ':last-child'
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
|
||||
cb = $( '<input>' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
|
||||
inp = $( '<input>' ).attr( 'type', 'text' ).attr 'class', 'textinput'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
tr.append( $( '<td>' ).append cb )
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
par.parent().append tr
|
||||
fChangeInputVisibility()
|
||||
else if $( this ).val() is '' and not par.is ':only-child'
|
||||
par.remove()
|
||||
$( '#tableParams' ).on 'keyup', 'input', ( e ) ->
|
||||
code = e.keyCode or e.which
|
||||
if code isnt 9
|
||||
par = $( this ).closest( 'tr' )
|
||||
if par.is ':last-child'
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
|
||||
cb = $( '<input>' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
|
||||
inp = $( '<input>' ).attr( 'type', 'text' ).attr 'class', 'textinput'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
tr.append( $( '<td>' ).append cb )
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
par.parent().append tr
|
||||
fChangeInputVisibility()
|
||||
else if $( this ).val() is '' and not par.is ':only-child'
|
||||
par.remove()
|
||||
|
||||
fChangeInputVisibility()
|
||||
fChangeInputVisibility()
|
||||
|
||||
# Add submit button logic
|
||||
$( '#but_submit' ).click () ->
|
||||
if $( '#input_id' ).val() is ''
|
||||
alert 'Please enter an action invoker name!'
|
||||
else
|
||||
listParams = {}
|
||||
$( '#tableParams tr' ).each () ->
|
||||
val = $( 'input.textinput', this ).val()
|
||||
shld = $( 'input[type=checkbox]', this ).is ':checked'
|
||||
if val isnt ""
|
||||
listParams[val] = shld
|
||||
true
|
||||
obj =
|
||||
command: 'forge_action_invoker'
|
||||
payload:
|
||||
id: $( '#input_id' ).val()
|
||||
lang: $( '#editor_mode' ).val()
|
||||
public: $( '#is_public' ).is ':checked'
|
||||
data: editor.getValue()
|
||||
params: JSON.stringify listParams
|
||||
obj.payload = JSON.stringify obj.payload
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_action_invoker'
|
||||
else
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text 'Action Invoker not stored! ' + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
# Add submit button logic
|
||||
$( '#but_submit' ).click () ->
|
||||
if $( '#input_id' ).val() is ''
|
||||
alert 'Please enter an action invoker name!'
|
||||
else
|
||||
listParams = {}
|
||||
$( '#tableParams tr' ).each () ->
|
||||
val = $( 'input.textinput', this ).val()
|
||||
shld = $( 'input[type=checkbox]', this ).is ':checked'
|
||||
if val isnt ""
|
||||
listParams[val] = shld
|
||||
true
|
||||
obj =
|
||||
command: 'forge_action_invoker'
|
||||
payload:
|
||||
id: $( '#input_id' ).val()
|
||||
lang: $( '#editor_mode' ).val()
|
||||
public: $( '#is_public' ).is ':checked'
|
||||
data: editor.getValue()
|
||||
params: JSON.stringify listParams
|
||||
obj.payload = JSON.stringify obj.payload
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_action_invoker'
|
||||
else
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text 'Action Invoker not stored! ' + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
|
|
|||
|
|
@ -1,38 +1,38 @@
|
|||
|
||||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Event Forge!'
|
||||
$( '#pagetitle' ).text 'Invoke your custom event!'
|
||||
document.title = 'Event Forge!'
|
||||
$( '#pagetitle' ).text 'Invoke your custom event!'
|
||||
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/json"
|
||||
editor.setShowPrintMargin false
|
||||
$( '#editor' ).css 'height', '400px'
|
||||
$( '#editor' ).css 'width', '600px'
|
||||
|
||||
$( '#but_submit' ).click () ->
|
||||
try
|
||||
val = editor.getValue()
|
||||
JSON.parse val # try to parse, throw an error if JSON not valid
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/event', val )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_event'
|
||||
else
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
err.responseText = 'No Response from Server!'
|
||||
$( '#info' ).text 'Error in upload: ' + err.responseText
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
catch err
|
||||
$( '#info' ).text 'You have errors in your JSON object! ' + err
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/json"
|
||||
editor.setShowPrintMargin false
|
||||
$( '#editor' ).css 'height', '400px'
|
||||
$( '#editor' ).css 'width', '600px'
|
||||
|
||||
$( '#but_submit' ).click () ->
|
||||
try
|
||||
val = editor.getValue()
|
||||
JSON.parse val # try to parse, throw an error if JSON not valid
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/event', val )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_event'
|
||||
else
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
err.responseText = 'No Response from Server!'
|
||||
$( '#info' ).text 'Error in upload: ' + err.responseText
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
catch err
|
||||
$( '#info' ).text 'You have errors in your JSON object! ' + err
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
|
|
|||
|
|
@ -1,95 +1,95 @@
|
|||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Forge Event Poller'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, forge your custom event poller!"
|
||||
document.title = 'Forge Event Poller'
|
||||
$( '#pagetitle' ).text "{{{user.username}}}, forge your custom event poller!"
|
||||
|
||||
# Setup the ACE editor
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
editor.setShowPrintMargin false
|
||||
|
||||
$( '#editor_mode' ).change ( el ) ->
|
||||
if $( this ).val() is 'CoffeeScript'
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
else
|
||||
editor.getSession().setMode "ace/mode/javascript"
|
||||
|
||||
# Add parameter list functionality
|
||||
fChangeInputVisibility = () ->
|
||||
$( '#tableParams tr' ).each ( id ) ->
|
||||
if $( this ).is ':last-child' or $( this ).is ':only-child'
|
||||
$( 'img', this ).hide()
|
||||
$( 'input[type=checkbox]', this ).hide()
|
||||
else
|
||||
$( 'img', this ).show()
|
||||
$( 'input[type=checkbox]', this ).show()
|
||||
# Setup the ACE editor
|
||||
editor = ace.edit "editor"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
editor.setShowPrintMargin false
|
||||
|
||||
$( '#editor_mode' ).change ( el ) ->
|
||||
if $( this ).val() is 'CoffeeScript'
|
||||
editor.getSession().setMode "ace/mode/coffee"
|
||||
else
|
||||
editor.getSession().setMode "ace/mode/javascript"
|
||||
|
||||
# Add parameter list functionality
|
||||
fChangeInputVisibility = () ->
|
||||
$( '#tableParams tr' ).each ( id ) ->
|
||||
if $( this ).is ':last-child' or $( this ).is ':only-child'
|
||||
$( 'img', this ).hide()
|
||||
$( 'input[type=checkbox]', this ).hide()
|
||||
else
|
||||
$( 'img', this ).show()
|
||||
$( 'input[type=checkbox]', this ).show()
|
||||
|
||||
$( '#tableParams' ).on 'click', 'img', () ->
|
||||
par = $( this ).closest 'tr'
|
||||
if not par.is ':last-child'
|
||||
par.remove()
|
||||
fChangeInputVisibility()
|
||||
$( '#tableParams' ).on 'click', 'img', () ->
|
||||
par = $( this ).closest 'tr'
|
||||
if not par.is ':last-child'
|
||||
par.remove()
|
||||
fChangeInputVisibility()
|
||||
|
||||
$( '#tableParams' ).on 'keyup', 'input', ( e ) ->
|
||||
code = e.keyCode or e.which
|
||||
if code isnt 9
|
||||
par = $( this ).closest( 'tr' )
|
||||
if par.is ':last-child'
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
|
||||
cb = $( '<input>' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
|
||||
inp = $( '<input>' ).attr( 'type', 'text' ).attr 'class', 'textinput'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
tr.append( $( '<td>' ).append cb )
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
tr.append $( '<td>' )
|
||||
par.parent().append tr
|
||||
fChangeInputVisibility()
|
||||
else if $( this ).val() is '' and not par.is ':only-child'
|
||||
par.remove()
|
||||
$( '#tableParams' ).on 'keyup', 'input', ( e ) ->
|
||||
code = e.keyCode or e.which
|
||||
if code isnt 9
|
||||
par = $( this ).closest( 'tr' )
|
||||
if par.is ':last-child'
|
||||
tr = $ '<tr>'
|
||||
img = $( '<img>' ).attr( 'title', 'Remove?').attr 'src', 'red_cross_small.png'
|
||||
cb = $( '<input>' ).attr( 'type', 'checkbox' ).attr 'title', 'Password shielded input?'
|
||||
inp = $( '<input>' ).attr( 'type', 'text' ).attr 'class', 'textinput'
|
||||
tr.append( $( '<td>' ).append img )
|
||||
tr.append( $( '<td>' ).append cb )
|
||||
tr.append( $( '<td>' ).append inp )
|
||||
tr.append $( '<td>' )
|
||||
par.parent().append tr
|
||||
fChangeInputVisibility()
|
||||
else if $( this ).val() is '' and not par.is ':only-child'
|
||||
par.remove()
|
||||
|
||||
fChangeInputVisibility()
|
||||
fChangeInputVisibility()
|
||||
|
||||
# Add submit button logic
|
||||
$( '#but_submit' ).click () ->
|
||||
if $( '#input_id' ).val() is ''
|
||||
alert 'Please enter an event poller name!'
|
||||
else
|
||||
listParams = {}
|
||||
$( '#tableParams tr' ).each () ->
|
||||
val = $( 'input.textinput', this ).val()
|
||||
shld = $( 'input[type=checkbox]', this ).is ':checked'
|
||||
if val isnt ""
|
||||
listParams[val] = shld
|
||||
true
|
||||
obj =
|
||||
command: 'forge_event_poller'
|
||||
payload:
|
||||
id: $( '#input_id' ).val()
|
||||
lang: $( '#editor_mode' ).val()
|
||||
public: $( '#is_public' ).is ':checked'
|
||||
data: editor.getValue()
|
||||
params: JSON.stringify listParams
|
||||
obj.payload = JSON.stringify obj.payload
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_event_poller'
|
||||
else
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text 'Event Poller not stored! ' + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
# Add submit button logic
|
||||
$( '#but_submit' ).click () ->
|
||||
if $( '#input_id' ).val() is ''
|
||||
alert 'Please enter an event poller name!'
|
||||
else
|
||||
listParams = {}
|
||||
$( '#tableParams tr' ).each () ->
|
||||
val = $( 'input.textinput', this ).val()
|
||||
shld = $( 'input[type=checkbox]', this ).is ':checked'
|
||||
if val isnt ""
|
||||
listParams[val] = shld
|
||||
true
|
||||
obj =
|
||||
command: 'forge_event_poller'
|
||||
payload:
|
||||
id: $( '#input_id' ).val()
|
||||
lang: $( '#editor_mode' ).val()
|
||||
public: $( '#is_public' ).is ':checked'
|
||||
data: editor.getValue()
|
||||
params: JSON.stringify listParams
|
||||
obj.payload = JSON.stringify obj.payload
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_event_poller'
|
||||
else
|
||||
fDelayed = () ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
oErr = JSON.parse err.responseText
|
||||
msg = oErr.message
|
||||
$( '#info' ).text 'Event Poller not stored! ' + msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
setTimeout fDelayed, 500
|
||||
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
|
|
|||
|
|
@ -1,280 +1,332 @@
|
|||
strPublicKey = ''
|
||||
|
||||
fPlaceAndPaintInterval = () ->
|
||||
$( '#input_interval' ).html 'Interval:
|
||||
<input id="event_interval" type="text" />
|
||||
<b>"days hours:minutes"</b>, default = 10 minutes'
|
||||
|
||||
fFailedRequest = ( msg ) ->
|
||||
( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_rule'
|
||||
else
|
||||
$( '#info' ).text msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_rule'
|
||||
else
|
||||
$( '#info' ).text msg
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
|
||||
$.post( '/usercommand', command: 'get_public_key' )
|
||||
.done ( data ) ->
|
||||
strPublicKey = data.message
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_rule'
|
||||
else
|
||||
$( '#info' ).text 'Error fetching public key, unable to send user specific parameters securely'
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
.done ( data ) ->
|
||||
strPublicKey = data.message
|
||||
.fail ( err ) ->
|
||||
if err.status is 401
|
||||
window.location.href = 'forge?page=forge_rule'
|
||||
else
|
||||
$( '#info' ).text 'Error fetching public key, unable to send user specific parameters securely'
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Rule Forge!'
|
||||
$( '#pagetitle' ).text '{{{user.username}}}, forge your ECA Rule!'
|
||||
document.title = 'Rule Forge!'
|
||||
$( '#pagetitle' ).text '{{{user.username}}}, forge your ECA Rule!'
|
||||
|
||||
editor = ace.edit "editor_conditions"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/json"
|
||||
editor.setShowPrintMargin false
|
||||
# editor.session.setUseSoftTabs false
|
||||
editor = ace.edit "editor_conditions"
|
||||
editor.setTheme "ace/theme/monokai"
|
||||
editor.getSession().setMode "ace/mode/json"
|
||||
editor.setShowPrintMargin false
|
||||
# editor.session.setUseSoftTabs false
|
||||
|
||||
# Fetch Event Poller user-specific parameters
|
||||
fFetchEventParams = ( name ) ->
|
||||
if name
|
||||
arr = name.split ' -> '
|
||||
obj =
|
||||
command: 'get_event_poller_params'
|
||||
payload:
|
||||
id: arr[0]
|
||||
obj.payload = JSON.stringify( obj.payload );
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
if data.message
|
||||
oParams = JSON.parse data.message
|
||||
$( '#event_poller_params table' ).remove()
|
||||
table = $ '<table>'
|
||||
$( '#event_poller_params' ).append table
|
||||
fAppendParam = ( name, shielded ) ->
|
||||
tr = $( '<tr>' )
|
||||
tr.append $( '<td>' ).css 'width', '20px'
|
||||
tr.append $( '<td>' ).attr( 'class', 'key' ).text name
|
||||
inp = $( '<input>' ).attr 'id', "#{ name }"
|
||||
if shielded
|
||||
inp.attr( 'type', 'password' )
|
||||
tr.append $( '<td>' ).text( ' : ' ).append inp
|
||||
table.append tr
|
||||
fAppendParam name, shielded for name, shielded of oParams
|
||||
.fail fFailedRequest 'Error fetching event poller params'
|
||||
# Fetch Event Poller user-specific parameters
|
||||
fFetchEventParams = ( name ) ->
|
||||
$( '#event_poller_params *' ).remove()
|
||||
if name
|
||||
arr = name.split ' -> '
|
||||
obj =
|
||||
command: 'get_event_poller_params'
|
||||
payload:
|
||||
id: arr[0]
|
||||
obj.payload = JSON.stringify( obj.payload );
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
if data.message
|
||||
oParams = JSON.parse data.message
|
||||
$( '#event_poller_params' ).html '<br><b>Required Parameters:</b>'
|
||||
table = $ '<table>'
|
||||
$( '#event_poller_params' ).append table
|
||||
fAppendParam = ( name, shielded ) ->
|
||||
tr = $( '<tr>' )
|
||||
tr.append $( '<td>' ).css 'width', '20px'
|
||||
tr.append $( '<td>' ).attr( 'class', 'key' ).text name
|
||||
inp = $( '<input>' ).attr 'id', "#{ name }"
|
||||
if shielded
|
||||
inp.attr( 'type', 'password' )
|
||||
tr.append $( '<td>' ).text( ' : ' ).append inp
|
||||
table.append tr
|
||||
fAppendParam name, shielded for name, shielded of oParams
|
||||
.fail fFailedRequest 'Error fetching event poller params'
|
||||
|
||||
# Init Event Pollers
|
||||
$.post( '/usercommand', command: 'get_event_pollers' )
|
||||
.done ( data ) ->
|
||||
try
|
||||
oEps = JSON.parse data.message
|
||||
catch err
|
||||
console.error 'ERROR: non-object received from server: ' + data.message
|
||||
return
|
||||
|
||||
fAppendEvents = ( id, events ) ->
|
||||
fAppendEvent = ( evt ) ->
|
||||
$( '#select_event' ).append $( '<option>' ).text id + ' -> ' + evt
|
||||
fAppendEvent evt for evt in events
|
||||
fAppendEvents id, events for id, events of oEps
|
||||
fFetchEventParams $( '#select_event option:selected' ).text()
|
||||
.fail fFailedRequest 'Error fetching event poller'
|
||||
# Init Event Pollers
|
||||
$.post( '/usercommand', command: 'get_event_pollers' )
|
||||
.done ( data ) ->
|
||||
try
|
||||
oEps = JSON.parse data.message
|
||||
catch err
|
||||
console.error 'ERROR: non-object received from server: ' + data.message
|
||||
return
|
||||
|
||||
fAppendEvents = ( id, events ) ->
|
||||
fAppendEvent = ( evt ) ->
|
||||
$( '#select_event' ).append $( '<option>' ).text id + ' -> ' + evt
|
||||
fAppendEvent evt for evt in events
|
||||
fAppendEvents id, events for id, events of oEps
|
||||
$( '#input_event' ).val $( '#select_event' ).val()
|
||||
fFetchEventParams $( '#select_event option:selected' ).text()
|
||||
.fail fFailedRequest 'Error fetching event poller'
|
||||
|
||||
$( '#select_event' ).change () ->
|
||||
fFetchEventParams $( this ).val()
|
||||
$( '#select_event' ).change () ->
|
||||
if $( this ).val() is ''
|
||||
$( '#input_interval' ).html ''
|
||||
else
|
||||
fPlaceAndPaintInterval()
|
||||
$( '#input_event' ).val $( this ).val()
|
||||
fFetchEventParams $( this ).val()
|
||||
|
||||
# Init Action Invoker
|
||||
obj =
|
||||
command: 'get_action_invokers'
|
||||
$.post( '/usercommand', obj )
|
||||
$( '#input_event' ).change () ->
|
||||
$( '#select_event' ).val ''
|
||||
$( '#select_event' ).val $( this ).val()
|
||||
fFetchEventParams $( '#select_event' ).val()
|
||||
if $( '#select_event' ).val() is ''
|
||||
$( '#input_interval' ).html ''
|
||||
else
|
||||
fPlaceAndPaintInterval()
|
||||
|
||||
.done ( data ) ->
|
||||
try
|
||||
oAis = JSON.parse data.message
|
||||
catch err
|
||||
console.error 'ERROR: non-object received from server: ' + data.message
|
||||
return
|
||||
fAppendActions = ( module, actions ) ->
|
||||
for act in actions
|
||||
$( '#select_actions' ).append $( '<option>' ).text module + ' -> ' + act
|
||||
fAppendActions module, actions for module, actions of oAis
|
||||
.fail fFailedRequest 'Error fetching event poller'
|
||||
# Init Action Invoker
|
||||
obj =
|
||||
command: 'get_action_invokers'
|
||||
$.post( '/usercommand', obj )
|
||||
|
||||
fFetchActionParams = ( div, modName ) ->
|
||||
obj =
|
||||
command: 'get_action_invoker_params'
|
||||
payload:
|
||||
id: modName
|
||||
obj.payload = JSON.stringify( obj.payload );
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
if data.message
|
||||
oParams = JSON.parse data.message
|
||||
table = $ '<table>'
|
||||
div.append table
|
||||
fAppendActionParam = ( name, shielded ) ->
|
||||
tr = $( '<tr>' )
|
||||
tr.append $( '<td>' ).css 'width', '20px'
|
||||
tr.append $( '<td>' ).attr( 'class', 'key').text name
|
||||
inp = $( '<input>' ).attr 'id', "#{ name }"
|
||||
if shielded
|
||||
inp.attr( 'type', 'password' )
|
||||
else
|
||||
inp.attr( 'type', 'text' )
|
||||
tr.append $( '<td>' ).text(' : ').append inp
|
||||
table.append tr
|
||||
fAppendActionParam name, sh for name, sh of oParams
|
||||
.fail fFailedRequest 'Error fetching action invoker params'
|
||||
.done ( data ) ->
|
||||
try
|
||||
oAis = JSON.parse data.message
|
||||
catch err
|
||||
console.error 'ERROR: non-object received from server: ' + data.message
|
||||
return
|
||||
fAppendActions = ( module, actions ) ->
|
||||
for act in actions
|
||||
$( '#select_actions' ).append $( '<option>' ).text module + ' -> ' + act
|
||||
fAppendActions module, actions for module, actions of oAis
|
||||
.fail fFailedRequest 'Error fetching event poller'
|
||||
|
||||
fFetchActionFunctionParams = ( tag, arrName ) ->
|
||||
obj =
|
||||
command: 'get_action_invoker_function_params'
|
||||
payload:
|
||||
id: arrName[ 0 ]
|
||||
obj.payload = JSON.stringify( obj.payload );
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
if data.message
|
||||
oParams = JSON.parse data.message
|
||||
if oParams[ arrName[ 1 ] ]
|
||||
table = $( '<table>' ).appendTo tag
|
||||
for functionArgument in oParams[ arrName[ 1 ] ]
|
||||
tr = $( '<tr>' ).appendTo table
|
||||
td = $( '<td>' ).appendTo tr
|
||||
td.append $( '<div>' ).attr( 'class', 'funcarg' ).text functionArgument
|
||||
tr.append td
|
||||
td = $( '<td>' ).appendTo tr
|
||||
td.append $( '<input>' ).attr 'type', 'text'
|
||||
tr.append td
|
||||
tr.append td
|
||||
td = $( '<td>' ).appendTo tr
|
||||
td.append $( '<input>' ).attr( 'type', 'checkbox' )
|
||||
.attr 'title', 'js-select expression to be resolved on event?'
|
||||
.fail fFailedRequest 'Error fetching action invoker function params'
|
||||
fFetchActionParams = ( div, modName ) ->
|
||||
obj =
|
||||
command: 'get_action_invoker_params'
|
||||
payload:
|
||||
id: modName
|
||||
obj.payload = JSON.stringify( obj.payload );
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
if data.message
|
||||
oParams = JSON.parse data.message
|
||||
table = $ '<table>'
|
||||
div.append table
|
||||
fAppendActionParam = ( name, shielded ) ->
|
||||
#TODO check if already stored, if yes, indicate no entry is required
|
||||
tr = $( '<tr>' )
|
||||
tr.append $( '<td>' ).css 'width', '20px'
|
||||
tr.append $( '<td>' ).attr( 'class', 'key').text name
|
||||
inp = $( '<input>' ).attr 'id', "#{ name }"
|
||||
if shielded
|
||||
inp.attr( 'type', 'password' )
|
||||
else
|
||||
inp.attr( 'type', 'text' )
|
||||
tr.append $( '<td>' ).text(' : ').append inp
|
||||
table.append tr
|
||||
fAppendActionParam name, sh for name, sh of oParams
|
||||
.fail fFailedRequest 'Error fetching action invoker params'
|
||||
|
||||
$( '#select_actions' ).on 'change', () ->
|
||||
opt = $ 'option:selected', this
|
||||
arrName = opt.text().split ' -> '
|
||||
|
||||
arrEls = $( "#action_params div.modName" ).map( () ->
|
||||
$( this ).text()
|
||||
).get()
|
||||
table = $( '#selected_actions' )
|
||||
tr = $( '<tr>' ).appendTo table
|
||||
img = $( '<img>' ).attr 'src', 'red_cross_small.png'
|
||||
tr.append $( '<td>' ).css( 'width', '20px' ).append img
|
||||
tr.append $( '<td>' ).attr( 'class', 'title').text opt.val()
|
||||
td = $( '<td>' ).attr( 'class', 'funcMappings').appendTo tr
|
||||
fFetchActionFunctionParams td, arrName
|
||||
if arrName[ 0 ] not in arrEls
|
||||
div = $( '<div>' ).appendTo $( '#action_params' )
|
||||
subdiv = $( '<div> ').appendTo div
|
||||
subdiv.append $( '<div>' )
|
||||
.attr( 'class', 'modName underlined' ).text arrName[ 0 ]
|
||||
fFetchActionParams div, arrName[ 0 ]
|
||||
opt.remove()
|
||||
fFetchActionFunctionParams = ( tag, arrName ) ->
|
||||
obj =
|
||||
command: 'get_action_invoker_function_params'
|
||||
payload:
|
||||
id: arrName[ 0 ]
|
||||
obj.payload = JSON.stringify( obj.payload );
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
if data.message
|
||||
oParams = JSON.parse data.message
|
||||
if oParams[ arrName[ 1 ] ]
|
||||
table = $( '<table>' ).appendTo tag
|
||||
for functionArgument in oParams[ arrName[ 1 ] ]
|
||||
tr = $( '<tr>' ).appendTo table
|
||||
td = $( '<td>' ).appendTo tr
|
||||
td.append $( '<div>' ).attr( 'class', 'funcarg' ).text functionArgument
|
||||
tr.append td
|
||||
td = $( '<td>' ).appendTo tr
|
||||
td.append $( '<input>' ).attr 'type', 'text'
|
||||
tr.append td
|
||||
tr.append td
|
||||
td = $( '<td>' ).appendTo tr
|
||||
td.append $( '<input>' ).attr( 'type', 'checkbox' )
|
||||
.attr 'title', 'js-select expression to be resolved on event?'
|
||||
.fail fFailedRequest 'Error fetching action invoker function params'
|
||||
|
||||
$( '#selected_actions' ).on 'click', 'img', () ->
|
||||
act = $( this ).closest( 'td' ).siblings( '.title' ).text()
|
||||
arrName = act.split ' -> '
|
||||
$( '#select_actions' ).on 'change', () ->
|
||||
opt = $ 'option:selected', this
|
||||
arrName = opt.text().split ' -> '
|
||||
|
||||
arrEls = $( "#action_params div.modName" ).map( () ->
|
||||
$( this ).text()
|
||||
).get()
|
||||
table = $( '#selected_actions' )
|
||||
tr = $( '<tr>' ).appendTo table
|
||||
img = $( '<img>' ).attr 'src', 'red_cross_small.png'
|
||||
tr.append $( '<td>' ).css( 'width', '20px' ).append img
|
||||
tr.append $( '<td>' ).attr( 'class', 'title').text opt.val()
|
||||
td = $( '<td>' ).attr( 'class', 'funcMappings').appendTo tr
|
||||
fFetchActionFunctionParams td, arrName
|
||||
if arrName[ 0 ] not in arrEls
|
||||
div = $( '<div>' ).appendTo $( '#action_params' )
|
||||
subdiv = $( '<div> ').appendTo div
|
||||
subdiv.append $( '<div>' )
|
||||
.attr( 'class', 'modName underlined' ).text arrName[ 0 ]
|
||||
fFetchActionParams div, arrName[ 0 ]
|
||||
opt.remove()
|
||||
|
||||
nMods = 0
|
||||
# Check whether we're the only function left that was selected from this module
|
||||
$( "#selected_actions td.title" ).each () ->
|
||||
arrNm = $( this ).text().split ' -> '
|
||||
nMods++ if arrNm[0] is arrName[0]
|
||||
if nMods is 1
|
||||
$('#action_params > div').each () ->
|
||||
if $( this ).children( 'div.modName' ).text() is arrName[ 0 ]
|
||||
$( this ).remove()
|
||||
$( '#selected_actions' ).on 'click', 'img', () ->
|
||||
act = $( this ).closest( 'td' ).siblings( '.title' ).text()
|
||||
arrName = act.split ' -> '
|
||||
|
||||
opt = $( '<option>' ).text arrName[ 0 ]
|
||||
$( '#select_actions' ).append opt
|
||||
$( this ).closest( 'tr' ).remove()
|
||||
nMods = 0
|
||||
# Check whether we're the only function left that was selected from this module
|
||||
$( "#selected_actions td.title" ).each () ->
|
||||
arrNm = $( this ).text().split ' -> '
|
||||
nMods++ if arrNm[0] is arrName[0]
|
||||
if nMods is 1
|
||||
$('#action_params > div').each () ->
|
||||
if $( this ).children( 'div.modName' ).text() is arrName[ 0 ]
|
||||
$( this ).remove()
|
||||
|
||||
opt = $( '<option>' ).text arrName[ 0 ]
|
||||
$( '#select_actions' ).append opt
|
||||
$( this ).closest( 'tr' ).remove()
|
||||
|
||||
|
||||
$( '#but_submit' ).click () ->
|
||||
try
|
||||
if $( '#select_event option:selected' ).length is 0
|
||||
throw new Error 'Please create an Event Poller first!'
|
||||
$( '#but_submit' ).click () ->
|
||||
window.scrollTo 0, 0
|
||||
$( '#info' ).text ''
|
||||
|
||||
if $( '#input_id' ).val() is ''
|
||||
throw new Error 'Please enter a rule name!'
|
||||
try
|
||||
if $( '#input_id' ).val() is ''
|
||||
$( '#input_id' ).focus()
|
||||
throw new Error 'Please enter a rule name!'
|
||||
|
||||
ep = {}
|
||||
$( "#event_poller_params tr" ).each () ->
|
||||
val = $( 'input', this ).val()
|
||||
name = $( this ).children( '.key' ).text()
|
||||
if val is ''
|
||||
throw new Error "Please enter a value for '#{ name }' in the event module!"
|
||||
ep[name] = val
|
||||
if $( '#input_event' ).val() is ''
|
||||
$( '#input_event' ).focus()
|
||||
throw new Error 'Please assign an event!'
|
||||
|
||||
if $( '#selected_actions tr' ).length is 0
|
||||
throw new Error 'Please select at least one action or create one!'
|
||||
ep = {}
|
||||
$( "#event_poller_params tr" ).each () ->
|
||||
val = $( 'input', this ).val()
|
||||
name = $( this ).children( '.key' ).text()
|
||||
if val is ''
|
||||
$( 'input', this ).focus()
|
||||
throw new Error "Please enter a value for '#{ name }' in the event module!"
|
||||
ep[name] = val
|
||||
|
||||
# Store all selected action invokers
|
||||
ap = {}
|
||||
$( '> div', $( '#action_params' ) ).each () ->
|
||||
modName = $( '.modName', this ).text()
|
||||
params = {}
|
||||
$( 'tr', this ).each () ->
|
||||
key = $( '.key', this ).text()
|
||||
val = $( 'input', this ).val()
|
||||
if val is ''
|
||||
throw new Error "'#{ key }' missing for '#{ modName }'"
|
||||
params[key] = val
|
||||
encryptedParams = cryptico.encrypt JSON.stringify( params ), strPublicKey
|
||||
ap[modName] = encryptedParams.cipher
|
||||
acts = []
|
||||
actParams = {}
|
||||
$( '#selected_actions' ).each () ->
|
||||
actionName = $( '.title', this ).text()
|
||||
acts.push actionName
|
||||
$( '.funcMappings tr' ).each () ->
|
||||
tmp =
|
||||
argument: $( 'div.funcarg', this ).val()
|
||||
value: $( 'input[type=text]', this ).val()
|
||||
regexp: $( 'input[type=checkbox]', this ).is( ':checked' )
|
||||
actParams[ actionName ] = cryptico.encrypt JSON.stringify( tmp ), strPublicKey
|
||||
|
||||
try
|
||||
conds = JSON.parse editor.getValue()
|
||||
catch err
|
||||
throw new Error "Parsing of your conditions failed! Needs to be an Array of Strings!"
|
||||
|
||||
if conds not instanceof Array
|
||||
throw new Error "Conditions Invalid! Needs to be an Array of Strings!"
|
||||
if $( '#selected_actions tr' ).length is 0
|
||||
throw new Error 'Please select at least one action or create one!'
|
||||
|
||||
encryptedParams = cryptico.encrypt JSON.stringify( ep ), strPublicKey
|
||||
obj =
|
||||
command: 'forge_rule'
|
||||
payload:
|
||||
id: $( '#input_id' ).val()
|
||||
event: $( '#select_event option:selected' ).val()
|
||||
event_params: encryptedParams.cipher
|
||||
conditions: conds
|
||||
actions: acts
|
||||
action_params: ap
|
||||
action_functions: actParams
|
||||
obj.payload = JSON.stringify obj.payload
|
||||
window.scrollTo 0, 0
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
msg = JSON.parse( err.responseText ).message
|
||||
fFailedRequest( 'Error in upload: ' + msg ) err
|
||||
catch err
|
||||
$( '#info' ).text 'Error in upload: ' + err.message
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
alert err.message
|
||||
# Store all selected action invokers
|
||||
ap = {}
|
||||
$( '> div', $( '#action_params' ) ).each () ->
|
||||
modName = $( '.modName', this ).text()
|
||||
params = {}
|
||||
$( 'tr', this ).each () ->
|
||||
key = $( '.key', this ).text()
|
||||
val = $( 'input', this ).val()
|
||||
if val is ''
|
||||
$( 'input', this ).focus()
|
||||
throw new Error "'#{ key }' missing for '#{ modName }'"
|
||||
params[key] = val
|
||||
encryptedParams = cryptico.encrypt JSON.stringify( params ), strPublicKey
|
||||
ap[modName] = encryptedParams.cipher
|
||||
acts = []
|
||||
actParams = {}
|
||||
$( '#selected_actions' ).each () ->
|
||||
actionName = $( '.title', this ).text()
|
||||
acts.push actionName
|
||||
$( '.funcMappings tr' ).each () ->
|
||||
tmp =
|
||||
argument: $( 'div.funcarg', this ).val()
|
||||
value: $( 'input[type=text]', this ).val()
|
||||
regexp: $( 'input[type=checkbox]', this ).is( ':checked' )
|
||||
actParams[ actionName ] = cryptico.encrypt JSON.stringify( tmp ), strPublicKey
|
||||
|
||||
try
|
||||
conds = JSON.parse editor.getValue()
|
||||
catch err
|
||||
throw new Error "Parsing of your conditions failed! Needs to be an Array of Strings!"
|
||||
|
||||
if conds not instanceof Array
|
||||
throw new Error "Conditions Invalid! Needs to be an Array of Strings!"
|
||||
|
||||
arrParams = window.location.search.substring(1).split '&'
|
||||
id = ''
|
||||
for param in arrParams
|
||||
arrKV = param.split '='
|
||||
if arrKV[ 0 ] is 'id'
|
||||
id = decodeURIComponent arrKV[ 1 ]
|
||||
if id isnt ''
|
||||
console.log id
|
||||
# Parse a time string
|
||||
fParseTime = ( str, hasDay ) ->
|
||||
arrTime = str.split ':'
|
||||
# If there's only one entry, this is the amount of minutes
|
||||
if arrTime.length = 1
|
||||
time = parseInt( str ) || 10
|
||||
if hasDay
|
||||
time * 60
|
||||
else
|
||||
time
|
||||
else
|
||||
h = parseInt( arrTime[ 0 ] ) || 0
|
||||
h * 60 + ( parseInt( arrTime[ 1 ] ) || 10 )
|
||||
|
||||
|
||||
arrInp = $( '#event_interval' ).text().split ' '
|
||||
# There's only one string entered, either day or hour
|
||||
if arrInp.length = 1
|
||||
mins = fParseTime arrInp[ 0 ]
|
||||
else
|
||||
d = parseInt( arrInp[ 0 ] ) || 0
|
||||
mins = d * 24 * 60 + fParseTime arrInp[ 1 ], true
|
||||
|
||||
encryptedParams = cryptico.encrypt JSON.stringify( ep ), strPublicKey
|
||||
obj =
|
||||
command: 'forge_rule'
|
||||
payload:
|
||||
id: $( '#input_id' ).val()
|
||||
event: $( '#input_event' ).val()
|
||||
event_params: encryptedParams.cipher
|
||||
event_interval: mins
|
||||
conditions: conds
|
||||
actions: acts
|
||||
action_params: ap
|
||||
action_functions: actParams
|
||||
obj.payload = JSON.stringify obj.payload
|
||||
$.post( '/usercommand', obj )
|
||||
.done ( data ) ->
|
||||
$( '#info' ).text data.message
|
||||
$( '#info' ).attr 'class', 'success'
|
||||
.fail ( err ) ->
|
||||
if err.responseText is ''
|
||||
msg = 'No Response from Server!'
|
||||
else
|
||||
try
|
||||
msg = JSON.parse( err.responseText ).message
|
||||
fFailedRequest( 'Error in upload: ' + msg ) err
|
||||
catch err
|
||||
$( '#info' ).text 'Error in upload: ' + err.message
|
||||
$( '#info' ).attr 'class', 'error'
|
||||
alert err.message
|
||||
|
||||
arrParams = window.location.search.substring(1).split '&'
|
||||
id = ''
|
||||
for param in arrParams
|
||||
arrKV = param.split '='
|
||||
if arrKV[ 0 ] is 'id'
|
||||
id = decodeURIComponent arrKV[ 1 ]
|
||||
if id isnt ''
|
||||
console.log id
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
|
||||
fOnLoad = () ->
|
||||
document.title = 'Login'
|
||||
$( '#pagetitle' ).text 'Login!'
|
||||
document.title = 'Login'
|
||||
$( '#pagetitle' ).text 'Login!'
|
||||
|
||||
if not window.CryptoJS
|
||||
$( '#info' ).text 'CryptoJS library missing! Are you connected to the internet?'
|
||||
if not window.CryptoJS
|
||||
$( '#info' ).text 'CryptoJS library missing! Are you connected to the internet?'
|
||||
|
||||
$( '#but_submit' ).click () ->
|
||||
hp = CryptoJS.SHA3 $( '#password' ).val(),
|
||||
outputLength: 512
|
||||
data =
|
||||
username: $( '#username' ).val()
|
||||
password: hp.toString()
|
||||
$.post( '/login', JSON.stringify( data ) )
|
||||
.done ( data ) ->
|
||||
window.location.href = document.URL
|
||||
.fail ( err ) ->
|
||||
alert 'Authentication not successful!'
|
||||
$( '#but_submit' ).click () ->
|
||||
hp = CryptoJS.SHA3 $( '#password' ).val(),
|
||||
outputLength: 512
|
||||
data =
|
||||
username: $( '#username' ).val()
|
||||
password: hp.toString()
|
||||
$.post( '/login', JSON.stringify( data ) )
|
||||
.done ( data ) ->
|
||||
window.location.href = document.URL
|
||||
.fail ( err ) ->
|
||||
alert 'Authentication not successful!'
|
||||
|
||||
window.addEventListener 'load', fOnLoad, true
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
// Generated by CoffeeScript 1.7.1
|
||||
(function() {
|
||||
var fFailedRequest, fOnLoad, strPublicKey,
|
||||
var fFailedRequest, fOnLoad, fPlaceAndPaintInterval, strPublicKey,
|
||||
__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; };
|
||||
|
||||
strPublicKey = '';
|
||||
|
||||
fPlaceAndPaintInterval = function() {
|
||||
return $('#input_interval').html('Interval: <input id="event_interval" type="text" /> <b>"days hours:minutes"</b>, default = 10 minutes');
|
||||
};
|
||||
|
||||
fFailedRequest = function(msg) {
|
||||
return function(err) {
|
||||
if (err.status === 401) {
|
||||
|
|
@ -39,6 +43,7 @@
|
|||
editor.setShowPrintMargin(false);
|
||||
fFetchEventParams = function(name) {
|
||||
var arr, obj;
|
||||
$('#event_poller_params *').remove();
|
||||
if (name) {
|
||||
arr = name.split(' -> ');
|
||||
obj = {
|
||||
|
|
@ -52,7 +57,7 @@
|
|||
var fAppendParam, oParams, shielded, table, _results;
|
||||
if (data.message) {
|
||||
oParams = JSON.parse(data.message);
|
||||
$('#event_poller_params table').remove();
|
||||
$('#event_poller_params').html('<br><b>Required Parameters:</b>');
|
||||
table = $('<table>');
|
||||
$('#event_poller_params').append(table);
|
||||
fAppendParam = function(name, shielded) {
|
||||
|
|
@ -104,11 +109,28 @@
|
|||
events = oEps[id];
|
||||
fAppendEvents(id, events);
|
||||
}
|
||||
$('#input_event').val($('#select_event').val());
|
||||
return fFetchEventParams($('#select_event option:selected').text());
|
||||
}).fail(fFailedRequest('Error fetching event poller'));
|
||||
$('#select_event').change(function() {
|
||||
if ($(this).val() === '') {
|
||||
$('#input_interval').html('');
|
||||
} else {
|
||||
fPlaceAndPaintInterval();
|
||||
}
|
||||
$('#input_event').val($(this).val());
|
||||
return fFetchEventParams($(this).val());
|
||||
});
|
||||
$('#input_event').change(function() {
|
||||
$('#select_event').val('');
|
||||
$('#select_event').val($(this).val());
|
||||
fFetchEventParams($('#select_event').val());
|
||||
if ($('#select_event').val() === '') {
|
||||
return $('#input_interval').html('');
|
||||
} else {
|
||||
return fPlaceAndPaintInterval();
|
||||
}
|
||||
});
|
||||
obj = {
|
||||
command: 'get_action_invokers'
|
||||
};
|
||||
|
|
@ -254,20 +276,25 @@
|
|||
return $(this).closest('tr').remove();
|
||||
});
|
||||
$('#but_submit').click(function() {
|
||||
var actParams, acts, ap, conds, encryptedParams, ep, err;
|
||||
var actParams, acts, ap, arrInp, conds, d, encryptedParams, ep, err, fParseTime, mins;
|
||||
window.scrollTo(0, 0);
|
||||
$('#info').text('');
|
||||
try {
|
||||
if ($('#select_event option:selected').length === 0) {
|
||||
throw new Error('Please create an Event Poller first!');
|
||||
}
|
||||
if ($('#input_id').val() === '') {
|
||||
$('#input_id').focus();
|
||||
throw new Error('Please enter a rule name!');
|
||||
}
|
||||
if ($('#input_event').val() === '') {
|
||||
$('#input_event').focus();
|
||||
throw new Error('Please assign an event!');
|
||||
}
|
||||
ep = {};
|
||||
$("#event_poller_params tr").each(function() {
|
||||
var name, val;
|
||||
val = $('input', this).val();
|
||||
name = $(this).children('.key').text();
|
||||
if (val === '') {
|
||||
$('input', this).focus();
|
||||
throw new Error("Please enter a value for '" + name + "' in the event module!");
|
||||
}
|
||||
return ep[name] = val;
|
||||
|
|
@ -285,6 +312,7 @@
|
|||
key = $('.key', this).text();
|
||||
val = $('input', this).val();
|
||||
if (val === '') {
|
||||
$('input', this).focus();
|
||||
throw new Error("'" + key + "' missing for '" + modName + "'");
|
||||
}
|
||||
return params[key] = val;
|
||||
|
|
@ -317,13 +345,36 @@
|
|||
if (!(conds instanceof Array)) {
|
||||
throw new Error("Conditions Invalid! Needs to be an Array of Strings!");
|
||||
}
|
||||
fParseTime = function(str, hasDay) {
|
||||
var arrTime, h, time;
|
||||
arrTime = str.split(':');
|
||||
if (arrTime.length = 1) {
|
||||
time = parseInt(str) || 10;
|
||||
if (hasDay) {
|
||||
return time * 60;
|
||||
} else {
|
||||
return time;
|
||||
}
|
||||
} else {
|
||||
h = parseInt(arrTime[0]) || 0;
|
||||
return h * 60 + (parseInt(arrTime[1]) || 10);
|
||||
}
|
||||
};
|
||||
arrInp = $('#event_interval').text().split(' ');
|
||||
if (arrInp.length = 1) {
|
||||
mins = fParseTime(arrInp[0]);
|
||||
} else {
|
||||
d = parseInt(arrInp[0]) || 0;
|
||||
mins = d * 24 * 60 + fParseTime(arrInp[1], true);
|
||||
}
|
||||
encryptedParams = cryptico.encrypt(JSON.stringify(ep), strPublicKey);
|
||||
obj = {
|
||||
command: 'forge_rule',
|
||||
payload: {
|
||||
id: $('#input_id').val(),
|
||||
event: $('#select_event option:selected').val(),
|
||||
event: $('#input_event').val(),
|
||||
event_params: encryptedParams.cipher,
|
||||
event_interval: mins,
|
||||
conditions: conds,
|
||||
actions: acts,
|
||||
action_params: ap,
|
||||
|
|
@ -331,7 +382,6 @@
|
|||
}
|
||||
};
|
||||
obj.payload = JSON.stringify(obj.payload);
|
||||
window.scrollTo(0, 0);
|
||||
return $.post('/usercommand', obj).done(function(data) {
|
||||
$('#info').text(data.message);
|
||||
return $('#info').attr('class', 'success');
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ callService = ( args ) ->
|
|||
if not args.callback
|
||||
args.callback = standardCallback 'call'
|
||||
url = urlService + args.service + '/' + args.method
|
||||
needlereq 'post', url, args.data, credentials, args.callback
|
||||
needle.request 'post', url, args.data, credentials, args.callback
|
||||
|
||||
|
||||
###
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<b>Rule Name: </b><input id="input_id" type="text" /><br>
|
||||
<h2>EVENT</h2>
|
||||
<select id="select_event"></select>
|
||||
<div id="event_poller_params">
|
||||
<br><b>Required Parameters:</b>
|
||||
</div>
|
||||
<select id="select_event"><option></option></select><br/>
|
||||
<input id="input_event" type="text" /><br/>
|
||||
<div id="input_interval"></div>
|
||||
<div id="event_poller_params"></div>
|
||||
<br>
|
||||
<h2>CONDITIONS</h2>
|
||||
Refer to <a target="_blank" href="https://github.com/harthur/js-select#selectors">js-select selectors</a> for valid selectors!
|
||||
|
|
|
|||
Loading…
Reference in a new issue