rhoconnect 5.1.1 → 5.5.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -8
- data/CREDITS +100 -100
- data/Gemfile +0 -2
- data/Gemfile.lock +56 -71
- data/LICENSE +5 -72
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/bench/bench +0 -0
- data/bench/benchapp/settings/settings.yml +0 -3
- data/bench/blobapp/settings/settings.yml +0 -3
- data/bench/distr_bench/distr_bench +0 -0
- data/bench/distr_bench/distr_bench_main +0 -0
- data/bench/distr_bench/run_distr_client.sh +0 -0
- data/bench/distr_bench/run_test_query_script.sh +0 -0
- data/bench/lib/bench/bench_result_processor.rb +0 -0
- data/bench/lib/bench.rb +0 -8
- data/bench/lib/testdata/images/icon.ico +0 -0
- data/bench/lib/testdata/images/icon.png +0 -0
- data/bench/lib/testdata/images/loading-Landscape.png +0 -0
- data/bench/lib/testdata/images/loading-LandscapeLeft.png +0 -0
- data/bench/lib/testdata/images/loading-LandscapeRight.png +0 -0
- data/bench/lib/testdata/images/loading-Portrait.png +0 -0
- data/bench/lib/testdata/images/loading-PortraitUpsideDown.png +0 -0
- data/bench/lib/testdata/images/loading.png +0 -0
- data/bench/lib/testdata/images/loading@2x.png +0 -0
- data/bench/prepare_bench +0 -0
- data/bench/run_bench.sh +0 -0
- data/bench/run_blob_script.sh +0 -0
- data/bench/run_cud_script.sh +0 -0
- data/bench/run_query_md_script.sh +0 -0
- data/bench/run_query_only_script.sh +0 -0
- data/bench/run_query_script.sh +0 -0
- data/bench/run_test_query_script.sh +0 -0
- data/bench/run_test_source_script.sh +0 -0
- data/bin/rhoconnect-benchmark +0 -22
- data/commands/rhoconnect/restart.rb +0 -1
- data/commands/rhoconnect/start.rb +2 -14
- data/doc/adapters-crm.txt +1 -1
- data/doc/benchmarks-running.txt +1 -1
- data/doc/benchmarks.txt +0 -1
- data/doc/bulk-sync.txt +0 -1
- data/doc/command-line.txt +0 -6
- data/doc/java-plugin.txt +0 -6
- data/doc/preparing-production.txt +1 -7
- data/doc/public/cli.txt +0 -2
- data/doc/public/css/print.css +0 -0
- data/doc/public/css/screen.css +0 -0
- data/doc/public/css/style.css +0 -0
- data/doc/push-client-setup-android.txt +0 -1
- data/doc/push-client-setup-ios.txt +0 -1
- data/doc/push-client-setup-rps.txt +3 -3
- data/doc/push-server-setup.txt +1 -4
- data/doc/rails-plugin.txt +0 -5
- data/doc/rest-api.txt +2 -14
- data/doc/rhoconnect-redis-stack.txt +0 -1
- data/doc/settings.txt +0 -3
- data/doc/supported-platforms.txt +0 -1
- data/doc/tutorial.txt +0 -2
- data/examples/simple/config.ru +0 -0
- data/examples/simple/settings/settings.yml +1 -4
- data/generators/rhoconnect.rb +0 -1
- data/generators/templates/application/config.ru +0 -0
- data/generators/templates/application/rcgemfile +1 -0
- data/generators/templates/application/settings/settings.yml +0 -3
- data/install.sh +0 -0
- data/installer/utils/create_sha1.rb +0 -0
- data/installer/utils/delete_from_s3.rb +0 -0
- data/installer/utils/download_from_s3.rb +0 -0
- data/installer/utils/nix_install_test.rb +0 -0
- data/installer/utils/package_upload/repos.rake +2 -2
- data/installer/utils/package_upload/s3_single_file.rb +0 -0
- data/installer/utils/package_upload/s3_upload.rb +0 -0
- data/installer/utils/verify_checksum.rb +0 -0
- data/lib/rhoconnect/api_token.rb +0 -0
- data/lib/rhoconnect/app.rb +0 -0
- data/lib/rhoconnect/bulk_data/bulk_data.rb +0 -0
- data/lib/rhoconnect/bulk_data/syncdb.index.schema +0 -0
- data/lib/rhoconnect/bulk_data/syncdb.schema +0 -0
- data/lib/rhoconnect/bulk_data.rb +0 -0
- data/lib/rhoconnect/client.rb +0 -2
- data/lib/rhoconnect/controller/system_controller.rb +0 -9
- data/lib/rhoconnect/credential.rb +0 -0
- data/lib/rhoconnect/document.rb +0 -0
- data/lib/rhoconnect/middleware/cors.rb +209 -209
- data/lib/rhoconnect/middleware/x_domain_session_wrapper.rb +57 -57
- data/lib/rhoconnect/model/base.rb +0 -0
- data/lib/rhoconnect/read_state.rb +0 -0
- data/lib/rhoconnect/rho_indifferent_access.rb +0 -0
- data/lib/rhoconnect/server.rb +0 -0
- data/lib/rhoconnect/source.rb +0 -0
- data/lib/rhoconnect/store.rb +2 -0
- data/lib/rhoconnect/store_orm.rb +0 -0
- data/lib/rhoconnect/user.rb +0 -0
- data/lib/rhoconnect/version.rb +1 -1
- data/lib/rhoconnect/web-console/models/doc.js +0 -13
- data/lib/rhoconnect/web-console/models/source.js +0 -31
- data/lib/rhoconnect/web-console/public/logo.png +0 -0
- data/lib/rhoconnect/web-console/server.rb +0 -0
- data/lib/rhoconnect/web-console/templates/index.erb +1 -2
- data/lib/rhoconnect/web-console/views/home.js +4 -6
- data/lib/rhoconnect.rb +1 -3
- data/spec/api/api_helper.rb +0 -0
- data/spec/api/system/login_spec.rb +0 -0
- data/spec/api/system/reset_spec.rb +0 -0
- data/spec/api/user/create_user_spec.rb +0 -0
- data/spec/api/user/update_user_spec.rb +0 -0
- data/spec/api_token_spec.rb +0 -0
- data/spec/app_spec.rb +0 -0
- data/spec/apps/emptyapp/settings/settings.yml +1 -4
- data/spec/apps/jstestapp/settings/settings.yml +0 -3
- data/spec/apps/rhotestapp/controllers/ruby/application_controller.rb +0 -0
- data/spec/apps/rhotestapp/models/ruby/sample_adapter.rb +0 -0
- data/spec/apps/rhotestapp/models/ruby/simple_adapter.rb +0 -0
- data/spec/apps/rhotestapp/settings/settings.yml +0 -3
- data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem/mygem.rb +0 -0
- data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem.rb +0 -0
- data/spec/bulk_data/bulk_data_spec.rb +0 -0
- data/spec/client_spec.rb +0 -14
- data/spec/client_sync_spec.rb +0 -0
- data/spec/doc/base.html +0 -0
- data/spec/doc/doc_spec.rb +0 -0
- data/spec/doc/footer.html +0 -0
- data/spec/doc/header.html +0 -0
- data/spec/document_spec.rb +0 -0
- data/spec/generator/generator_spec.rb +1 -3
- data/spec/jobs/bulk_data_job_spec.rb +0 -0
- data/spec/perf/bulk_data_perf_spec.rb +0 -0
- data/spec/perf/perf_spec_helper.rb +0 -0
- data/spec/perf/store_perf_spec.rb +0 -0
- data/spec/read_state_spec.rb +0 -0
- data/spec/server/cors_spec.rb +283 -283
- data/spec/server/server_spec.rb +0 -15
- data/spec/server/x_domain_session_wrapper_spec.rb +150 -150
- data/spec/source_adapter_spec.rb +0 -0
- data/spec/source_spec.rb +0 -0
- data/spec/source_sync_spec.rb +0 -0
- data/spec/spec_helper.rb +0 -0
- data/spec/store_orm_spec.rb +0 -0
- data/spec/store_spec.rb +0 -0
- data/spec/sync_states_spec.rb +0 -0
- data/spec/testdata/1000-data.txt +0 -0
- data/spec/testdata/compressed/compress-data.txt +0 -0
- data/spec/user_spec.rb +0 -9
- metadata +116 -132
- data/bench/benchapp/settings/license.key +0 -1
- data/bench/blobapp/settings/license.key +0 -1
- data/doc/licensing.txt +0 -18
- data/examples/simple/settings/license.key +0 -1
- data/generators/templates/application/settings/license.key +0 -1
- data/lib/rhoconnect/license.rb +0 -94
- data/spec/api/system/get_license_info_spec.rb +0 -15
- data/spec/apps/emptyapp/settings/license.key +0 -1
- data/spec/apps/jstestapp/settings/license.key +0 -1
- data/spec/apps/rhotestapp/settings/license.key +0 -1
- data/spec/license_spec.rb +0 -67
|
@@ -1,209 +1,209 @@
|
|
|
1
|
-
require 'logger'
|
|
2
|
-
require 'rhoconnect/middleware/helpers'
|
|
3
|
-
|
|
4
|
-
module Rack
|
|
5
|
-
class Cors
|
|
6
|
-
def initialize(app, opts={})
|
|
7
|
-
@app = app
|
|
8
|
-
@logger = opts[:logger]
|
|
9
|
-
yield self if block_given?
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def allow
|
|
13
|
-
all_resources << (resources = Resources.new)
|
|
14
|
-
yield resources
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def call(env)
|
|
18
|
-
if env['HTTP_ORIGIN'] == 'null'
|
|
19
|
-
env['HTTP_ORIGIN'] = 'file://'
|
|
20
|
-
end
|
|
21
|
-
if env['HTTP_X_ORIGIN'] and not env['HTTP_ORIGIN']
|
|
22
|
-
log 'ORIGIN header is empty, X-ORIGIN workaround header applied.'
|
|
23
|
-
env['HTTP_ORIGIN'] = env['HTTP_X_ORIGIN']
|
|
24
|
-
end
|
|
25
|
-
cors_headers = nil
|
|
26
|
-
if env['HTTP_ORIGIN']
|
|
27
|
-
if env['REQUEST_METHOD'] == 'OPTIONS'
|
|
28
|
-
if headers = process_preflight(env)
|
|
29
|
-
return [200, headers, ['']]
|
|
30
|
-
end
|
|
31
|
-
else
|
|
32
|
-
cors_headers = process_cors(env)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
status, headers, body = @app.call env
|
|
36
|
-
headers = headers.merge(cors_headers) if cors_headers
|
|
37
|
-
[status, headers, body]
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
protected
|
|
41
|
-
def all_resources
|
|
42
|
-
@all_resources ||= []
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def process_preflight(env)
|
|
46
|
-
resource = find_resource(env['HTTP_ORIGIN'], env['PATH_INFO'])
|
|
47
|
-
resource && resource.process_preflight(env)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def process_cors(env)
|
|
51
|
-
resource = find_resource(env['HTTP_ORIGIN'], env['PATH_INFO'])
|
|
52
|
-
resource.to_headers(env) if resource
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def find_resource(origin, path)
|
|
56
|
-
allowed = all_resources.detect {|r| r.allow_origin?(origin)}
|
|
57
|
-
allowed ? allowed.find_resource(path) : nil
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
class Resources
|
|
61
|
-
|
|
62
|
-
def initialize
|
|
63
|
-
@origins = []
|
|
64
|
-
@resources = []
|
|
65
|
-
@public_resources = false
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def origins(*args)
|
|
69
|
-
@origins = args.flatten.collect do |n|
|
|
70
|
-
if n.class == Regexp
|
|
71
|
-
n
|
|
72
|
-
else
|
|
73
|
-
case n
|
|
74
|
-
when /^[a-z]+:\/\// then n
|
|
75
|
-
when '*'
|
|
76
|
-
@public_resources = true
|
|
77
|
-
n
|
|
78
|
-
else
|
|
79
|
-
"http://#{n}"
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def resource(path, opts={})
|
|
86
|
-
@resources << Resource.new(public_resources?, path, opts)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def public_resources?
|
|
90
|
-
@public_resources
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def allow_origin?(source)
|
|
94
|
-
result = public_resources? || @origins.include?(source) ||
|
|
95
|
-
(not (@origins.select {|n| n.class == Regexp && n.match(source)}).empty?)
|
|
96
|
-
#TODO: to fix "n.match(source)". Unsure, but it may lead to security risks.
|
|
97
|
-
result
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def find_resource(path)
|
|
101
|
-
@resources.detect{|r| r.match?(path)}
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
class Resource
|
|
106
|
-
attr_accessor :path, :methods, :headers, :expose, :max_age, :credentials, :pattern
|
|
107
|
-
|
|
108
|
-
def initialize(public_resource, path, opts={})
|
|
109
|
-
self.path = path
|
|
110
|
-
self.methods = ensure_enum(opts[:methods]) || [:get]
|
|
111
|
-
self.credentials = opts[:credentials] || true
|
|
112
|
-
self.max_age = opts[:max_age] || 1728000
|
|
113
|
-
self.pattern = compile(path)
|
|
114
|
-
@public_resource = public_resource
|
|
115
|
-
|
|
116
|
-
self.headers = case opts[:headers]
|
|
117
|
-
when :any then :any
|
|
118
|
-
when nil then nil
|
|
119
|
-
else
|
|
120
|
-
[opts[:headers]].flatten.collect{|h| h.downcase}
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
self.expose = case opts[:expose]
|
|
124
|
-
when nil then nil
|
|
125
|
-
else
|
|
126
|
-
[opts[:expose]].flatten
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def match?(path)
|
|
131
|
-
pattern =~ path
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def process_preflight(env)
|
|
135
|
-
return nil if invalid_method_request?(env) || invalid_headers_request?(env)
|
|
136
|
-
{'Content-Type' => 'text/plain'}.merge(to_preflight_headers(env))
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def to_headers(env)
|
|
140
|
-
x_origin = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
|
|
141
|
-
h = { 'Access-Control-Allow-Origin' => public_resource? ? '*' : env['HTTP_ORIGIN'],
|
|
142
|
-
'Access-Control-Allow-Methods' => methods.collect{|m| m.to_s.upcase}.join(', '),
|
|
143
|
-
'Access-Control-Expose-Headers' => expose.nil? ? '' : expose.join(', '),
|
|
144
|
-
'Access-Control-Max-Age' => max_age.to_s }
|
|
145
|
-
h['Access-Control-Allow-Credentials'] = 'true' if credentials
|
|
146
|
-
h
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
protected
|
|
150
|
-
def public_resource?
|
|
151
|
-
@public_resource
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def to_preflight_headers(env)
|
|
155
|
-
h = to_headers(env)
|
|
156
|
-
if env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
|
|
157
|
-
h.merge!('Access-Control-Allow-Headers' => env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])
|
|
158
|
-
end
|
|
159
|
-
h
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def invalid_method_request?(env)
|
|
163
|
-
request_method = env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']
|
|
164
|
-
request_method.nil? || !methods.include?(request_method.downcase.to_sym)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def invalid_headers_request?(env)
|
|
168
|
-
request_headers = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
|
|
169
|
-
request_headers && !allow_headers?(request_headers)
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def allow_headers?(request_headers)
|
|
173
|
-
return false if headers.nil?
|
|
174
|
-
headers == :any || begin
|
|
175
|
-
request_headers = request_headers.split(/,\s*/) if request_headers.kind_of?(String)
|
|
176
|
-
request_headers.all?{|h| headers.include?(h.downcase)}
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def ensure_enum(v)
|
|
181
|
-
return nil if v.nil?
|
|
182
|
-
[v].flatten
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def compile(path)
|
|
186
|
-
if path.respond_to? :to_str
|
|
187
|
-
special_chars = %w{. + ( )}
|
|
188
|
-
pattern =
|
|
189
|
-
path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
|
|
190
|
-
case match
|
|
191
|
-
when "*"
|
|
192
|
-
"(.*?)"
|
|
193
|
-
when *special_chars
|
|
194
|
-
Regexp.escape(match)
|
|
195
|
-
else
|
|
196
|
-
"([^/?&#]+)"
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
/^#{pattern}$/
|
|
200
|
-
elsif path.respond_to? :match
|
|
201
|
-
path
|
|
202
|
-
else
|
|
203
|
-
raise TypeError, path
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
end
|
|
209
|
-
end
|
|
1
|
+
require 'logger'
|
|
2
|
+
require 'rhoconnect/middleware/helpers'
|
|
3
|
+
|
|
4
|
+
module Rack
|
|
5
|
+
class Cors
|
|
6
|
+
def initialize(app, opts={})
|
|
7
|
+
@app = app
|
|
8
|
+
@logger = opts[:logger]
|
|
9
|
+
yield self if block_given?
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def allow
|
|
13
|
+
all_resources << (resources = Resources.new)
|
|
14
|
+
yield resources
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call(env)
|
|
18
|
+
if env['HTTP_ORIGIN'] == 'null'
|
|
19
|
+
env['HTTP_ORIGIN'] = 'file://'
|
|
20
|
+
end
|
|
21
|
+
if env['HTTP_X_ORIGIN'] and not env['HTTP_ORIGIN']
|
|
22
|
+
log 'ORIGIN header is empty, X-ORIGIN workaround header applied.'
|
|
23
|
+
env['HTTP_ORIGIN'] = env['HTTP_X_ORIGIN']
|
|
24
|
+
end
|
|
25
|
+
cors_headers = nil
|
|
26
|
+
if env['HTTP_ORIGIN']
|
|
27
|
+
if env['REQUEST_METHOD'] == 'OPTIONS'
|
|
28
|
+
if headers = process_preflight(env)
|
|
29
|
+
return [200, headers, ['']]
|
|
30
|
+
end
|
|
31
|
+
else
|
|
32
|
+
cors_headers = process_cors(env)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
status, headers, body = @app.call env
|
|
36
|
+
headers = headers.merge(cors_headers) if cors_headers
|
|
37
|
+
[status, headers, body]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
protected
|
|
41
|
+
def all_resources
|
|
42
|
+
@all_resources ||= []
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def process_preflight(env)
|
|
46
|
+
resource = find_resource(env['HTTP_ORIGIN'], env['PATH_INFO'])
|
|
47
|
+
resource && resource.process_preflight(env)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def process_cors(env)
|
|
51
|
+
resource = find_resource(env['HTTP_ORIGIN'], env['PATH_INFO'])
|
|
52
|
+
resource.to_headers(env) if resource
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def find_resource(origin, path)
|
|
56
|
+
allowed = all_resources.detect {|r| r.allow_origin?(origin)}
|
|
57
|
+
allowed ? allowed.find_resource(path) : nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Resources
|
|
61
|
+
|
|
62
|
+
def initialize
|
|
63
|
+
@origins = []
|
|
64
|
+
@resources = []
|
|
65
|
+
@public_resources = false
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def origins(*args)
|
|
69
|
+
@origins = args.flatten.collect do |n|
|
|
70
|
+
if n.class == Regexp
|
|
71
|
+
n
|
|
72
|
+
else
|
|
73
|
+
case n
|
|
74
|
+
when /^[a-z]+:\/\// then n
|
|
75
|
+
when '*'
|
|
76
|
+
@public_resources = true
|
|
77
|
+
n
|
|
78
|
+
else
|
|
79
|
+
"http://#{n}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def resource(path, opts={})
|
|
86
|
+
@resources << Resource.new(public_resources?, path, opts)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def public_resources?
|
|
90
|
+
@public_resources
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def allow_origin?(source)
|
|
94
|
+
result = public_resources? || @origins.include?(source) ||
|
|
95
|
+
(not (@origins.select {|n| n.class == Regexp && n.match(source)}).empty?)
|
|
96
|
+
#TODO: to fix "n.match(source)". Unsure, but it may lead to security risks.
|
|
97
|
+
result
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def find_resource(path)
|
|
101
|
+
@resources.detect{|r| r.match?(path)}
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
class Resource
|
|
106
|
+
attr_accessor :path, :methods, :headers, :expose, :max_age, :credentials, :pattern
|
|
107
|
+
|
|
108
|
+
def initialize(public_resource, path, opts={})
|
|
109
|
+
self.path = path
|
|
110
|
+
self.methods = ensure_enum(opts[:methods]) || [:get]
|
|
111
|
+
self.credentials = opts[:credentials] || true
|
|
112
|
+
self.max_age = opts[:max_age] || 1728000
|
|
113
|
+
self.pattern = compile(path)
|
|
114
|
+
@public_resource = public_resource
|
|
115
|
+
|
|
116
|
+
self.headers = case opts[:headers]
|
|
117
|
+
when :any then :any
|
|
118
|
+
when nil then nil
|
|
119
|
+
else
|
|
120
|
+
[opts[:headers]].flatten.collect{|h| h.downcase}
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
self.expose = case opts[:expose]
|
|
124
|
+
when nil then nil
|
|
125
|
+
else
|
|
126
|
+
[opts[:expose]].flatten
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def match?(path)
|
|
131
|
+
pattern =~ path
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def process_preflight(env)
|
|
135
|
+
return nil if invalid_method_request?(env) || invalid_headers_request?(env)
|
|
136
|
+
{'Content-Type' => 'text/plain'}.merge(to_preflight_headers(env))
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def to_headers(env)
|
|
140
|
+
x_origin = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
|
|
141
|
+
h = { 'Access-Control-Allow-Origin' => public_resource? ? '*' : env['HTTP_ORIGIN'],
|
|
142
|
+
'Access-Control-Allow-Methods' => methods.collect{|m| m.to_s.upcase}.join(', '),
|
|
143
|
+
'Access-Control-Expose-Headers' => expose.nil? ? '' : expose.join(', '),
|
|
144
|
+
'Access-Control-Max-Age' => max_age.to_s }
|
|
145
|
+
h['Access-Control-Allow-Credentials'] = 'true' if credentials
|
|
146
|
+
h
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
protected
|
|
150
|
+
def public_resource?
|
|
151
|
+
@public_resource
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def to_preflight_headers(env)
|
|
155
|
+
h = to_headers(env)
|
|
156
|
+
if env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
|
|
157
|
+
h.merge!('Access-Control-Allow-Headers' => env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])
|
|
158
|
+
end
|
|
159
|
+
h
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def invalid_method_request?(env)
|
|
163
|
+
request_method = env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']
|
|
164
|
+
request_method.nil? || !methods.include?(request_method.downcase.to_sym)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def invalid_headers_request?(env)
|
|
168
|
+
request_headers = env['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
|
|
169
|
+
request_headers && !allow_headers?(request_headers)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def allow_headers?(request_headers)
|
|
173
|
+
return false if headers.nil?
|
|
174
|
+
headers == :any || begin
|
|
175
|
+
request_headers = request_headers.split(/,\s*/) if request_headers.kind_of?(String)
|
|
176
|
+
request_headers.all?{|h| headers.include?(h.downcase)}
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def ensure_enum(v)
|
|
181
|
+
return nil if v.nil?
|
|
182
|
+
[v].flatten
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def compile(path)
|
|
186
|
+
if path.respond_to? :to_str
|
|
187
|
+
special_chars = %w{. + ( )}
|
|
188
|
+
pattern =
|
|
189
|
+
path.to_str.gsub(/((:\w+)|[\*#{special_chars.join}])/) do |match|
|
|
190
|
+
case match
|
|
191
|
+
when "*"
|
|
192
|
+
"(.*?)"
|
|
193
|
+
when *special_chars
|
|
194
|
+
Regexp.escape(match)
|
|
195
|
+
else
|
|
196
|
+
"([^/?&#]+)"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
/^#{pattern}$/
|
|
200
|
+
elsif path.respond_to? :match
|
|
201
|
+
path
|
|
202
|
+
else
|
|
203
|
+
raise TypeError, path
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
end
|
|
209
|
+
end
|
|
@@ -1,58 +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
|
-
#puts "and here #{@app.inspect} #{env.inspect}"
|
|
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
|
|
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
|
+
#puts "and here #{@app.inspect} #{env.inspect}"
|
|
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
58
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/rhoconnect/server.rb
CHANGED
|
File without changes
|
data/lib/rhoconnect/source.rb
CHANGED
|
File without changes
|
data/lib/rhoconnect/store.rb
CHANGED
data/lib/rhoconnect/store_orm.rb
CHANGED
|
File without changes
|
data/lib/rhoconnect/user.rb
CHANGED
|
File without changes
|
data/lib/rhoconnect/version.rb
CHANGED
|
@@ -10,19 +10,6 @@ var Doc = Backbone.Model.extend({
|
|
|
10
10
|
var session = new Session();
|
|
11
11
|
this.set('api_token', session.getApiKey())
|
|
12
12
|
},
|
|
13
|
-
|
|
14
|
-
methodUrl: {
|
|
15
|
-
'read': '/rc/v1/system/license'
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
sync: function(method, model, options) {
|
|
19
|
-
if (model.methodUrl && model.methodUrl[method.toLowerCase()]) {
|
|
20
|
-
options = options || {};
|
|
21
|
-
options.url = model.methodUrl[method.toLowerCase()];
|
|
22
|
-
options.token = this.get('api_token')
|
|
23
|
-
}
|
|
24
|
-
Backbone.sync(method, model, options);
|
|
25
|
-
},
|
|
26
13
|
|
|
27
14
|
get_doc: function(dbkey,d_type){
|
|
28
15
|
self = this;
|
|
@@ -3,7 +3,6 @@ var Source = Backbone.Model.extend({
|
|
|
3
3
|
defaults: {
|
|
4
4
|
api_token: null,
|
|
5
5
|
rhoconnect_version: null,
|
|
6
|
-
licensee: null,
|
|
7
6
|
seats: null,
|
|
8
7
|
issued: null,
|
|
9
8
|
source_id: null,
|
|
@@ -48,36 +47,6 @@ var Source = Backbone.Model.extend({
|
|
|
48
47
|
$('tr.remove-tr-user').remove();
|
|
49
48
|
$('#source-table tr:last').after(adapters);
|
|
50
49
|
},
|
|
51
|
-
|
|
52
|
-
get_license_info: function(){
|
|
53
|
-
var session = new Session();
|
|
54
|
-
$.ajax({
|
|
55
|
-
type: 'GET',
|
|
56
|
-
url: '/rc/v1/system/license',
|
|
57
|
-
beforeSend: function (HttpRequest) {
|
|
58
|
-
HttpRequest.setRequestHeader("X-RhoConnect-API-TOKEN", session.getApiKey());
|
|
59
|
-
},
|
|
60
|
-
success: function(resp){
|
|
61
|
-
if(resp != 'testtoken'){
|
|
62
|
-
var r = JSON.parse(resp)
|
|
63
|
-
var license_text = "Licensed to " + r["licensee"] +
|
|
64
|
-
" on " + r["issued"] + ", available " +
|
|
65
|
-
r["available"] + " out of " +
|
|
66
|
-
r['seats'] + " devices"
|
|
67
|
-
var license_footer = "Licensed to Rhomobile "+r['available']+"/"+r['seats']+" devices available"
|
|
68
|
-
$('#license').html(license_text);
|
|
69
|
-
$('#license_info').html(license_footer);
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
error: function(resp){
|
|
73
|
-
if(resp.status == 422){
|
|
74
|
-
new App.Views.Index()
|
|
75
|
-
}
|
|
76
|
-
$('#docalert')[0].innerHTML = resp.responseText;
|
|
77
|
-
$('#docalert').css('display','block');
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
},
|
|
81
50
|
|
|
82
51
|
list_source_docs: function(source_id,user_id){
|
|
83
52
|
var session = new Session();
|
|
Binary file
|
|
File without changes
|
|
@@ -84,10 +84,9 @@
|
|
|
84
84
|
<footer>
|
|
85
85
|
<div class="pull-left">
|
|
86
86
|
RhoConnect
|
|
87
|
-
<p>©
|
|
87
|
+
<p>© Rhomobile All rights reserved.</p>
|
|
88
88
|
</div>
|
|
89
89
|
<div class="pull-right">
|
|
90
|
-
<div id='license_info'></div>
|
|
91
90
|
RhoConnect v<%=@version%>
|
|
92
91
|
</div>
|
|
93
92
|
</footer>
|