stormpath-sdk 1.0.0.beta.4 → 1.0.0.beta.5
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 +1 -0
- data/CHANGES.md +15 -0
- data/README.md +35 -3
- data/lib/stormpath-sdk.rb +5 -6
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +2 -0
- data/lib/stormpath-sdk/auth/basic_login_attempt.rb +11 -0
- data/lib/stormpath-sdk/auth/username_password_request.rb +6 -12
- data/lib/stormpath-sdk/data_store.rb +118 -127
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +10 -42
- data/lib/stormpath-sdk/resource/account.rb +13 -3
- data/lib/stormpath-sdk/resource/account_membership.rb +16 -0
- data/lib/stormpath-sdk/resource/account_status.rb +26 -0
- data/lib/stormpath-sdk/resource/account_store_mapping.rb +4 -2
- data/lib/stormpath-sdk/resource/application.rb +4 -2
- data/lib/stormpath-sdk/resource/associations.rb +7 -3
- data/lib/stormpath-sdk/resource/base.rb +21 -15
- data/lib/stormpath-sdk/resource/custom_data.rb +86 -0
- data/lib/stormpath-sdk/resource/custom_data_hash_methods.rb +33 -0
- data/lib/stormpath-sdk/resource/custom_data_storage.rb +39 -0
- data/lib/stormpath-sdk/resource/directory.rb +4 -4
- data/lib/stormpath-sdk/resource/expansion.rb +15 -0
- data/lib/stormpath-sdk/resource/group.rb +10 -0
- data/lib/stormpath-sdk/resource/status.rb +16 -5
- data/lib/stormpath-sdk/version.rb +2 -2
- data/spec/client_spec.rb +6 -1
- data/spec/data_store_spec.rb +7 -2
- data/spec/resource/account_spec.rb +73 -30
- data/spec/resource/account_store_mapping_spec.rb +20 -5
- data/spec/resource/application_spec.rb +135 -0
- data/spec/resource/custom_data_spec.rb +198 -0
- data/spec/resource/directory_spec.rb +192 -9
- data/spec/resource/group_membership_spec.rb +35 -0
- data/spec/resource/group_spec.rb +44 -26
- data/spec/resource/status_spec.rb +81 -0
- data/spec/resource/tenant_spec.rb +19 -0
- data/stormpath-sdk.gemspec +2 -2
- metadata +13 -3
@@ -14,25 +14,18 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
module Stormpath
|
17
|
-
|
18
17
|
module Http
|
19
|
-
|
20
18
|
class HttpClientRequestExecutor
|
21
|
-
|
22
19
|
include Stormpath::Http::Authc
|
23
20
|
include Stormpath::Util::Assert
|
24
21
|
|
25
|
-
REDIRECTS_LIMIT = 10
|
26
|
-
|
27
22
|
def initialize(api_key, options = {})
|
28
23
|
@signer = Sauthc1Signer.new
|
29
24
|
@api_key = api_key
|
30
25
|
@http_client = HTTPClient.new options[:proxy]
|
31
|
-
@redirects_limit = REDIRECTS_LIMIT
|
32
26
|
end
|
33
27
|
|
34
|
-
def execute_request(request)
|
35
|
-
|
28
|
+
def execute_request(request, redirects_limit = 10)
|
36
29
|
assert_not_nil request, "Request argument cannot be null."
|
37
30
|
|
38
31
|
@redirect_response = nil
|
@@ -47,56 +40,31 @@ module Stormpath
|
|
47
40
|
|
48
41
|
method = @http_client.method(request.http_method.downcase)
|
49
42
|
|
50
|
-
|
51
|
-
|
52
|
-
response = method.call domain, nil, request.http_headers
|
43
|
+
response = method.call domain, request.body, request.http_headers
|
53
44
|
|
54
|
-
|
55
|
-
|
56
|
-
response = method.call domain, request.body, request.http_headers
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
if response.redirect? and @redirects_limit > 0
|
45
|
+
if response.redirect? and redirects_limit > 0
|
61
46
|
request.href = response.http_header['location'][0]
|
62
|
-
|
63
|
-
@redirect_response = execute_request request
|
47
|
+
redirects_limit -= 1
|
48
|
+
@redirect_response = execute_request request, redirects_limit
|
64
49
|
return @redirect_response
|
65
50
|
end
|
66
51
|
|
67
|
-
|
68
|
-
@redirects_limit = REDIRECTS_LIMIT
|
69
|
-
@redirect_response
|
70
|
-
else
|
71
|
-
Response.new response.http_header.status_code,
|
52
|
+
Response.new response.http_header.status_code,
|
72
53
|
response.http_header.body_type,
|
73
54
|
response.content,
|
74
55
|
response.http_header.body_size
|
75
|
-
end
|
76
|
-
|
77
56
|
end
|
78
57
|
|
79
58
|
private
|
80
59
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
if href.include? '?'
|
86
|
-
|
87
|
-
href << '&' << key.to_s << '=' << value.to_s
|
88
|
-
|
89
|
-
else
|
90
|
-
href << '?' << key.to_s << '=' << value.to_s
|
60
|
+
def add_query_string href, query_string
|
61
|
+
query_string.each do |key, value|
|
62
|
+
prefix = if href.include? '?' then '&' else '?' end
|
63
|
+
href << prefix << key.to_s << '=' << value.to_s
|
91
64
|
end
|
92
|
-
|
93
65
|
end
|
94
66
|
|
95
|
-
end
|
96
|
-
|
97
67
|
end
|
98
|
-
|
99
68
|
end
|
100
|
-
|
101
69
|
end
|
102
70
|
|
@@ -13,8 +13,9 @@
|
|
13
13
|
# See the License for the specific language governing permissions and
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
|
-
class
|
17
|
-
include Stormpath::Resource::
|
16
|
+
class Stormpath::Resource::Account < Stormpath::Resource::Instance
|
17
|
+
include Stormpath::Resource::AccountStatus
|
18
|
+
include Stormpath::Resource::CustomDataStorage
|
18
19
|
|
19
20
|
prop_accessor :username, :email, :given_name, :middle_name, :surname
|
20
21
|
prop_writer :password
|
@@ -22,13 +23,22 @@ class Stormpath::Resource::Account < Stormpath::Resource::Instance
|
|
22
23
|
prop_non_printable :password
|
23
24
|
|
24
25
|
belongs_to :directory
|
26
|
+
belongs_to :tenant
|
27
|
+
|
25
28
|
has_one :email_verification_token
|
26
29
|
|
27
30
|
has_many :groups
|
28
31
|
has_many :group_memberships
|
29
32
|
|
33
|
+
has_one :custom_data
|
34
|
+
|
30
35
|
def add_group group
|
31
36
|
client.group_memberships.create group: group, account: self
|
32
37
|
end
|
33
|
-
|
38
|
+
|
39
|
+
def remove_group group
|
40
|
+
group_membership = group_memberships.find {|group_membership| group_membership.group.href == group.href }
|
41
|
+
group_membership.delete if group_membership
|
42
|
+
end
|
43
|
+
|
34
44
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2014 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
|
+
Stormpath::Resource::AccountMembership = Stormpath::Resource::GroupMembership
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2014 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
|
+
module Stormpath::Resource::AccountStatus
|
17
|
+
include Stormpath::Resource::Status
|
18
|
+
|
19
|
+
UNVERIFIED = 'UNVERIFIED'
|
20
|
+
LOCKED = 'LOCKED'
|
21
|
+
|
22
|
+
def status_hash
|
23
|
+
super.merge UNVERIFIED => UNVERIFIED, LOCKED => LOCKED
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -14,7 +14,6 @@
|
|
14
14
|
# limitations under the License.
|
15
15
|
#
|
16
16
|
class Stormpath::Resource::AccountStoreMapping < Stormpath::Resource::Instance
|
17
|
-
include Stormpath::Resource::Status
|
18
17
|
|
19
18
|
prop_accessor :list_index, :is_default_account_store, :is_default_group_store
|
20
19
|
|
@@ -24,9 +23,12 @@ class Stormpath::Resource::AccountStoreMapping < Stormpath::Resource::Instance
|
|
24
23
|
|
25
24
|
alias_method :default_account_store, :is_default_account_store
|
26
25
|
alias_method :default_account_store?, :is_default_account_store
|
26
|
+
|
27
|
+
alias_method :default_account_store=, :is_default_account_store=
|
28
|
+
|
27
29
|
alias_method :default_group_store, :is_default_group_store
|
28
30
|
alias_method :default_group_store?, :is_default_group_store
|
29
|
-
|
31
|
+
|
30
32
|
alias_method :default_group_store=, :is_default_group_store=
|
31
33
|
|
32
34
|
end
|
@@ -21,10 +21,12 @@ class Stormpath::Resource::Application < Stormpath::Resource::Instance
|
|
21
21
|
prop_accessor :name, :description
|
22
22
|
|
23
23
|
belongs_to :tenant
|
24
|
-
|
24
|
+
|
25
|
+
has_many :accounts, can: [:get, :create]
|
25
26
|
has_many :password_reset_tokens, can: [:get, :create]
|
26
27
|
has_many :account_store_mappings, can: [:get, :create]
|
27
|
-
|
28
|
+
has_many :groups, can: [:get, :create]
|
29
|
+
|
28
30
|
has_one :default_account_store_mapping, class_name: :accountStoreMapping
|
29
31
|
has_one :default_group_store_mapping, class_name: :accountStoreMapping
|
30
32
|
|
@@ -24,7 +24,6 @@ module Stormpath
|
|
24
24
|
options[:class_name] ||= name
|
25
25
|
resource_class = "Stormpath::Resource::#{options[:class_name].to_s.camelize}".constantize
|
26
26
|
property_name = name.to_s.camelize :lower
|
27
|
-
|
28
27
|
define_method(name) do
|
29
28
|
get_resource_property property_name, resource_class
|
30
29
|
end
|
@@ -90,9 +89,14 @@ module Stormpath
|
|
90
89
|
href = get_href_from_hash value
|
91
90
|
end
|
92
91
|
|
93
|
-
if
|
94
|
-
|
92
|
+
if instance_variable_get("@_#{key.underscore}").nil?
|
93
|
+
if href
|
94
|
+
instance_variable_set("@_#{key.underscore}", data_store.instantiate(clazz, value))
|
95
|
+
else
|
96
|
+
instance_variable_set("@_#{key.underscore}", clazz.new(value))
|
97
|
+
end
|
95
98
|
end
|
99
|
+
instance_variable_get("@_#{key.underscore}")
|
96
100
|
end
|
97
101
|
|
98
102
|
def get_resource_href_property(key)
|
@@ -18,26 +18,22 @@ class Stormpath::Resource::Base
|
|
18
18
|
include Stormpath::Resource::Associations
|
19
19
|
|
20
20
|
HREF_PROP_NAME = "href"
|
21
|
-
|
21
|
+
DEFAULT_SERVER_HOST = Stormpath::DataStore::DEFAULT_SERVER_HOST
|
22
22
|
attr_reader :client, :properties
|
23
23
|
|
24
24
|
class << self
|
25
25
|
def prop_reader(*args)
|
26
26
|
args.each do |name|
|
27
|
-
property_name = name.to_s.camelize :lower
|
28
|
-
|
29
27
|
define_method(name) do
|
30
|
-
get_property
|
28
|
+
get_property name
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
35
33
|
def prop_writer(*args)
|
36
34
|
args.each do |name|
|
37
|
-
property_name = name.to_s.camelize :lower
|
38
|
-
|
39
35
|
define_method("#{name.to_s}=") do |value|
|
40
|
-
set_property
|
36
|
+
set_property name, value
|
41
37
|
end
|
42
38
|
end
|
43
39
|
end
|
@@ -79,6 +75,7 @@ class Stormpath::Resource::Base
|
|
79
75
|
@write_lock = Mutex.new
|
80
76
|
@properties = Hash.new
|
81
77
|
@dirty_properties = Hash.new
|
78
|
+
@deleted_properties = Array.new
|
82
79
|
set_properties properties
|
83
80
|
end
|
84
81
|
|
@@ -106,6 +103,16 @@ class Stormpath::Resource::Base
|
|
106
103
|
end
|
107
104
|
end
|
108
105
|
|
106
|
+
def get_dirty_property_names
|
107
|
+
@read_lock.lock
|
108
|
+
|
109
|
+
begin
|
110
|
+
@dirty_properties.keys
|
111
|
+
ensure
|
112
|
+
@read_lock.unlock
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
109
116
|
def set_properties properties
|
110
117
|
@write_lock.lock
|
111
118
|
|
@@ -114,9 +121,9 @@ class Stormpath::Resource::Base
|
|
114
121
|
@dirty_properties.clear
|
115
122
|
@dirty = false
|
116
123
|
|
117
|
-
|
124
|
+
if properties
|
118
125
|
@properties = deep_sanitize properties
|
119
|
-
|
126
|
+
@dirty_properties = @properties if new?
|
120
127
|
# Don't consider this resource materialized if it is only a reference. A reference is any object that
|
121
128
|
# has only one 'href' property.
|
122
129
|
href_only = (@properties.size == 1 and @properties.has_key? HREF_PROP_NAME)
|
@@ -133,7 +140,7 @@ class Stormpath::Resource::Base
|
|
133
140
|
def get_property name
|
134
141
|
property_name = name.to_s.camelize :lower
|
135
142
|
|
136
|
-
if
|
143
|
+
if HREF_PROP_NAME != property_name
|
137
144
|
#not the href/id, must be a property that requires materialization:
|
138
145
|
unless new? or materialized?
|
139
146
|
|
@@ -155,7 +162,7 @@ class Stormpath::Resource::Base
|
|
155
162
|
end
|
156
163
|
end
|
157
164
|
|
158
|
-
read_property
|
165
|
+
read_property property_name
|
159
166
|
end
|
160
167
|
|
161
168
|
def set_property name, value
|
@@ -214,7 +221,7 @@ class Stormpath::Resource::Base
|
|
214
221
|
private
|
215
222
|
|
216
223
|
def get_href_from_hash(props)
|
217
|
-
if
|
224
|
+
if props and props.is_a? Hash
|
218
225
|
props[HREF_PROP_NAME]
|
219
226
|
end
|
220
227
|
end
|
@@ -233,10 +240,8 @@ class Stormpath::Resource::Base
|
|
233
240
|
{}.tap do |sanitized_properties|
|
234
241
|
properties.map do |key, value|
|
235
242
|
property_name = key.to_s.camelize :lower
|
236
|
-
|
237
243
|
sanitized_properties[property_name] =
|
238
|
-
if
|
239
|
-
(value.kind_of? Stormpath::Resource::Base)
|
244
|
+
if value.kind_of? Hash or value.kind_of? Stormpath::Resource::Base
|
240
245
|
deep_sanitize value
|
241
246
|
else
|
242
247
|
value
|
@@ -253,4 +258,5 @@ class Stormpath::Resource::Base
|
|
253
258
|
sanitize hash_or_resource
|
254
259
|
end
|
255
260
|
end
|
261
|
+
|
256
262
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2013 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::Resource::CustomData < Stormpath::Resource::Instance
|
17
|
+
include Stormpath::Resource::CustomDataHashMethods
|
18
|
+
|
19
|
+
def [](property_name)
|
20
|
+
get_property property_name
|
21
|
+
end
|
22
|
+
|
23
|
+
def []=(property_name, property_value)
|
24
|
+
set_property property_name, property_value
|
25
|
+
end
|
26
|
+
|
27
|
+
def save
|
28
|
+
if has_removed_properties?
|
29
|
+
delete_removed_properties
|
30
|
+
end
|
31
|
+
if has_new_properties?
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete(name = nil)
|
37
|
+
super() if name.nil?
|
38
|
+
|
39
|
+
@write_lock.lock
|
40
|
+
property_name = name.to_s
|
41
|
+
begin
|
42
|
+
@properties.delete(property_name)
|
43
|
+
@dirty_properties.delete(property_name)
|
44
|
+
@deleted_properties << property_name
|
45
|
+
@dirty = true
|
46
|
+
ensure
|
47
|
+
@write_lock.unlock
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def sanitize(properties)
|
54
|
+
{}.tap do |sanitized_properties|
|
55
|
+
properties.map do |key, value|
|
56
|
+
property_name = key.to_s.camelize :lower
|
57
|
+
sanitized_properties[property_name] = value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def has_removed_properties?
|
63
|
+
@read_lock.lock
|
64
|
+
begin
|
65
|
+
!@deleted_properties.empty?
|
66
|
+
ensure
|
67
|
+
@read_lock.unlock
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def has_new_properties?
|
72
|
+
@read_lock.lock
|
73
|
+
begin
|
74
|
+
!@dirty_properties.empty?
|
75
|
+
ensure
|
76
|
+
@read_lock.unlock
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def delete_removed_properties
|
81
|
+
@deleted_properties.each do |deleted_property_name|
|
82
|
+
data_store.delete self, deleted_property_name
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Stormpath::Resource::CustomDataHashMethods
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
def has_key?(key)
|
6
|
+
materialize unless materialized?
|
7
|
+
properties.has_key? key.to_s.camelize(:lower)
|
8
|
+
end
|
9
|
+
|
10
|
+
alias_method :include?, :has_key?
|
11
|
+
|
12
|
+
def has_value?(value)
|
13
|
+
materialize unless materialized?
|
14
|
+
properties.has_value? value
|
15
|
+
end
|
16
|
+
|
17
|
+
def store(key, value)
|
18
|
+
materialize unless materialized?
|
19
|
+
self[key] = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def keys
|
23
|
+
materialize unless materialized?
|
24
|
+
properties.keys.map {|key| key.to_s.underscore}
|
25
|
+
end
|
26
|
+
|
27
|
+
def values
|
28
|
+
materialize unless materialized?
|
29
|
+
properties.values
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|