rhoconnect 3.2.1 → 3.3.1.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. data/CHANGELOG.md +24 -5
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +20 -20
  4. data/bench/benchapp/Gemfile +17 -20
  5. data/bench/benchapp/config.ru +2 -2
  6. data/bench/benchapp/settings/settings.yml +3 -3
  7. data/bench/blobapp/Gemfile +16 -13
  8. data/bench/blobapp/config.ru +2 -2
  9. data/bench/blobapp/settings/settings.yml +5 -3
  10. data/bench/lib/bench.rb +35 -32
  11. data/bench/lib/bench/session.rb +9 -1
  12. data/bench/scripts/blob_cud_script.rb +13 -17
  13. data/bench/scripts/cud_script.rb +11 -12
  14. data/bench/scripts/helpers.rb +5 -7
  15. data/bench/scripts/query_md_script.rb +18 -12
  16. data/bench/scripts/query_only_script.rb +19 -11
  17. data/bench/scripts/query_script.rb +17 -13
  18. data/bench/scripts/test_query_script.rb +46 -17
  19. data/bench/scripts/test_source_script.rb +7 -7
  20. data/commands/commands/dtach_commands/dtach_install.rb +44 -16
  21. data/commands/commands/rhoconnect/spec.rb +13 -9
  22. data/commands/commands/rhoconnect/version.rb +6 -0
  23. data/commands/execute.rb +10 -6
  24. data/doc/deploying.txt +75 -13
  25. data/doc/install.txt +3 -3
  26. data/doc/push-client-setup.txt +1 -1
  27. data/doc/rest-api.txt +4 -23
  28. data/doc/rhoconnect-redis-stack.txt +26 -7
  29. data/doc/settings.txt +9 -3
  30. data/examples/simple/Gemfile +3 -1
  31. data/examples/simple/application.rb +5 -0
  32. data/examples/simple/config.ru +3 -2
  33. data/examples/simple/my_server.rb +14 -0
  34. data/examples/simple/settings/settings.yml +1 -0
  35. data/generators/templates/application/Gemfile +4 -4
  36. data/generators/templates/application/application.rb +4 -0
  37. data/generators/templates/application/settings/settings.yml +4 -1
  38. data/installer/unix-like/create_texts.rb +39 -1
  39. data/installer/unix-like/rho_connect_install_constants.rb +1 -1
  40. data/installer/utils/package_upload/repos.rake +7 -5
  41. data/lib/rhoconnect.rb +3 -2
  42. data/lib/rhoconnect/api/app/ans_login.rb +3 -0
  43. data/lib/rhoconnect/api/app/bulk_data.rb +6 -0
  44. data/lib/rhoconnect/api/{source → app}/fast_delete.rb +1 -1
  45. data/lib/rhoconnect/api/{source → app}/fast_insert.rb +2 -2
  46. data/lib/rhoconnect/api/{source → app}/fast_update.rb +2 -2
  47. data/lib/rhoconnect/api/app/login.rb +5 -0
  48. data/lib/rhoconnect/api/{source → app}/push_deletes.rb +1 -1
  49. data/lib/rhoconnect/api/{source → app}/push_objects.rb +1 -1
  50. data/lib/rhoconnect/api/app/query.rb +4 -0
  51. data/lib/rhoconnect/api/app/queue_updates.rb +94 -0
  52. data/lib/rhoconnect/api/app/search.rb +4 -0
  53. data/lib/rhoconnect/api/client/client_get_db_doc.rb +5 -0
  54. data/lib/rhoconnect/api/client/client_set_db_doc.rb +8 -0
  55. data/lib/rhoconnect/api/client/create.rb +7 -0
  56. data/lib/rhoconnect/api/client/get_client_params.rb +2 -1
  57. data/lib/rhoconnect/api/client/list_client_docs.rb +2 -1
  58. data/lib/rhoconnect/api/client/register.rb +12 -0
  59. data/lib/rhoconnect/api/client/reset.rb +5 -0
  60. data/lib/rhoconnect/api/{source → readstate}/set_refresh_time.rb +2 -1
  61. data/lib/rhoconnect/api/source/get_source_params.rb +3 -2
  62. data/lib/rhoconnect/api/source/list_sources.rb +2 -1
  63. data/lib/rhoconnect/api/source/update_source_params.rb +3 -3
  64. data/lib/rhoconnect/api/store/get_db_doc.rb +4 -0
  65. data/lib/rhoconnect/api/store/set_db_doc.rb +7 -0
  66. data/lib/rhoconnect/api/system/get_adapter.rb +4 -0
  67. data/lib/rhoconnect/api/{admin → system}/get_license_info.rb +2 -1
  68. data/lib/rhoconnect/api/system/login.rb +15 -0
  69. data/lib/rhoconnect/api/{admin → system}/reset.rb +3 -2
  70. data/lib/rhoconnect/api/system/save_adapter.rb +4 -0
  71. data/lib/rhoconnect/api/{admin → system}/stats.rb +2 -1
  72. data/lib/rhoconnect/api/user/create_user.rb +2 -2
  73. data/lib/rhoconnect/api/user/delete_client.rb +6 -0
  74. data/lib/rhoconnect/api/user/delete_user.rb +2 -1
  75. data/lib/rhoconnect/api/user/list_clients.rb +4 -0
  76. data/lib/rhoconnect/api/user/list_source_docs.rb +11 -0
  77. data/lib/rhoconnect/api/user/list_users.rb +1 -1
  78. data/lib/rhoconnect/api/user/ping.rb +7 -0
  79. data/lib/rhoconnect/api/user/show_user.rb +3 -0
  80. data/lib/rhoconnect/api/user/update_user.rb +3 -2
  81. data/lib/rhoconnect/api/user/user_get_db_doc.rb +5 -0
  82. data/lib/rhoconnect/api/user/user_set_db_doc.rb +10 -0
  83. data/lib/rhoconnect/app.rb +12 -2
  84. data/lib/rhoconnect/async.rb +6 -10
  85. data/lib/rhoconnect/bulk_data/bulk_data.rb +4 -4
  86. data/lib/rhoconnect/client.rb +10 -9
  87. data/lib/rhoconnect/client_sync.rb +24 -19
  88. data/lib/rhoconnect/document.rb +18 -4
  89. data/lib/rhoconnect/graph_helper.rb +4 -2
  90. data/lib/rhoconnect/jobs/bulk_data_job.rb +1 -1
  91. data/lib/rhoconnect/jobs/ping_job.rb +39 -29
  92. data/lib/rhoconnect/middleware/admin_user.rb +23 -0
  93. data/lib/rhoconnect/middleware/body_content_type_parser.rb +35 -0
  94. data/lib/rhoconnect/{cors.rb → middleware/cors.rb} +1 -0
  95. data/lib/rhoconnect/middleware/current_app.rb +16 -0
  96. data/lib/rhoconnect/middleware/current_request.rb +16 -0
  97. data/lib/rhoconnect/middleware/current_user.rb +17 -0
  98. data/lib/rhoconnect/middleware/helpers.rb +105 -0
  99. data/lib/rhoconnect/middleware/login_required.rb +22 -0
  100. data/lib/rhoconnect/{stats/middleware.rb → middleware/stats.rb} +5 -3
  101. data/lib/rhoconnect/middleware/x_domain_session_wrapper.rb +58 -0
  102. data/lib/rhoconnect/ping.rb +1 -0
  103. data/lib/rhoconnect/ping/apple.rb +18 -16
  104. data/lib/rhoconnect/ping/blackberry.rb +9 -9
  105. data/lib/rhoconnect/ping/rhoconnect_push.rb +45 -0
  106. data/lib/rhoconnect/server.rb +98 -91
  107. data/lib/rhoconnect/source.rb +5 -1
  108. data/lib/rhoconnect/source_sync.rb +4 -3
  109. data/lib/rhoconnect/stats/record.rb +15 -15
  110. data/lib/rhoconnect/store.rb +253 -75
  111. data/lib/rhoconnect/tasks.rb +3 -3
  112. data/lib/rhoconnect/version.rb +1 -1
  113. data/lib/rhoconnect/web-console/controllers/admins.js +1 -14
  114. data/lib/rhoconnect/web-console/models/adapter.js +18 -8
  115. data/lib/rhoconnect/web-console/models/client.js +15 -9
  116. data/lib/rhoconnect/web-console/models/doc.js +7 -11
  117. data/lib/rhoconnect/web-console/models/session.js +5 -2
  118. data/lib/rhoconnect/web-console/models/source.js +55 -36
  119. data/lib/rhoconnect/web-console/models/user.js +20 -11
  120. data/lib/rhoconnect/web-console/public/backbone.js +8 -2
  121. data/lib/rhoconnect/web-console/templates/index.erb +11 -5
  122. data/lib/rhoconnect/web-console/views/doc.js +6 -8
  123. data/lib/rhoconnect/web-console/views/edit_user.js +6 -3
  124. data/lib/rhoconnect/web-console/views/home.js +98 -25
  125. data/lib/rhoconnect/web-console/views/index.js +1 -1
  126. data/lib/rhoconnect/web-console/views/new_ping.js +6 -3
  127. data/lib/rhoconnect/web-console/views/server_doc.js +12 -4
  128. data/lib/rhoconnect/web-console/views/show_device.js +6 -3
  129. data/rhoconnect.gemspec +1 -2
  130. data/spec/api/{source → app}/fast_delete_spec.rb +4 -4
  131. data/spec/api/{source → app}/fast_insert_spec.rb +4 -4
  132. data/spec/api/{source → app}/fast_update_spec.rb +22 -6
  133. data/spec/api/{source → app}/push_deletes_spec.rb +2 -2
  134. data/spec/api/app/push_objects_spec.rb +45 -0
  135. data/spec/api/client/client_get_db_doc_spec.rb +31 -0
  136. data/spec/api/client/client_set_db_doc_spec.rb +14 -0
  137. data/spec/api/client/get_client_params_spec.rb +3 -2
  138. data/spec/api/client/list_client_docs_spec.rb +2 -2
  139. data/spec/api/{source → readstate}/set_refresh_time_spec.rb +15 -9
  140. data/spec/api/source/get_source_params_spec.rb +3 -2
  141. data/spec/api/source/list_sources_spec.rb +3 -9
  142. data/spec/api/source/update_source_params_spec.rb +4 -4
  143. data/spec/api/store/get_db_doc_spec.rb +32 -0
  144. data/spec/api/store/set_db_doc_spec.rb +43 -0
  145. data/spec/api/system/adapter_spec.rb +33 -0
  146. data/spec/api/{admin → system}/get_license_info_spec.rb +2 -5
  147. data/spec/api/{admin/get_api_token_spec.rb → system/login_spec.rb} +4 -11
  148. data/spec/api/{admin → system}/reset_spec.rb +2 -2
  149. data/spec/api/{admin → system}/stats_spec.rb +19 -13
  150. data/spec/api/user/create_user_spec.rb +15 -8
  151. data/spec/api/{client → user}/delete_client_spec.rb +3 -4
  152. data/spec/api/user/delete_user_spec.rb +33 -4
  153. data/spec/api/user/list_clients_spec.rb +30 -0
  154. data/spec/api/user/list_source_docs_spec.rb +35 -0
  155. data/spec/api/user/list_users_spec.rb +5 -6
  156. data/spec/api/{client → user}/ping_spec.rb +4 -6
  157. data/spec/api/user/show_user_spec.rb +14 -0
  158. data/spec/api/user/update_user_spec.rb +28 -10
  159. data/spec/api/user/user_get_db_doc_spec.rb +16 -0
  160. data/spec/api/user/user_set_db_doc_spec.rb +41 -0
  161. data/spec/apps/rhotestapp/application.rb +4 -0
  162. data/spec/apps/rhotestapp/settings/settings.yml +3 -1
  163. data/spec/bulk_data/bulk_data_spec.rb +13 -0
  164. data/spec/client_sync_spec.rb +41 -59
  165. data/spec/document_spec.rb +23 -0
  166. data/spec/javascripts/doc_view_spec.js +1 -1
  167. data/spec/javascripts/home_view_spec.js +10 -5
  168. data/spec/javascripts/index_view_spec.js +1 -1
  169. data/spec/jobs/ping_job_spec.rb +26 -0
  170. data/spec/perf/store_perf_spec.rb +1 -1
  171. data/spec/ping/android_spec.rb +0 -7
  172. data/spec/ping/apple_spec.rb +7 -0
  173. data/spec/ping/blackberry_spec.rb +10 -0
  174. data/spec/ping/rhoconnect_push_spec.rb +58 -0
  175. data/spec/server/cors_spec.rb +1 -1
  176. data/spec/server/server_spec.rb +152 -104
  177. data/spec/{stats/middleware_spec.rb → server/stats_spec.rb} +4 -5
  178. data/spec/server/x_domain_session_wrapper_spec.rb +3 -3
  179. data/spec/source_spec.rb +2 -2
  180. data/spec/source_sync_spec.rb +2 -0
  181. data/spec/spec_helper.rb +17 -3
  182. data/spec/stats/record_spec.rb +18 -19
  183. data/spec/store_spec.rb +51 -26
  184. data/spec/support/shared_examples.rb +4 -0
  185. data/spec/sync_states_spec.rb +2 -2
  186. metadata +104 -88
  187. data/bench/benchapp/Gemfile.lock +0 -87
  188. data/bench/blobapp/Gemfile.lock +0 -107
  189. data/bench/lib/testdata/5-data.txt +0 -8
  190. data/doc/release.txt +0 -41
  191. data/lib/rhoconnect/api/admin/get_api_token.rb +0 -14
  192. data/lib/rhoconnect/api/admin/login.rb +0 -6
  193. data/lib/rhoconnect/api/application/bulk_data.rb +0 -7
  194. data/lib/rhoconnect/api/application/clientcreate.rb +0 -8
  195. data/lib/rhoconnect/api/application/clientlogin.rb +0 -6
  196. data/lib/rhoconnect/api/application/clientregister.rb +0 -13
  197. data/lib/rhoconnect/api/application/clientreset.rb +0 -6
  198. data/lib/rhoconnect/api/application/query.rb +0 -7
  199. data/lib/rhoconnect/api/application/queue_updates.rb +0 -20
  200. data/lib/rhoconnect/api/application/search.rb +0 -6
  201. data/lib/rhoconnect/api/client/create_client.rb +0 -3
  202. data/lib/rhoconnect/api/client/delete_client.rb +0 -5
  203. data/lib/rhoconnect/api/client/list_clients.rb +0 -3
  204. data/lib/rhoconnect/api/client/ping.rb +0 -7
  205. data/lib/rhoconnect/api/source/get_adapter.rb +0 -3
  206. data/lib/rhoconnect/api/source/get_db_doc.rb +0 -7
  207. data/lib/rhoconnect/api/source/list_source_docs.rb +0 -10
  208. data/lib/rhoconnect/api/source/save_adapter.rb +0 -3
  209. data/lib/rhoconnect/api/source/set_db_doc.rb +0 -10
  210. data/lib/rhoconnect/api/source/upload_file.rb +0 -4
  211. data/lib/rhoconnect/body_content_type_parser.rb +0 -32
  212. data/lib/rhoconnect/x_domain_session_wrapper.rb +0 -53
  213. data/spec/api/admin/api_token_spec.rb +0 -13
  214. data/spec/api/client/create_client_spec.rb +0 -13
  215. data/spec/api/client/list_clients_spec.rb +0 -22
  216. data/spec/api/source/adapter_spec.rb +0 -29
  217. data/spec/api/source/get_db_doc_spec.rb +0 -21
  218. data/spec/api/source/list_source_docs_spec.rb +0 -25
  219. data/spec/api/source/push_objects_spec.rb +0 -27
  220. data/spec/api/source/set_db_doc_spec.rb +0 -32
  221. data/spec/api/source/upload_file_spec.rb +0 -26
