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.
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