stormpath-sdk 0.4.0 → 1.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|