@@ -154,7 +154,7 @@ module Rhoconnect
154
154
  db.execute_batch(File.open(schema,'r').read)
155
155
 
156
156
  src_counter = 1
157
- bulk_data.sources.members.sort.each do |source_name|
157
+ bulk_data.sources[0, -1].each do |source_name|
158
158
  timer = start_timer("start importing sqlite data for #{source_name}")
159
159
  source = Source.load(source_name,{:app_id => bulk_data.app_id,
160
160
  :user_id => bulk_data.user_id})
@@ -25,41 +25,51 @@ module Rhoconnect
25
25
  # all errors are recorded here
26
26
  errors = []
27
27
  user = User.load(user_id)
28
- user.clients.members.each do |client_id|
29
- client = Client.load(client_id,{:source_name => '*'})
30
- params.merge!('device_port' => client.device_port, 'device_pin' => client.device_pin, 'phone_id' => client.phone_id)
31
- send_push = false
32
- if client.device_type and client.device_type.size > 0
33
- if client.phone_id and client.phone_id.size > 0
34
- unless phone_ids.include? client.phone_id
35
- phone_ids << client.phone_id
36
- send_push = true
37
- end
38
- elsif client.device_pin and client.device_pin.size > 0
39
- unless device_pins.include? client.device_pin
40
- device_pins << client.device_pin
41
- send_push = true
28
+ clients = user.clients if user
29
+ if clients
30
+ clients.members.each do |client_id|
31
+ client = Client.load(client_id,{:source_name => '*'})
32
+ params.merge!(
33
+ 'device_port' => client.device_port,
34
+ 'device_pin' => client.device_pin,
35
+ 'phone_id' => client.phone_id
36
+ )
37
+ send_push = false
38
+ if client.device_type and client.device_type.size > 0
39
+ if client.phone_id and client.phone_id.size > 0
40
+ unless phone_ids.include? client.phone_id
41
+ phone_ids << client.phone_id
42
+ send_push = true
43
+ end
44
+ elsif client.device_pin and client.device_pin.size > 0
45
+ unless device_pins.include? client.device_pin
46
+ device_pins << client.device_pin
47
+ send_push = true
48
+ end
49
+ else
50
+ log "Skipping ping for non-registered client_id '#{client_id}'..."
51
+ next
42
52
  end
