#!/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