stormpath-sdk 1.0.0.beta.8 → 1.0.0.beta.9
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/.travis.yml +5 -5
- data/CHANGES.md +11 -0
- data/README.md +1 -0
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +0 -2
- data/lib/stormpath-sdk/client.rb +2 -0
- data/lib/stormpath-sdk/data_store.rb +45 -5
- data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +1 -1
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +4 -0
- data/lib/stormpath-sdk/http/request.rb +1 -1
- data/lib/stormpath-sdk/id_site/error.rb +42 -0
- data/lib/stormpath-sdk/id_site/id_site_result.rb +6 -1
- data/lib/stormpath-sdk/oauth/authenticator.rb +26 -0
- data/lib/stormpath-sdk/oauth/password_grant.rb +17 -0
- data/lib/stormpath-sdk/oauth/password_grant_request.rb +13 -0
- data/lib/stormpath-sdk/oauth/refresh_grant_request.rb +12 -0
- data/lib/stormpath-sdk/oauth/refresh_token.rb +16 -0
- data/lib/stormpath-sdk/oauth/verify_access_token.rb +15 -0
- data/lib/stormpath-sdk/oauth/verify_token.rb +7 -0
- data/lib/stormpath-sdk/resource/access_token.rb +12 -0
- data/lib/stormpath-sdk/resource/account.rb +1 -0
- data/lib/stormpath-sdk/resource/application.rb +31 -6
- data/lib/stormpath-sdk/resource/oauth_policy.rb +5 -0
- data/lib/stormpath-sdk/resource/organization.rb +12 -0
- data/lib/stormpath-sdk/resource/organization_account_store_mapping.rb +6 -0
- data/lib/stormpath-sdk/resource/verification_email.rb +5 -0
- data/lib/stormpath-sdk/version.rb +2 -2
- data/lib/stormpath-sdk.rb +17 -1
- data/spec/client_spec.rb +29 -0
- data/spec/resource/account_spec.rb +13 -0
- data/spec/resource/application_spec.rb +243 -3
- data/spec/resource/directory_spec.rb +9 -0
- data/spec/resource/organization_spec.rb +185 -0
- data/spec/support/custom_data_storage_behavior.rb +2 -2
- data/stormpath-sdk.gemspec +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ffd1ce3b14483c0ba0f564a704d5e7d6d079a99e
|
|
4
|
+
data.tar.gz: b59460eaea481ca8e83d4a4bf4accb8728481554
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6fa8d912dd6323c2dcfe19d08bbc7a2efce1c8eea0d74ab2f34dfbbb1d891e78126ee4022045bc4d39faae429a98784ec9cfdd479cd920eafca443271cd10d32
|
|
7
|
+
data.tar.gz: 08e1230337d60e8e55026ca367ac2103cd9c5414a1cc075301384d8550b78a1b2f2f35ea6001bd60296e03e2715582fc3fff77c516fb04924aece923a15a70ce
|
data/.travis.yml
CHANGED
|
@@ -7,8 +7,8 @@ services:
|
|
|
7
7
|
- redis-server
|
|
8
8
|
env:
|
|
9
9
|
global:
|
|
10
|
-
- secure:
|
|
11
|
-
- secure:
|
|
12
|
-
- secure:
|
|
13
|
-
- secure:
|
|
14
|
-
- secure:
|
|
10
|
+
- secure: MeyjZGgySZvpYVRm2i7wkrhvu9KUeU7eQ5aKj7FXqIYlQe3T67k+KKA3Ejp6WC3wUEVPUFseWMZCuNkRc0UeGA5/4e4LLc++XuaZn1jLTm1yNofh/CFAAjt5VdIYz4R7sKxpyLxs0orK2+HcaiCoqSDj7ehw2SlDca9VEi0GoQk=
|
|
11
|
+
- secure: MrtbhfH1IfwDkkvf0pq6trgj68to/fK4c+L1daKvMaNiNvwggbA3s0ea9QjHxXfWmPqL5bf8Q5N7YqXUw8cLpRPrKUA65JkyhyzIju8FgzXz83aCvjJD+5XhJIGzpLM8qHeKh7F0K6/iURTKIUgZXbguK4HpEeCMrrdPYcof3Ew=
|
|
12
|
+
- secure: JChx6k5NOw/PBzH6gpHdqxHPy8hpaTALVs2riTVXorJZ5p06F3riqFBQbMh6REzXdJLjD6VKPORt19WOkmLHCPW8x0g7HxIRHT0DCDLX/4980dZZAev3blSvfJ7t1cWlBVsZb0LgVEkswvKdSYEZvDQTy5XlWsIMuNhHUclsTZk=
|
|
13
|
+
- secure: c5tUXb7FPMDD/KkpDwYNfnZ2k0N0RltBAQt1IYOFkdcztIAdcGmWPtT4l07He+UJiF2Vy92KrsSK709FFDwdxAleSgFKwpCrtgJRXXqRqT/gDiJUsGU1jC4QgXpu/QWCWsCSs/v1l1GzZyZF61aQzqINVrGwF5n2/MeMGOAJkaA=
|
|
14
|
+
- secure: SepFOaSOjRr5EJLBlXKT60FgSmKZ604zhhDaes+s9rQgJcaUsVkTxFYhkE6mkDadH7dZ6ACW1TaWWTmFm+JMFuli/bcyvX9wm5akWM6EF3BdJ8djMac34iJuTB3MWED+fOaFco9oZjMQOYZlSu9nS4VOvH0ekcTnQnThzxYxpfs=
|
data/CHANGES.md
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
stormpath-sdk-ruby Changelog
|
|
2
2
|
============================
|
|
3
3
|
|
|
4
|
+
Version 1.0.0.beta.9
|
|
5
|
+
--------------------
|
|
6
|
+
|
|
7
|
+
Released on December 2, 2015
|
|
8
|
+
|
|
9
|
+
- Organization CRUD
|
|
10
|
+
- Token Management
|
|
11
|
+
- Ability to specify an organization nameKey as an accountStore for loginAttempt
|
|
12
|
+
- Get applications for an account
|
|
13
|
+
- Resending email verification
|
|
14
|
+
|
|
4
15
|
Version 1.0.0.beta.8
|
|
5
16
|
--------------------
|
|
6
17
|
|
data/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
[](https://travis-ci.org/stormpath/stormpath-sdk-ruby)
|
|
2
|
+
[](https://codeclimate.com/github/stormpath/stormpath-sdk-ruby)
|
|
2
3
|
|
|
3
4
|
# Stormpath Ruby SDK
|
|
4
5
|
|
data/lib/stormpath-sdk/client.rb
CHANGED
|
@@ -53,9 +53,11 @@ module Stormpath
|
|
|
53
53
|
data_store.save token, Stormpath::Resource::Account
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
|
+
has_many :organizations, href: '/organizations', can: [:get, :create]
|
|
56
57
|
has_many :groups, href: '/groups', can: :get
|
|
57
58
|
has_many :group_memberships, href: '/groupMemberships', can: [:get, :create]
|
|
58
59
|
has_many :account_store_mappings, href: '/accountStoreMappings', can: [:get, :create]
|
|
60
|
+
has_many :organization_account_store_mappings, href: '/organizationAccountStoreMappings', can: [:get, :create]
|
|
59
61
|
|
|
60
62
|
private
|
|
61
63
|
|
|
@@ -115,12 +115,16 @@ class Stormpath::DataStore
|
|
|
115
115
|
return cached_result if cached_result
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
body =
|
|
119
|
-
MultiJson.dump(to_hash(resource))
|
|
120
|
-
end
|
|
118
|
+
body = extract_body_from_resource(resource)
|
|
121
119
|
|
|
122
120
|
request = Request.new(http_method, href, query, Hash.new, body, @api_key)
|
|
123
|
-
|
|
121
|
+
|
|
122
|
+
if resource.try(:form_data?)
|
|
123
|
+
apply_form_data_request_headers request
|
|
124
|
+
else
|
|
125
|
+
apply_default_request_headers request
|
|
126
|
+
end
|
|
127
|
+
|
|
124
128
|
response = @request_executor.execute_request request
|
|
125
129
|
|
|
126
130
|
result = response.body.length > 0 ? MultiJson.load(response.body) : ''
|
|
@@ -209,6 +213,11 @@ class Stormpath::DataStore
|
|
|
209
213
|
request.http_headers.store 'Content-Type', 'application/json'
|
|
210
214
|
end
|
|
211
215
|
end
|
|
216
|
+
|
|
217
|
+
def apply_form_data_request_headers(request)
|
|
218
|
+
request.http_headers.store 'Content-Type', 'application/x-www-form-urlencoded'
|
|
219
|
+
request.http_headers.store 'User-Agent', 'Stormpath-RubySDK/' + Stormpath::VERSION
|
|
220
|
+
end
|
|
212
221
|
|
|
213
222
|
def save_resource(href, resource, return_type)
|
|
214
223
|
assert_not_nil resource, "resource argument cannot be null."
|
|
@@ -221,7 +230,12 @@ class Stormpath::DataStore
|
|
|
221
230
|
|
|
222
231
|
response = execute_request 'post', q_href, resource
|
|
223
232
|
|
|
224
|
-
instantiate return_type, response
|
|
233
|
+
instantiate return_type, parse_response(response)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def parse_response(response)
|
|
237
|
+
return {} if response.is_a? String and response.blank?
|
|
238
|
+
response.to_hash
|
|
225
239
|
end
|
|
226
240
|
|
|
227
241
|
def clear_cache_on_save(resource)
|
|
@@ -252,6 +266,32 @@ class Stormpath::DataStore
|
|
|
252
266
|
end
|
|
253
267
|
end
|
|
254
268
|
|
|
269
|
+
def extract_body_from_resource(resource)
|
|
270
|
+
return if resource.nil?
|
|
271
|
+
form_data = resource.try(:form_data?)
|
|
272
|
+
|
|
273
|
+
if form_data
|
|
274
|
+
form_request_parse(resource)
|
|
275
|
+
else
|
|
276
|
+
MultiJson.dump(to_hash(resource))
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def form_request_parse(resource)
|
|
281
|
+
data = ""
|
|
282
|
+
|
|
283
|
+
property_names = resource.get_dirty_property_names
|
|
284
|
+
property_names.each do |name|
|
|
285
|
+
if name != "formData"
|
|
286
|
+
property = resource.get_property name, ignore_camelcasing: true
|
|
287
|
+
data += name.underscore + '=' + property.to_s
|
|
288
|
+
data += '&' unless name == property_names.last
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
data
|
|
293
|
+
end
|
|
294
|
+
|
|
255
295
|
def to_hash(resource)
|
|
256
296
|
Hash.new.tap do |properties|
|
|
257
297
|
resource.get_dirty_property_names.each do |name|
|
|
@@ -36,6 +36,10 @@ module Stormpath
|
|
|
36
36
|
else
|
|
37
37
|
request.href
|
|
38
38
|
end
|
|
39
|
+
|
|
40
|
+
if request.http_headers["Content-Type"] == "application/x-www-form-urlencoded"
|
|
41
|
+
@http_client.set_auth(request.href, request.api_key.id, request.api_key.secret)
|
|
42
|
+
end
|
|
39
43
|
|
|
40
44
|
method = @http_client.method(request.http_method.downcase)
|
|
41
45
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Stormpath
|
|
2
|
+
module IdSite
|
|
3
|
+
class Error < Stormpath::Error
|
|
4
|
+
attr_accessor :status, :code, :message, :developer_message, :more_info
|
|
5
|
+
|
|
6
|
+
def initialize(type)
|
|
7
|
+
@status = errors[type][:status]
|
|
8
|
+
@code = errors[type][:code]
|
|
9
|
+
@message = errors[type][:message]
|
|
10
|
+
@developer_message = errors[type][:developer_message]
|
|
11
|
+
super(self)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def errors
|
|
17
|
+
{
|
|
18
|
+
jwt_cb_uri_incorrect: {
|
|
19
|
+
status: 400,
|
|
20
|
+
code: 400,
|
|
21
|
+
message: "The specified callback URI (cb_uri) is not valid",
|
|
22
|
+
developer_message: "The specified callback URI (cb_uri) is not valid. Make "\
|
|
23
|
+
"sure the callback URI specified in your ID Site configuration matches the value specified."
|
|
24
|
+
},
|
|
25
|
+
jwt_expired: {
|
|
26
|
+
status: 400,
|
|
27
|
+
code: 10011,
|
|
28
|
+
message: "Token is invalid",
|
|
29
|
+
developer_message: "Token is no longer valid because it has expired"
|
|
30
|
+
},
|
|
31
|
+
jwt_invalid: {
|
|
32
|
+
status: 400,
|
|
33
|
+
code: 10012,
|
|
34
|
+
message: "Token is invalid",
|
|
35
|
+
developer_message: "Token is invalid because the issued at time (iat) is after the current time"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
module Stormpath
|
|
2
2
|
module IdSite
|
|
3
3
|
class IdSiteResult
|
|
4
|
-
attr_accessor :account_href, :state, :status, :is_new_account
|
|
4
|
+
attr_accessor :jwt_response, :account_href, :state, :status, :is_new_account
|
|
5
5
|
|
|
6
6
|
alias_method :new_account?, :is_new_account
|
|
7
7
|
|
|
8
8
|
def initialize(jwt_response)
|
|
9
|
+
@jwt_response = jwt_response
|
|
9
10
|
@account_href = jwt_response["sub"]
|
|
10
11
|
@status = jwt_response["status"]
|
|
11
12
|
@state = jwt_response["state"]
|
|
12
13
|
@is_new_account = jwt_response["isNewSub"]
|
|
13
14
|
end
|
|
15
|
+
|
|
16
|
+
def jwt_invalid?(api_key_id)
|
|
17
|
+
@jwt_response['aud'] != api_key_id
|
|
18
|
+
end
|
|
14
19
|
end
|
|
15
20
|
end
|
|
16
21
|
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Stormpath
|
|
2
|
+
module Oauth
|
|
3
|
+
class Authenticator
|
|
4
|
+
include Stormpath::Util::Assert
|
|
5
|
+
|
|
6
|
+
def initialize(data_store)
|
|
7
|
+
@data_store = data_store
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def authenticate parent_href, request
|
|
11
|
+
assert_not_nil parent_href, "parent_href must be specified"
|
|
12
|
+
|
|
13
|
+
if request.grant_type == 'password'
|
|
14
|
+
attempt = @data_store.instantiate PasswordGrant
|
|
15
|
+
elsif request.grant_type == 'refresh_token'
|
|
16
|
+
attempt = @data_store.instantiate RefreshToken
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attempt.set_options(request)
|
|
20
|
+
|
|
21
|
+
href = parent_href + '/oauth/token'
|
|
22
|
+
@data_store.create href, attempt, Stormpath::Resource::AccessToken
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Stormpath
|
|
2
|
+
module Oauth
|
|
3
|
+
class PasswordGrant < Stormpath::Resource::Base
|
|
4
|
+
prop_accessor :grant_type, :username, :password
|
|
5
|
+
|
|
6
|
+
def set_options(request)
|
|
7
|
+
set_property :username, request.username
|
|
8
|
+
set_property :password, request.password
|
|
9
|
+
set_property :grant_type, request.grant_type
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def form_data?
|
|
13
|
+
true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Stormpath
|
|
2
|
+
module Oauth
|
|
3
|
+
class RefreshToken < Stormpath::Resource::Base
|
|
4
|
+
prop_accessor :grant_type, :refresh_token
|
|
5
|
+
|
|
6
|
+
def set_options(request)
|
|
7
|
+
set_property :refresh_token, request.refresh_token
|
|
8
|
+
set_property :grant_type, request.grant_type
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def form_data?
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Stormpath
|
|
2
|
+
module Oauth
|
|
3
|
+
class VerifyAccessToken
|
|
4
|
+
def initialize(application)
|
|
5
|
+
@href = application.href
|
|
6
|
+
@data_store = application.client.data_store
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def verify authorization_token
|
|
10
|
+
href = @href + '/authTokens/' + authorization_token
|
|
11
|
+
@data_store.get_resource href, VerifyToken
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Stormpath::Resource::AccessToken < Stormpath::Resource::Instance
|
|
2
|
+
prop_reader :access_token, :refresh_token, :token_type, :expires_in,
|
|
3
|
+
:stormpath_access_token_href
|
|
4
|
+
|
|
5
|
+
alias_method :href, :stormpath_access_token_href
|
|
6
|
+
|
|
7
|
+
def delete
|
|
8
|
+
unless href.respond_to?(:empty) and href.empty?
|
|
9
|
+
data_store.delete self
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -28,10 +28,14 @@ class Stormpath::Resource::Application < Stormpath::Resource::Instance
|
|
|
28
28
|
has_many :password_reset_tokens, can: [:get, :create]
|
|
29
29
|
has_many :account_store_mappings, can: [:get, :create]
|
|
30
30
|
has_many :groups, can: [:get, :create]
|
|
31
|
+
has_many :verification_emails, can: :create
|
|
31
32
|
|
|
32
33
|
has_one :default_account_store_mapping, class_name: :accountStoreMapping
|
|
33
34
|
has_one :default_group_store_mapping, class_name: :accountStoreMapping
|
|
34
35
|
has_one :custom_data
|
|
36
|
+
has_one :o_auth_policy, class_name: :oauthPolicy
|
|
37
|
+
|
|
38
|
+
alias_method :oauth_policy, :o_auth_policy
|
|
35
39
|
|
|
36
40
|
def self.load composite_url
|
|
37
41
|
begin
|
|
@@ -54,6 +58,10 @@ class Stormpath::Resource::Application < Stormpath::Resource::Instance
|
|
|
54
58
|
base = client.data_store.base_url.sub("v" + Stormpath::DataStore::DEFAULT_API_VERSION.to_s, "sso")
|
|
55
59
|
base += '/logout' if options[:logout]
|
|
56
60
|
|
|
61
|
+
if options[:callback_uri].empty?
|
|
62
|
+
raise Stormpath::IdSite::Error.new(:jwt_cb_uri_incorrect)
|
|
63
|
+
end
|
|
64
|
+
|
|
57
65
|
token = JWT.encode({
|
|
58
66
|
'iat' => Time.now.to_i,
|
|
59
67
|
'jti' => UUID.method(:random_create).call.to_s,
|
|
@@ -74,11 +82,21 @@ class Stormpath::Resource::Application < Stormpath::Resource::Instance
|
|
|
74
82
|
params = CGI::parse(uri.query)
|
|
75
83
|
token = params["jwtResponse"].first
|
|
76
84
|
|
|
77
|
-
|
|
85
|
+
begin
|
|
86
|
+
jwt_response, _header = JWT.decode(token, client.data_store.api_key.secret)
|
|
87
|
+
rescue JWT::ExpiredSignature => error
|
|
88
|
+
# JWT raises error if the signature expired, we need to capture this and
|
|
89
|
+
# rerase IdSite::Error
|
|
90
|
+
raise Stormpath::IdSite::Error.new(:jwt_expired)
|
|
91
|
+
end
|
|
78
92
|
|
|
79
|
-
|
|
93
|
+
id_site_result = Stormpath::IdSite::IdSiteResult.new(jwt_response)
|
|
80
94
|
|
|
81
|
-
|
|
95
|
+
if id_site_result.jwt_invalid?(api_key_id)
|
|
96
|
+
raise Stormpath::IdSite::Error.new(:jwt_invalid)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
id_site_result
|
|
82
100
|
end
|
|
83
101
|
|
|
84
102
|
def send_password_reset_email email
|
|
@@ -98,10 +116,17 @@ class Stormpath::Resource::Application < Stormpath::Resource::Instance
|
|
|
98
116
|
Stormpath::Provider::AccountResolver.new(data_store).resolve_provider_account(href, request)
|
|
99
117
|
end
|
|
100
118
|
|
|
119
|
+
def authenticate_oauth(request)
|
|
120
|
+
Stormpath::Oauth::Authenticator.new(data_store).authenticate(href, request)
|
|
121
|
+
end
|
|
122
|
+
|
|
101
123
|
private
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
def api_key_id
|
|
126
|
+
client.data_store.api_key.id
|
|
127
|
+
end
|
|
106
128
|
|
|
129
|
+
def create_password_reset_token email
|
|
130
|
+
password_reset_tokens.create email: email
|
|
131
|
+
end
|
|
107
132
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class Stormpath::Resource::Organization < Stormpath::Resource::Instance
|
|
2
|
+
include Stormpath::Resource::CustomDataStorage
|
|
3
|
+
|
|
4
|
+
prop_accessor :name, :description, :name_key, :status, :account_store_mappings,
|
|
5
|
+
:default_account_store_mapping, :default_group_store_mapping
|
|
6
|
+
|
|
7
|
+
has_many :groups
|
|
8
|
+
has_many :accounts
|
|
9
|
+
belongs_to :tenant
|
|
10
|
+
|
|
11
|
+
has_one :custom_data
|
|
12
|
+
end
|
data/lib/stormpath-sdk.rb
CHANGED
|
@@ -47,6 +47,11 @@ module Stormpath
|
|
|
47
47
|
autoload :GroupMembership, 'stormpath-sdk/resource/group_membership'
|
|
48
48
|
autoload :AccountMembership, 'stormpath-sdk/resource/account_membership'
|
|
49
49
|
autoload :PasswordResetToken, 'stormpath-sdk/resource/password_reset_token'
|
|
50
|
+
autoload :VerificationEmail, 'stormpath-sdk/resource/verification_email'
|
|
51
|
+
autoload :OauthPolicy, 'stormpath-sdk/resource/oauth_policy'
|
|
52
|
+
autoload :AccessToken, 'stormpath-sdk/resource/access_token'
|
|
53
|
+
autoload :Organization, 'stormpath-sdk/resource/organization'
|
|
54
|
+
autoload :OrganizationAccountStoreMapping, 'stormpath-sdk/resource/organization_account_store_mapping'
|
|
50
55
|
end
|
|
51
56
|
|
|
52
57
|
module Cache
|
|
@@ -94,5 +99,16 @@ module Stormpath
|
|
|
94
99
|
|
|
95
100
|
module IdSite
|
|
96
101
|
autoload :IdSiteResult, 'stormpath-sdk/id_site/id_site_result'
|
|
102
|
+
autoload :Error, 'stormpath-sdk/id_site/error'
|
|
97
103
|
end
|
|
98
|
-
|
|
104
|
+
|
|
105
|
+
module Oauth
|
|
106
|
+
autoload :Authenticator, "stormpath-sdk/oauth/authenticator"
|
|
107
|
+
autoload :PasswordGrant, "stormpath-sdk/oauth/password_grant"
|
|
108
|
+
autoload :RefreshToken, "stormpath-sdk/oauth/refresh_token"
|
|
109
|
+
autoload :PasswordGrantRequest, "stormpath-sdk/oauth/password_grant_request"
|
|
110
|
+
autoload :RefreshGrantRequest, "stormpath-sdk/oauth/refresh_grant_request"
|
|
111
|
+
autoload :VerifyAccessToken, "stormpath-sdk/oauth/verify_access_token"
|
|
112
|
+
autoload :VerifyToken, "stormpath-sdk/oauth/verify_token"
|
|
113
|
+
end
|
|
114
|
+
end
|
data/spec/client_spec.rb
CHANGED
|
@@ -628,6 +628,35 @@ properties
|
|
|
628
628
|
end
|
|
629
629
|
end
|
|
630
630
|
|
|
631
|
+
describe "#organization_account_store_mappings" do
|
|
632
|
+
let(:organization) do
|
|
633
|
+
test_api_client.organizations.create name: 'test_organization',
|
|
634
|
+
name_key: "testorganization"
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
638
|
+
|
|
639
|
+
let(:organization_account_store_mappings) do
|
|
640
|
+
test_api_client.organization_account_store_mappings.create({
|
|
641
|
+
account_store: { href: directory.href },
|
|
642
|
+
organization: { href: organization.href }
|
|
643
|
+
})
|
|
644
|
+
end
|
|
645
|
+
|
|
646
|
+
after do
|
|
647
|
+
organization.delete if organization
|
|
648
|
+
directory.delete if directory
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
it "returns the mapping" do
|
|
652
|
+
expect(organization_account_store_mappings.is_default_account_store).to eq(false)
|
|
653
|
+
expect(organization_account_store_mappings.is_default_group_store).to eq(false)
|
|
654
|
+
expect(organization_account_store_mappings.organization).to eq(organization)
|
|
655
|
+
expect(organization_account_store_mappings.list_index).to eq(0)
|
|
656
|
+
expect(organization_account_store_mappings.account_store).to be_kind_of(Stormpath::Resource::Directory)
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
|
|
631
660
|
describe '#accounts.verify_account_email' do
|
|
632
661
|
context 'given a verfication token of an account' do
|
|
633
662
|
let(:directory) { test_directory_with_verification }
|
|
@@ -39,12 +39,20 @@ describe Stormpath::Resource::Account, :vcr do
|
|
|
39
39
|
expect(account.email_verification_token).to be_nil
|
|
40
40
|
expect(account.groups).to be_a Stormpath::Resource::Collection
|
|
41
41
|
expect(account.group_memberships).to be_a Stormpath::Resource::Collection
|
|
42
|
+
expect(account.applications).to be_a Stormpath::Resource::Collection
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
|
|
45
46
|
describe 'account_associations' do
|
|
47
|
+
let(:app) { test_api_client.applications.create name: random_application_name, description: 'Dummy desc.' }
|
|
48
|
+
let(:application) { test_api_client.applications.get app.href }
|
|
46
49
|
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
47
50
|
|
|
51
|
+
before do
|
|
52
|
+
test_api_client.account_store_mappings.create({ application: app, account_store: directory,
|
|
53
|
+
list_index: 1, is_default_account_store: true, is_default_group_store: true })
|
|
54
|
+
end
|
|
55
|
+
|
|
48
56
|
let(:account) do
|
|
49
57
|
directory.accounts.create email: 'test@example.com',
|
|
50
58
|
givenName: 'Ruby SDK',
|
|
@@ -57,12 +65,17 @@ describe Stormpath::Resource::Account, :vcr do
|
|
|
57
65
|
expect(account.directory).to eq(directory)
|
|
58
66
|
end
|
|
59
67
|
|
|
68
|
+
it 'should have many applications' do
|
|
69
|
+
expect(account.applications.count).to eq(1)
|
|
70
|
+
end
|
|
71
|
+
|
|
60
72
|
it 'should belong_to tenant' do
|
|
61
73
|
expect(account.tenant).to be
|
|
62
74
|
expect(account.tenant).to eq(account.directory.tenant)
|
|
63
75
|
end
|
|
64
76
|
|
|
65
77
|
after do
|
|
78
|
+
application.delete if application
|
|
66
79
|
account.delete if account
|
|
67
80
|
directory.delete if directory
|
|
68
81
|
end
|
|
@@ -5,6 +5,7 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
5
5
|
let(:app) { test_api_client.applications.create name: random_application_name, description: 'Dummy desc.' }
|
|
6
6
|
let(:application) { test_api_client.applications.get app.href }
|
|
7
7
|
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
8
|
+
let(:directory_with_verification) { test_directory_with_verification }
|
|
8
9
|
|
|
9
10
|
before do
|
|
10
11
|
test_api_client.account_store_mappings.create({ application: app, account_store: directory,
|
|
@@ -34,6 +35,7 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
34
35
|
expect(application.groups).to be_a Stormpath::Resource::Collection
|
|
35
36
|
expect(application.accounts).to be_a Stormpath::Resource::Collection
|
|
36
37
|
expect(application.password_reset_tokens).to be_a Stormpath::Resource::Collection
|
|
38
|
+
expect(application.verification_emails).to be_a Stormpath::Resource::Collection
|
|
37
39
|
expect(application.account_store_mappings).to be_a Stormpath::Resource::Collection
|
|
38
40
|
end
|
|
39
41
|
|
|
@@ -236,6 +238,125 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
236
238
|
end
|
|
237
239
|
end
|
|
238
240
|
|
|
241
|
+
describe '#verification_emails' do
|
|
242
|
+
let(:directory_with_verification) { test_directory_with_verification }
|
|
243
|
+
|
|
244
|
+
before do
|
|
245
|
+
test_api_client.account_store_mappings.create({ application: app, account_store: directory_with_verification,
|
|
246
|
+
list_index: 1, is_default_account_store: false, is_default_group_store: false })
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
let(:account) do
|
|
250
|
+
directory_with_verification.accounts.create({
|
|
251
|
+
email: random_email,
|
|
252
|
+
given_name: 'Ruby SDK',
|
|
253
|
+
password: 'P@$$w0rd',
|
|
254
|
+
surname: 'SDK',
|
|
255
|
+
username: random_user_name
|
|
256
|
+
})
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
let(:verification_emails) do
|
|
260
|
+
application.verification_emails.create(login: account.email)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
after do
|
|
264
|
+
account.delete if account
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
it 'returns verification email' do
|
|
268
|
+
expect(verification_emails).to be_kind_of Stormpath::Resource::VerificationEmail
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
describe 'create_login_attempt' do
|
|
273
|
+
let(:account) do
|
|
274
|
+
directory.accounts.create({
|
|
275
|
+
email: random_email,
|
|
276
|
+
given_name: 'Ruby SDK',
|
|
277
|
+
password: 'P@$$w0rd',
|
|
278
|
+
surname: 'SDK',
|
|
279
|
+
username: random_user_name
|
|
280
|
+
})
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
context 'valid credentials' do
|
|
284
|
+
let(:username_password_request) do
|
|
285
|
+
Stormpath::Authentication::UsernamePasswordRequest.new(
|
|
286
|
+
account.email,
|
|
287
|
+
"P@$$w0rd"
|
|
288
|
+
)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
let(:auth_request) { application.authenticate_account(username_password_request) }
|
|
292
|
+
|
|
293
|
+
it 'returns login attempt response' do
|
|
294
|
+
expect(auth_request).to be_kind_of Stormpath::Authentication::AuthenticationResult
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it 'containes account data' do
|
|
298
|
+
expect(auth_request.account.href).to eq(account.href)
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
context 'with organization as account store option' do
|
|
303
|
+
def create_organization_account_store_mapping(organization, account_store)
|
|
304
|
+
test_api_client.organization_account_store_mappings.create({
|
|
305
|
+
account_store: { href: account_store.href },
|
|
306
|
+
organization: { href: organization.href }
|
|
307
|
+
})
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
let(:organization) do
|
|
311
|
+
test_api_client.organizations.create name: 'test_organization',
|
|
312
|
+
name_key: "testorganization"
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
let(:username_password_request) do
|
|
316
|
+
Stormpath::Authentication::UsernamePasswordRequest.new(
|
|
317
|
+
account.email,
|
|
318
|
+
"P@$$w0rd",
|
|
319
|
+
account_store: organization.name_key
|
|
320
|
+
)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
let(:auth_request) { application.authenticate_account(username_password_request) }
|
|
324
|
+
|
|
325
|
+
before do
|
|
326
|
+
create_organization_account_store_mapping(organization, directory)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
after do
|
|
330
|
+
organization.delete if organization
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it 'returns login attempt response' do
|
|
334
|
+
expect(auth_request).to be_kind_of Stormpath::Authentication::AuthenticationResult
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it 'containes account data' do
|
|
338
|
+
expect(auth_request.account.href).to eq(account.href)
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
context 'with invalid credentials' do
|
|
343
|
+
let(:username_password_request) do
|
|
344
|
+
Stormpath::Authentication::UsernamePasswordRequest.new(
|
|
345
|
+
account.email,
|
|
346
|
+
"invalid"
|
|
347
|
+
)
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
let(:auth_request) { application.authenticate_account(username_password_request) }
|
|
351
|
+
|
|
352
|
+
it 'returns stormpath error' do
|
|
353
|
+
expect {
|
|
354
|
+
auth_request
|
|
355
|
+
}.to raise_error(Stormpath::Error)
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
239
360
|
describe '#verify_password_reset_token' do
|
|
240
361
|
let(:account) do
|
|
241
362
|
directory.accounts.create({
|
|
@@ -338,6 +459,25 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
338
459
|
it 'shoud create a request to /sso/logout' do
|
|
339
460
|
end
|
|
340
461
|
end
|
|
462
|
+
|
|
463
|
+
context 'without providing cb_uri' do
|
|
464
|
+
let(:create_id_site_url_result) do
|
|
465
|
+
options = { callback_uri: '' }
|
|
466
|
+
application.create_id_site_url options
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it 'should raise Stormpath Error with correct id_site error data' do
|
|
470
|
+
begin
|
|
471
|
+
create_id_site_url_result
|
|
472
|
+
rescue Stormpath::Error => error
|
|
473
|
+
expect(error.status).to eq(400)
|
|
474
|
+
expect(error.code).to eq(400)
|
|
475
|
+
expect(error.message).to eq("The specified callback URI (cb_uri) is not valid")
|
|
476
|
+
expect(error.developer_message).to eq("The specified callback URI (cb_uri) is not valid. Make sure the "\
|
|
477
|
+
"callback URI specified in your ID Site configuration matches the value specified.")
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
end
|
|
341
481
|
end
|
|
342
482
|
|
|
343
483
|
describe '#handle_id_site_callback' do
|
|
@@ -399,10 +539,21 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
399
539
|
}, test_api_key_secret, 'HS256')
|
|
400
540
|
}
|
|
401
541
|
|
|
542
|
+
it 'should raise Stormpath Error with correct data' do
|
|
543
|
+
begin
|
|
544
|
+
application.handle_id_site_callback(callback_uri_base + jwt_token)
|
|
545
|
+
rescue Stormpath::Error => error
|
|
546
|
+
expect(error.status).to eq(400)
|
|
547
|
+
expect(error.code).to eq(10011)
|
|
548
|
+
expect(error.message).to eq("Token is invalid")
|
|
549
|
+
expect(error.developer_message).to eq("Token is no longer valid because it has expired")
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
402
553
|
it 'should raise expiration error' do
|
|
403
554
|
expect {
|
|
404
555
|
application.handle_id_site_callback(callback_uri_base + jwt_token)
|
|
405
|
-
}.to raise_error(
|
|
556
|
+
}.to raise_error(Stormpath::Error)
|
|
406
557
|
end
|
|
407
558
|
end
|
|
408
559
|
|
|
@@ -423,6 +574,18 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
423
574
|
application.handle_id_site_callback(callback_uri_base + jwt_token)
|
|
424
575
|
}.to raise_error(Stormpath::Error)
|
|
425
576
|
end
|
|
577
|
+
|
|
578
|
+
it 'should raise Stormpath Error with correct id_site error data' do
|
|
579
|
+
begin
|
|
580
|
+
application.handle_id_site_callback(callback_uri_base + jwt_token)
|
|
581
|
+
rescue Stormpath::Error => error
|
|
582
|
+
expect(error.status).to eq(400)
|
|
583
|
+
expect(error.code).to eq(10012)
|
|
584
|
+
expect(error.message).to eq("Token is invalid")
|
|
585
|
+
expect(error.developer_message).to eq("Token is invalid because the issued at time (iat) "\
|
|
586
|
+
"is after the current time")
|
|
587
|
+
end
|
|
588
|
+
end
|
|
426
589
|
end
|
|
427
590
|
|
|
428
591
|
context 'with an invalid exp value' do
|
|
@@ -438,10 +601,10 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
438
601
|
}, test_api_key_secret, 'HS256')
|
|
439
602
|
}
|
|
440
603
|
|
|
441
|
-
it 'should error with the
|
|
604
|
+
it 'should error with the stormpath error' do
|
|
442
605
|
expect {
|
|
443
606
|
application.handle_id_site_callback(callback_uri_base + jwt_token)
|
|
444
|
-
}.to raise_error(
|
|
607
|
+
}.to raise_error(Stormpath::Error)
|
|
445
608
|
end
|
|
446
609
|
end
|
|
447
610
|
|
|
@@ -464,4 +627,81 @@ describe Stormpath::Resource::Application, :vcr do
|
|
|
464
627
|
end
|
|
465
628
|
end
|
|
466
629
|
end
|
|
630
|
+
|
|
631
|
+
describe '#authenticate_oauth' do
|
|
632
|
+
let(:account_data) { build_account }
|
|
633
|
+
let(:password_grant_request) { Stormpath::Oauth::PasswordGrantRequest.new account_data[:email], account_data[:password] }
|
|
634
|
+
let(:aquire_token) { application.authenticate_oauth(password_grant_request) }
|
|
635
|
+
|
|
636
|
+
before do
|
|
637
|
+
application.accounts.create account_data
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
context 'generate access token' do
|
|
641
|
+
let(:password_grant_request) { Stormpath::Oauth::PasswordGrantRequest.new account_data[:email], account_data[:password] }
|
|
642
|
+
let(:authenticate_oauth) { application.authenticate_oauth(password_grant_request) }
|
|
643
|
+
|
|
644
|
+
it 'should return access token response' do
|
|
645
|
+
expect(authenticate_oauth).to be_kind_of(Stormpath::Resource::AccessToken)
|
|
646
|
+
end
|
|
647
|
+
|
|
648
|
+
it 'response should contain token data' do
|
|
649
|
+
expect(authenticate_oauth.access_token).not_to be_empty
|
|
650
|
+
expect(authenticate_oauth.refresh_token).not_to be_empty
|
|
651
|
+
expect(authenticate_oauth.token_type).not_to be_empty
|
|
652
|
+
expect(authenticate_oauth.expires_in).not_to be_nil
|
|
653
|
+
expect(authenticate_oauth.stormpath_access_token_href).not_to be_empty
|
|
654
|
+
end
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
context 'refresh token' do
|
|
658
|
+
let(:refresh_grant_request) { Stormpath::Oauth::RefreshGrantRequest.new aquire_token.refresh_token }
|
|
659
|
+
let(:authenticate_oauth) { application.authenticate_oauth(refresh_grant_request) }
|
|
660
|
+
|
|
661
|
+
it 'should return access token response with refreshed token' do
|
|
662
|
+
expect(authenticate_oauth).to be_kind_of(Stormpath::Resource::AccessToken)
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
it 'refreshed token is not the same as previous one' do
|
|
666
|
+
expect(authenticate_oauth.access_token).not_to be_equal(aquire_token.access_token)
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
it 'returens success with data' do
|
|
670
|
+
expect(authenticate_oauth.access_token).not_to be_empty
|
|
671
|
+
expect(authenticate_oauth.refresh_token).not_to be_empty
|
|
672
|
+
expect(authenticate_oauth.token_type).not_to be_empty
|
|
673
|
+
expect(authenticate_oauth.expires_in).not_to be_nil
|
|
674
|
+
expect(authenticate_oauth.stormpath_access_token_href).not_to be_empty
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
context 'validate access token' do
|
|
679
|
+
let(:access_token) { aquire_token.access_token }
|
|
680
|
+
let(:authenticate_oauth) { Stormpath::Oauth::VerifyAccessToken.new(application).verify(access_token) }
|
|
681
|
+
|
|
682
|
+
it 'should return authentication result response' do
|
|
683
|
+
expect(authenticate_oauth).to be_kind_of(Stormpath::Oauth::VerifyToken)
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
it 'returens success on valid token' do
|
|
687
|
+
expect(authenticate_oauth.href).not_to be_empty
|
|
688
|
+
expect(authenticate_oauth.account).not_to be_empty
|
|
689
|
+
expect(authenticate_oauth.application).not_to be_empty
|
|
690
|
+
expect(authenticate_oauth.jwt).not_to be_empty
|
|
691
|
+
expect(authenticate_oauth.tenant).not_to be_empty
|
|
692
|
+
expect(authenticate_oauth.expanded_jwt).not_to be_empty
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
context 'delete token' do
|
|
697
|
+
it 'after token was deleted user can authenticate with the same token' do
|
|
698
|
+
access_token = aquire_token.access_token
|
|
699
|
+
aquire_token.delete
|
|
700
|
+
|
|
701
|
+
expect {
|
|
702
|
+
Stormpath::Oauth::VerifyAccessToken.new(application).verify(access_token)
|
|
703
|
+
}.to raise_error(Stormpath::Error)
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
end
|
|
467
707
|
end
|
|
@@ -3,10 +3,19 @@ require 'spec_helper'
|
|
|
3
3
|
describe Stormpath::Resource::Directory, :vcr do
|
|
4
4
|
|
|
5
5
|
describe "instances should respond to attribute property methods" do
|
|
6
|
+
let(:app) { test_api_client.applications.create name: random_application_name, description: 'Dummy desc.' }
|
|
7
|
+
let(:application) { test_api_client.applications.get app.href }
|
|
6
8
|
let(:directory) { test_api_client.directories.create name: random_directory_name, description: 'description_for_some_test_directory' }
|
|
9
|
+
let(:directory_with_verification) { test_directory_with_verification }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
test_api_client.account_store_mappings.create({ application: app, account_store: directory_with_verification,
|
|
13
|
+
list_index: 1, is_default_account_store: false, is_default_group_store: false })
|
|
14
|
+
end
|
|
7
15
|
|
|
8
16
|
after do
|
|
9
17
|
directory.delete if directory
|
|
18
|
+
application.delete if application
|
|
10
19
|
end
|
|
11
20
|
|
|
12
21
|
it do
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Stormpath::Resource::Organization, :vcr do
|
|
4
|
+
|
|
5
|
+
let(:organization) do
|
|
6
|
+
test_api_client.organizations.create name: 'test_organization',
|
|
7
|
+
name_key: "testorganization"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after do
|
|
11
|
+
organization.delete if organization
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create_organization_account_store_mapping(organization, account_store)
|
|
15
|
+
test_api_client.organization_account_store_mappings.create({
|
|
16
|
+
account_store: { href: account_store.href },
|
|
17
|
+
organization: { href: organization.href }
|
|
18
|
+
})
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
describe 'get resource' do
|
|
22
|
+
let(:fetched_organization) { test_api_client.organizations.get organization.href }
|
|
23
|
+
|
|
24
|
+
it 'returns the organization resource with correct attribute properties' do
|
|
25
|
+
expect(fetched_organization).to be_kind_of(Stormpath::Resource::Organization)
|
|
26
|
+
expect(fetched_organization.name).to eq(organization.name)
|
|
27
|
+
expect(fetched_organization.description).to eq(organization.description)
|
|
28
|
+
expect(fetched_organization.name_key).to eq(organization.name_key)
|
|
29
|
+
expect(fetched_organization.status).to eq(organization.status)
|
|
30
|
+
expect(fetched_organization.account_store_mappings).to eq(organization.account_store_mappings)
|
|
31
|
+
expect(fetched_organization.default_account_store_mapping).to eq(organization.default_account_store_mapping)
|
|
32
|
+
expect(fetched_organization.default_group_store_mapping).to eq(organization.default_group_store_mapping)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'returns custom_data' do
|
|
36
|
+
expect(organization.custom_data).to be_a Stormpath::Resource::CustomData
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe 'create' do
|
|
41
|
+
context 'invalid data' do
|
|
42
|
+
it 'should raise Stormpath::Error' do
|
|
43
|
+
expect do
|
|
44
|
+
test_api_client.organizations.create name: 'test_organization',
|
|
45
|
+
name_key: "test_org"
|
|
46
|
+
end.to raise_error(Stormpath::Error)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe 'associations' do
|
|
52
|
+
context 'groups' do
|
|
53
|
+
|
|
54
|
+
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
55
|
+
|
|
56
|
+
let(:group) { directory.groups.create name: "test_group" }
|
|
57
|
+
|
|
58
|
+
before do
|
|
59
|
+
create_organization_account_store_mapping(organization, group)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
after do
|
|
63
|
+
organization.delete if organization
|
|
64
|
+
directory.delete if directory
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'returns a collection of groups' do
|
|
68
|
+
expect(organization.groups).to be_kind_of(Stormpath::Resource::Collection)
|
|
69
|
+
expect(organization.groups).to include(group)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context 'accounts' do
|
|
74
|
+
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
75
|
+
|
|
76
|
+
let(:account) { directory.accounts.create({ email: 'rubysdk@example.com', given_name: 'Ruby SDK', password: 'P@$$w0rd',surname: 'SDK' }) }
|
|
77
|
+
|
|
78
|
+
before do
|
|
79
|
+
create_organization_account_store_mapping(organization, directory)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
after do
|
|
83
|
+
organization.delete if organization
|
|
84
|
+
directory.delete if directory
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'returns a collection of groups' do
|
|
88
|
+
expect(organization.accounts).to be_kind_of(Stormpath::Resource::Collection)
|
|
89
|
+
expect(organization.accounts).to include(account)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'tenant' do
|
|
94
|
+
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
95
|
+
|
|
96
|
+
before do
|
|
97
|
+
create_organization_account_store_mapping(organization, directory)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
after do
|
|
101
|
+
organization.delete if organization
|
|
102
|
+
directory.delete if directory
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'returns tenant' do
|
|
106
|
+
expect(organization.tenant).to eq(directory.tenant)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe 'delete' do
|
|
112
|
+
let(:href) { organization.href }
|
|
113
|
+
|
|
114
|
+
before do
|
|
115
|
+
organization.delete
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it 'removes the organization' do
|
|
119
|
+
expect do
|
|
120
|
+
test_api_client.organizations.get href
|
|
121
|
+
end.to raise_error(Stormpath::Error)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe 'update' do
|
|
126
|
+
before do
|
|
127
|
+
organization.name_key = "changed-test-organization"
|
|
128
|
+
organization.save
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it 'can change the data of the existing organization' do
|
|
132
|
+
org = test_api_client.organizations.get organization.href
|
|
133
|
+
expect(org.name_key).to eq("changed-test-organization")
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
describe 'organization account store mapping' do
|
|
138
|
+
context 'given an account_store is a directory' do
|
|
139
|
+
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
140
|
+
|
|
141
|
+
let(:organization_account_store_mapping) do
|
|
142
|
+
create_organization_account_store_mapping(organization, directory)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
let(:reloaded_mapping) do
|
|
146
|
+
test_api_client.account_store_mappings.get organization_account_store_mapping.href
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
after do
|
|
150
|
+
organization.delete if organization
|
|
151
|
+
directory.delete if directory
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'should return a directory' do
|
|
155
|
+
expect(reloaded_mapping.account_store.class).to eq(Stormpath::Resource::Directory)
|
|
156
|
+
expect(reloaded_mapping.account_store).to eq(directory)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
context 'given an account_store is a group' do
|
|
161
|
+
let(:directory) { test_api_client.directories.create name: random_directory_name }
|
|
162
|
+
|
|
163
|
+
let(:group) { directory.groups.create name: "test_group" }
|
|
164
|
+
|
|
165
|
+
let(:organization_account_store_mapping) do
|
|
166
|
+
create_organization_account_store_mapping(organization, group)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
let(:reloaded_mapping) do
|
|
170
|
+
test_api_client.account_store_mappings.get organization_account_store_mapping.href
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
after do
|
|
174
|
+
organization.delete if organization
|
|
175
|
+
group.delete if group
|
|
176
|
+
directory.delete if directory
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it 'should return group' do
|
|
180
|
+
expect(reloaded_mapping.account_store.class).to eq(Stormpath::Resource::Group)
|
|
181
|
+
expect(reloaded_mapping.account_store).to eq(group)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -74,7 +74,7 @@ shared_examples_for 'custom_data_storage' do
|
|
|
74
74
|
RESERVED_FIELDS.each do |reserved_field|
|
|
75
75
|
it "set reserved data #{reserved_field} should raise error" do
|
|
76
76
|
custom_data_storage.custom_data[reserved_field] = 12
|
|
77
|
-
expect{ custom_data_storage.custom_data.save }.to raise_error
|
|
77
|
+
expect{ custom_data_storage.custom_data.save }.to raise_error Stormpath::Error
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -388,4 +388,4 @@ shared_examples_for 'custom_data_storage' do
|
|
|
388
388
|
def deleted_properties
|
|
389
389
|
custom_data_storage.custom_data.instance_variable_get("@deleted_properties")
|
|
390
390
|
end
|
|
391
|
-
end
|
|
391
|
+
end
|
data/stormpath-sdk.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stormpath-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.0.beta.
|
|
4
|
+
version: 1.0.0.beta.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stormpath, Inc
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2015-
|
|
12
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: multi_json
|
|
@@ -283,7 +283,15 @@ files:
|
|
|
283
283
|
- lib/stormpath-sdk/http/request.rb
|
|
284
284
|
- lib/stormpath-sdk/http/response.rb
|
|
285
285
|
- lib/stormpath-sdk/http/utils.rb
|
|
286
|
+
- lib/stormpath-sdk/id_site/error.rb
|
|
286
287
|
- lib/stormpath-sdk/id_site/id_site_result.rb
|
|
288
|
+
- lib/stormpath-sdk/oauth/authenticator.rb
|
|
289
|
+
- lib/stormpath-sdk/oauth/password_grant.rb
|
|
290
|
+
- lib/stormpath-sdk/oauth/password_grant_request.rb
|
|
291
|
+
- lib/stormpath-sdk/oauth/refresh_grant_request.rb
|
|
292
|
+
- lib/stormpath-sdk/oauth/refresh_token.rb
|
|
293
|
+
- lib/stormpath-sdk/oauth/verify_access_token.rb
|
|
294
|
+
- lib/stormpath-sdk/oauth/verify_token.rb
|
|
287
295
|
- lib/stormpath-sdk/provider/account_access.rb
|
|
288
296
|
- lib/stormpath-sdk/provider/account_request.rb
|
|
289
297
|
- lib/stormpath-sdk/provider/account_resolver.rb
|
|
@@ -296,6 +304,7 @@ files:
|
|
|
296
304
|
- lib/stormpath-sdk/provider/provider_data.rb
|
|
297
305
|
- lib/stormpath-sdk/provider/stormpath/stormpath_provider.rb
|
|
298
306
|
- lib/stormpath-sdk/provider/stormpath/stormpath_provider_data.rb
|
|
307
|
+
- lib/stormpath-sdk/resource/access_token.rb
|
|
299
308
|
- lib/stormpath-sdk/resource/account.rb
|
|
300
309
|
- lib/stormpath-sdk/resource/account_membership.rb
|
|
301
310
|
- lib/stormpath-sdk/resource/account_status.rb
|
|
@@ -315,10 +324,14 @@ files:
|
|
|
315
324
|
- lib/stormpath-sdk/resource/group.rb
|
|
316
325
|
- lib/stormpath-sdk/resource/group_membership.rb
|
|
317
326
|
- lib/stormpath-sdk/resource/instance.rb
|
|
327
|
+
- lib/stormpath-sdk/resource/oauth_policy.rb
|
|
328
|
+
- lib/stormpath-sdk/resource/organization.rb
|
|
329
|
+
- lib/stormpath-sdk/resource/organization_account_store_mapping.rb
|
|
318
330
|
- lib/stormpath-sdk/resource/password_reset_token.rb
|
|
319
331
|
- lib/stormpath-sdk/resource/status.rb
|
|
320
332
|
- lib/stormpath-sdk/resource/tenant.rb
|
|
321
333
|
- lib/stormpath-sdk/resource/utils.rb
|
|
334
|
+
- lib/stormpath-sdk/resource/verification_email.rb
|
|
322
335
|
- lib/stormpath-sdk/util/assert.rb
|
|
323
336
|
- lib/stormpath-sdk/version.rb
|
|
324
337
|
- spec/api_key_spec.rb
|
|
@@ -342,6 +355,7 @@ files:
|
|
|
342
355
|
- spec/resource/expansion_spec.rb
|
|
343
356
|
- spec/resource/group_membership_spec.rb
|
|
344
357
|
- spec/resource/group_spec.rb
|
|
358
|
+
- spec/resource/organization_spec.rb
|
|
345
359
|
- spec/resource/status_spec.rb
|
|
346
360
|
- spec/resource/tenant_spec.rb
|
|
347
361
|
- spec/spec_helper.rb
|
|
@@ -382,3 +396,4 @@ signing_key:
|
|
|
382
396
|
specification_version: 4
|
|
383
397
|
summary: Stormpath SDK
|
|
384
398
|
test_files: []
|
|
399
|
+
has_rdoc:
|