g5_authentication_client 0.2.0
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +39 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +351 -0
- data/Rakefile +14 -0
- data/g5_authentication_client.gemspec +34 -0
- data/lib/g5_authentication_client/client.rb +177 -0
- data/lib/g5_authentication_client/configuration.rb +138 -0
- data/lib/g5_authentication_client/token_info.rb +27 -0
- data/lib/g5_authentication_client/user.rb +32 -0
- data/lib/g5_authentication_client/version.rb +3 -0
- data/lib/g5_authentication_client.rb +11 -0
- data/spec/g5_authentication_client/client_spec.rb +335 -0
- data/spec/g5_authentication_client/configuration_spec.rb +210 -0
- data/spec/g5_authentication_client/token_info_spec.rb +36 -0
- data/spec/g5_authentication_client/user_spec.rb +92 -0
- data/spec/g5_authentication_client_spec.rb +11 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/module_configured_attribute.rb +37 -0
- data/spec/support/oauth_protected_resource.rb +81 -0
- metadata +252 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 97c68343930b548666879d796904ea3345cd791b
|
4
|
+
data.tar.gz: 9a41e522f8fd8ab0ded0d797ce29d2292b272dac
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ff4eeaa114f7693c555bffc53a360a762897fb3f60e8dccee176eaf64c82af9d9e957e044f482826ecc33df5242a0692878c59a8b552a354c49bffed3c73290
|
7
|
+
data.tar.gz: 1d377a2678b5435e6f11f8003417cb5a25148fe0889f728d23a266160b09fbeb2dbd4356822a83f9531e3d949da9f5818afd39ef9e1887ae2a4b4c3c05ae8687
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
g5_authentication_client
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.0
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
## v0.2.0 (2014-03-10)
|
2
|
+
|
3
|
+
* First open source release to [RubyGems](http://rubygems.org/)
|
4
|
+
|
5
|
+
## v0.1.5 (2014-03-07)
|
6
|
+
|
7
|
+
* Add allow_password_credentials flag to determine whether client instances
|
8
|
+
* will allow use of username/passwored attributes
|
9
|
+
|
10
|
+
## v0.1.4 (2014-03-06)
|
11
|
+
|
12
|
+
* Change configure method namespace to g5_auth from g5_authentication_client
|
13
|
+
|
14
|
+
## v0.1.1 (2013-11-15)
|
15
|
+
|
16
|
+
* Add `G5AuthenticationClient::Client#sign_out_url`. The client should
|
17
|
+
redirect to this target URL in order sign out the current user.
|
18
|
+
|
19
|
+
## v0.1.0 (2013-11-05)
|
20
|
+
|
21
|
+
* Rename all references to `client_callback_url` to `redirect_uri`.
|
22
|
+
This is in order to maintain consistency with the terminology used
|
23
|
+
in the OAuth 2.0 spec. This is a breaking change for any code written
|
24
|
+
against earlier versions of the client.
|
25
|
+
|
26
|
+
## v0.0.3 (2013-09-23)
|
27
|
+
|
28
|
+
* Add support for retrieving user data based on current credentials
|
29
|
+
* Add `User#password_confirmation`
|
30
|
+
* Allow client to configure an OAuth access token directly (thereby
|
31
|
+
bypassing the OAuth authorization flow)
|
32
|
+
|
33
|
+
## v0.0.2 (2013-07-13)
|
34
|
+
|
35
|
+
* Update dependency on modelish to v0.3.x
|
36
|
+
|
37
|
+
## v0.0.1
|
38
|
+
|
39
|
+
* Initial release
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 G5
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,351 @@
|
|
1
|
+
# G5 Authentication Client #
|
2
|
+
|
3
|
+
A client library for the g5-authentication service.
|
4
|
+
|
5
|
+
## Current version ##
|
6
|
+
|
7
|
+
0.2.0
|
8
|
+
|
9
|
+
## Requirements ##
|
10
|
+
|
11
|
+
* Ruby >= 1.9.3
|
12
|
+
|
13
|
+
## Installation ##
|
14
|
+
|
15
|
+
In Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'g5_authentication_client'
|
19
|
+
```
|
20
|
+
|
21
|
+
Just rubygems:
|
22
|
+
|
23
|
+
```console
|
24
|
+
$ gem install g5_authentication_client
|
25
|
+
```
|
26
|
+
|
27
|
+
## Configuration ##
|
28
|
+
|
29
|
+
### Environment variables ###
|
30
|
+
|
31
|
+
You can set the default value for several configuration settings via
|
32
|
+
environment variable (not all of these will be used concurrently!):
|
33
|
+
|
34
|
+
* `G5_AUTH_CLIENT_ID` - the OAuth 2.0 application ID from the auth server
|
35
|
+
* `G5_AUTH_CLIENT_SECRET` - the OAuth 2.0 application secret from the auth server
|
36
|
+
* `G5_AUTH_REDIRECT_URI` - the OAuth 2.0 redirect URI registered with the auth server
|
37
|
+
* `G5_AUTH_ENDPOINT` - the endpoint URL for the G5 auth server
|
38
|
+
* `G5_AUTH_USERNAME` - the username for the end user to authenticate as
|
39
|
+
* `G5_AUTH_PASSWORD` - the password for the end user to authenticate as
|
40
|
+
* `G5_AUTH_ACCESS_TOKEN` - a valid OAuth 2.0 access token (note that tokens do expire)
|
41
|
+
|
42
|
+
### Module-level config ###
|
43
|
+
|
44
|
+
Any settings that are configured on the `G5AuthenticationClient` module will
|
45
|
+
apply to all instances of `G5AuthenticationClient::Client`, unless that setting
|
46
|
+
is overridden at the client level.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
G5AuthenticationClient.configure do |config|
|
50
|
+
config.client_id = 'blah'
|
51
|
+
config.client_secret = 'blah'
|
52
|
+
config.redirect_uri = 'blah'
|
53
|
+
config.endpoint = 'blah'
|
54
|
+
config.debug = true
|
55
|
+
config.logger = Rails.logger
|
56
|
+
|
57
|
+
# It would be unusual to configure non-client credentials at the module
|
58
|
+
# level, but it is possible. You would only need to configure one of the
|
59
|
+
# following:
|
60
|
+
|
61
|
+
# If you already have an OAuth access token
|
62
|
+
config.access_token = 'blah'
|
63
|
+
|
64
|
+
# For the OAuth authorization code grant type
|
65
|
+
config.authorization_code = 'blah'
|
66
|
+
|
67
|
+
# For the resource owner password credentials grant type
|
68
|
+
config.username = 'blah'
|
69
|
+
config.password = 'blah'
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
### Client-level config ###
|
74
|
+
|
75
|
+
To override a setting for a particular instance of `G5AuthenticationClient::Client`
|
76
|
+
without affecting any other instances, you can pass the configuration option
|
77
|
+
into the initializer:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
G5AuthenticationClient.configure do |config|
|
81
|
+
config.endpoint = 'https://dev-auth.g5search.com'
|
82
|
+
end
|
83
|
+
|
84
|
+
client = G5AuthenticationClient::Client.new(endpoint: 'http://localhost:3000')
|
85
|
+
client.endpoint
|
86
|
+
# => "http://localhost:3000"
|
87
|
+
|
88
|
+
client = G5AuthenticationClient::Client.new
|
89
|
+
client.endpoint
|
90
|
+
# => "https://dev-auth.g5search.com"
|
91
|
+
```
|
92
|
+
|
93
|
+
## Usage ##
|
94
|
+
|
95
|
+
### Retrieving user information ###
|
96
|
+
|
97
|
+
Assuming you have a valid access token, set up your client instance:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
auth_client = G5AuthenticationClient::Client.new(access_token: 'my_token')
|
101
|
+
```
|
102
|
+
|
103
|
+
You can retrieve information for the user associated with the access token:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
current_user = auth_client.me
|
107
|
+
# => #<G5AuthenticationClient::User email="my.user@test.host" id=1>
|
108
|
+
```
|
109
|
+
|
110
|
+
You can also retrieve informatino about any other user by ID:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
user = auth_client.get_user(42)
|
114
|
+
# => #<G5AuthenticationClient::User email="another.user@test.host" id=42>
|
115
|
+
```
|
116
|
+
|
117
|
+
### Retrieving token information ###
|
118
|
+
|
119
|
+
You can retrieve information specific to the current access token, including
|
120
|
+
scopes and expiration time:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
auth_client = G5AuthenticationClient::Client.new(access_token: 'my_access_token')
|
124
|
+
token_info = auth_client.token_info
|
125
|
+
# => #<G5AuthenticationClient::TokenInfo application_uid={"uid"=>"my_application_id"} expires_in_seconds=5183805 resource_owner_id=1 scopes=[]>
|
126
|
+
```
|
127
|
+
|
128
|
+
To retrieve the token value itself:
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
auth_client.get_access_token
|
132
|
+
# => "my_access_token"
|
133
|
+
```
|
134
|
+
|
135
|
+
### Creating a user ###
|
136
|
+
|
137
|
+
To create a user, you need their email and password. You can either pass in
|
138
|
+
these credentials as an option hash:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
auth_client = G5AuthenticationClient::Client.new(access_token: 'my_access_token')
|
142
|
+
user = auth_client.create_user(email: 'new.user@test.host',
|
143
|
+
password: 'testing',
|
144
|
+
password_confirmation: 'testing')
|
145
|
+
# => #<G5AuthenticationClient::User email="new.user@test.host" id=123>
|
146
|
+
```
|
147
|
+
|
148
|
+
Or you can pass in an instance of `G5AuthenticationClient::User`:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
user = G5AuthenticationClient::User.new(email: 'new.user@test.host',
|
152
|
+
password: 'testing',
|
153
|
+
password_confirmation: 'testing')
|
154
|
+
auth_client.create_user(user)
|
155
|
+
```
|
156
|
+
|
157
|
+
### Updating a user ###
|
158
|
+
|
159
|
+
To update an existing user, you'll need the user ID and the new credentials:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
auth_client = G5AuthenticationClient::Client.new(access_token: 'my_access_token')
|
163
|
+
auth_client.update_user(id: 42,
|
164
|
+
email: 'updated.email@test.host',
|
165
|
+
password: 'updated_secret',
|
166
|
+
password_confirmation: 'updated_secret')
|
167
|
+
```
|
168
|
+
|
169
|
+
You can also pass in a `G5AuthenticationClient::User` instance instead:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
user = auth_client.create_user(email: 'new.user@test.host',
|
173
|
+
password: 'secret',
|
174
|
+
password_confirmation: 'secret')
|
175
|
+
user.email = 'updated.email@test.host'
|
176
|
+
auth_client.update_user(user)
|
177
|
+
```
|
178
|
+
|
179
|
+
### Deleting a user ###
|
180
|
+
|
181
|
+
To delete a user, you need the user ID:
|
182
|
+
|
183
|
+
```ruby
|
184
|
+
auth_client = G5AuthenticationClient::Client.new(access_token: 'my_access_token')
|
185
|
+
auth_client.delete_user(42)
|
186
|
+
```
|
187
|
+
|
188
|
+
### Sign-out URL ###
|
189
|
+
|
190
|
+
In order to sign out of the G5 auth service from a web browser, your client
|
191
|
+
application must redirect to the auth server's sign-out URL. You can
|
192
|
+
pass in a redirect URL for the auth server to redirect back to after the
|
193
|
+
sign-out process is complete.
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
auth_client = G5AuthenticationClient::Client.new
|
197
|
+
auth_client.sign_out_url('https://myapp.host/callback')
|
198
|
+
# => "https://auth.g5search.com/users/sign_out?redirect_url=https%3A%2F%2Fmyapp.host%2Fcallback"
|
199
|
+
```
|
200
|
+
|
201
|
+
## Examples ##
|
202
|
+
|
203
|
+
These examples assume that you have already registered your client application
|
204
|
+
and at least one end user on the auth server.
|
205
|
+
|
206
|
+
### Authorization grant ####
|
207
|
+
|
208
|
+
You will need the following credentials:
|
209
|
+
|
210
|
+
* Client ID
|
211
|
+
* Client secret
|
212
|
+
* Redirect URI
|
213
|
+
* Authorization code
|
214
|
+
|
215
|
+
The client ID, client secret, and redirect URI will be the same for any request
|
216
|
+
your application may make, so you will probably want to configure these either
|
217
|
+
via environment variables or at the module level:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
G5AuthenticationClient.configure do |config|
|
221
|
+
config.client_id = 'my-client-id'
|
222
|
+
config.client_secret = 'my-client-secret'
|
223
|
+
config.redirect_uri = 'https://test.host/callback'
|
224
|
+
end
|
225
|
+
```
|
226
|
+
|
227
|
+
Each authorization code can only be used once, so it's best configured on the
|
228
|
+
client instance:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
auth_client = G5AuthenticationClient::Client.new(authorization_code: 'my_one_time_use_code')
|
232
|
+
```
|
233
|
+
|
234
|
+
You can now execute actions against the auth service using that client:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
auth_client.me
|
238
|
+
# => #<G5AuthenticationClient::User email="another.user@test.host" id=42>
|
239
|
+
```
|
240
|
+
|
241
|
+
Or you can retrieve an access token in order to authenticate to another G5
|
242
|
+
service:
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
auth_client.get_access_token
|
246
|
+
# => "my-g5-access-token-value-abc123"
|
247
|
+
```
|
248
|
+
|
249
|
+
### Resource owner password credentials grant ###
|
250
|
+
|
251
|
+
This grant type is only available to highly trusted client applications that
|
252
|
+
do not require explicit authorization by the end user.
|
253
|
+
|
254
|
+
You will need the following credentials:
|
255
|
+
|
256
|
+
* Client ID
|
257
|
+
* Client secret
|
258
|
+
* Redirect URI
|
259
|
+
* Username
|
260
|
+
* Password
|
261
|
+
|
262
|
+
Your client credentials will always be the same for every request, so use
|
263
|
+
module-level configuration or environment variables for those:
|
264
|
+
|
265
|
+
```bash
|
266
|
+
export G5_AUTH_CLIENT_ID='my-client-id'
|
267
|
+
export G5_AUTH_CLIENT_SECRET='my-client-secret'
|
268
|
+
export G5_AUTH_REDIRECT_URI='https://test.host/callback'
|
269
|
+
```
|
270
|
+
|
271
|
+
If you want to use a different username and password per request, then you
|
272
|
+
should configure these on each client instance:
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
auth_client = G5AuthenticationClient::Client.new(username: 'user1@test.host', password: 'secret1')
|
276
|
+
auth_client.me
|
277
|
+
# => #<G5AuthenticationClient::User email="user1@test.host" id=1>
|
278
|
+
|
279
|
+
auth_client = G5AuthenticationClient::Client.new(username: 'user2@test.host', password: 'secret2')
|
280
|
+
auth_client.me
|
281
|
+
# => #<G5AuthenticationClient::User email="user2@test.host" id=2>
|
282
|
+
```
|
283
|
+
|
284
|
+
However, if you want to use the same user credentials for all requests,
|
285
|
+
you can set them using environment variables:
|
286
|
+
|
287
|
+
```bash
|
288
|
+
export G5_AUTH_USERNAME='user1@test.host'
|
289
|
+
export G5_AUTH_PASSWORD='secret1'
|
290
|
+
```
|
291
|
+
|
292
|
+
Now every client instance will authenticate as the same user by default:
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
G5AuthenticationClient::Client.new.me
|
296
|
+
# => #<G5AuthenticationClient::User email="user1@test.host" id=1>
|
297
|
+
|
298
|
+
G5AuthenticationClient::Client.new.me
|
299
|
+
# => #<G5AuthenticationClient::User email="user1@test.host" id=1>
|
300
|
+
```
|
301
|
+
|
302
|
+
## Authors ##
|
303
|
+
|
304
|
+
* Rob Revels / [@sleverbor](https://github.com/sleverbor)
|
305
|
+
* Maeve Revels / [@maeve](https://github.com/maeve)
|
306
|
+
|
307
|
+
## Contributing ##
|
308
|
+
|
309
|
+
1. Fork it
|
310
|
+
2. Get it running
|
311
|
+
3. Create your feature branch (`git checkout -b my-new-feature`)
|
312
|
+
4. Write your code and **specs**
|
313
|
+
5. Commit your changes (`git commit -am 'Add some feature'`)
|
314
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
315
|
+
7. Create new Pull Request
|
316
|
+
|
317
|
+
If you find bugs, have feature requests or questions, please
|
318
|
+
[file an issue](https://github.com/G5/g5_authentication_client/issues).
|
319
|
+
|
320
|
+
### Running the specs ###
|
321
|
+
|
322
|
+
All you have to do is execute rspec through bundler:
|
323
|
+
|
324
|
+
```console
|
325
|
+
$ bundle exec rspec spec
|
326
|
+
```
|
327
|
+
|
328
|
+
## License ##
|
329
|
+
|
330
|
+
Copyright (c) 2014 G5
|
331
|
+
|
332
|
+
MIT License
|
333
|
+
|
334
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
335
|
+
a copy of this software and associated documentation files (the
|
336
|
+
"Software"), to deal in the Software without restriction, including
|
337
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
338
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
339
|
+
permit persons to whom the Software is furnished to do so, subject to
|
340
|
+
the following conditions:
|
341
|
+
|
342
|
+
The above copyright notice and this permission notice shall be
|
343
|
+
included in all copies or substantial portions of the Software.
|
344
|
+
|
345
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
346
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
347
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
348
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
349
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
350
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
351
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task :default => :spec
|
7
|
+
|
8
|
+
namespace :doc do
|
9
|
+
require 'yard'
|
10
|
+
YARD::Rake::YardocTask.new do |task|
|
11
|
+
task.files = ['README.md', 'lib/**/*.rb']
|
12
|
+
task.options = ['--markup', 'markdown']
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "g5_authentication_client/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "g5_authentication_client"
|
6
|
+
s.version = G5AuthenticationClient::VERSION
|
7
|
+
s.authors = ["Rob Revels", "Maeve Revels"]
|
8
|
+
s.email = ["rob.revels@getg5.com", "maeve.revels@getg5.com"]
|
9
|
+
s.homepage = "https://github.com/G5/g5_authentication_client"
|
10
|
+
s.summary = "Client for the G5 Auth service"
|
11
|
+
s.description = "Client for the G5 Auth service"
|
12
|
+
|
13
|
+
s.rubyforge_project = "g5_authentication_client"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency('modelish', '~> 0.3')
|
21
|
+
s.add_dependency('configlet', '~> 2.1')
|
22
|
+
s.add_dependency('oauth2')
|
23
|
+
s.add_dependency('addressable')
|
24
|
+
|
25
|
+
s.add_development_dependency('rake')
|
26
|
+
s.add_development_dependency('rspec')
|
27
|
+
s.add_development_dependency('webmock')
|
28
|
+
s.add_development_dependency('fakefs')
|
29
|
+
s.add_development_dependency('simplecov')
|
30
|
+
s.add_development_dependency('codeclimate-test-reporter')
|
31
|
+
s.add_development_dependency('yard')
|
32
|
+
s.add_development_dependency('rdiscount')
|
33
|
+
s.add_development_dependency('vcr')
|
34
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module G5AuthenticationClient
|
4
|
+
# G5AuthenticationClient::Client can be used to authenticate with the G5 OAuth 2
|
5
|
+
# authorization server. It can also be used to create G5 users.
|
6
|
+
class Client
|
7
|
+
# Mutators for configuration options
|
8
|
+
attr_writer *G5AuthenticationClient::VALID_CONFIG_OPTIONS
|
9
|
+
# Accessors for configuration options
|
10
|
+
G5AuthenticationClient::VALID_CONFIG_OPTIONS.each do |opt|
|
11
|
+
define_method(opt) { get_value(opt) }
|
12
|
+
end
|
13
|
+
|
14
|
+
# @!attribute [rw] allow_password_credentials
|
15
|
+
# @return [String] 'true' if the client is using the
|
16
|
+
# username and password attributes
|
17
|
+
|
18
|
+
# @!attribute [rw] endpoint
|
19
|
+
# @return [String] the g5-authentication service endpoint URL
|
20
|
+
|
21
|
+
# @!attribute [rw] username
|
22
|
+
# @return [String] the username for authentication
|
23
|
+
|
24
|
+
# @!attribute [rw] password
|
25
|
+
# @return [String] the password for authentication
|
26
|
+
|
27
|
+
# @!attribute [rw] debug
|
28
|
+
# @return [String] 'true' if debug logging is enabled
|
29
|
+
|
30
|
+
# @!attribute [rw] logger
|
31
|
+
# @return [Logger] custom logger instance
|
32
|
+
|
33
|
+
# @!attribute [rw] client_id
|
34
|
+
# @return [String] client id for this application
|
35
|
+
|
36
|
+
# @!attribute [rw] client_secret
|
37
|
+
# @return [String] client secret for this application
|
38
|
+
|
39
|
+
# @!attribute [rw] redirect_uri
|
40
|
+
# @return [String] callback url for application
|
41
|
+
|
42
|
+
# @!attribute [rw] authorization_code
|
43
|
+
# @return [String] code provided by authorization server
|
44
|
+
|
45
|
+
# @!attribute [rw] access_token
|
46
|
+
# @return [String] access token value provided by authorization server
|
47
|
+
|
48
|
+
def debug?
|
49
|
+
self.debug.to_s == 'true'
|
50
|
+
end
|
51
|
+
|
52
|
+
# Initializes the client.
|
53
|
+
#
|
54
|
+
# @param [Hash] options
|
55
|
+
# @option options [true,false] :debug true enabled debug logging (defaults to false)
|
56
|
+
# @option options [Logger] :logger a custom logger instance (defaults to STDOUT)
|
57
|
+
# @option options [String] :username The username for authenticating
|
58
|
+
# @option options [String] :password The password for authenticating
|
59
|
+
# @option options [String] :endpoint The authentication endpoint
|
60
|
+
# @option options [String] :client_id The client id for this application
|
61
|
+
# @option options [String] :client_secret The client secret for this application
|
62
|
+
# @option options [String] :redirect_uri The client callback url for this application.
|
63
|
+
# @option options [String] :authorization_code The authentication code from the authorization server.
|
64
|
+
# @option options [String] :allow_password_credentials The client will use username and password if true.
|
65
|
+
def initialize(options={})
|
66
|
+
options.each { |k,v| self.send("#{k}=", v) if self.respond_to?("#{k}=") }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Tells whether a client instance will use the username/password credentials
|
70
|
+
# @return [Boolean] whether the client will use username/password
|
71
|
+
def allow_password_credentials?
|
72
|
+
allow_password_credentials=='true' && !username.nil? && !password.nil?
|
73
|
+
end
|
74
|
+
|
75
|
+
# Retrieves the access token as a string
|
76
|
+
# @return [String] the access token value
|
77
|
+
def get_access_token
|
78
|
+
oauth_access_token.token
|
79
|
+
end
|
80
|
+
|
81
|
+
# Retrieves an attribute's value. If the attribute has not been set
|
82
|
+
# on this object, it is retrieved from the global configuration.
|
83
|
+
#
|
84
|
+
# @see G5AuthenticationClient.configure
|
85
|
+
#
|
86
|
+
# @param [Symbol] attribute the name of the attribute
|
87
|
+
# @return [String] the value of the attribute
|
88
|
+
def get_value(attribute)
|
89
|
+
instance_variable_get("@#{attribute}") || G5AuthenticationClient.send(attribute)
|
90
|
+
end
|
91
|
+
|
92
|
+
# Create a user from the options
|
93
|
+
# @param [Hash] options
|
94
|
+
# @option options [String] :email The new user's email address
|
95
|
+
# @option options [String] :password The new user's password
|
96
|
+
# @option options [String] :password_confirmation The new user's password confirmation string
|
97
|
+
# @return [G5AuthenticationClient::User]
|
98
|
+
def create_user(options={})
|
99
|
+
user=User.new(options)
|
100
|
+
user.validate_for_create!
|
101
|
+
response=oauth_access_token.post('/v1/users', params: {user: user.to_hash})
|
102
|
+
User.new(response.parsed)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Update an existing user
|
106
|
+
# @param [Hash] options
|
107
|
+
# @option options [String] :email The new user's email address
|
108
|
+
# @option options [String] :password The new user's password
|
109
|
+
# @option options [String] :password_confirmation The new user's password confirmation string
|
110
|
+
# @return [G5AuthenticationClient::User]
|
111
|
+
def update_user(options={})
|
112
|
+
user=User.new(options)
|
113
|
+
user.validate!
|
114
|
+
response=oauth_access_token.put("/v1/users/#{user.id}", params: {user: user.to_hash})
|
115
|
+
User.new(response.parsed)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Get a user
|
119
|
+
# @param [Integer] id the user ID in the remote service
|
120
|
+
# @return [G5AuthenticationClient::User]
|
121
|
+
def get_user(id)
|
122
|
+
response=oauth_access_token.get("/v1/users/#{id}")
|
123
|
+
User.new(response.parsed)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Delete a user
|
127
|
+
# @param [Integer] id the user ID in the remote service
|
128
|
+
# @return [G5AuthenticationClient::User]
|
129
|
+
def delete_user(id)
|
130
|
+
response=oauth_access_token.delete("/v1/users/#{id}")
|
131
|
+
User.new(response.parsed)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Get the current user based on configured credentials
|
135
|
+
# @return [G5AuthenticationClient::User]
|
136
|
+
def me
|
137
|
+
response = oauth_access_token.get('/v1/me')
|
138
|
+
User.new(response.parsed)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Get the access token info for the currently active token
|
142
|
+
# @return [G5AuthenticationClient::TokenInfo]
|
143
|
+
def token_info
|
144
|
+
response = oauth_access_token.get('/oauth/token/info')
|
145
|
+
TokenInfo.new(response.parsed)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Return the URL for signing out of the auth server.
|
149
|
+
# Clients should redirect to this URL to globally sign out.
|
150
|
+
#
|
151
|
+
# @param [String] redirect_url the URL that the auth server should redirect back to after sign out
|
152
|
+
# @return [String] the auth server endpoint for signing out
|
153
|
+
def sign_out_url(redirect_url=nil)
|
154
|
+
auth_server_url = Addressable::URI.parse(endpoint)
|
155
|
+
auth_server_url.path = '/users/sign_out'
|
156
|
+
auth_server_url.query_values = {redirect_url: redirect_url} if redirect_url
|
157
|
+
auth_server_url.to_s
|
158
|
+
end
|
159
|
+
|
160
|
+
private
|
161
|
+
def oauth_client
|
162
|
+
OAuth2::Client.new(client_id, client_secret, site: endpoint)
|
163
|
+
end
|
164
|
+
|
165
|
+
def oauth_access_token
|
166
|
+
@oauth_access_token ||= if access_token
|
167
|
+
OAuth2::AccessToken.new(oauth_client, access_token)
|
168
|
+
elsif authorization_code
|
169
|
+
oauth_client.auth_code.get_token(authorization_code, redirect_uri: redirect_uri)
|
170
|
+
elsif allow_password_credentials?
|
171
|
+
oauth_client.password.get_token(username,password)
|
172
|
+
else
|
173
|
+
raise "Insufficient credentials for access token. Supply a username/password or authentication code"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|