presence/ejabberd/ejabberd_scripts/rest_api_client_script
#!/usr/bin/env ruby
####################################
# Rest Api Client Script
#Generate and send requests to Social Stream presence API
#@author Aldo Gordillo < agordillos@gmail.com >
#@version 2.0 - 24-2-2012
####################################
require 'logger'
require 'rest_client'
path = "/var/log/ejabberd/scripts.log"
file = File.open(path, File::WRONLY | File::APPEND | File::CREAT)
file.sync = true
$logger = Logger.new(file)
$logger.level = Logger::DEBUG
def getOption(option)
File.open('/etc/ejabberd/ssconfig.cfg', 'r') do |f1|
while line = f1.gets
line = line.gsub(/\n/,'')
if line.match(/^#/)
#Comments
elsif line.match(/^#{option}/)
return line.gsub(/#{option}/,'')
end
end
end
return "Undefined"
end
#Constants
$secure_rest_api = getOption("secure_rest_api=")
$pass = getOption("ejabberd_password=")
$scripts_path = getOption("scripts_path=")
$script_title = "Rest Api Client"
def log(title,text)
$logger.info title + ": " + text
end
def getMethodName
caller[0] =~ /`(.*?)'/
$1
end
#####################
##### Example #####
#####################
#def myHook(param1,param2)
# log(getMethodName,"(My message: #{param1},#{param2})")
# url = "http://" + getWebDomainUrlFromDomain(domain) + "/xmpp/hookRoute"
# params = {}
# encrypted_params = {}
# #Add params to sent in clear
# params[:param1_in_server]=param1
# #Add params to sent cipher
# encrypted_params[:param2_in_server]=param2
# return [getMethodName,generic_api_call(url,params,encrypted_params)]
#end
def setConnection(userJid)
log($script_title,"#{getMethodName}(#{userJid})")
url = "http://" + getWebDomainUrlFromDomain(getDomainFromJid(userJid)) + "/xmpp/setConnection"
params = {}
encrypted_params = {}
encrypted_params[:name]=getUsernameFromJid(userJid)
return [getMethodName,generic_api_call(url,params,encrypted_params)]
end
def unsetConnection(userJid)
log($script_title,"#{getMethodName}(#{userJid})")
url = "http://" + getWebDomainUrlFromDomain(getDomainFromJid(userJid)) + "/xmpp/unsetConnection"
params = {}
encrypted_params = {}
encrypted_params[:name]=getUsernameFromJid(userJid)
return [getMethodName,generic_api_call(url,params,encrypted_params)]
end
def setPresence(userJid,status)
log($script_title,"#{getMethodName}(#{userJid},#{status})")
url = "http://" + getWebDomainUrlFromDomain(getDomainFromJid(userJid)) + "/xmpp/setPresence"
params = {}
encrypted_params = {}
encrypted_params[:name]=getUsernameFromJid(userJid)
encrypted_params[:status]=status
return [getMethodName,generic_api_call(url,params,encrypted_params)]
end
def unsetPresence(userJid)
log($script_title,"#{getMethodName}(#{userJid})")
url = "http://" + getWebDomainUrlFromDomain(getDomainFromJid(userJid)) + "/xmpp/unsetPresence"
params = {}
encrypted_params = {}
encrypted_params[:name]=getUsernameFromJid(userJid)
return [getMethodName,generic_api_call(url,params,encrypted_params)]
end
#Reset all domains connections
def resetConnection()
log($script_title,"Call #{getMethodName}()")
url = "http://" + getWebDomainUrlFromDomain("all") + "/xmpp/resetConnection"
params = {}
encrypted_params = {}
return [getMethodName,generic_api_call(url,params,encrypted_params)]
end
def synchronize(domain)
log($script_title,"Call #{getMethodName}(#{domain})")
url = "http://" + getWebDomainUrlFromDomain(domain) + "/xmpp/synchronizePresence"
#Get connected users using Emanagement
jids = []
if domain=="all"
command = $scripts_path + "/emanagement getConnectedJids"
else
command = $scripts_path + "/emanagement getConnectedJidsByDomain " + domain
end
output = %x[#{command}]
sessions = output.split("\n")
sessions.each do |session|
jids << session.split("/")[0]
end
#Finish
#In this cases users always will be sent in clear (not cipher)
#(Too much data to cipher)
#Anyway, we must to build the hash to pass the authentication
params = {}
encrypted_params = {}
params[:name]=jids.join(",")
return [getMethodName,generic_api_call(url,params,encrypted_params)]
end
#Params must include the password and all the parameters to be sent in clear.
#Anyway, If "secure_rest_api" is disable, encrypted_params will be send in clear.
def generic_api_call(url,params,encrypted_params)
begin
unless params
params = {}
end
unless encrypted_params
encrypted_params = {}
end
params[:password]=$pass
response=sendHttpRequest(url,params,encrypted_params)
puts response.body
if response.body.include?("Ok")
return true
else
return false
end
rescue => e
log($script_title,"#{e.class.name}: #{e.message}")
puts("#{e.class.name}: #{e.message}")
return false
end
end
#Send HTTP Request to Social Stream Presence API
def sendHttpRequest(url,params,encrypted_params)
unless params[:password]
return "params[:password] required in sendHttpRequest";
end
if $secure_rest_api == "true"
#Require libraries
require 'openssl'
xmpp_private_key_path = $scripts_path + "/rsa_keys/xmpp_rsa_key_private.pem";
web_public_key_path = $scripts_path + "/rsa_keys/web_rsa_key_public.pem";
xmpp_private_key = OpenSSL::PKey::RSA.new(File.read(xmpp_private_key_path))
web_public_key = OpenSSL::PKey::RSA.new(File.read(web_public_key_path))
request_params = {};
#Copy non encypted params
params.each do |key,value|
unless key.to_s == "password"
request_params[key] = value
end
end
#Include encrypted params
if encrypted_params and encrypted_params.empty? == false
request_params[:encrypted_params] = web_public_key.public_encrypt(encrypted_params.to_s)
end
#Generating stamp
#1 Get constant password
password = params[:password];
#2 Generating timestamp
timestamp = Time.now.utc.to_s
#3 Calculating Hash
hash = calculateHash(request_params)
#Add cipher stamp to the request
request_params[:password] = xmpp_private_key.private_encrypt(password+"#####"+timestamp+"#####"+hash)
#Replace previous params
params = request_params
else
#Non secure mode: send encrypted params in clear
if encrypted_params
encrypted_params.each do |key,value|
params[key] = value
end
end
end
response = RestClient.get url, :params => params
return response
end
def calculateHash(request_params)
require 'digest/md5'
unless request_params
request_params = {};
end
hash = "";
request_params.each do |key,value|
hash = hash + key.to_s + value.to_s
end
return Digest::MD5.hexdigest(hash)
end
def invokeApiCall(method,args)
length = args.length;
case length
when 0
return send(method)
when 1
return send(method,args[0])
when 2
return send(method,args[0],args[1])
when 3
return send(method,args[0],args[1],args[2])
when 4
return send(method,args[0],args[1],args[2],args[3])
else
return send(method,args)
end
end
def getUsernameFromJid(jid)
return jid.split("@")[0];
end
def getDomainFromJid(jid)
return jid.split("@")[1];
end
def getWebDomainUrlFromDomain(domain)
if domain=="all"
return getWebDomainUrlFromDomain(getWebDomains()[0])
end
web_domain = getOption(domain + "=");
if (web_domain != "Undefined")
return web_domain
else
return domain
end
end
def getWebDomains()
begin
web_domains = getOption("web_domains=");
#web_domains=["domain1","domain2"]
return getElementsFromStringArray(web_domains);
rescue Exception=>e
return [""]
end
end
def getElementsFromStringArray(stringArray)
stringArray=stringArray[1,stringArray.length-2]
return stringArray.split(",")
end
#Main Program
begin
args = []
method = ARGV[0];
ARGV.each do |arg|
args.push(arg)
end
args.shift;
if (response = invokeApiCall(method, args) and response[1])
puts $script_title + ": #{response[0]} [OK]"
log( $script_title , "#{response[0]} [OK]" )
else
puts $script_title + ": #{response[0]} [FAIL]"
log( $script_title , "#{response[0]} [FAIL]" )
end
rescue => e
log($script_title,"#{e.class.name}: #{e.message}")
puts("#{e.class.name}: #{e.message}")
exit 1
end