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