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.
Files changed (89) hide show
  1. data/.gitignore +6 -0
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +27 -0
  5. data/CHANGES.md +21 -1
  6. data/Gemfile +1 -2
  7. data/README.md +457 -11
  8. data/Rakefile +15 -1
  9. data/lib/stormpath-sdk.rb +52 -33
  10. data/lib/stormpath-sdk/{resource/group_list.rb → api_key.rb} +5 -9
  11. data/lib/stormpath-sdk/auth/authentication_result.rb +3 -13
  12. data/lib/stormpath-sdk/auth/basic_authenticator.rb +5 -11
  13. data/lib/stormpath-sdk/auth/basic_login_attempt.rb +6 -8
  14. data/lib/stormpath-sdk/auth/username_password_request.rb +2 -5
  15. data/lib/stormpath-sdk/cache/cache.rb +54 -0
  16. data/lib/stormpath-sdk/cache/cache_entry.rb +33 -0
  17. data/lib/stormpath-sdk/cache/cache_manager.rb +22 -0
  18. data/lib/stormpath-sdk/cache/cache_stats.rb +35 -0
  19. data/lib/stormpath-sdk/cache/memory_store.rb +29 -0
  20. data/lib/stormpath-sdk/cache/redis_store.rb +32 -0
  21. data/lib/stormpath-sdk/client.rb +111 -0
  22. data/lib/stormpath-sdk/data_store.rb +241 -0
  23. data/lib/stormpath-sdk/{client/api_key.rb → error.rb} +16 -10
  24. data/lib/stormpath-sdk/{util → ext}/hash.rb +1 -2
  25. data/lib/stormpath-sdk/http/authc/sauthc1_signer.rb +8 -4
  26. data/lib/stormpath-sdk/http/http_client_request_executor.rb +8 -7
  27. data/lib/stormpath-sdk/http/request.rb +4 -8
  28. data/lib/stormpath-sdk/{util/request_utils.rb → http/utils.rb} +17 -38
  29. data/lib/stormpath-sdk/resource/account.rb +12 -108
  30. data/lib/stormpath-sdk/resource/application.rb +35 -171
  31. data/lib/stormpath-sdk/resource/associations.rb +97 -0
  32. data/lib/stormpath-sdk/resource/base.rb +256 -0
  33. data/lib/stormpath-sdk/resource/collection.rb +94 -0
  34. data/lib/stormpath-sdk/resource/directory.rb +11 -68
  35. data/lib/stormpath-sdk/resource/email_verification_token.rb +3 -9
  36. data/lib/stormpath-sdk/resource/error.rb +4 -38
  37. data/lib/stormpath-sdk/resource/expansion.rb +28 -0
  38. data/lib/stormpath-sdk/resource/group.rb +8 -66
  39. data/lib/stormpath-sdk/resource/group_membership.rb +4 -55
  40. data/lib/stormpath-sdk/resource/{application_list.rb → instance.rb} +7 -13
  41. data/lib/stormpath-sdk/resource/password_reset_token.rb +5 -23
  42. data/lib/stormpath-sdk/resource/status.rb +22 -28
  43. data/lib/stormpath-sdk/resource/tenant.rb +5 -52
  44. data/lib/stormpath-sdk/resource/utils.rb +43 -13
  45. data/lib/stormpath-sdk/util/assert.rb +5 -15
  46. data/lib/stormpath-sdk/version.rb +3 -3
  47. data/spec/api_key_spec.rb +19 -0
  48. data/spec/auth/basic_authenticator_spec.rb +25 -0
  49. data/spec/auth/sauthc1_signer_spec.rb +42 -0
  50. data/spec/cache/cache_entry_spec.rb +157 -0
  51. data/spec/cache/cache_spec.rb +89 -0
  52. data/spec/cache/cache_stats_spec.rb +106 -0
  53. data/spec/client_spec.rb +538 -0
  54. data/spec/data_store_spec.rb +130 -0
  55. data/spec/resource/account_spec.rb +74 -0
  56. data/spec/resource/application_spec.rb +148 -0
  57. data/spec/resource/base_spec.rb +114 -0
  58. data/spec/resource/collection_spec.rb +169 -0
  59. data/spec/resource/directory_spec.rb +30 -0
  60. data/spec/resource/expansion_spec.rb +100 -0
  61. data/spec/resource/group_spec.rb +49 -0
  62. data/spec/spec_helper.rb +135 -0
  63. data/spec/support/resource_factory.rb +48 -0
  64. data/spec/support/resource_matchers.rb +27 -0
  65. data/spec/support/test_cache_stores.rb +9 -0
  66. data/spec/support/test_request_executor.rb +11 -0
  67. data/stormpath-sdk.gemspec +14 -4
  68. data/support/api.rb +55 -0
  69. metadata +214 -44
  70. data/lib/stormpath-sdk/client/client.rb +0 -38
  71. data/lib/stormpath-sdk/client/client_application.rb +0 -38
  72. data/lib/stormpath-sdk/client/client_application_builder.rb +0 -351
  73. data/lib/stormpath-sdk/client/client_builder.rb +0 -305
  74. data/lib/stormpath-sdk/ds/data_store.rb +0 -210
  75. data/lib/stormpath-sdk/ds/resource_factory.rb +0 -37
  76. data/lib/stormpath-sdk/resource/account_list.rb +0 -32
  77. data/lib/stormpath-sdk/resource/collection_resource.rb +0 -91
  78. data/lib/stormpath-sdk/resource/directory_list.rb +0 -30
  79. data/lib/stormpath-sdk/resource/group_membership_list.rb +0 -32
  80. data/lib/stormpath-sdk/resource/instance_resource.rb +0 -28
  81. data/lib/stormpath-sdk/resource/resource.rb +0 -327
  82. data/lib/stormpath-sdk/resource/resource_error.rb +0 -47
  83. data/test/client/client.yml +0 -16
  84. data/test/client/client_application_builder_spec.rb +0 -114
  85. data/test/client/client_builder_spec.rb +0 -176
  86. data/test/client/read_spec.rb +0 -254
  87. data/test/client/write_spec.rb +0 -420
  88. data/test/resource/resource_spec.rb +0 -41
  89. data/test/resource/test_resource.rb +0 -28
