social_stream-presence 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ rsa_keys/*
@@ -1,5 +1,7 @@
1
1
  class XmppController < ApplicationController
2
2
 
3
+ before_filter :authorization, :only => [:setConnection, :unsetConecction, :setPresence, :unsetPresence, :resetConnection, :synchronizePresence ]
4
+
3
5
  #Mapping XMPP Standar Status to Social Stream Chat Status
4
6
  STATUS = {
5
7
  '' => 'available',
@@ -10,14 +12,12 @@ class XmppController < ApplicationController
10
12
  }
11
13
 
12
14
 
13
- #API METHODS
15
+ ##############################
16
+ ########## REST API ##########
17
+ ##############################
14
18
 
15
- def setConnection
16
- unless authorization
17
- render :text => "Authorization error"
18
- return
19
- end
20
-
19
+ def setConnection
20
+ params = @dparams
21
21
  user = User.find_by_slug(params[:name])
22
22
 
23
23
  if user && !user.connected
@@ -28,16 +28,12 @@ class XmppController < ApplicationController
28
28
  return
29
29
  end
30
30
 
31
- render :text => "Error"
31
+ render :text => "Ok: The user was already connected"
32
32
  end
33
33
 
34
34
 
35
35
  def unsetConecction
36
- unless authorization
37
- render :text => "Authorization error"
38
- return
39
- end
40
-
36
+ params = @dparams
41
37
  user = User.find_by_slug(params[:name])
42
38
 
43
39
  if user && user.connected
@@ -47,16 +43,12 @@ class XmppController < ApplicationController
47
43
  return
48
44
  end
49
45
 
50
- render :text => "User not connected"
46
+ render :text => "Ok: The user was already disconnected"
51
47
  end
52
48
 
53
49
 
54
- def setPresence
55
- unless authorization
56
- render :text => "Authorization error"
57
- return
58
- end
59
-
50
+ def setPresence
51
+ params = @dparams
60
52
  user = User.find_by_slug(params[:name])
61
53
  status = params[:status]
62
54
 
@@ -65,20 +57,16 @@ class XmppController < ApplicationController
65
57
  user.connected = true
66
58
  user.save!
67
59
  end
68
- render :text => 'Status changed'
60
+ render :text => "Ok: Status changed"
69
61
  else
70
- render :text => 'Status not changed'
62
+ render :text => "Ok: Status not changed"
71
63
  end
72
64
 
73
65
  end
74
66
 
75
67
 
76
- def unsetPresence
77
- unless authorization
78
- render :text => "Authorization error"
79
- return
80
- end
81
-
68
+ def unsetPresence
69
+ params = @dparams
82
70
  user = User.find_by_slug(params[:name])
83
71
 
84
72
  if user && user.connected
@@ -88,44 +76,36 @@ class XmppController < ApplicationController
88
76
  return
89
77
  end
90
78
 
91
- render :text => "User not connected"
79
+ render :text => "Ok: The user was already disconnected"
92
80
  end
93
81
 
94
82
 
95
83
  def resetConnection
96
- unless authorization
97
- render :text => "Authorization error"
98
- return
99
- end
100
-
101
84
  SocialStream::Presence::XmppServerOrder::resetPresence
102
-
103
85
  render :text => "Ok"
104
86
  end
105
87
 
106
88
 
107
- def synchronizePresence
108
- unless authorization
109
- render :text => "Authorization error"
89
+ def synchronizePresence
90
+ params = @dparams
91
+
92
+ #Work without encrypted params
93
+ if params[:name] == nil or params[:name].empty? or params[:name]==""
94
+ render :text => "Ok: No users received"
110
95
  return
111
- end
112
-
113
- #Actual connected users
114
- user_slugs = params[:name]
96
+ end
115
97
 
98
+ #Actual connected users
99
+ user_slugs = params[:name].split(",")
116
100
  SocialStream::Presence::XmppServerOrder::synchronizePresenceForSlugs(user_slugs)
117
-
118
- render :text => "ok"
119
- end
120
-
121
-
122
- def authorization
123
- return params[:password] == SocialStream::Presence.xmpp_server_password
101
+ render :text => "Ok"
124
102
  end
125
103
 
126
104
 
127
- def chatWindow
128
-
105
+
106
+ #OPEN METHODS
107
+
108
+ def chatWindow
129
109
  if current_user and current_user.chat_enabled and (params[:userConnected]=="true")
130
110
  render :partial => 'chat/contacts'
131
111
  elsif current_user and current_user.chat_enabled
@@ -183,7 +163,7 @@ class XmppController < ApplicationController
183
163
  private
184
164
 
185
165
  def setStatus(user,status)
186
- if user and status and user.status != status and validStatus(status)
166
+ if user and status and validStatus(status) and user.status != STATUS[status]
187
167
  user.status = STATUS[status]
188
168
  user.save!
189
169
  return true
@@ -195,4 +175,13 @@ class XmppController < ApplicationController
195
175
  return STATUS.keys.include?(status)
196
176
  end
197
177
 
178
+
179
+ #Authorization to use REST API
180
+ def authorization
181
+ unless SocialStream::Presence::XmppServerOrder::authorization(params)
182
+ render :text => "Authorization error"
183
+ end
184
+ @dparams = SocialStream::Presence::XmppServerOrder::decryptParams(params)
185
+ end
186
+
198
187
  end
@@ -24,7 +24,8 @@ cookie_name=_rails_server_cookie
24
24
 
25
25
  #Ejabberd Server Password
26
26
  ejabberd_password=password
27
-
27
+ #True to enable REST API Security
28
+ secure_rest_api=false
28
29
 
29
30
  #Emanagement configuration
30
31
  ejabberd_server_user=ejabberd
Binary file
@@ -1,9 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
- #Reset Connection Script
2
+ #Rest Api Client Script
3
+ #Version: 13-12-2011
3
4
  #@author Aldo
4
5
 
6
+
5
7
  require 'logger'
6
8
  require 'rest_client'
9
+ require 'openssl'
10
+ require 'digest/md5'
11
+
7
12
 
8
13
  path = "/var/log/ejabberd/scripts.log"
9
14
  file = File.open(path, File::WRONLY | File::APPEND | File::CREAT)
@@ -25,31 +30,268 @@ def getOption(option)
25
30
  return "Undefined"
26
31
  end
27
32
 
28
- $url = "http://" + getOption("web_domain=") + "/xmpp/resetConnection"
33
+ #Constants
34
+ $secure_rest_api = getOption("secure_rest_api=")
29
35
  $pass = getOption("ejabberd_password=")
36
+ $scripts_path = getOption("scripts_path=")
37
+ $script_title = "Reset Connection script"
38
+
39
+
40
+ def log(title,text)
41
+ $logger.info title + ": " + text
42
+ end
43
+
44
+ def getMethodName
45
+ caller[0] =~ /`(.*?)'/
46
+ $1
47
+ end
48
+
49
+
50
+ #####################
51
+ ##### Example #####
52
+ #####################
53
+ #def myHook(param1,param2)
54
+ # log(getMethodName,"(My message: #{param1},#{param2})")
55
+ # url = "http://" + getOption("web_domain=") + "/xmpp/hookRoute"
56
+
57
+ # params = {}
58
+ # encrypted_params = {}
59
+ # #Add params to sent in clear
60
+ # params[:param1_in_server]=param1
61
+ # #Add params to sent cipher
62
+ # encrypted_params[:param2_in_server]=param2
63
+
64
+ # return [getMethodName,generic_api_call(url,params,encrypted_params)]
65
+ #end
66
+
67
+ def setConnection(username)
68
+ log($script_title,"#{getMethodName}(#{username})")
69
+ url = "http://" + getOption("web_domain=") + "/xmpp/setConnection"
70
+
71
+ params = {}
72
+ encrypted_params = {}
73
+ encrypted_params[:name]=username
74
+
75
+ return [getMethodName,generic_api_call(url,params,encrypted_params)]
76
+ end
77
+
78
+
79
+ def unsetConnection(username)
80
+ log($script_title,"#{getMethodName}(#{username})")
81
+ url = "http://" + getOption("web_domain=") + "/xmpp/unsetConnection"
82
+
83
+ params = {}
84
+ encrypted_params = {}
85
+ encrypted_params[:name]=username
30
86
 
87
+ return [getMethodName,generic_api_call(url,params,encrypted_params)]
88
+ end
89
+
90
+
91
+ def setPresence(username,status)
92
+ log($script_title,"#{getMethodName}(#{username},#{status})")
93
+ url = "http://" + getOption("web_domain=") + "/xmpp/setPresence"
94
+
95
+ params = {}
96
+ encrypted_params = {}
97
+ encrypted_params[:name]=username
98
+ encrypted_params[:status]=status
99
+
100
+ return [getMethodName,generic_api_call(url,params,encrypted_params)]
101
+ end
102
+
103
+
104
+ def unsetPresence(username)
105
+ log($script_title,"#{getMethodName}(#{username})")
106
+ url = "http://" + getOption("web_domain=") + "/xmpp/unsetPresence"
107
+
108
+ params = {}
109
+ encrypted_params = {}
110
+ encrypted_params[:name]=username
31
111
 
32
- def log(text)
33
- $logger.info "Reset Connection Script: " + text
112
+ return [getMethodName,generic_api_call(url,params,encrypted_params)]
34
113
  end
35
114
 
36
115
 
37
116
  def resetConnection()
117
+ log($script_title,"Call #{getMethodName}()")
118
+ url = "http://" + getOption("web_domain=") + "/xmpp/resetConnection"
119
+
120
+ params = {}
121
+ encrypted_params = {}
122
+
123
+ return [getMethodName,generic_api_call(url,params,encrypted_params)]
124
+ end
125
+
126
+
127
+ def synchronize()
128
+ log($script_title,"Call #{getMethodName}()")
129
+ url = "http://" + getOption("web_domain=") + "/xmpp/synchronizePresence"
130
+
131
+
132
+ #Get connected users using Emanagement
133
+ users = []
134
+ command = $scripts_path + "/emanagement getConnectedUsers"
135
+ output = %x[#{command}]
136
+ sessions = output.split("\n")
137
+
138
+ sessions.each do |session|
139
+ users << session.split("@")[0]
140
+ end
141
+ #Finish
142
+
143
+
144
+ #In this cases users always will be sent in clear (not cipher)
145
+ #(Too much data to cipher)
146
+ #Anyway, we must to build the hash to pass the authentication
147
+ params = {}
148
+ encrypted_params = {}
149
+ params[:name]=users.join(",")
150
+
151
+ return [getMethodName,generic_api_call(url,params,encrypted_params)]
152
+ end
153
+
154
+
155
+
156
+ #Params must include the password and all the parameters to be sent in clear.
157
+ #Anyway, If "secure_rest_api" is disable, encrypted_params will be send in clear.
158
+ def generic_api_call(url,params,encrypted_params)
159
+
38
160
  begin
39
- RestClient.post($url, :password => $pass)
40
- return true
161
+ unless params
162
+ params = {}
163
+ end
164
+
165
+ unless encrypted_params
166
+ encrypted_params = {}
167
+ end
168
+
169
+ params[:password]=$pass
170
+
171
+ response=sendHttpRequest(url,params,encrypted_params)
172
+ puts response.body
173
+
174
+ if response.body.include?("Ok")
175
+ return true
176
+ else
177
+ return false
178
+ end
179
+
41
180
  rescue => e
42
- log("#{e.class.name}: #{e.message}")
181
+ log($script_title,"#{e.class.name}: #{e.message}")
182
+ puts("#{e.class.name}: #{e.message}")
43
183
  return false
44
184
  end
45
185
  end
46
186
 
47
- if (resetConnection())
48
- puts "Reset Connection [OK]"
49
- log( "Reset Connection [OK]" )
50
- else
51
- puts "Reset Connection [FAIL]"
52
- log( "Reset Connection [FAIL]" )
187
+
188
+ #Send HTTP Request to Social Stream Presence API
189
+ def sendHttpRequest(url,params,encrypted_params)
190
+
191
+ unless params[:password]
192
+ return "params[:password] required in sendHttpRequest";
193
+ end
194
+
195
+
196
+ if $secure_rest_api == "true"
197
+ xmpp_private_key_path = $scripts_path + "/rsa_keys/xmpp_rsa_key_private.pem";
198
+ web_public_key_path = $scripts_path + "/rsa_keys/web_rsa_key_public.pem";
199
+ xmpp_private_key = OpenSSL::PKey::RSA.new(File.read(xmpp_private_key_path))
200
+ web_public_key = OpenSSL::PKey::RSA.new(File.read(web_public_key_path))
201
+
202
+ request_params = {};
203
+
204
+ #Copy non encypted params
205
+ params.each do |key,value|
206
+ unless key.to_s == "password"
207
+ request_params[key] = value
208
+ end
209
+ end
210
+
211
+ #Include encrypted params
212
+ if encrypted_params and encrypted_params.empty? == false
213
+ request_params[:encrypted_params] = web_public_key.public_encrypt(encrypted_params.to_s)
214
+ end
215
+
216
+ #Generating stamp
217
+ #1 Get constant password
218
+ password = params[:password];
219
+ #2 Generating timestamp
220
+ timestamp = Time.now.utc.to_s
221
+ #3 Calculating Hash
222
+ hash = calculateHash(request_params)
223
+
224
+ #Add cipher stamp to the request
225
+ request_params[:password] = xmpp_private_key.private_encrypt(password+"#####"+timestamp+"#####"+hash)
226
+
227
+ #Replace previous params
228
+ params = request_params
229
+ else
230
+ #Non secure mode: send encrypted params in clear
231
+ if encrypted_params
232
+ encrypted_params.each do |key,value|
233
+ params[key] = value
234
+ end
235
+ end
236
+ end
237
+
238
+ response = RestClient.get url, :params => params
239
+ return response
53
240
  end
54
241
 
55
242
 
243
+ def calculateHash(request_params)
244
+ unless request_params
245
+ request_params = {};
246
+ end
247
+
248
+ hash = "";
249
+ request_params.each do |key,value|
250
+ hash = hash + key.to_s + value.to_s
251
+ end
252
+ return Digest::MD5.hexdigest(hash)
253
+ end
254
+
255
+
256
+
257
+
258
+ def invokeApiCall(method,args)
259
+ length = args.length;
260
+ case length
261
+ when 0
262
+ return send(method)
263
+ when 1
264
+ return send(method,args[0])
265
+ when 2
266
+ return send(method,args[0],args[1])
267
+ when 3
268
+ return send(method,args[0],args[1],args[2])
269
+ when 4
270
+ return send(method,args[0],args[1],args[2],args[3])
271
+ else
272
+ return send(method,args)
273
+ end
274
+ end
275
+
276
+
277
+ #Main Program
278
+
279
+ begin
280
+
281
+ args = []
282
+ method = "resetConnection";
283
+
284
+ if (response = invokeApiCall(method, args) and response[1])
285
+ puts $script_title + ": #{response[0]} [OK]"
286
+ log( $script_title , "#{response[0]} [OK]" )
287
+ else
288
+ puts $script_title + ": #{response[0]} [FAIL]"
289
+ log( $script_title , "#{response[0]} [FAIL]" )
290
+ end
291
+
292
+ rescue => e
293
+ log($script_title,"#{e.class.name}: #{e.message}")
294
+ puts("#{e.class.name}: #{e.message}")
295
+ exit 1
296
+ end
297
+