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
@@ -0,0 +1,6 @@
1
+ *~
2
+ !.travis.yml
3
+ pkg/*
4
+ Gemfile.lock
5
+ coverage
6
+ spec/fixtures/vcr_cassettes
@@ -0,0 +1 @@
1
+ stormpath-sdk-ruby
@@ -0,0 +1 @@
1
+ 1.9.3-p429
@@ -0,0 +1,27 @@
1
+ ---
2
+ env:
3
+ global:
4
+ - secure: |-
5
+ USqTzWnRXTxgwF6wpwT3UHx4hoo5QIWP6bmmJMOIG/jLWTV3cCZ4y3LEuGx/
6
+ 2x4gTyRuAAbVpJD8n9k/h7Vh6xZ8ts715kRL2OCqD+yOEioKG9RTWWzFCsNY
7
+ V3wic2+25BHgyCcnXtNFTjP/TfIKjVQETQjn3Ast2foThmyLVYo=
8
+ - secure: |-
9
+ UDZPetAAzPMtlosw481STlt60UFEei28DlBrHzDS7j/MKgkum9ZECPm4h7Dr
10
+ MXsDBp3GghLqGWc5+yNvlV2RSSZdI6YCeTSG7dXu3Tb1vTLd8Ia7pVZg3Ut2
11
+ 5Ru3+xBVHZ/4xrc+8bfL2FGpH8T1mT6GZt9BfkY8v4a+rsn8FLA=
12
+ - secure: |-
13
+ FRAT9Sjpv2MUmIu9/uaXAa2LRKmsR0vHz3Vc8oCiDIKihqFq4YF9DpHtQ0nF
14
+ OYwdcprSH5RzV/bFsf6XcPP4IlIhSRj333FJoHXfmon5cdPcpt70O4in+4YI
15
+ gXPNGgbzCpZ4WRsFbmtVazQwpXBUg2fYK8y0jNrhZoVZ9UK61Zc=
16
+ - secure: |-
17
+ WvFXv/1RKdnh/tJFRlCDMKpiNre0+K3qWLf9PaQzjvWyTAVtq3NK7Av3JSoR
18
+ EoPy/0VCzlBJPfcPa+EmLO518trgsAJ1dmBOSUmNhQOyl9bfOFlzvjqZ20Ru
19
+ eMksU4t3HbbBdh3LqR9LPxViJGfUk3LvaiuWwp8y0GB5jMjrASg=
20
+ - secure: |-
21
+ HggUi1F44G7uHy3PyKcBE54JpBMIjrmROvzrKkCPOmRP5DoeZQ+wU+8zJ89z
22
+ 4YsxOzQjYLwStB4U95LEZgQYvcbdfjkCY4uthb8XbmSeT7KSkMifhNT619+D
23
+ sTekVOlY9Ei+8O/BUr4ZCE+Fs8/8obFOxooWxxdHlaYsjj/atm4=
24
+ - secure: |-
25
+ cJ2ExNmmGSjBHIgjZ6zs+AUEVBSfyTj2qG9SNV0j/P9mnjg32irU/tG7f1yI
26
+ yvaGCsPr2h6rwtiMb8QHA4tMqHsoay0e9s7jyBtn6amgUaLsV2vdhQTWDuIU
27
+ cksOE3PMIovYl9ANLb6KrhDWt7ue/fOxEALh0a5rAu50C/tNvgo=
data/CHANGES.md CHANGED
@@ -1,6 +1,26 @@
1
1
  stormpath-sdk-ruby Changelog
2
2
  ====================
3
3
 
4
+ Version 1.0.0.beta
5
+ ------------------
6
+
7
+ Released on June 12, 2013
8
+
9
+ - Bumping version to reflect stability
10
+
11
+ Version 1.0.0.alpha
12
+ -------------
13
+
14
+ Released on June 11, 2013
15
+
16
+ - Added a new API on client for accessing applications and directories
17
+ - Added a new API on directories for accessing and creating accounts and groups
18
+ - Added account authentication by application
19
+ - Added the ability to load an application by credentialed uri
20
+ - Added caching, with Redis default
21
+ - Added pagination and querying to collections
22
+ - Added entity expansion
23
+
4
24
  Version 0.4.0
5
25
  -------------
6
26
 
@@ -45,4 +65,4 @@ Version 0.1.0
45
65
 
46
66
  Released on July 27, 2012
47
67
 
48
- - First release of the Stormpath Ruby SDK where all of the features available on the REST API by the release date were implemented.
68
+ - First release of the Stormpath Ruby SDK where all of the features available on the REST API by the release date were implemented.
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
data/README.md CHANGED
@@ -1,27 +1,473 @@
1
- Stormpath SDK For Ruby
2
- Copyright (c) 2012 Stormpath, Inc. and contributors.
1
+ [![Build Status](https://api.travis-ci.org/stormpath/stormpath-sdk-ruby.png?branch=master)](https://travis-ci.org/stormpath/stormpath-sdk-ruby)
3
2
 
4
- This project is licensed under the Apache 2.0 Open Source License:
3
+ # Stormpath Ruby SDK
5
4
 
6
- http://www.apache.org/licenses/LICENSE-2.0
5
+ Stormpath is the first easy, secure user management and authentication service for developers.
6
+ This is the Ruby SDK to ease integration of its features with any Ruby language based
7
+ application.
7
8
 
8
- Project Documentation is here:
9
+ ## Install
9
10
 
10
- https://github.com/stormpath/stormpath-sdk-ruby/wiki
11
+ ```sh
12
+ $ gem install stormpath-sdk
13
+ ```
14
+
15
+ ## Quickstart Guide
16
+
17
+ 1. If you have not already done so, register as a developer on
18
+ [Stormpath][stormpath] and set up your API credentials and resources:
19
+
20
+ 1. Create a [Stormpath][stormpath] developer account and [create your API Keys][create-api-keys]
21
+ downloading the <code>apiKey.properties</code> file into a <code>.stormpath</code>
22
+ folder under your local home directory.
23
+
24
+ 1. Create an application and a directory to store your users'
25
+ accounts. Make sure the directory is assigned as a login source
26
+ to the application.
27
+
28
+ 1. Take note of the _REST URL_ of the application and of directory
29
+ you just created.
30
+
31
+ 1. **Require the Stormpath Ruby SDK**
32
+
33
+ ```ruby
34
+ require 'stormpath-sdk'
35
+ ```
36
+
37
+ 1. **Create a client** using the API key properties file
38
+
39
+ ```ruby
40
+ client = Stormpath::Client.new api_key_file_location: File.join(ENV['HOME']), '.stormpath', 'apiKey.properties')
41
+ ```
42
+
43
+ 1. **List all your applications and directories**
44
+
45
+ ```ruby
46
+ client.applications.each do |application|
47
+ p "Application: #{application.name}"
48
+ end
49
+
50
+ client.directories.each do |directory|
51
+ p "Directory: #{directory.name}"
52
+ end
53
+ ```
54
+
55
+ 1. **Get access to the specific application and directory** using the
56
+ URLs you acquired above.
57
+
58
+ ```ruby
59
+ application = client.applications.get application_url
60
+
61
+ directory = client.directories.get application_url
62
+ ```
63
+
64
+ 1. **Create an account for a user** on the directory.
65
+
66
+ ```ruby
67
+ account = directory.accounts.create({
68
+ given_name: 'John',
69
+ surname: 'Smith',
70
+ email: 'john.smith@example.com',
71
+ username: 'johnsmith',
72
+ password: '4P@$$w0rd!'
73
+ })
74
+ ```
75
+
76
+ 1. **Update an account**
77
+
78
+ ```ruby
79
+ account.given_name = 'Johnathan'
80
+ account.middle_name = 'A.'
81
+ account.save
82
+ ```
83
+
84
+ 1. **Authenticate the Account** for use with an application:
85
+
86
+ ```ruby
87
+ auth_request =
88
+ Stormpath::Authentication::UsernamePasswordRequest.new 'johnsmith', '4P@$$w0rd!'
89
+
90
+ begin
91
+ auth_result = application.authenticate_account auth_request
92
+ account = auth_result.account
93
+ rescue Stormpath::Error => e
94
+ #If credentials are invalid or account doesn't exist
95
+ end
96
+ ```
97
+
98
+ 1. **Send a password reset request**
99
+
100
+ ```ruby
101
+ application.send_password_reset_email 'john.smith@example.com'
102
+ ```
103
+
104
+ 1. **Create a group** in a directory
105
+
106
+ ```ruby
107
+ directory.groups.create name: 'Admins'
108
+ ```
109
+
110
+ 1. **Add the account to the group**
111
+
112
+ ```ruby
113
+ group.add_account account
114
+ ```
115
+
116
+ 1. **Check for account inclusion in group** by reloading the account
117
+
118
+ ```ruby
119
+ account = clients.accounts.get account.href
120
+ is_admin = account.groups.any? { |group| group.name == 'Admins' }
121
+ ```
11
122
 
12
- # Build Instructions
123
+ ## Common Uses
13
124
 
14
- Via rubygems.org:
125
+ ### Creating a client
15
126
 
127
+ All Stormpath features are accessed through a
128
+ <code>Stormpath::Client</code> instance, or a resource
129
+ created from one. A client needs an API key (made up of an _id_ and a
130
+ _secret_) from your Stormpath developer account to manage resources
131
+ on that account. That API key can be specified any number of ways
132
+ in the hash of values passed on Client initialization:
133
+
134
+ * The location of API key properties file:
135
+
136
+ ```ruby
137
+ client = Stormpath::Client.new
138
+ api_key_file_location: '/some/path/to/apiKey.properties'
139
+ ```
140
+
141
+ You can even identify the names of the properties to use as the API
142
+ key id and secret. For example, suppose your properties was:
143
+
144
+ ```
145
+ foo=APIKEYID
146
+ bar=APIKEYSECRET
147
+ ```
148
+
149
+ You could load it with the following:
150
+
151
+ ```ruby
152
+ client = Stormpath::Client.new
153
+ api_key_file_location: '/some/path/to/apiKey.properties',
154
+ api_key_id_property_name: 'foo',
155
+ api_key_secret_property_name: 'bar'
156
+ ```
157
+
158
+ * Passing in a Stormpath::APIKey instance:
159
+
160
+ ```ruby
161
+ api_key = Stormpath::APIKey.new api_id, api_secret
162
+ client = Stormpath::Client.new api_key: api_key
163
+ ```
164
+
165
+ * By explicitly setting the API key id and secret:
166
+
167
+ ```ruby
168
+ client = Stormpath::Client.new
169
+ api_key: { id: api_id, secret: api_secret }
170
+ ```
171
+
172
+ * By passing the REST URL of a Stormpath application on your account
173
+ with the API id and secret embedded. For example, the URL would look
174
+ like:
175
+
176
+ ```
177
+ http://#{api_key_id}:#{api_key_secret}@api.stormpath.com/v1/applications/#{application_id}
178
+ ```
179
+
180
+ The client could then be created with the above URL:
181
+
182
+ ```ruby
183
+ client = Stormpath::Client.new application_url: application_url
184
+ ```
185
+
186
+ This method will also provide a <code>application</code> property on
187
+ on the client to directly access that resource.
188
+
189
+ ### Accessing Resources
190
+
191
+ Most of the work you do with Stormpath is done through the applications
192
+ and directories you have registered. You use the client to access them
193
+ with their REST URL:
194
+
195
+ ```ruby
196
+ application = client.applications.get application_url
197
+
198
+ directory = client.directories.get directory_url
16
199
  ```
17
- $ gem install stormpath-sdk
200
+
201
+ The <code>applications</code> and <code>directories</code> property on a
202
+ client instance are also <code>Enumerable</code> allowing you to iterate
203
+ and scan for resources via that interface.
204
+
205
+ Additional resources are <code>accounts</code>, <code>groups</code>,
206
+ <code>group_membership</code>, and the single reference to your
207
+ <code>tenant</code>.
208
+
209
+ ### Registering Accounts
210
+
211
+ Accounts are created on a directory instance. They can be created in two
212
+ ways:
213
+
214
+ * With the <code>create_account</code> method:
215
+
216
+ ```ruby
217
+ account = directory.create_account({
218
+ given_name: 'John',
219
+ surname: 'Smith',
220
+ email: 'john.smith@example.com',
221
+ username: 'johnsmith',
222
+ password: '4P@$$w0rd!'
223
+ })
224
+ ```
225
+
226
+ This metod can take an additional flag to indicate if the account
227
+ can skip any registration workflow configured on the directory.
228
+
229
+ ```ruby
230
+ ## Will skip workflow, if any
231
+ account = directory.create_account account_props, false
232
+ ```
233
+
234
+ * Creating it directly on the <code>accounts</code> collection property
235
+ on the directory:
236
+
237
+ ```ruby
238
+ account = directory.accounts.create({
239
+ given_name: 'John',
240
+ surname: 'Smith',
241
+ email: 'john.smith@example.com',
242
+ username: 'johnsmith',
243
+ password: '4P@$$w0rd!'
244
+ })
245
+ ```
246
+
247
+ Both these methods can take either a <code>Hash</code> of the account
248
+ properties, or a <code>Stormpath::Account</code>.
249
+
250
+ If the directory has been configured with an email verification workflow
251
+ and a non-Stormpath URL, you have to pass the verification token sent to
252
+ the URL in a <code>sptoken</code> query parameter back to Stormpath to
253
+ complete the workflow. This is done through the
254
+ <code>verify_email_token</code> on the <code>accounts</code> collection.
255
+
256
+ For example, suppose you have a Sinatra application
257
+ that is handling the email verification at the path
258
+ <code>/users/verify</code>. You could use the following code:
259
+
260
+ ```ruby
261
+ get '/users/verify' do
262
+ token = params[:sptoken]
263
+ account = client.accounts.verify_email_token token
264
+ #proceed to update session, display account, etc
265
+ end
266
+ ```
267
+
268
+ ### Authentication
269
+
270
+ Authentication is accomplished by passing a username or an email and a
271
+ password to <code>authenticate_account</code> of an application we've
272
+ registered on Stormpath. This will either return a
273
+ <code>Stormpath::Authentication::AuthenticationResult</code> instance if
274
+ the credentials are valid, or raise a <code>Stormpath::Error</code>
275
+ otherwise. In the former case, you can get the <code>account</code>
276
+ associated with the credentials.
277
+
278
+ ```ruby
279
+ auth_request =
280
+ Stormpath::Authentication::UsernamePasswordRequest.new 'johnsmith', '4P@$$w0rd!'
281
+
282
+ begin
283
+ auth_result = application.authenticate_account auth_request
284
+ account = auth_result.account
285
+ rescue Stormpath::Error => e
286
+ #If credentials are invalid or account doesn't exist
287
+ end
288
+ ```
289
+
290
+ ### Password Reset
291
+
292
+ A password reset workflow, if configured on the directory the account is
293
+ registered on, can be kicked off with the
294
+ <code>send_password_reset_email</code> method on an application:
295
+
296
+ ```ruby
297
+ application.send_password_reset_email 'john.smith@example.com'
298
+ ```
299
+
300
+ If the workflow has been configured to verify through a non-Stormpath
301
+ URL, you can verify the token sent in the query parameter
302
+ <code>sptoken</code> with the <code>verify_password_reset_token</code>
303
+ method on the application.
304
+
305
+ For example, suppose you have a Sinatra application that is verifying
306
+ the tokens. You use the following to carry it out:
307
+
308
+ ```ruby
309
+ get '/users/verify' do
310
+ token = params[:sptoken]
311
+ account = application.verify_password_reset_token token
312
+ #proceed to update session, display account, etc
313
+ end
314
+ ```
315
+
316
+ With the account acquired you can then update the password:
317
+
318
+ ```ruby
319
+ account.password = new_password
320
+ account.save
321
+ ```
322
+
323
+ _NOTE :_ Confirming a new password is left up to the web application
324
+ code calling the Stormpath SDK. The SDK does not require confirmation.
325
+
326
+ ### ACL through Groups
327
+
328
+ Memberships of accounts in certain groups can be used as an
329
+ authorization mechanism. As the <code>groups</code> collection property
330
+ on an account instance is <code>Enumerable</code>, you can use any of
331
+ that module's methods to determine if an account belongs to a specific
332
+ group:
333
+
334
+ ```ruby
335
+ account.groups.any?{|group| group.name == 'administrators'
336
+ ```
337
+
338
+ You can create groups and assign them to accounts using the Stormpath
339
+ web console, or programmatically. Groups are created on directories:
340
+
341
+ ```ruby
342
+ group = directory.groups.create name: 'administrators'
343
+ ```
344
+
345
+ Group membership can be created by:
346
+
347
+ * Explicitly creating a group membership resource with your client:
348
+
349
+ ```ruby
350
+ group_memebership = client.group_memberships.create group, account
351
+ ```
352
+
353
+ * Using the <code>add_group</code> method on the account instance:
354
+
355
+ ```ruby
356
+ account.add_group group
357
+ ```
358
+
359
+ * Using the <code>add_account</code> method on the group instance:
360
+
361
+ ```ruby
362
+ group.add_group account
363
+ ```
364
+
365
+ You will need to reload the account or group resource after these
366
+ operations to ensure they've picked up the changes.
367
+
368
+ ## Testing
369
+
370
+ ### Setup
371
+
372
+ The functional tests of the SDK run against a Stormpath tenant. In that
373
+ account, create:
374
+
375
+ * An application reserved for testing.
376
+ * A directory reserved for test accounts. _Be sure to associate this
377
+ directory to the test application as a login source_.
378
+ * Another directory reserved for test accounts with the account
379
+ verification workflow turned on. _Be sure to associate this directory
380
+ to the test application as a login source_.
381
+
382
+ The following environment variables need will then need to be set:
383
+
384
+ * <code>STORMPATH_SDK_TEST_API_KEY_ID</code> - The <code>id</code> from
385
+ your Stormpath API key.
386
+ * <code>STORMPATH_SDK_TEST_API_KEY_SECRET</code> - The
387
+ <code>secret</code> from your Stormpath API key.
388
+ * <code>STORMPATH_SDK_TEST_APPLICATION_URL</code> - The URL to the
389
+ application created above.
390
+ * <code>STORMPATH_SDK_TEST_DIRECTORY_URL</code> - The URL to the first
391
+ directory created above.
392
+ * <code>STORMPATH_SDK_TEST_DIRECTORY_WITH_VERIFICATION_URL</code> - The
393
+ URL to the second directory created above.
394
+
395
+ ### Running
396
+
397
+ Once properly configured, the tests can be run as the default
398
+ <code>Rake<code> task:
399
+
400
+ ```sh
401
+ $ rake
18
402
  ```
19
403
 
404
+ Or by specifying the <code>spec</code> task:
405
+
406
+ ```sh
407
+ $ rake spec
408
+ ```
409
+
410
+ Or through <code>rspec</code>.
411
+
412
+ ## Contributing
413
+
414
+ You can make your own contributions by forking the <code>development</code>
415
+ branch, making your changes, and issuing pull-requests on the
416
+ <code>development</code> branch.
417
+
418
+ ### Building the Gem
419
+
20
420
  To build and install the development branch yourself from the latest source:
21
421
 
22
422
  ```
23
423
  $ git clone git@github.com:stormpath/stormpath-sdk-ruby.git
24
424
  $ cd stormpath-sdk-ruby
25
425
  $ rake gem
26
- $ gem install pkg/stormpath-sdk-{version}
27
- ```
426
+ $ gem install pkg/stormpath-sdk-{version}.gem
427
+ ```
428
+
429
+ ## Quick Class Diagram
430
+
431
+ ```
432
+ +-------------+
433
+ | Application |
434
+ | |
435
+ +-------------+
436
+ + 1
437
+ |
438
+ | +-------------+
439
+ | | LoginSource |
440
+ o- - - - - -| |
441
+ | +-------------+
442
+ |
443
+ v 0..*
444
+ +--------------+ +--------------+
445
+ | Directory | 1 1 | Account |1
446
+ | |<----------+| |+----------+
447
+ | | | | |
448
+ | | 1 0..* | |0..* |
449
+ | |+---------->| |+-----+ |
450
+ | | +--------------+ | | +-----------------+
451
+ | | | | | GroupMembership |
452
+ | | o- - o - - - - | |
453
+ | | +--------------+ | | +-----------------+
454
+ | | 1 0..* | Group |1 | |
455
+ | |+---------->| |<-----+ |
456
+ | | | | |
457
+ | | 1 1 | |0..* |
458
+ | |<----------+| |<----------+
459
+ +--------------+ +--------------+
460
+ ```
461
+
462
+ ## Copyright & Licensing
463
+
464
+ Copyright &copy; 2012 Stormpath, Inc. and contributors.
465
+
466
+ This project is licensed under the [Apache 2.0 Open Source License](http://www.apache.org/licenses/LICENSE-2.0).
467
+
468
+ For additional information, please see the full [Project Documentation](https://www.stormpath.com/docs/ruby/product-guide).
469
+
470
+ [bundler]: http://gembundler.com/
471
+ [stormpath]: http://stormpath.com/
472
+ [create-api-keys]: http://www.stormpath.com/docs/ruby/product-guide#AssignAPIkeys
473
+ [stormpath_bootstrap]: https://github.com/stormpath/stormpath-sdk-ruby/wiki/Bootstrapping-Stormpath