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.
- data/CHANGELOG.md +24 -5
- data/Gemfile +2 -2
- data/Gemfile.lock +20 -20
- data/bench/benchapp/Gemfile +17 -20
- data/bench/benchapp/config.ru +2 -2
- data/bench/benchapp/settings/settings.yml +3 -3
- data/bench/blobapp/Gemfile +16 -13
- data/bench/blobapp/config.ru +2 -2
- data/bench/blobapp/settings/settings.yml +5 -3
- data/bench/lib/bench.rb +35 -32
- data/bench/lib/bench/session.rb +9 -1
- data/bench/scripts/blob_cud_script.rb +13 -17
- data/bench/scripts/cud_script.rb +11 -12
- data/bench/scripts/helpers.rb +5 -7
- data/bench/scripts/query_md_script.rb +18 -12
- data/bench/scripts/query_only_script.rb +19 -11
- data/bench/scripts/query_script.rb +17 -13
- data/bench/scripts/test_query_script.rb +46 -17
- data/bench/scripts/test_source_script.rb +7 -7
- data/commands/commands/dtach_commands/dtach_install.rb +44 -16
- data/commands/commands/rhoconnect/spec.rb +13 -9
- data/commands/commands/rhoconnect/version.rb +6 -0
- data/commands/execute.rb +10 -6
- data/doc/deploying.txt +75 -13
- data/doc/install.txt +3 -3
- data/doc/push-client-setup.txt +1 -1
- data/doc/rest-api.txt +4 -23
- data/doc/rhoconnect-redis-stack.txt +26 -7
- data/doc/settings.txt +9 -3
- data/examples/simple/Gemfile +3 -1
- data/examples/simple/application.rb +5 -0
- data/examples/simple/config.ru +3 -2
- data/examples/simple/my_server.rb +14 -0
- data/examples/simple/settings/settings.yml +1 -0
- data/generators/templates/application/Gemfile +4 -4
- data/generators/templates/application/application.rb +4 -0
- data/generators/templates/application/settings/settings.yml +4 -1
- data/installer/unix-like/create_texts.rb +39 -1
- data/installer/unix-like/rho_connect_install_constants.rb +1 -1
- data/installer/utils/package_upload/repos.rake +7 -5
- data/lib/rhoconnect.rb +3 -2
- data/lib/rhoconnect/api/app/ans_login.rb +3 -0
- data/lib/rhoconnect/api/app/bulk_data.rb +6 -0
- data/lib/rhoconnect/api/{source → app}/fast_delete.rb +1 -1
- data/lib/rhoconnect/api/{source → app}/fast_insert.rb +2 -2
- data/lib/rhoconnect/api/{source → app}/fast_update.rb +2 -2
- data/lib/rhoconnect/api/app/login.rb +5 -0
- data/lib/rhoconnect/api/{source → app}/push_deletes.rb +1 -1
- data/lib/rhoconnect/api/{source → app}/push_objects.rb +1 -1
- data/lib/rhoconnect/api/app/query.rb +4 -0
- data/lib/rhoconnect/api/app/queue_updates.rb +94 -0
- data/lib/rhoconnect/api/app/search.rb +4 -0
- data/lib/rhoconnect/api/client/client_get_db_doc.rb +5 -0
- data/lib/rhoconnect/api/client/client_set_db_doc.rb +8 -0
- data/lib/rhoconnect/api/client/create.rb +7 -0
- data/lib/rhoconnect/api/client/get_client_params.rb +2 -1
- data/lib/rhoconnect/api/client/list_client_docs.rb +2 -1
- data/lib/rhoconnect/api/client/register.rb +12 -0
- data/lib/rhoconnect/api/client/reset.rb +5 -0
- data/lib/rhoconnect/api/{source → readstate}/set_refresh_time.rb +2 -1
- data/lib/rhoconnect/api/source/get_source_params.rb +3 -2
- data/lib/rhoconnect/api/source/list_sources.rb +2 -1
- data/lib/rhoconnect/api/source/update_source_params.rb +3 -3
- data/lib/rhoconnect/api/store/get_db_doc.rb +4 -0
- data/lib/rhoconnect/api/store/set_db_doc.rb +7 -0
- data/lib/rhoconnect/api/system/get_adapter.rb +4 -0
- data/lib/rhoconnect/api/{admin → system}/get_license_info.rb +2 -1
- data/lib/rhoconnect/api/system/login.rb +15 -0
- data/lib/rhoconnect/api/{admin → system}/reset.rb +3 -2
- data/lib/rhoconnect/api/system/save_adapter.rb +4 -0
- data/lib/rhoconnect/api/{admin → system}/stats.rb +2 -1
- data/lib/rhoconnect/api/user/create_user.rb +2 -2
- data/lib/rhoconnect/api/user/delete_client.rb +6 -0
- data/lib/rhoconnect/api/user/delete_user.rb +2 -1
- data/lib/rhoconnect/api/user/list_clients.rb +4 -0
- data/lib/rhoconnect/api/user/list_source_docs.rb +11 -0
- data/lib/rhoconnect/api/user/list_users.rb +1 -1
- data/lib/rhoconnect/api/user/ping.rb +7 -0
- data/lib/rhoconnect/api/user/show_user.rb +3 -0
- data/lib/rhoconnect/api/user/update_user.rb +3 -2
- data/lib/rhoconnect/api/user/user_get_db_doc.rb +5 -0
- data/lib/rhoconnect/api/user/user_set_db_doc.rb +10 -0
- data/lib/rhoconnect/app.rb +12 -2
- data/lib/rhoconnect/async.rb +6 -10
- data/lib/rhoconnect/bulk_data/bulk_data.rb +4 -4
- data/lib/rhoconnect/client.rb +10 -9
- data/lib/rhoconnect/client_sync.rb +24 -19
- data/lib/rhoconnect/document.rb +18 -4
- data/lib/rhoconnect/graph_helper.rb +4 -2
- data/lib/rhoconnect/jobs/bulk_data_job.rb +1 -1
- data/lib/rhoconnect/jobs/ping_job.rb +39 -29
- data/lib/rhoconnect/middleware/admin_user.rb +23 -0
- data/lib/rhoconnect/middleware/body_content_type_parser.rb +35 -0
- data/lib/rhoconnect/{cors.rb → middleware/cors.rb} +1 -0
- data/lib/rhoconnect/middleware/current_app.rb +16 -0
- data/lib/rhoconnect/middleware/current_request.rb +16 -0
- data/lib/rhoconnect/middleware/current_user.rb +17 -0
- data/lib/rhoconnect/middleware/helpers.rb +105 -0
- data/lib/rhoconnect/middleware/login_required.rb +22 -0
- data/lib/rhoconnect/{stats/middleware.rb → middleware/stats.rb} +5 -3
- data/lib/rhoconnect/middleware/x_domain_session_wrapper.rb +58 -0
- data/lib/rhoconnect/ping.rb +1 -0
- data/lib/rhoconnect/ping/apple.rb +18 -16
- data/lib/rhoconnect/ping/blackberry.rb +9 -9
- data/lib/rhoconnect/ping/rhoconnect_push.rb +45 -0
- data/lib/rhoconnect/server.rb +98 -91
- data/lib/rhoconnect/source.rb +5 -1
- data/lib/rhoconnect/source_sync.rb +4 -3
- data/lib/rhoconnect/stats/record.rb +15 -15
- data/lib/rhoconnect/store.rb +253 -75
- data/lib/rhoconnect/tasks.rb +3 -3
- data/lib/rhoconnect/version.rb +1 -1
- data/lib/rhoconnect/web-console/controllers/admins.js +1 -14
- data/lib/rhoconnect/web-console/models/adapter.js +18 -8
- data/lib/rhoconnect/web-console/models/client.js +15 -9
- data/lib/rhoconnect/web-console/models/doc.js +7 -11
- data/lib/rhoconnect/web-console/models/session.js +5 -2
- data/lib/rhoconnect/web-console/models/source.js +55 -36
- data/lib/rhoconnect/web-console/models/user.js +20 -11
- data/lib/rhoconnect/web-console/public/backbone.js +8 -2
- data/lib/rhoconnect/web-console/templates/index.erb +11 -5
- data/lib/rhoconnect/web-console/views/doc.js +6 -8
- data/lib/rhoconnect/web-console/views/edit_user.js +6 -3
- data/lib/rhoconnect/web-console/views/home.js +98 -25
- data/lib/rhoconnect/web-console/views/index.js +1 -1
- data/lib/rhoconnect/web-console/views/new_ping.js +6 -3
- data/lib/rhoconnect/web-console/views/server_doc.js +12 -4
- data/lib/rhoconnect/web-console/views/show_device.js +6 -3
- data/rhoconnect.gemspec +1 -2
- data/spec/api/{source → app}/fast_delete_spec.rb +4 -4
- data/spec/api/{source → app}/fast_insert_spec.rb +4 -4
- data/spec/api/{source → app}/fast_update_spec.rb +22 -6
- data/spec/api/{source → app}/push_deletes_spec.rb +2 -2
- data/spec/api/app/push_objects_spec.rb +45 -0
- data/spec/api/client/client_get_db_doc_spec.rb +31 -0
- data/spec/api/client/client_set_db_doc_spec.rb +14 -0
- data/spec/api/client/get_client_params_spec.rb +3 -2
- data/spec/api/client/list_client_docs_spec.rb +2 -2
- data/spec/api/{source → readstate}/set_refresh_time_spec.rb +15 -9
- data/spec/api/source/get_source_params_spec.rb +3 -2
- data/spec/api/source/list_sources_spec.rb +3 -9
- data/spec/api/source/update_source_params_spec.rb +4 -4
- data/spec/api/store/get_db_doc_spec.rb +32 -0
- data/spec/api/store/set_db_doc_spec.rb +43 -0
- data/spec/api/system/adapter_spec.rb +33 -0
- data/spec/api/{admin → system}/get_license_info_spec.rb +2 -5
- data/spec/api/{admin/get_api_token_spec.rb → system/login_spec.rb} +4 -11
- data/spec/api/{admin → system}/reset_spec.rb +2 -2
- data/spec/api/{admin → system}/stats_spec.rb +19 -13
- data/spec/api/user/create_user_spec.rb +15 -8
- data/spec/api/{client → user}/delete_client_spec.rb +3 -4
- data/spec/api/user/delete_user_spec.rb +33 -4
- data/spec/api/user/list_clients_spec.rb +30 -0
- data/spec/api/user/list_source_docs_spec.rb +35 -0
- data/spec/api/user/list_users_spec.rb +5 -6
- data/spec/api/{client → user}/ping_spec.rb +4 -6
- data/spec/api/user/show_user_spec.rb +14 -0
- data/spec/api/user/update_user_spec.rb +28 -10
- data/spec/api/user/user_get_db_doc_spec.rb +16 -0
- data/spec/api/user/user_set_db_doc_spec.rb +41 -0
- data/spec/apps/rhotestapp/application.rb +4 -0
- data/spec/apps/rhotestapp/settings/settings.yml +3 -1
- data/spec/bulk_data/bulk_data_spec.rb +13 -0
- data/spec/client_sync_spec.rb +41 -59
- data/spec/document_spec.rb +23 -0
- data/spec/javascripts/doc_view_spec.js +1 -1
- data/spec/javascripts/home_view_spec.js +10 -5
- data/spec/javascripts/index_view_spec.js +1 -1
- data/spec/jobs/ping_job_spec.rb +26 -0
- data/spec/perf/store_perf_spec.rb +1 -1
- data/spec/ping/android_spec.rb +0 -7
- data/spec/ping/apple_spec.rb +7 -0
- data/spec/ping/blackberry_spec.rb +10 -0
- data/spec/ping/rhoconnect_push_spec.rb +58 -0
- data/spec/server/cors_spec.rb +1 -1
- data/spec/server/server_spec.rb +152 -104
- data/spec/{stats/middleware_spec.rb → server/stats_spec.rb} +4 -5
- data/spec/server/x_domain_session_wrapper_spec.rb +3 -3
- data/spec/source_spec.rb +2 -2
- data/spec/source_sync_spec.rb +2 -0
- data/spec/spec_helper.rb +17 -3
- data/spec/stats/record_spec.rb +18 -19
- data/spec/store_spec.rb +51 -26
- data/spec/support/shared_examples.rb +4 -0
- data/spec/sync_states_spec.rb +2 -2
- metadata +104 -88
- data/bench/benchapp/Gemfile.lock +0 -87
- data/bench/blobapp/Gemfile.lock +0 -107
- data/bench/lib/testdata/5-data.txt +0 -8
- data/doc/release.txt +0 -41
- data/lib/rhoconnect/api/admin/get_api_token.rb +0 -14
- data/lib/rhoconnect/api/admin/login.rb +0 -6
- data/lib/rhoconnect/api/application/bulk_data.rb +0 -7
- data/lib/rhoconnect/api/application/clientcreate.rb +0 -8
- data/lib/rhoconnect/api/application/clientlogin.rb +0 -6
- data/lib/rhoconnect/api/application/clientregister.rb +0 -13
- data/lib/rhoconnect/api/application/clientreset.rb +0 -6
- data/lib/rhoconnect/api/application/query.rb +0 -7
- data/lib/rhoconnect/api/application/queue_updates.rb +0 -20
- data/lib/rhoconnect/api/application/search.rb +0 -6
- data/lib/rhoconnect/api/client/create_client.rb +0 -3
- data/lib/rhoconnect/api/client/delete_client.rb +0 -5
- data/lib/rhoconnect/api/client/list_clients.rb +0 -3
- data/lib/rhoconnect/api/client/ping.rb +0 -7
- data/lib/rhoconnect/api/source/get_adapter.rb +0 -3
- data/lib/rhoconnect/api/source/get_db_doc.rb +0 -7
- data/lib/rhoconnect/api/source/list_source_docs.rb +0 -10
- data/lib/rhoconnect/api/source/save_adapter.rb +0 -3
- data/lib/rhoconnect/api/source/set_db_doc.rb +0 -10
- data/lib/rhoconnect/api/source/upload_file.rb +0 -4
- data/lib/rhoconnect/body_content_type_parser.rb +0 -32
- data/lib/rhoconnect/x_domain_session_wrapper.rb +0 -53
- data/spec/api/admin/api_token_spec.rb +0 -13
- data/spec/api/client/create_client_spec.rb +0 -13
- data/spec/api/client/list_clients_spec.rb +0 -22
- data/spec/api/source/adapter_spec.rb +0 -29
- data/spec/api/source/get_db_doc_spec.rb +0 -21
- data/spec/api/source/list_source_docs_spec.rb +0 -25
- data/spec/api/source/push_objects_spec.rb +0 -27
- data/spec/api/source/set_db_doc_spec.rb +0 -32
- 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.
|
|
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
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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 "
|
|
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
|
|
@@ -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
|
|
3
|
-
class
|
|
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
|
data/lib/rhoconnect/ping.rb
CHANGED
|
@@ -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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|