stormpath-sdk 0.4.0 → 1.0.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +27 -0
- data/CHANGES.md +21 -1
- data/Gemfile +1 -2
- data/README.md +457 -11
- data/Rakefile +15 -1
- data/lib/stormpath-sdk.rb +52 -33
- data/lib/stormpath-sdk/{resource/group_list.rb → api_key.rb} +5 -9
- data/lib/stormpath-sdk/auth/authentication_result.rb +3 -13
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +5 -11
- data/lib/stormpath-sdk/auth/basic_login_attempt.rb +6 -8
- data/lib/stormpath-sdk/auth/username_password_request.rb +2 -5
- data/lib/stormpath-sdk/cache/cache.rb +54 -0
- data/lib/stormpath-sdk/cache/cache_entry.rb +33 -0
- data/lib/stormpath-sdk/cache/cache_manager.rb +22 -0
- data/lib/stormpath-sdk/cache/cache_stats.rb +35 -0
- data/lib/stormpath-sdk/cache/memory_store.rb +29 -0
- data/lib/stormpath-sdk/cache/redis_store.rb +32 -0
- data/lib/stormpath-sdk/client.rb +111 -0
- data/lib/stormpath-sdk/data_store.rb +241 -0
- data/lib/stormpath-sdk/{client/api_key.rb → error.rb} +16 -10
- data/lib/stormpath-sdk/{util → ext}/hash.rb +1 -2
- data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +8 -4
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +8 -7
- data/lib/stormpath-sdk/http/request.rb +4 -8
- data/lib/stormpath-sdk/{util/request_utils.rb → http/utils.rb} +17 -38
- data/lib/stormpath-sdk/resource/account.rb +12 -108
- data/lib/stormpath-sdk/resource/application.rb +35 -171
- data/lib/stormpath-sdk/resource/associations.rb +97 -0
- data/lib/stormpath-sdk/resource/base.rb +256 -0
- data/lib/stormpath-sdk/resource/collection.rb +94 -0
- data/lib/stormpath-sdk/resource/directory.rb +11 -68
- data/lib/stormpath-sdk/resource/email_verification_token.rb +3 -9
- data/lib/stormpath-sdk/resource/error.rb +4 -38
- data/lib/stormpath-sdk/resource/expansion.rb +28 -0
- data/lib/stormpath-sdk/resource/group.rb +8 -66
- data/lib/stormpath-sdk/resource/group_membership.rb +4 -55
- data/lib/stormpath-sdk/resource/{application_list.rb → instance.rb} +7 -13
- data/lib/stormpath-sdk/resource/password_reset_token.rb +5 -23
- data/lib/stormpath-sdk/resource/status.rb +22 -28
- data/lib/stormpath-sdk/resource/tenant.rb +5 -52
- data/lib/stormpath-sdk/resource/utils.rb +43 -13
- data/lib/stormpath-sdk/util/assert.rb +5 -15
- data/lib/stormpath-sdk/version.rb +3 -3
- data/spec/api_key_spec.rb +19 -0
- data/spec/auth/basic_authenticator_spec.rb +25 -0
- data/spec/auth/sauthc1_signer_spec.rb +42 -0
- data/spec/cache/cache_entry_spec.rb +157 -0
- data/spec/cache/cache_spec.rb +89 -0
- data/spec/cache/cache_stats_spec.rb +106 -0
- data/spec/client_spec.rb +538 -0
- data/spec/data_store_spec.rb +130 -0
- data/spec/resource/account_spec.rb +74 -0
- data/spec/resource/application_spec.rb +148 -0
- data/spec/resource/base_spec.rb +114 -0
- data/spec/resource/collection_spec.rb +169 -0
- data/spec/resource/directory_spec.rb +30 -0
- data/spec/resource/expansion_spec.rb +100 -0
- data/spec/resource/group_spec.rb +49 -0
- data/spec/spec_helper.rb +135 -0
- data/spec/support/resource_factory.rb +48 -0
- data/spec/support/resource_matchers.rb +27 -0
- data/spec/support/test_cache_stores.rb +9 -0
- data/spec/support/test_request_executor.rb +11 -0
- data/stormpath-sdk.gemspec +14 -4
- data/support/api.rb +55 -0
- metadata +214 -44
- data/lib/stormpath-sdk/client/client.rb +0 -38
- data/lib/stormpath-sdk/client/client_application.rb +0 -38
- data/lib/stormpath-sdk/client/client_application_builder.rb +0 -351
- data/lib/stormpath-sdk/client/client_builder.rb +0 -305
- data/lib/stormpath-sdk/ds/data_store.rb +0 -210
- data/lib/stormpath-sdk/ds/resource_factory.rb +0 -37
- data/lib/stormpath-sdk/resource/account_list.rb +0 -32
- data/lib/stormpath-sdk/resource/collection_resource.rb +0 -91
- data/lib/stormpath-sdk/resource/directory_list.rb +0 -30
- data/lib/stormpath-sdk/resource/group_membership_list.rb +0 -32
- data/lib/stormpath-sdk/resource/instance_resource.rb +0 -28
- data/lib/stormpath-sdk/resource/resource.rb +0 -327
- data/lib/stormpath-sdk/resource/resource_error.rb +0 -47
- data/test/client/client.yml +0 -16
- data/test/client/client_application_builder_spec.rb +0 -114
- data/test/client/client_builder_spec.rb +0 -176
- data/test/client/read_spec.rb +0 -254
- data/test/client/write_spec.rb +0 -420
- data/test/resource/resource_spec.rb +0 -41
- data/test/resource/test_resource.rb +0 -28
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'redis'
|
2
|
+
|
3
|
+
module Stormpath
|
4
|
+
module Cache
|
5
|
+
class RedisStore
|
6
|
+
def initialize(opts = {})
|
7
|
+
@redis = Redis.new opts
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(key)
|
11
|
+
entry = @redis.get key
|
12
|
+
entry && Stormpath::Cache::CacheEntry.from_h(MultiJson.load(entry))
|
13
|
+
end
|
14
|
+
|
15
|
+
def put(key, entry)
|
16
|
+
@redis.set key, MultiJson.dump(entry.to_h)
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(key)
|
20
|
+
@redis.del key
|
21
|
+
end
|
22
|
+
|
23
|
+
def clear
|
24
|
+
@redis.flushdb
|
25
|
+
end
|
26
|
+
|
27
|
+
def size
|
28
|
+
@redis.dbsize
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Stormpath, Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
require 'java_properties'
|
17
|
+
|
18
|
+
module Stormpath
|
19
|
+
|
20
|
+
class Client
|
21
|
+
include Stormpath::Util::Assert
|
22
|
+
|
23
|
+
attr_reader :data_store, :application
|
24
|
+
|
25
|
+
def initialize(options)
|
26
|
+
api_key = options[:api_key]
|
27
|
+
base_url = options[:base_url]
|
28
|
+
cache_opts = options[:cache] || {}
|
29
|
+
|
30
|
+
api_key = if api_key
|
31
|
+
case api_key
|
32
|
+
when ApiKey then api_key
|
33
|
+
when Hash then ApiKey.new api_key[:id], api_key[:secret]
|
34
|
+
end
|
35
|
+
elsif options[:api_key_file_location]
|
36
|
+
load_api_key_file options[:api_key_file_location],
|
37
|
+
options[:api_key_id_property_name],
|
38
|
+
options[:api_key_secret_property_name]
|
39
|
+
end
|
40
|
+
|
41
|
+
assert_not_nil api_key, "No API key has been provided. Please " +
|
42
|
+
"pass an 'api_key' or 'api_key_file_location' to the " +
|
43
|
+
"Stormpath::Client constructor."
|
44
|
+
|
45
|
+
request_executor = Stormpath::Http::HttpClientRequestExecutor.new(api_key, proxy: options[:proxy])
|
46
|
+
@data_store = Stormpath::DataStore.new(request_executor, cache_opts, self, base_url)
|
47
|
+
end
|
48
|
+
|
49
|
+
def tenant
|
50
|
+
Stormpath::Resource::Tenant.new '/tenants/current', self
|
51
|
+
end
|
52
|
+
|
53
|
+
def client
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def cache_stats
|
58
|
+
@data_source.cache_stats
|
59
|
+
end
|
60
|
+
|
61
|
+
include Stormpath::Resource::Associations
|
62
|
+
|
63
|
+
has_many :applications, href: '/applications', can: [:get, :create], delegate: true
|
64
|
+
has_many :directories, href: '/directories', can: [:get, :create], delegate: true
|
65
|
+
has_many(:accounts, href: '/accounts', can: :get) do
|
66
|
+
def verify_email_token(token)
|
67
|
+
token_href = "#{href}/emailVerificationTokens/#{token}"
|
68
|
+
token = Stormpath::Resource::EmailVerificationToken.new(
|
69
|
+
token_href,
|
70
|
+
client
|
71
|
+
)
|
72
|
+
data_store.save token, Stormpath::Resource::Account
|
73
|
+
end
|
74
|
+
end
|
75
|
+
has_many :groups, href: '/groups', can: :get
|
76
|
+
has_many :group_memberships, href: '/groupMemberships', can: [:get, :create]
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def load_api_key_file(api_key_file_location, id_property_name, secret_property_name)
|
81
|
+
begin
|
82
|
+
api_key_properties = JavaProperties::Properties.new api_key_file_location
|
83
|
+
rescue
|
84
|
+
raise ArgumentError,
|
85
|
+
"No API Key file could be found or loaded from '" +
|
86
|
+
api_key_file_location +
|
87
|
+
"'."
|
88
|
+
end
|
89
|
+
|
90
|
+
id_property_name ||= 'apiKey.id'
|
91
|
+
secret_property_name ||= 'apiKey.secret'
|
92
|
+
|
93
|
+
api_key_id = api_key_properties[id_property_name]
|
94
|
+
assert_not_nil api_key_id,
|
95
|
+
"No API id in properties. Please provide a 'apiKey.id' property in '" +
|
96
|
+
api_key_file_location +
|
97
|
+
"' or pass in an 'api_key_id_property_name' to the Stormpath::Client " +
|
98
|
+
"constructor to specify an alternative property."
|
99
|
+
|
100
|
+
api_key_secret = api_key_properties[secret_property_name]
|
101
|
+
assert_not_nil api_key_secret,
|
102
|
+
"No API secret in properties. Please provide a 'apiKey.secret' property in '" +
|
103
|
+
api_key_file_location +
|
104
|
+
"' or pass in an 'api_key_secret_property_name' to the Stormpath::Client " +
|
105
|
+
"constructor to specify an alternative property."
|
106
|
+
|
107
|
+
ApiKey.new api_key_id, api_key_secret
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2012 Stormpath, Inc.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
class Stormpath::DataStore
|
17
|
+
include Stormpath::Http
|
18
|
+
include Stormpath::Util::Assert
|
19
|
+
|
20
|
+
DEFAULT_SERVER_HOST = "api.stormpath.com"
|
21
|
+
DEFAULT_API_VERSION = 1
|
22
|
+
|
23
|
+
CACHE_REGIONS = %w( applications directories accounts groups groupMemberships tenants )
|
24
|
+
|
25
|
+
attr_reader :client, :request_executor
|
26
|
+
|
27
|
+
def initialize(request_executor, cache_opts, client, *base_url)
|
28
|
+
assert_not_nil request_executor, "RequestExecutor cannot be null."
|
29
|
+
|
30
|
+
@client = client
|
31
|
+
@base_url = get_base_url(*base_url)
|
32
|
+
@request_executor = request_executor
|
33
|
+
initialize_cache cache_opts
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize_cache(cache_opts)
|
37
|
+
@cache_manager = Stormpath::Cache::CacheManager.new
|
38
|
+
regions_opts = cache_opts[:regions] || {}
|
39
|
+
CACHE_REGIONS.each do |region|
|
40
|
+
region_opts = regions_opts[region.to_sym] || {}
|
41
|
+
region_opts[:store] ||= cache_opts[:store]
|
42
|
+
@cache_manager.create_cache region, region_opts
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def instantiate(clazz, properties = {})
|
47
|
+
clazz.new properties, client
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_resource(href, clazz, query=nil)
|
51
|
+
q_href = if needs_to_be_fully_qualified href
|
52
|
+
qualify href
|
53
|
+
else
|
54
|
+
href
|
55
|
+
end
|
56
|
+
|
57
|
+
data = execute_request('get', q_href, nil, query)
|
58
|
+
instantiate clazz, data.to_hash
|
59
|
+
end
|
60
|
+
|
61
|
+
def create(parent_href, resource, return_type)
|
62
|
+
save_resource(parent_href, resource, return_type).tap do |returned_resource|
|
63
|
+
if resource.kind_of? return_type
|
64
|
+
resource.set_properties to_hash(returned_resource)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def save(resource, clazz = nil)
|
70
|
+
assert_not_nil resource, "resource argument cannot be null."
|
71
|
+
assert_kind_of Stormpath::Resource::Base, resource, "resource argument must be instance of Stormpath::Resource::Base"
|
72
|
+
|
73
|
+
href = resource.href
|
74
|
+
assert_true href.length > 0, "save may only be called on objects that have already been persisted (i.e. they have an existing href)."
|
75
|
+
|
76
|
+
href = if needs_to_be_fully_qualified(href)
|
77
|
+
qualify(href)
|
78
|
+
else
|
79
|
+
href
|
80
|
+
end
|
81
|
+
|
82
|
+
clazz ||= resource.class
|
83
|
+
|
84
|
+
save_resource(href, resource, clazz).tap do |return_value|
|
85
|
+
resource.set_properties return_value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def delete(resource)
|
90
|
+
assert_not_nil resource, "resource argument cannot be null."
|
91
|
+
assert_kind_of Stormpath::Resource::Base, resource, "resource argument must be instance of Stormpath::Resource::Base"
|
92
|
+
|
93
|
+
execute_request('delete', resource.href)
|
94
|
+
end
|
95
|
+
|
96
|
+
def cache_manager
|
97
|
+
@cache_manager
|
98
|
+
end
|
99
|
+
|
100
|
+
protected
|
101
|
+
|
102
|
+
def needs_to_be_fully_qualified(href)
|
103
|
+
!href.downcase.start_with? 'http'
|
104
|
+
end
|
105
|
+
|
106
|
+
def qualify(href)
|
107
|
+
slash_added = ''
|
108
|
+
|
109
|
+
if !href.start_with? '/'
|
110
|
+
slash_added = '/'
|
111
|
+
end
|
112
|
+
|
113
|
+
@base_url + slash_added + href
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def execute_request(http_method, href, body=nil, query=nil)
|
119
|
+
if http_method == 'get' && (cache = cache_for href)
|
120
|
+
cached_result = cache.get href
|
121
|
+
return cached_result if cached_result
|
122
|
+
end
|
123
|
+
|
124
|
+
request = Request.new(http_method, href, query, Hash.new, body)
|
125
|
+
apply_default_request_headers request
|
126
|
+
response = @request_executor.execute_request request
|
127
|
+
|
128
|
+
result = response.body.length > 0 ? MultiJson.load(response.body) : ''
|
129
|
+
|
130
|
+
if response.error?
|
131
|
+
error = Stormpath::Resource::Error.new result
|
132
|
+
#puts "Error with request: #{http_method.upcase}: #{href}"
|
133
|
+
raise Stormpath::Error.new error
|
134
|
+
end
|
135
|
+
|
136
|
+
if http_method == 'delete'
|
137
|
+
cache = cache_for href
|
138
|
+
cache.delete href if cache
|
139
|
+
return nil
|
140
|
+
end
|
141
|
+
|
142
|
+
if result['href']
|
143
|
+
cache_walk result
|
144
|
+
else
|
145
|
+
result
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def cache_walk(resource)
|
150
|
+
assert_not_nil resource['href'], "resource must have 'href' property"
|
151
|
+
items = resource['items']
|
152
|
+
|
153
|
+
if items # collection resource
|
154
|
+
resource['items'] = items.map do |item|
|
155
|
+
cache_walk item
|
156
|
+
{ 'href' => item['href'] }
|
157
|
+
end
|
158
|
+
else # single resource
|
159
|
+
resource.each do |attr, value|
|
160
|
+
if value.is_a? Hash
|
161
|
+
walked = cache_walk value
|
162
|
+
resource[attr] = { 'href' => value['href'] }
|
163
|
+
resource[attr]['items'] = walked['items'] if walked['items']
|
164
|
+
end
|
165
|
+
end
|
166
|
+
cache resource if resource.length > 1
|
167
|
+
end
|
168
|
+
resource
|
169
|
+
end
|
170
|
+
|
171
|
+
def cache(resource)
|
172
|
+
cache = cache_for resource['href']
|
173
|
+
cache.put resource['href'], resource if cache
|
174
|
+
end
|
175
|
+
|
176
|
+
def cache_for(href)
|
177
|
+
@cache_manager.get_cache(region_for href)
|
178
|
+
end
|
179
|
+
|
180
|
+
def region_for(href)
|
181
|
+
return nil unless href
|
182
|
+
region = href.split('/')[-2]
|
183
|
+
CACHE_REGIONS.include?(region) ? region : nil
|
184
|
+
end
|
185
|
+
|
186
|
+
def apply_default_request_headers(request)
|
187
|
+
request.http_headers.store 'Accept', 'application/json'
|
188
|
+
request.http_headers.store 'User-Agent', 'Stormpath-RubySDK/' + Stormpath::VERSION
|
189
|
+
|
190
|
+
if !request.body.nil? and request.body.length > 0
|
191
|
+
request.http_headers.store 'Content-Type', 'application/json'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def save_resource(href, resource, return_type)
|
196
|
+
assert_not_nil resource, "resource argument cannot be null."
|
197
|
+
assert_not_nil return_type, "returnType class cannot be null."
|
198
|
+
assert_kind_of Stormpath::Resource::Base, resource, "resource argument must be instance of Stormpath::Resource::Base"
|
199
|
+
|
200
|
+
q_href = if needs_to_be_fully_qualified href
|
201
|
+
qualify href
|
202
|
+
else
|
203
|
+
href
|
204
|
+
end
|
205
|
+
|
206
|
+
response = execute_request('post', q_href, MultiJson.dump(to_hash(resource)))
|
207
|
+
instantiate return_type, response.to_hash
|
208
|
+
end
|
209
|
+
|
210
|
+
def get_base_url(*base_url)
|
211
|
+
(!base_url.empty? and !base_url[0].nil?) ?
|
212
|
+
base_url[0] :
|
213
|
+
"https://" + DEFAULT_SERVER_HOST + "/v" + DEFAULT_API_VERSION.to_s
|
214
|
+
end
|
215
|
+
|
216
|
+
def to_hash(resource)
|
217
|
+
Hash.new.tap do |properties|
|
218
|
+
resource.get_property_names.each do |name|
|
219
|
+
property = resource.get_property name
|
220
|
+
|
221
|
+
if property.kind_of? Hash
|
222
|
+
property = to_simple_reference name, property
|
223
|
+
end
|
224
|
+
|
225
|
+
properties.store name, property
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def to_simple_reference(property_name, hash)
|
231
|
+
href_prop_name = Stormpath::Resource::Base::HREF_PROP_NAME
|
232
|
+
assert_true(
|
233
|
+
(hash.kind_of?(Hash) and !hash.empty? and hash.has_key?(href_prop_name)),
|
234
|
+
"Nested resource '#{property_name}' must have an 'href' property."
|
235
|
+
)
|
236
|
+
|
237
|
+
href = hash[href_prop_name]
|
238
|
+
|
239
|
+
{href_prop_name => href}
|
240
|
+
end
|
241
|
+
end
|
@@ -13,21 +13,27 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
|
-
|
16
|
+
class Stormpath::Error < RuntimeError
|
17
17
|
|
18
|
-
|
18
|
+
def initialize error = nil
|
19
|
+
super !error.nil? ? error.message : ''
|
20
|
+
@error = error
|
21
|
+
end
|
19
22
|
|
20
|
-
|
23
|
+
def status
|
24
|
+
!@error.nil? ? @error.status : -1
|
25
|
+
end
|
21
26
|
|
22
|
-
|
27
|
+
def code
|
28
|
+
!@error.nil? ? @error.code : -1
|
29
|
+
end
|
23
30
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
31
|
+
def developer_message
|
32
|
+
!@error.nil? ? @error.developer_message : nil
|
33
|
+
end
|
29
34
|
|
35
|
+
def more_info
|
36
|
+
!@error.nil? ? @error.more_info : nil
|
30
37
|
end
|
31
38
|
|
32
39
|
end
|
33
|
-
|
@@ -15,8 +15,6 @@
|
|
15
15
|
#
|
16
16
|
class Hash
|
17
17
|
|
18
|
-
# implementation borrowed from the vine project at
|
19
|
-
# https://github.com/guangnan/vine/blob/master/lib/vine.rb
|
20
18
|
def access(path, separator)
|
21
19
|
ret = self
|
22
20
|
path.split(separator).each do |p|
|
@@ -29,4 +27,5 @@ class Hash
|
|
29
27
|
end
|
30
28
|
ret
|
31
29
|
end
|
30
|
+
|
32
31
|
end
|
@@ -23,7 +23,7 @@ module Stormpath
|
|
23
23
|
|
24
24
|
include OpenSSL
|
25
25
|
include UUIDTools
|
26
|
-
include Stormpath::
|
26
|
+
include Stormpath::Http::Utils
|
27
27
|
|
28
28
|
DEFAULT_ALGORITHM = "SHA256"
|
29
29
|
HOST_HEADER = "Host"
|
@@ -40,20 +40,24 @@ module Stormpath
|
|
40
40
|
#noinspection RubyConstantNamingConvention
|
41
41
|
NL = "\n"
|
42
42
|
|
43
|
+
def initialize(uuid_generator=UUID.method(:random_create))
|
44
|
+
@uuid_generator = uuid_generator
|
45
|
+
end
|
46
|
+
|
43
47
|
def sign_request request, api_key
|
44
48
|
|
45
49
|
time = Time.now
|
46
50
|
time_stamp = time.utc.strftime TIMESTAMP_FORMAT
|
47
51
|
date_stamp = time.utc.strftime DATE_FORMAT
|
48
52
|
|
49
|
-
nonce =
|
53
|
+
nonce = @uuid_generator.call.to_s
|
50
54
|
|
51
55
|
uri = request.resource_uri
|
52
56
|
|
53
57
|
# SAuthc1 requires that we sign the Host header so we
|
54
58
|
# have to have it in the request by the time we sign.
|
55
59
|
host_header = uri.host
|
56
|
-
if !
|
60
|
+
if !default_port?(uri)
|
57
61
|
|
58
62
|
host_header << ":" << uri.port.to_s
|
59
63
|
end
|
@@ -180,7 +184,7 @@ module Stormpath
|
|
180
184
|
if resource_path.nil? or resource_path.empty?
|
181
185
|
'/'
|
182
186
|
else
|
183
|
-
|
187
|
+
encode_url resource_path, true, true
|
184
188
|
end
|
185
189
|
end
|
186
190
|
|