rhoconnect 3.2.1 → 3.3.1.beta2

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.
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