g5_authenticatable 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.env +1 -0
  3. data/.gitignore +25 -0
  4. data/.rspec +1 -0
  5. data/.ruby-version +1 -0
  6. data/CHANGELOG.md +45 -0
  7. data/Gemfile +37 -0
  8. data/LICENSE +22 -0
  9. data/README.md +519 -0
  10. data/Rakefile +20 -0
  11. data/app/assets/images/g5_authenticatable/.gitkeep +0 -0
  12. data/app/assets/javascripts/g5_authenticatable/application.js +15 -0
  13. data/app/assets/stylesheets/g5_authenticatable/application.css +13 -0
  14. data/app/controllers/g5_authenticatable/application_controller.rb +4 -0
  15. data/app/controllers/g5_authenticatable/error_controller.rb +9 -0
  16. data/app/controllers/g5_authenticatable/sessions_controller.rb +23 -0
  17. data/app/helpers/g5_authenticatable/application_helper.rb +4 -0
  18. data/app/models/g5_authenticatable/user.rb +8 -0
  19. data/app/views/g5_authenticatable/error/auth_error.html.erb +1 -0
  20. data/app/views/layouts/g5_authenticatable/application.html.erb +20 -0
  21. data/circle.yml +4 -0
  22. data/config/initializers/devise.rb +257 -0
  23. data/config/locales/devise.en.yml +59 -0
  24. data/config/routes.rb +6 -0
  25. data/g5_authenticatable.gemspec +25 -0
  26. data/lib/g5_authenticatable.rb +7 -0
  27. data/lib/g5_authenticatable/engine.rb +15 -0
  28. data/lib/g5_authenticatable/rspec.rb +4 -0
  29. data/lib/g5_authenticatable/test/controller_helpers.rb +59 -0
  30. data/lib/g5_authenticatable/test/factory.rb +10 -0
  31. data/lib/g5_authenticatable/test/feature_helpers.rb +38 -0
  32. data/lib/g5_authenticatable/test/request_helpers.rb +29 -0
  33. data/lib/g5_authenticatable/version.rb +3 -0
  34. data/lib/generators/g5_authenticatable/install/USAGE +11 -0
  35. data/lib/generators/g5_authenticatable/install/install_generator.rb +20 -0
  36. data/lib/generators/g5_authenticatable/install/templates/create_g5_authenticatable_users.rb +23 -0
  37. data/lib/tasks/g5_authenticatable_tasks.rake +4 -0
  38. data/script/rails +8 -0
  39. data/spec/config/application_spec.rb +7 -0
  40. data/spec/controllers/.gitkeep +0 -0
  41. data/spec/controllers/application_controller_spec.rb +22 -0
  42. data/spec/dummy/README.rdoc +261 -0
  43. data/spec/dummy/Rakefile +7 -0
  44. data/spec/dummy/app/api/secure_api.rb +8 -0
  45. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  46. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  47. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  48. data/spec/dummy/app/controllers/home_controller.rb +9 -0
  49. data/spec/dummy/app/controllers/rails_api/secure_resources_controller.rb +17 -0
  50. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  51. data/spec/dummy/app/mailers/.gitkeep +0 -0
  52. data/spec/dummy/app/models/.gitkeep +0 -0
  53. data/spec/dummy/app/views/home/index.html.erb +1 -0
  54. data/spec/dummy/app/views/home/show.html.erb +1 -0
  55. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  56. data/spec/dummy/app/views/rails_api/secure_resources/show.html.erb +0 -0
  57. data/spec/dummy/config.ru +4 -0
  58. data/spec/dummy/config/application.rb +63 -0
  59. data/spec/dummy/config/boot.rb +10 -0
  60. data/spec/dummy/config/database.yml.ci +6 -0
  61. data/spec/dummy/config/database.yml.sample +13 -0
  62. data/spec/dummy/config/environment.rb +5 -0
  63. data/spec/dummy/config/environments/development.rb +29 -0
  64. data/spec/dummy/config/environments/production.rb +65 -0
  65. data/spec/dummy/config/environments/test.rb +33 -0
  66. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  67. data/spec/dummy/config/initializers/inflections.rb +15 -0
  68. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  69. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  70. data/spec/dummy/config/initializers/session_store.rb +8 -0
  71. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  72. data/spec/dummy/config/locales/en.yml +5 -0
  73. data/spec/dummy/config/routes.rb +15 -0
  74. data/spec/dummy/db/migrate/20140206070137_create_g5_authenticatable_users.rb +23 -0
  75. data/spec/dummy/db/schema.rb +33 -0
  76. data/spec/dummy/lib/assets/.gitkeep +0 -0
  77. data/spec/dummy/log/.gitkeep +0 -0
  78. data/spec/dummy/public/404.html +26 -0
  79. data/spec/dummy/public/422.html +26 -0
  80. data/spec/dummy/public/500.html +25 -0
  81. data/spec/dummy/public/favicon.ico +0 -0
  82. data/spec/dummy/script/rails +6 -0
  83. data/spec/features/auth_error_path_spec.rb +21 -0
  84. data/spec/features/sign_in_spec.rb +68 -0
  85. data/spec/g5_authenticatable/version_spec.rb +7 -0
  86. data/spec/lib/generators/g5_authenticatable/install_generator_spec.rb +55 -0
  87. data/spec/models/.gitkeep +0 -0
  88. data/spec/models/g5_authenticatable/user_spec.rb +39 -0
  89. data/spec/requests/grape_api_spec.rb +19 -0
  90. data/spec/requests/rails_api_spec.rb +53 -0
  91. data/spec/routing/auth_error_routing_spec.rb +15 -0
  92. data/spec/spec_helper.rb +52 -0
  93. data/spec/support/devise.rb +3 -0
  94. 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/.env ADDED
@@ -0,0 +1 @@
1
+ DEVISE_SECRET_KEY='generate-this-value-using-rake-secret'
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.