43
- else
44
- log "Skipping ping for non-registered client_id '#{client_id}'..."
45
- next
46
- end
47
- if send_push
48
- klass = Object.const_get(camelize(client.device_type.downcase))
49
- if klass
50
- params['vibrate'] = params['vibrate'].to_s
51
- begin
52
- klass.ping(params)
53
- rescue Exception => e
54
- errors << e
53
+ if send_push
54
+ type = client.device_push_type || client.device_type
55
+ klass = Object.const_get(camelize(type.downcase))
56
+ if klass
57
+ params['vibrate'] = params['vibrate'].to_s
58
+ begin
59
+ klass.ping(params)
60
+ rescue Exception => e
61
+ errors << e
62
+ end
55
63
  end
64
+ else
65
+ log "Dropping ping request for client_id '#{client_id}' because it's already in user's device pin or phone_id list."
56
66
  end
57
67
  else
58
- log "Dropping ping request for client_id '#{client_id}' because it's already in user's device pin or phone_id list."
68
+ log "Skipping ping for non-registered client_id '#{client_id}'..."
59
69
  end
60
- else
61
- log "Skipping ping for non-registered client_id '#{client_id}'..."
62
70
  end
71
+ else
72
+ log "Skipping ping for unknown user '#{user_id}' or '#{user_id}' has no registered clients..."
63
73
  end