@@ -14,35 +14,25 @@
14
14
  # limitations under the License.
15
15
  #
16
16
  module Stormpath
17
-
18
17
  module Util
19
-
20
18
  module Assert
21
19
 
22
- def assert_not_nil object, message
23
-
20
+ def assert_not_nil(object, message)
24
21
  raise ArgumentError, message, caller unless !object.nil?
25
-
26
22
  end
27
23
 
28
- def assert_kind_of clazz, object, message
29
-
24
+ def assert_kind_of(clazz, object, message)
30
25
  raise ArgumentError, message, caller unless object.kind_of? clazz
31
-
32
26
  end
33
27
 
34
- def assert_true arg, message
35
-
28
+ def assert_true(arg, message)
36
29
  raise ArgumentError, message, caller unless arg
37
-
38
30
  end
39
31
 
40
- def assert_false arg, message
41
-
32
+ def assert_false(arg, message)
42
33
  raise ArgumentError, message, caller unless !arg
43
-
44
34
  end
45
35
 
46
36
  end
47
37
  end
48
- end
38
+ end
@@ -14,6 +14,6 @@
14
14
  # limitations under the License.
15
15
  #
16
16
  module Stormpath
17
- VERSION = '0.4.0'
18
- VERSION_DATE = '2012-10-26'
19
- end
17
+ VERSION = '1.0.0.beta'
18
+ VERSION_DATE = '2013-06-12'
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stormpath::ApiKey do
4
+ describe '.new' do
5
+ context 'given an id and secret' do
6
+ id = 'an_api_id'
7
+ secret = 'a_secret'
8
+ let(:apiKey) { Stormpath::ApiKey.new(id, secret) }
9
+
10
+ it 'sets the id' do
11
+ expect(apiKey.id).to eq(id)
12
+ end
13
+
14
+ it 'sets the secret' do
15
+ expect(apiKey.secret).to eq(secret)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe "BasicAuthenticator" do
4
+ context "given an instance of BasicAuthenticator" do
5
+
6
+ before do
7
+ ds = Stormpath::DataStore.new "", {}, ""
8
+ allow(test_api_client).to receive(:data_store).and_return(ds)
9
+ auth_result = Stormpath::Authentication::AuthenticationResult.new({}, test_api_client)
10
+ allow(ds).to receive(:create).and_return(auth_result)
11
+
12
+ @ba = Stormpath::Authentication::BasicAuthenticator.new ds
13
+ end
14
+
15
+ context "when authenticating" do
16
+ before do
17
+ @response = @ba.authenticate "foo/bar", Stormpath::Authentication::UsernamePasswordRequest.new("fake-username", "fake-password")
18
+ end
19
+
20
+ it "an AuthenticationResult is returned" do
21
+ expect(@response).to be_a Stormpath::Authentication::AuthenticationResult
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ describe Stormpath::Http::Authc::Sauthc1Signer do
5
+ let(:fake_uuid_generator) do
6
+ Proc.new { 'fake-uuid' }
7
+ end
8
+ let(:signer) do
9
+ Stormpath::Http::Authc::Sauthc1Signer.new fake_uuid_generator
10
+ end
11
+
12
+ after do
13
+ Timecop.return
14
+ end
15
+
16
+ describe '#sign_request' do
17
+ context 'for two GET requests to the same URL' do
18
+ context 'with one request using the query_string hash' do
19
+ let(:fake_api_key) { Stormpath::ApiKey.new('foo', 'bar') }
20
+
21
+ let(:empty_query_hash_request) do
22
+ Stormpath::Http::Request.new 'get', 'http://example.com/resources/abc123?q=red blue', nil, Hash.new, nil
23
+ end
24
+
25
+ let(:filled_query_hash_request) do
26
+ Stormpath::Http::Request.new 'get', 'http://example.com/resources/abc123', {'q' => 'red blue'}, Hash.new, nil
27
+ end
28
+
29
+ before do
30
+ Timecop.freeze(Time.now)
31
+ signer.sign_request empty_query_hash_request, fake_api_key
32
+ signer.sign_request filled_query_hash_request, fake_api_key
33
+ end
34
+
35
+ it 'assigns identical headers to both requests' do
36
+ expect(empty_query_hash_request.http_headers['Host']).to eq(filled_query_hash_request.http_headers['Host'])
37
+ expect(empty_query_hash_request.http_headers['Authorization']).to eq(filled_query_hash_request.http_headers['Authorization'])
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ describe Stormpath::Cache::CacheEntry do
5
+ after do
6
+ Timecop.return
7
+ end
8
+
9
+ context 'by default' do
10
+ let(:cache_entry) do
11
+ Stormpath::Cache::CacheEntry.new 'foo'
12
+ end
13
+
14
+ let(:now) { Time.now }
15
+ before { Timecop.freeze now }
16
+
17
+ it 'initializes the value' do
18
+ expect(cache_entry.value).to eq 'foo'
19
+ end
20
+
21
+ it 'initializes the creation time to now' do
22
+ expect(cache_entry.created_at).to eq now
23
+ end
24
+
25
+ it 'initializes the last accessed time to now' do
26
+ expect(cache_entry.last_accessed_at).to eq now
27
+ end
28
+ end
29
+
30
+ describe '#touch' do
31
+ let(:cache_entry) do
32
+ Stormpath::Cache::CacheEntry.new 'foo'
33
+ end
34
+
35
+ let(:now) { Time.now }
36
+
37
+ before do
38
+ Timecop.freeze now
39
+ cache_entry.touch
40
+ end
41
+
42
+ it 'updates the last accessed at time' do
43
+ expect(cache_entry.last_accessed_at).to eq now
44
+ end
45
+ end
46
+
47
+ describe '#expired?=' do
48
+ let(:now) { Time.now }
49
+
50
+ let(:ttl_seconds) { 300 }
51
+ let(:tti_seconds) { 300 }
52
+
53
+ context 'has not expired' do
54
+ let(:cache_entry) do
55
+ Stormpath::Cache::CacheEntry.new 'foo'
56
+ end
57
+
58
+ let(:expired) do
59
+ cache_entry.expired? ttl_seconds, tti_seconds
60
+ end
61
+
62
+ it 'returns false' do
63
+ expect(expired).to be_false
64
+ end
65
+ end
66
+
67
+ context 'when TTL has expired' do
68
+ before do
69
+ cache_entry = Stormpath::Cache::CacheEntry.new 'foo'
70
+ Timecop.freeze now + ttl_seconds + 1
71
+
72
+ @expired = cache_entry.expired? ttl_seconds, tti_seconds
73
+ end
74
+
75
+ it 'returns true' do
76
+ expect(@expired).to be_true
77
+ end
78
+ end
79
+
80
+ context 'when TTI has expired' do
81
+ before do
82
+ cache_entry = Stormpath::Cache::CacheEntry.new 'foo'
83
+ Timecop.freeze now + tti_seconds + 1
84
+
85
+ @expired = cache_entry.expired? ttl_seconds, tti_seconds
86
+ end
87
+
88
+ it 'returns true' do
89
+ expect(@expired).to be_true
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#to_h' do
95
+ let(:cache_entry) do
96
+ Stormpath::Cache::CacheEntry.new 'foo'
97
+ end
98
+
99
+ let(:now) { Time.now }
100
+ before { Timecop.freeze now }
101
+
102
+ it 'returns a hash of the attributes' do
103
+ expect(cache_entry.to_h).to eq({
104
+ 'value' => cache_entry.value,
105
+ 'created_at' => cache_entry.created_at,
106
+ 'last_accessed_at' => cache_entry.last_accessed_at
107
+ })
108
+ end
109
+ end
110
+
111
+ describe '.from_h=' do
112
+ let(:hash) do
113
+ {
114
+ "value" =>
115
+ {
116
+ "href" => "https://api.stormpath.com/v1/applications/app1",
117
+ "name" => "application app1",
118
+ "tenant" => {
119
+ "href" => "https://api.stormpath.com/v1/tenants/ten2"
120
+ },
121
+ "groups" =>
122
+ {"href" => "https://api.stormpath.com/v1/applications/app3/groups",
123
+ "items" =>
124
+ [{"href" => "https://api.stormpath.com/v1/groups/gro4"},
125
+ {"href" => "https://api.stormpath.com/v1/groups/gro5"}]
126
+ }
127
+ },
128
+ "created_at" => "2013-06-05T10:01:31-07:00",
129
+ "last_accessed_at" => "2013-06-05T10:01:31-07:00"
130
+ }
131
+ end
132
+
133
+ let(:cache_entry) do
134
+ Stormpath::Cache::CacheEntry.from_h(hash)
135
+ end
136
+
137
+ let(:created_at) do
138
+ Time.parse(hash['created_at'])
139
+ end
140
+
141
+ let(:last_accessed_at) do
142
+ Time.parse(hash['last_accessed_at'])
143
+ end
144
+
145
+ it 'returns a cache entry' do
146
+ expect(cache_entry).to be_kind_of Stormpath::Cache::CacheEntry
147
+ end
148
+
149
+ it 'sets created at' do
150
+ expect(cache_entry.created_at).to eq created_at
151
+ end
152
+
153
+ it 'sets the last accessed at' do
154
+ expect(cache_entry.last_accessed_at).to eq last_accessed_at
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+ require 'timecop'
3
+
4
+ describe Stormpath::Cache::Cache do
5
+ let(:cache) { Stormpath::Cache::Cache.new ttl_seconds: 7, tti_seconds: 3 }
6
+ let(:now) { Time.now }
7
+
8
+ before do
9
+ cache.put 'foo', 'bar'
10
+ end
11
+
12
+ after do
13
+ Timecop.return
14
+ end
15
+
16
+ describe '#put' do
17
+ it 'adds entry to the cache' do
18
+ expect(cache.size).to eq(1)
19
+ expect(cache.stats.summary).to eq [1, 0, 0, 0, 1]
20
+ end
21
+ end
22
+
23
+ describe '#get' do
24
+ context 'miss' do
25
+ before do
26
+ @foo = cache.get 'not-foo'
27
+ end
28
+
29
+ it 'gets nil' do
30
+ expect(@foo).not_to be
31
+ expect(cache.stats.summary).to eq [1, 0, 1, 0, 1]
32
+ end
33
+ end
34
+
35
+ context 'live before tti' do
36
+ before do
37
+ Timecop.freeze now + 2
38
+ @foo = cache.get 'foo'
39
+ end
40
+
41
+ it 'gets bar' do
42
+ expect(@foo).to eq('bar')
43
+ expect(cache.stats.summary).to eq [1, 1, 0, 0, 1]
44
+ end
45
+ end
46
+
47
+ context 'live after tti' do
48
+ before do
49
+ Timecop.freeze now + 2
50
+ cache.get 'foo'
51
+ Timecop.freeze now + 5
52
+ @foo = cache.get 'foo'
53
+ end
54
+
55
+ it 'gets bar' do
56
+ expect(@foo).to eq('bar')
57
+ expect(cache.stats.summary).to eq [1, 2, 0, 0, 1]
58
+ end
59
+ end
60
+
61
+ context 'expired by tti' do
62
+ before do
63
+ Timecop.freeze now + 4
64
+ @foo = cache.get 'foo'
65
+ end
66
+
67
+ it 'gets nil' do
68
+ expect(@foo).not_to be
69
+ expect(cache.stats.summary).to eq [1, 0, 1, 1, 1]
70
+ end
71
+ end
72
+
73
+ context 'expired by ttl' do
74
+ before do
75
+ Timecop.freeze now + 2
76
+ cache.get 'foo'
77
+ Timecop.freeze now + 5
78
+ cache.get 'foo'
79
+ Timecop.freeze now + 8
80
+ @foo = cache.get 'foo'
81
+ end
82
+
83
+ it 'gets nil' do
84
+ expect(@foo).not_to be
85
+ expect(cache.stats.summary).to eq [1, 2, 1, 1, 1]
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stormpath::Cache::CacheStats do
4
+ let(:cache_stats) do
5
+ Stormpath::Cache::CacheStats.new
6
+ end
7
+
8
+ context 'by default' do
9
+ it 'intializes counters' do
10
+ expect(cache_stats.puts).to eq 0
11
+ expect(cache_stats.hits).to eq 0
12
+ expect(cache_stats.misses).to eq 0
13
+ expect(cache_stats.expirations).to eq 0
14
+ expect(cache_stats.size).to eq 0
15
+ end
16
+ end
17
+
18
+ describe '#put' do
19
+ before { cache_stats.put }
20
+
21
+ it 'increments puts' do
22
+ expect(cache_stats.puts).to eq 1
23
+ end
24
+
25
+ it 'increments size' do
26
+ expect(cache_stats.puts).to eq 1
27
+ end
28
+
29
+ it 'updates summary' do
30
+ expect(cache_stats.summary).to eq [1, 0, 0, 0, 1]
31
+ end
32
+ end
33
+
34
+ describe '#hit' do
35
+ before { cache_stats.hit }
36
+
37
+ it 'increments hits' do
38
+ expect(cache_stats.hits).to eq 1
39
+ end
40
+
41
+ it 'updates summary' do
42
+ expect(cache_stats.summary).to eq [0, 1, 0, 0, 0]
43
+ end
44
+ end
45
+
46
+ describe '#miss=' do
47
+ context 'expired is true' do
48
+ before { cache_stats.miss true }
49
+
50
+ it 'increments misses' do
51
+ expect(cache_stats.misses).to eq 1
52
+ end
53
+
54
+ it 'increments expirations' do
55
+ expect(cache_stats.expirations).to eq 1
56
+ end
57
+
58
+ it 'updates summary' do
59
+ expect(cache_stats.summary).to eq [0, 0, 1, 1, 0]
60
+ end
61
+ end
62
+
63
+ context 'expired is true' do
64
+ before { cache_stats.miss false }
65
+
66
+ it 'increments misses' do
67
+ expect(cache_stats.misses).to eq 1
68
+ end
69
+
70
+ it 'does not increment expirations' do
71
+ expect(cache_stats.expirations).to eq 0
72
+ end
73
+
74
+ it 'updates summary' do
75
+ expect(cache_stats.summary).to eq [0, 0, 1, 0, 0]
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#delete' do
81
+ context 'when size is greater than zero' do
82
+ before do
83
+ 3.times { cache_stats.put }
84
+ cache_stats.delete
85
+ end
86
+
87
+ it 'decrements size' do
88
+ expect(cache_stats.size).to eq 2
89
+ end
90
+
91
+ it 'updates summary' do
92
+ expect(cache_stats.summary).to eq [3, 0, 0, 0, 2]
93
+ end
94
+ end
95
+
96
+ context 'when size is zero' do
97
+ before do
98
+ cache_stats.delete
99
+ end
100
+
101
+ it 'does nothing' do
102
+ expect(cache_stats.size).to eq 0
103
+ end
104
+ end
105
+ end
106
+ end