g5_authenticatable 0.3.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/.env +1 -0
- data/.gitignore +25 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +45 -0
- data/Gemfile +37 -0
- data/LICENSE +22 -0
- data/README.md +519 -0
- data/Rakefile +20 -0
- data/app/assets/images/g5_authenticatable/.gitkeep +0 -0
- data/app/assets/javascripts/g5_authenticatable/application.js +15 -0
- data/app/assets/stylesheets/g5_authenticatable/application.css +13 -0
- data/app/controllers/g5_authenticatable/application_controller.rb +4 -0
- data/app/controllers/g5_authenticatable/error_controller.rb +9 -0
- data/app/controllers/g5_authenticatable/sessions_controller.rb +23 -0
- data/app/helpers/g5_authenticatable/application_helper.rb +4 -0
- data/app/models/g5_authenticatable/user.rb +8 -0
- data/app/views/g5_authenticatable/error/auth_error.html.erb +1 -0
- data/app/views/layouts/g5_authenticatable/application.html.erb +20 -0
- data/circle.yml +4 -0
- data/config/initializers/devise.rb +257 -0
- data/config/locales/devise.en.yml +59 -0
- data/config/routes.rb +6 -0
- data/g5_authenticatable.gemspec +25 -0
- data/lib/g5_authenticatable.rb +7 -0
- data/lib/g5_authenticatable/engine.rb +15 -0
- data/lib/g5_authenticatable/rspec.rb +4 -0
- data/lib/g5_authenticatable/test/controller_helpers.rb +59 -0
- data/lib/g5_authenticatable/test/factory.rb +10 -0
- data/lib/g5_authenticatable/test/feature_helpers.rb +38 -0
- data/lib/g5_authenticatable/test/request_helpers.rb +29 -0
- data/lib/g5_authenticatable/version.rb +3 -0
- data/lib/generators/g5_authenticatable/install/USAGE +11 -0
- data/lib/generators/g5_authenticatable/install/install_generator.rb +20 -0
- data/lib/generators/g5_authenticatable/install/templates/create_g5_authenticatable_users.rb +23 -0
- data/lib/tasks/g5_authenticatable_tasks.rake +4 -0
- data/script/rails +8 -0
- data/spec/config/application_spec.rb +7 -0
- data/spec/controllers/.gitkeep +0 -0
- data/spec/controllers/application_controller_spec.rb +22 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/api/secure_api.rb +8 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/home_controller.rb +9 -0
- data/spec/dummy/app/controllers/rails_api/secure_resources_controller.rb +17 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/home/index.html.erb +1 -0
- data/spec/dummy/app/views/home/show.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +16 -0
- data/spec/dummy/app/views/rails_api/secure_resources/show.html.erb +0 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +63 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml.ci +6 -0
- data/spec/dummy/config/database.yml.sample +13 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +65 -0
- data/spec/dummy/config/environments/test.rb +33 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +15 -0
- data/spec/dummy/db/migrate/20140206070137_create_g5_authenticatable_users.rb +23 -0
- data/spec/dummy/db/schema.rb +33 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/features/auth_error_path_spec.rb +21 -0
- data/spec/features/sign_in_spec.rb +68 -0
- data/spec/g5_authenticatable/version_spec.rb +7 -0
- data/spec/lib/generators/g5_authenticatable/install_generator_spec.rb +55 -0
- data/spec/models/.gitkeep +0 -0
- data/spec/models/g5_authenticatable/user_spec.rb +39 -0
- data/spec/requests/grape_api_spec.rb +19 -0
- data/spec/requests/rails_api_spec.rb +53 -0
- data/spec/routing/auth_error_routing_spec.rb +15 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/support/devise.rb +3 -0
- metadata +222 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 7a62091f31bef8d7d3b0dbd2b57aa2e3dc627ebc
|
|
4
|
+
data.tar.gz: e74855a8c9bf2e5e89edf97d40cb4d11ba004427
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b815696a057a7e20ff3a0d6e67fe831ac69c8f17663a8419039b501e76da81fef1ab7cd3122fdbbe6166504f46ad943df072be16ed89d80945a24a908c568194
|
|
7
|
+
data.tar.gz: 077e3c67efa60753a0333cb6a749c0e7066a07605737a9148af854a819a532781a32effc1f7f9c51ee81920fef946136552e1765a84845d36bc6854d3d4837ef
|
data/.gitignore
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
*.gem
|
|
3
|
+
*.rbc
|
|
4
|
+
.bundle
|
|
5
|
+
.config
|
|
6
|
+
.yardoc
|
|
7
|
+
Gemfile.lock
|
|
8
|
+
InstalledFiles
|
|
9
|
+
_yardoc
|
|
10
|
+
coverage
|
|
11
|
+
doc/
|
|
12
|
+
lib/bundler/man
|
|
13
|
+
pkg
|
|
14
|
+
rdoc
|
|
15
|
+
spec/reports
|
|
16
|
+
test/tmp
|
|
17
|
+
test/version_tmp
|
|
18
|
+
tmp
|
|
19
|
+
log/*.log
|
|
20
|
+
spec/dummy/db/*.sqlite3
|
|
21
|
+
spec/dummy/log/*.log
|
|
22
|
+
spec/dummy/tmp/
|
|
23
|
+
spec/dummy/.sass-cache
|
|
24
|
+
spec/dummy/config/database.yml
|
|
25
|
+
.env.*
|
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.1.0
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
## v0.3.0 (2014-03-13)
|
|
2
|
+
|
|
3
|
+
* First open source release to [RubyGems](https://rubygems.org)
|
|
4
|
+
|
|
5
|
+
## v0.2.0 (2014-03-11)
|
|
6
|
+
|
|
7
|
+
* Controller test helpers
|
|
8
|
+
|
|
9
|
+
## v0.1.4 (2014-03-07)
|
|
10
|
+
|
|
11
|
+
* Update dependency on [g5_authenticatable_api](https://github.com/G5/g5_authenticatable_api)
|
|
12
|
+
for bug fix to ignore password credential configuration during token validation.
|
|
13
|
+
|
|
14
|
+
## v0.1.3 (2014-03-06)
|
|
15
|
+
|
|
16
|
+
* Remove auth client defaults in favor of env variables
|
|
17
|
+
|
|
18
|
+
## v0.1.2 (2014-03-05)
|
|
19
|
+
|
|
20
|
+
* Set G5_AUTH_USERNAME and G5_AUTH_PASSWORD on auth client defaults
|
|
21
|
+
|
|
22
|
+
## v0.1.0 (2014-02-26)
|
|
23
|
+
|
|
24
|
+
* Update dependency on [g5_authenticatable_api](https://github.com/G5/g5_authenticatable_api)
|
|
25
|
+
to include new Rails API helpers.
|
|
26
|
+
* Fix shared test helpers for client applications that do not mixin the FactoryGirl syntax methods
|
|
27
|
+
in their RSpec config.
|
|
28
|
+
|
|
29
|
+
## v0.0.4 (2014-02-20)
|
|
30
|
+
|
|
31
|
+
* Integrate [g5_authenticatable_api](https://github.com/G5/g5_authenticatable_api)
|
|
32
|
+
for securing API methods.
|
|
33
|
+
|
|
34
|
+
## v0.0.3 (2014-02-13)
|
|
35
|
+
|
|
36
|
+
* Test helpers and shared context for integration tests in client applications.
|
|
37
|
+
|
|
38
|
+
## v0.0.2 (2014-02-10)
|
|
39
|
+
|
|
40
|
+
* Bump version for [devise_g5_authenticatable](https://github.com/G5/devise_g5_authenticatable)
|
|
41
|
+
to pick up PostgreSQL fix.
|
|
42
|
+
|
|
43
|
+
## v0.0.1 (2014-02-07)
|
|
44
|
+
|
|
45
|
+
* Initial release
|
data/Gemfile
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
# Declare your gem's dependencies in g5_authenticatable.gemspec.
|
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
|
5
|
+
# development dependencies will be added by default to the :development group.
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
# Gems used by the dummy application
|
|
9
|
+
gem 'rails', '~> 4.0.2'
|
|
10
|
+
gem 'jquery-rails'
|
|
11
|
+
gem 'pg'
|
|
12
|
+
gem 'grape'
|
|
13
|
+
|
|
14
|
+
group :test, :development do
|
|
15
|
+
gem 'rspec-rails', '~> 2.14'
|
|
16
|
+
gem 'pry'
|
|
17
|
+
gem 'dotenv-rails'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
group :test do
|
|
21
|
+
gem 'capybara'
|
|
22
|
+
gem 'factory_girl_rails', '~> 4.3', require: false
|
|
23
|
+
gem 'simplecov', require: false
|
|
24
|
+
gem 'codeclimate-test-reporter', require: false
|
|
25
|
+
gem 'webmock'
|
|
26
|
+
gem 'shoulda-matchers'
|
|
27
|
+
gem 'generator_spec'
|
|
28
|
+
gem 'rspec-http', require: 'rspec/http'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Declare any dependencies that are still in development here instead of in
|
|
32
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
|
33
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
|
34
|
+
# your gem to rubygems.org.
|
|
35
|
+
|
|
36
|
+
# To use debugger
|
|
37
|
+
# gem 'debugger'
|
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,519 @@
|
|
|
1
|
+
# G5 Authenticatable
|
|
2
|
+
|
|
3
|
+
G5 Authenticatable provides a default authentication solution for G5
|
|
4
|
+
Rails applications. This gem configures and mounts
|
|
5
|
+
[Devise](https://github.com/plataformatec/devise) with a default User
|
|
6
|
+
model, using [OmniAuth](https://github.com/intridea/omniauth) to authenticate
|
|
7
|
+
to the G5 Auth server. Helpers are also provided to secure your API methods.
|
|
8
|
+
|
|
9
|
+
If you are already using Devise with your own model, this is not the
|
|
10
|
+
library you are looking for. Consider using the
|
|
11
|
+
[devise_g5_authenticatable](https://github.com/G5/devise_g5_authenticatable)
|
|
12
|
+
extension directly.
|
|
13
|
+
|
|
14
|
+
If you have a stand-alone service without a UI, you may not need Devise at
|
|
15
|
+
all. Consider using the
|
|
16
|
+
[g5_authenticatable_api](https://github.com/G5/g5_authenticatable_api)
|
|
17
|
+
library in isolation.
|
|
18
|
+
|
|
19
|
+
## Current Version
|
|
20
|
+
|
|
21
|
+
0.3.0
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
* [rails](https://github.com/rails/rails) >= 3.2
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
1. Set the environment variable `DEVISE_SECRET_KEY` to the value
|
|
30
|
+
generated by:
|
|
31
|
+
|
|
32
|
+
```console
|
|
33
|
+
rake secret
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
2. Add this line to your application's Gemfile:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
gem 'g5_authenticatable'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
3. And then execute:
|
|
43
|
+
|
|
44
|
+
```console
|
|
45
|
+
bundle
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
4. Run the generator:
|
|
49
|
+
|
|
50
|
+
```console
|
|
51
|
+
rails g g5_authenticatable:install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This creates a migration for the new g5_authenticatable_users
|
|
55
|
+
table, and mounts the engine at `/g5_auth`.
|
|
56
|
+
|
|
57
|
+
5. Update your database:
|
|
58
|
+
|
|
59
|
+
```console
|
|
60
|
+
rake db:migrate db:test:prepare
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
### Root route
|
|
66
|
+
|
|
67
|
+
Devise requires you to define a root route in your application's
|
|
68
|
+
`config/routes.rb`. For example:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
root :to => 'home#index'
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Registering your OAuth application
|
|
75
|
+
|
|
76
|
+
1. Visit the auth server admin console and login:
|
|
77
|
+
* For development, visit https://dev-auth.g5search.com/admin
|
|
78
|
+
* For production, visit https://auth.g5search.com/admin
|
|
79
|
+
2. Click "New Application"
|
|
80
|
+
3. Enter a name that recognizably identifies your application.
|
|
81
|
+
4. Enter the redirect URI where the auth server should redirect
|
|
82
|
+
after the user successfully authenticates. It will be
|
|
83
|
+
of the form `http://<your_host>/g5_auth/users/auth/g5/callback`.
|
|
84
|
+
|
|
85
|
+
For non-production environments, this redirect URI does not have to
|
|
86
|
+
be publicly accessible, but it must be accessible from the browser
|
|
87
|
+
where you will be testing (so using something like
|
|
88
|
+
http://localhost:3000/users/auth/g5/callback is fine if your browser
|
|
89
|
+
and client application server are both local).
|
|
90
|
+
|
|
91
|
+
If you are using the production G5 Auth server, the redirect URI **MUST**
|
|
92
|
+
use HTTPS.
|
|
93
|
+
5. For a trusted G5 application, check the "Auto-authorize?" checkbox. This
|
|
94
|
+
skips the OAuth authorization step where the user is prompted to explicitly
|
|
95
|
+
authorize the client application to access the user's data.
|
|
96
|
+
6. Click "Submit" to obtain the client application's credentials.
|
|
97
|
+
|
|
98
|
+
### Environment variables
|
|
99
|
+
|
|
100
|
+
Once you have your OAuth 2.0 credentials, you'll need to set the following
|
|
101
|
+
environment variables for your client application:
|
|
102
|
+
|
|
103
|
+
* `G5_AUTH_CLIENT_ID` - the OAuth 2.0 application ID from the auth server
|
|
104
|
+
* `G5_AUTH_CLIENT_SECRET` - the OAuth 2.0 application secret from the auth server
|
|
105
|
+
* `G5_AUTH_REDIRECT_URI` - the OAuth 2.0 redirect URI registered with the auth server
|
|
106
|
+
* `G5_AUTH_ENDPOINT` - the endpoint URL for the G5 auth server
|
|
107
|
+
|
|
108
|
+
You can also set up a default user's credentials with:
|
|
109
|
+
|
|
110
|
+
* `G5_AUTH_USERNAME` - the G5 auth server user name
|
|
111
|
+
* `G5_AUTH_PASSWORD` - the G5 auth server user's password
|
|
112
|
+
|
|
113
|
+
## Usage
|
|
114
|
+
|
|
115
|
+
### Controller filters and helpers
|
|
116
|
+
|
|
117
|
+
G5 Authenticatable installs all of the usual devise controllers and helpers.
|
|
118
|
+
To set up a controller that requires authentication, use this before_filter:
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
before_filter :authenticate_user!
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
To verify if a user is signed in, use the following helper:
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
user_signed_in?
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
To access the model instance for the currently signed-in user:
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
current_user
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
To access scoped session storage:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
user_session
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Route helpers
|
|
143
|
+
|
|
144
|
+
There are several generic helper methods for session and omniauth
|
|
145
|
+
URLs. To sign in:
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
new_session_path(:user)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
To sign out:
|
|
152
|
+
|
|
153
|
+
```ruby
|
|
154
|
+
destroy_session_path(:user)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
There are also generic helpers for the OmniAuth paths, though you
|
|
158
|
+
are unlikely to ever use these directly. The OmniAuth entry point
|
|
159
|
+
is mounted at:
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
g5_authorize_path(:user)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
And the OmniAuth callback is:
|
|
166
|
+
|
|
167
|
+
```ruby
|
|
168
|
+
g5_callback_path(:user)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
You may be more familiar with Devise's generated scoped URL helpers.
|
|
172
|
+
These are still available, but are isolated to the engine's namespace.
|
|
173
|
+
For example:
|
|
174
|
+
|
|
175
|
+
```ruby
|
|
176
|
+
g5_authenticatable.new_user_session_path
|
|
177
|
+
g5_authenticatable.destroy_user_session_path
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Access token ###
|
|
181
|
+
|
|
182
|
+
When a user authenticates, their OAuth access token will be stored on
|
|
183
|
+
the local user:
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
current_user.g5_access_token
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This is to support server-to-server API calls with G5 services that are
|
|
190
|
+
protected by OAuth.
|
|
191
|
+
|
|
192
|
+
### Securing an API ###
|
|
193
|
+
|
|
194
|
+
#### Grape ####
|
|
195
|
+
|
|
196
|
+
If you include `G5AuthenticatableApi::Helpers::Grape`, you can use the
|
|
197
|
+
`authenticate_user!` method to protect your API actions:
|
|
198
|
+
|
|
199
|
+
```ruby
|
|
200
|
+
class MyApi < Grape::API
|
|
201
|
+
helpers G5AuthenticatableApi::GrapeHelpers
|
|
202
|
+
|
|
203
|
+
before { authenticate_user! }
|
|
204
|
+
|
|
205
|
+
# ...
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### Rails ####
|
|
210
|
+
|
|
211
|
+
You can secure API actions that respond to json using the `authenticate_api_user!`
|
|
212
|
+
method:
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
class MyResourcesController < ApplicationController
|
|
216
|
+
respond_to :json
|
|
217
|
+
|
|
218
|
+
before_filter :authenticate_api_user!
|
|
219
|
+
|
|
220
|
+
def get
|
|
221
|
+
@resource = MyResource.find(params[:id])
|
|
222
|
+
respond_with(@resource)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Secure Clients ####
|
|
228
|
+
|
|
229
|
+
If you have an ember application, no client-side changes are necessary to use a
|
|
230
|
+
secure API method, as long as the action that serves your ember app requires
|
|
231
|
+
users to authenticate with G5 via devise.
|
|
232
|
+
|
|
233
|
+
Any non-browser clients must use token-based authentication. In contexts where
|
|
234
|
+
a valid OAuth 2.0 access token is not already available, you may request a new
|
|
235
|
+
token from the G5 Auth server using
|
|
236
|
+
[g5_authentication_client](https://github.com/G5/g5_authentication_client).
|
|
237
|
+
Clients may pass the token to secure API actions either in the HTTP
|
|
238
|
+
Authorization header, or in a request parameter named `access_token`.
|
|
239
|
+
|
|
240
|
+
For more details, see the documentation for
|
|
241
|
+
[g5_authenticatable_api](https://github.com/G5/g5_authenticatable_api).
|
|
242
|
+
|
|
243
|
+
### Test Helpers ###
|
|
244
|
+
|
|
245
|
+
G5 Authenticatable currently only supports [rspec-rails](https://github.com/rspec/rspec-rails).
|
|
246
|
+
Helpers and shared contexts are provided for integration testing secure pages
|
|
247
|
+
and API methods.
|
|
248
|
+
|
|
249
|
+
#### Installation ####
|
|
250
|
+
|
|
251
|
+
To automatically mix in helpers to your feature and request specs, include the
|
|
252
|
+
following line in your `spec/spec_helper.rb`:
|
|
253
|
+
|
|
254
|
+
```ruby
|
|
255
|
+
require 'g5_authenticatable/rspec'
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### Feature Specs ####
|
|
259
|
+
|
|
260
|
+
The easiest way to use g5_authenticatable in feature specs is through
|
|
261
|
+
the shared auth context. This context creates a user (available via
|
|
262
|
+
`let(:user)`) and then authenticates as that user. To use the shared
|
|
263
|
+
context, simply include `:auth` in the RSpec metadata for your example
|
|
264
|
+
or group:
|
|
265
|
+
|
|
266
|
+
```ruby
|
|
267
|
+
context 'my secure context', :auth do
|
|
268
|
+
it 'can access some resource' do
|
|
269
|
+
visit('the place')
|
|
270
|
+
expect(page).to ...
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
If you prefer, you can use the helper methods from
|
|
276
|
+
`G5Authenticatable::Test::FeatureHelpers` instead of relying on the shared
|
|
277
|
+
context. For example:
|
|
278
|
+
|
|
279
|
+
```ruby
|
|
280
|
+
describe 'my page' do
|
|
281
|
+
context 'with valid user credentials' do
|
|
282
|
+
let(:my_user) { create(:g5_authenticatable_user, email: 'my.email@test.host') }
|
|
283
|
+
before { stub_g5_omniauth(my_user) }
|
|
284
|
+
|
|
285
|
+
it 'should display the secure page' do
|
|
286
|
+
visit('the page')
|
|
287
|
+
expect(page).to ...
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
context 'with invalid OAuth credentials' do
|
|
292
|
+
before { stub_g5_invalid_credentials }
|
|
293
|
+
|
|
294
|
+
it 'should display an error' do
|
|
295
|
+
visit('the page')
|
|
296
|
+
expect(page). to ...
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
context 'when user has previously authenticated' do
|
|
301
|
+
let(:my_user) { create(:g5_authenticatable_user, email: 'my.email@test.host') }
|
|
302
|
+
before { visit_path_and_login_with('some other path', my_user) }
|
|
303
|
+
|
|
304
|
+
it 'should display the thing I expect' do
|
|
305
|
+
visit('the page')
|
|
306
|
+
expect(page).to ...
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
#### Request Specs ####
|
|
313
|
+
|
|
314
|
+
You can test API methods that have been secured with g5_authenticatable by
|
|
315
|
+
using the auth request shared context. This context creates a user (available
|
|
316
|
+
via `let(:user)`) and then automatically authenticates as that user. To use the
|
|
317
|
+
shared context, simply tag your example group with the `:auth_request` RSpec
|
|
318
|
+
metadata:
|
|
319
|
+
|
|
320
|
+
```ruby
|
|
321
|
+
describe 'my secure API', :auth_request do
|
|
322
|
+
it 'can access some resource' do
|
|
323
|
+
get '/api/v1/resource'
|
|
324
|
+
expect(response).to ...
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Alternatively, you may wish to use the helper methods from
|
|
330
|
+
`G5Authenticatable::Test::RequestHelpers` directly:
|
|
331
|
+
|
|
332
|
+
```ruby
|
|
333
|
+
describe 'my secure API' do
|
|
334
|
+
context 'when user is authenticated' do
|
|
335
|
+
before { login_user }
|
|
336
|
+
|
|
337
|
+
it 'can access some resource' do
|
|
338
|
+
get '/api/v1/resource'
|
|
339
|
+
expect(response).to be_success
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
context 'when there is no authenticated user' do
|
|
344
|
+
before { logout_user }
|
|
345
|
+
|
|
346
|
+
it 'cannot access the resource' do
|
|
347
|
+
get '/api/v1/resource'
|
|
348
|
+
expect(response.status).to eq(401)
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
#### Controller Specs ####
|
|
355
|
+
|
|
356
|
+
You can test controller specs that have been secured with g5_authenticatable
|
|
357
|
+
by using the controller spec shared context. This context creates a user
|
|
358
|
+
available via `let(:user)` and then automatically authenticates as that user.
|
|
359
|
+
To use the shared context, tag your example group with the `:auth_controller`
|
|
360
|
+
Rspec metadata:
|
|
361
|
+
|
|
362
|
+
```ruby
|
|
363
|
+
describe 'my secure action', :auth_controller do
|
|
364
|
+
context 'when the user is authenticated' do
|
|
365
|
+
it 'can access some secure path' do
|
|
366
|
+
get :my_action
|
|
367
|
+
expect(response). to be_success
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
context 'whent there is no authenticated user' do
|
|
372
|
+
it 'cannot access the secure path' do
|
|
373
|
+
get :my_action
|
|
374
|
+
expect(reponse).to be_redirect
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Examples
|
|
381
|
+
|
|
382
|
+
### Protecting a particular Rails controller action
|
|
383
|
+
|
|
384
|
+
You can use all of the usual options to `before_filter` for more fine-grained
|
|
385
|
+
control over where authentication is required. For example, to require
|
|
386
|
+
authentication only to edit a resource while leaving all other actions
|
|
387
|
+
unsecured:
|
|
388
|
+
|
|
389
|
+
```ruby
|
|
390
|
+
class MyResourcesController < ApplicationController
|
|
391
|
+
before_filter :authenticate_user!, only: [:edit, :update]
|
|
392
|
+
|
|
393
|
+
# ...
|
|
394
|
+
end
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Adding a link to sign in
|
|
398
|
+
|
|
399
|
+
In your view template, add the following:
|
|
400
|
+
|
|
401
|
+
```html+erb
|
|
402
|
+
<%= link_to('Login', new_session_path(:user)) %>
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Adding a link to sign out
|
|
406
|
+
|
|
407
|
+
In order to sign out, the link must not only have the correct path,
|
|
408
|
+
but must also use the DELETE HTTP method:
|
|
409
|
+
|
|
410
|
+
```html+erb
|
|
411
|
+
<%= link_to('Logout', destroy_session_path(:user), :method => :delete) %>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### Selectively securing Grape API methods
|
|
415
|
+
|
|
416
|
+
To selectively secure an individual API method:
|
|
417
|
+
|
|
418
|
+
```ruby
|
|
419
|
+
class MyApi < Grape::API
|
|
420
|
+
get :my_secure_action do
|
|
421
|
+
authenticate_user!
|
|
422
|
+
{message: 'secure action'}
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
get :anonymous_action do
|
|
426
|
+
{message: 'hello world'}
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Securing a Rails controller that mixes API and website methods
|
|
432
|
+
|
|
433
|
+
Within a Rails controller, the `authenticate_api_user!` looks for a token
|
|
434
|
+
in the request and returns a 401 when a user cannot be authenticated.
|
|
435
|
+
In contrast, devise's `authenticate_user!` filter assumes that client is a
|
|
436
|
+
web browser, and redirects to the auth server sign in page when there is
|
|
437
|
+
no authenticated user.
|
|
438
|
+
|
|
439
|
+
Most of the time, there is a clear delineation between controllers
|
|
440
|
+
that service API requests and controllers that service website requests,
|
|
441
|
+
but not always. If you have a mixture of API and website actions in
|
|
442
|
+
your controller, you can selectively apply the auth filters based on
|
|
443
|
+
the request format:
|
|
444
|
+
|
|
445
|
+
```ruby
|
|
446
|
+
class MyMixedUpController < ApplicationController
|
|
447
|
+
before_filter :authenticate_api_user!, unless: :is_navigational_format?
|
|
448
|
+
before_filter :authenticate_user!, if: :is_navigational_format?
|
|
449
|
+
|
|
450
|
+
respond_to :html, :json
|
|
451
|
+
|
|
452
|
+
def show
|
|
453
|
+
resource = MyResource.find(params[:id])
|
|
454
|
+
respond_with(resource)
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
In the code above, we assume that HTML requests come from a client that
|
|
460
|
+
can display the auth server's sign in page to the end user, while all other
|
|
461
|
+
formats are assumed to be API requests.
|
|
462
|
+
|
|
463
|
+
## Authors
|
|
464
|
+
|
|
465
|
+
* Maeve Revels / [@maeve](https://github.com/maeve)
|
|
466
|
+
* Rob Revels / [@sleverbor](https://github.com/sleverbor)
|
|
467
|
+
|
|
468
|
+
## Contributing
|
|
469
|
+
|
|
470
|
+
1. [Fork it](https://github.com/G5/g5_authenticatable/fork)
|
|
471
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
472
|
+
3. Write your code and **specs**
|
|
473
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
|
474
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
|
475
|
+
6. Create a new Pull Request
|
|
476
|
+
|
|
477
|
+
If you find bugs, have feature requests or questions, please
|
|
478
|
+
[file an issue](https://github.com/G5/g5_authenticatable/issues).
|
|
479
|
+
|
|
480
|
+
### Specs
|
|
481
|
+
|
|
482
|
+
Before running the specs for the first time, you will need to initialize the
|
|
483
|
+
database for the test Rails application.
|
|
484
|
+
|
|
485
|
+
```console
|
|
486
|
+
$ cp spec/dummy/config/database.yml.sample spec/dummy/config/database.yml
|
|
487
|
+
$ RAILS_ENV=test bundle exec rake app:db:setup
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
To execute the entire test suite:
|
|
491
|
+
|
|
492
|
+
```console
|
|
493
|
+
$ bundle exec rspec spec
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
## License
|
|
497
|
+
|
|
498
|
+
Copyright (c) 2014 G5
|
|
499
|
+
|
|
500
|
+
MIT License
|
|
501
|
+
|
|
502
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
503
|
+
a copy of this software and associated documentation files (the
|
|
504
|
+
"Software"), to deal in the Software without restriction, including
|
|
505
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
506
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
507
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
508
|
+
the following conditions:
|
|
509
|
+
|
|
510
|
+
The above copyright notice and this permission notice shall be
|
|
511
|
+
included in all copies or substantial portions of the Software.
|
|
512
|
+
|
|
513
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
514
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
515
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
516
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
517
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
518
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
519
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|