64
74
  errors
65
75
  end
@@ -0,0 +1,23 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
3
+ module Rhoconnect
4
+ module Middleware
5
+ class AdminUser
6
+ def initialize(app, opts={})
7
+ @app = app
8
+ yield self if block_given?
9
+ end
10
+
11
+ def call(env)
12
+ begin
13
+ if Rhoconnect.is_admin_route(env)
14
+ env[Rhoconnect::CURRENT_USER] = Rhoconnect.extract_api_user(env)
15
+ end
16
+ rescue Rhoconnect::ApiException => ae
17
+ return [422, {'Content-Type' => 'text/plain'}, [ae.message]]
18
+ end
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
3
+ module Rhoconnect
4
+ module Middleware
5
+ class BodyContentTypeParser
6
+ # Constants
7
+ #
8
+ CONTENT_TYPE = 'CONTENT_TYPE'.freeze
9
+ POST_BODY = 'rack.input'.freeze
10
+ FORM_INPUT = 'rack.request.form_input'.freeze
11
+ FORM_HASH = 'rack.request.form_hash'.freeze
12
+
13
+ def initialize(app)
14
+ @app = app
15
+ end
16
+
17
+ def call(env)
18
+ if env[CONTENT_TYPE] && env[CONTENT_TYPE].match(/^application\/json/)
19
+ begin
20
+ if (body = env[POST_BODY].read).length != 0
21
+ # for some reason , if we do not do this
22
+ # Ruby 1.9 will fail
23
+ env[POST_BODY] = StringIO.new(body)
24
+ env.update(FORM_HASH => JSON.parse(body), FORM_INPUT => env[POST_BODY])
25
+ end
26
+ rescue JSON::ParserError => jpe
27
+ log jpe.message + jpe.backtrace.join("\n")
28
+ return [500, {'Content-Type' => 'text/plain'}, ["Server error while processing client data"]]
29
+ end
30
+ end
31
+ @app.call(env)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,4 +1,5 @@
1
1
  require 'logger'
2
+ require 'rhoconnect/middleware/helpers'
2
3
 
3
4
  module Rack
4
5
  class Cors
@@ -0,0 +1,16 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
3
+ module Rhoconnect
4
+ module Middleware
5
+ class CurrentApp
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ env[Rhoconnect::CURRENT_APP] = App.load(APP_NAME)
12
+ @app.call(env)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
3
+ module Rhoconnect
4
+ module Middleware
5
+ class CurrentRequest
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ env[Rhoconnect::CURRENT_REQUEST] = Rack::Request.new(env)
12
+ @app.call(env)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
3
+ module Rhoconnect
4
+ module Middleware
5
+ class CurrentUser
6
+
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ env[Rhoconnect::CURRENT_USER] = Rhoconnect.extract_current_user(env)
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,105 @@
1
+ module Rhoconnect
2
+ # Constants
3
+ #
4
+ CURRENT_REQUEST = 'CURRENT_REQUEST'.freeze
5
+ CURRENT_APP = 'CURRENT_APP'.freeze
6
+ CURRENT_USER = 'CURRENT_USER'.freeze
7
+
8
+ # header names, in the form of server's HTTP variables
9
+ # X-RhoConnect-API-TOKEN
10
+ API_TOKEN_HEADER = 'HTTP_X_RHOCONNECT_API_TOKEN'.freeze
11
+ # X-RhoConnect-CLIENT-ID
12
+ CLIENT_ID_HEADER = 'HTTP_X_RHOCONNECT_CLIENT_ID'.freeze
13
+
14
+ # old-way admin routes
15
+ OLD_API_URI_REGEXP = /\/api\//
16
+ # new way system routes will be:
17
+ # /rc/<version>/system/<method>
18
+ # /rc/<version>/<resource>/<method>
19
+ SYSTEM_API_URI_REGEXP = /\/rc\/\w+\/\w+/
20
+ # also, /app/v1/<Controller>/push_* are still remain Admin routes
21
+ PUSH_API_URI_REGEXP = /\/app\/\w+\/\w+\/push\w+/
22
+ # also, /app/v1/<Controller>/fast_* are still remain Admin routes
23
+ FAST_CUD_API_URI_REGEXP = /\/app\/\w+\/\w+\/fast\w+/
24
+
25
+ def is_clients_non_admin_route(env)
26
+ # FIXME : not all routes for Clients protocol are admin routes
27
+ full_path = env['SCRIPT_NAME'] + env['PATH_INFO']
28
+ /\/rc\/\w+\/clients/.match(full_path) and not ((env[CURRENT_REQUEST].request_method == 'GET') ||
29
+ (env[CURRENT_REQUEST].request_method == 'POST' and /\/rc\/\w+\/clients\/\w+\/sources/.match(full_path)))
30
+ end
31
+
32
+ def is_client_route(env)
33
+ # FIXME - once Controllers concept is implemented
34
+ # remove this - since the inclusion of Admin Middleware
35
+ # will automatically imply what routes are Admin and which are not
36
+ full_path = env['SCRIPT_NAME'] + env['PATH_INFO']
37
+ # login route and index route doesn't need a token
38
+ return true if /\/login/.match(full_path) || full_path == '/'
39
+ # old application routes are not admin
40
+ return true if full_path == '/application'
41
+ return true if full_path == '/api/application'
42
+ return true if /\/application\//.match(full_path)
43
+ # some of the clients routes are not admin
44
+ return true if is_clients_non_admin_route(env)
45
+ # push_objects and push_deletes methods are admin
46
+ return false if PUSH_API_URI_REGEXP.match(full_path)
47
+ # fast_insert/update/delete methods are admin
48
+ return false if FAST_CUD_API_URI_REGEXP.match(full_path)
49
+ # old api methods + every method in /rc/v1/app namespace
50
+ return true if /\/app\//.match(full_path)
51
+ # all other methods in the /rc/v1/ are admin routes
52
+ return false if SYSTEM_API_URI_REGEXP.match(full_path)
53
+ # all old /api methods are admin as well
54
+ return false if OLD_API_URI_REGEXP.match(full_path)
55
+
56
+ # everything else should not be admin
57
+ true
58
+ end
59
+
60
+ def is_admin_route(env)
61
+ not is_client_route(env)
62
+ end
63
+
64
+ def is_login_required(env)
65
+ # FIXME - once Controllers concept is implemented
66
+ # remove this - since the inclusion of LoginRequired Middleware
67
+ # will automatically imply what routes require Login and which are not
68
+ full_path = env['SCRIPT_NAME'] + env['PATH_INFO']
69
+ return false if full_path == '/' or /login/.match(full_path)
70
+ # all methods in app namespace
71
+ return true if /\/app\//.match(full_path)
72
+ # old application routes are not admin
73
+ return true if full_path == '/application'
74
+ return true if full_path == '/api/application'
75
+ return true if /\/application\//.match(full_path)
76
+ # also methods that operate on clients should have an associated user
77
+ return true if is_clients_non_admin_route(env)
78
+
79
+ # for every other route login is not required
80
+ # because it's either an admin route (where api_user must be supplied anyway)
81
+ # or it's a custom route extending RhoConnect server
82
+ false
83
+ end
84
+
85
+ def extract_current_user(env)
86
+ user = nil
87
+ if User.is_exist?(env['rack.session'][:login])
88
+ user = User.load(env['rack.session'][:login])
89
+ end
90
+ if user and (user.admin == 1 || env['rack.session'][:app_name] == APP_NAME)
91
+ user
92
+ else
93
+ nil
94
+ end
95
+ end
96
+
97
+ def extract_api_user(env)
98
+ r = env[CURRENT_REQUEST]
99
+ # API_TOKEN is either a param or a header
100
+ u = ApiToken.load(env[API_TOKEN_HEADER])
101
+ u = ApiToken.load(r.params['api_token']) unless u
102
+ raise Rhoconnect::ApiException.new(422, "No API token provided") unless u
103
+ u.user
104
+ end
105
+ end
@@ -0,0 +1,22 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
3
+ module Rhoconnect
4
+ module Middleware
5
+ class LoginRequired
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ begin
12
+ if Rhoconnect.is_login_required(env)
13
+ raise LoginException.new("Not authenticated") if env[Rhoconnect::CURRENT_USER].nil?
14
+ end
15
+ @app.call(env)
16
+ rescue LoginException => le
17
+ return [401, {'Content-Type' => 'text/plain'}, le.message]
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,6 +1,8 @@
1
+ require 'rhoconnect/middleware/helpers'
2
+
1
3
  module Rhoconnect
2
- module Stats
3
- class Middleware
4
+ module Middleware
5
+ class Stats
4
6
  def initialize(app)
5
7
  @app = app
6
8
  end
@@ -13,7 +15,7 @@ module Rhoconnect
13
15
  metric = "http:#{env['REQUEST_METHOD']}:#{env['PATH_INFO']}"
14
16
  source_name = env['rack.request.query_hash']["source_name"] if env['rack.request.query_hash']
15
17
  metric << ":#{source_name}" if source_name
16
- Record.save_average(metric,finish - start)
18
+ Rhoconnect::Stats::Record.save_average(metric,finish - start)
17
19
  [status, headers, body]
18
20
  else
19
21
  status, headers, body = @app.call(env)
@@ -0,0 +1,58 @@
1
+ require "cgi"
2
+ require 'rhoconnect/middleware/helpers'
3
+
4
+ module Rhoconnect
5
+ module Middleware
6
+ class XDomainSessionWrapper
7
+ def initialize(app, opts={})
8
+ @app = app
9
+ @session_cookie = opts[:session_cookie] || 'rhoconnect_session'
10
+ @api_uri_regexp = opts[:api_uri_regexp] || /\A\/api\/application/
11
+ @login_uri_regexp = opts[:login_uri_regexp] || /\A\/api\/application\/clientlogin/
12
+ yield self if block_given?
13
+ end
14
+
15
+ def is_sync_protocol(env)
16
+ # if it is rhoconnect protocol URI
17
+ @api_uri_regexp.match(env['PATH_INFO'])
18
+ end
19
+
20
+ def call(env)
21
+ if is_sync_protocol(env)
22
+ env['HTTP_COOKIE'] = env['HTTP_COOKIE'] || CGI.unescape(get_session_from_url(env))
23
+ end
24
+
25
+ status, headers, body = @app.call(env)
26
+
27
+ if is_sync_protocol(env)
28
+ cookies = headers['Set-Cookie'].to_s
29
+ #puts "<----- Cookies: #{cookies}"
30
+ # put cookies to body as JSON on login success
31
+ if @login_uri_regexp.match(env['PATH_INFO']) && status == 200
32
+ body = session_json_from(cookies)
33
+ headers['Content-Length'] = body.length.to_s
34
+ end
35
+ end
36
+
37
+ # The Body itself should not be an instance of String,as this will break in Ruby 1.9
38
+ body = ["#{body}"] if body.is_a?(String)
39
+ [status, headers, body]
40
+ end
41
+
42
+ def session_json_from(cookies)
43
+ rexp = Regexp.new(@session_cookie +'=[^\s]*')
44
+ sc = cookies.to_s.slice rexp
45
+ "{\"" +@session_cookie +"\": \"#{CGI.escape sc.to_s}\"}"
46
+ end
47
+
48
+ def get_session_from_url(env)
49
+ rexp = Regexp.new(@session_cookie +'=.*\Z')
50
+ qs = env['QUERY_STRING'].to_s.slice rexp
51
+ qs = qs.to_s.split(/&/)[0]
52
+ nv = qs.to_s.split(/=/)
53
+ return nv[1] if nv.length > 1
54
+ ''
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,3 +1,4 @@
1
1
  require 'rhoconnect/ping/android'
2
2
  require 'rhoconnect/ping/apple'
3
3
  require 'rhoconnect/ping/blackberry'
4
+ require 'rhoconnect/ping/rhoconnect_push'
@@ -8,24 +8,26 @@ module Rhoconnect
8
8
  cert = File.read(cert_file) if File.exists?(cert_file)
9
9
  passphrase = settings[:iphonepassphrase]
10
10
  host = settings[:iphoneserver]
11
- port = settings[:iphoneport]
12
- begin
13
- ssl_ctx = OpenSSL::SSL::SSLContext.new
14
- ssl_ctx.key = OpenSSL::PKey::RSA.new(cert, passphrase)
15
- ssl_ctx.cert = OpenSSL::X509::Certificate.new(cert)
11
+ port = settings[:iphoneport]
12
+ if(cert and host and port)
13
+ begin
14
+ ssl_ctx = OpenSSL::SSL::SSLContext.new
15
+ ssl_ctx.key = OpenSSL::PKey::RSA.new(cert, passphrase)
16
+ ssl_ctx.cert = OpenSSL::X509::Certificate.new(cert)
16
17
 
17
- socket = TCPSocket.new(host, port)
18
- ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_ctx)
19
- ssl_socket.sync = true
20
- ssl_socket.connect
18
+ socket = TCPSocket.new(host, port)
19
+ ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_ctx)
20
+ ssl_socket.sync = true
21
+ ssl_socket.connect
21
22
 
22
- ssl_socket.write(apn_message(params))
23
- ssl_socket.close
24
- socket.close
25
- rescue SocketError => error
26
- log "Error while sending ping: #{error}"
27
- raise error
28
- end
23
+ ssl_socket.write(apn_message(params))
24
+ ssl_socket.close
25
+ socket.close
26
+ rescue SocketError => error
27
+ log "Error while sending ping: #{error}"
28
+ raise error
29
+ end
30
+ end
29
31
  end
30
32
 
31
33
  # Generates APNS package