From ee7e3f6600a1139232da28858efa002661a11319 Mon Sep 17 00:00:00 2001 From: Brent Dearth Date: Fri, 30 Oct 2015 14:21:57 -0600 Subject: [PATCH] feat(enable-standard-devise): allow configurable support of legacy Devise authentication. update default to disabled. --- CHANGELOG.md | 11 ++ Gemfile.lock | 3 - README.md | 12 ++- .../concerns/set_user_by_token.rb | 14 +-- lib/devise_token_auth/engine.rb | 6 +- .../templates/devise_token_auth.rb | 15 ++- test/controllers/demo_user_controller_test.rb | 101 ++++++++++-------- 7 files changed, 100 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ab6c0b5..00478055d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,19 @@ ## Features +- **Standard Devise**: Allow conditional support of legacy Devise. Now defaults to disabled. +- **Localization**: Add German translation(de) - **Batch Requests**: Prevent batching of requests by appending `unbatch=true` param to request URL +## Fixes + +- **URL Helper**: Preserve query parameters when building urls + +## Breaking Changes + +- This version updates legacy Devise support to default to disabled rather than enabled. This support causing all sorts of random issues for people who may not have needed the integration. This feature is considered experimental. + + # 0.1.36 (2015-10-13) diff --git a/Gemfile.lock b/Gemfile.lock index 8f1c95547..9dcba307c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -261,6 +261,3 @@ DEPENDENCIES rack-cors sqlite3 (~> 1.3) thor - -BUNDLED WITH - 1.10.5 diff --git a/README.md b/README.md index 787554ed5..ddcf52014 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,8 @@ The following settings are available for configuration in `config/initializers/d | **`default_confirm_success_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful email confirmation. If this param is set, the API will redirect to this value when no value is provided by the cilent. | | **`default_password_reset_url`** | `nil` | By default this value is expected to be sent by the client so that the API knows where to redirect users after successful password resets. If this param is set, the API will redirect to this value when no value is provided by the cilent. | | **`redirect_whitelist`** | `nil` | As an added security measure, you can limit the URLs to which the API will redirect after email token validation (password reset, email confirmation, etc.). This value should be an array containing exact matches to the client URLs to be visited after validation. | +| **`enable_standard_devise_support`** | `false` | By default, only Bearer Token authentication is implemented out of the box. If, however, you wish to integrate with legacy Devise authentication, you can do so by enabling this flag. NOTE: This feature is highly experimental! | + Additionally, you can configure other aspects of devise by manually creating the traditional devise.rb file at `config/initializers/devise.rb`. Here are some examples of what you can do in this file: @@ -773,8 +775,16 @@ When posting issues, please include the following information to speed up the tr ### Can I use this gem alongside standard Devise? -Yes! But you will need to use separate routes for standard Devise. So do something like this: +Yes! But you will need to enable the support use separate routes for standard Devise. So do something like this: + +#### config/initializers/devise_token_auth.rb +~~~ruby +DeviseTokenAuth.setup do |config| + # enable_standard_devise_support = false +end +~~~ +#### config/routes.rb ~~~ruby Rails.application.routes.draw do diff --git a/app/controllers/devise_token_auth/concerns/set_user_by_token.rb b/app/controllers/devise_token_auth/concerns/set_user_by_token.rb index c3264a0ab..35101b586 100644 --- a/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +++ b/app/controllers/devise_token_auth/concerns/set_user_by_token.rb @@ -31,12 +31,14 @@ def set_user_by_token(mapping=nil) # client_id isn't required, set to 'default' if absent @client_id ||= 'default' - # check for an existing user, authenticated via warden/devise - devise_warden_user = warden.user(rc.to_s.underscore.to_sym) - if devise_warden_user && devise_warden_user.tokens[@client_id].nil? - @used_auth_by_token = false - @resource = devise_warden_user - @resource.create_new_auth_token + # check for an existing user, authenticated via warden/devise, if enabled + if DeviseTokenAuth.enable_standard_devise_support + devise_warden_user = warden.user(rc.to_s.underscore.to_sym) + if devise_warden_user && devise_warden_user.tokens[@client_id].nil? + @used_auth_by_token = false + @resource = devise_warden_user + @resource.create_new_auth_token + end end # user has already been found and authenticated diff --git a/lib/devise_token_auth/engine.rb b/lib/devise_token_auth/engine.rb index b40a4d66b..aa0441c11 100644 --- a/lib/devise_token_auth/engine.rb +++ b/lib/devise_token_auth/engine.rb @@ -16,7 +16,8 @@ class Engine < ::Rails::Engine :default_confirm_success_url, :default_password_reset_url, :redirect_whitelist, - :check_current_password_before_update + :check_current_password_before_update, + :enable_standard_devise_support self.change_headers_on_each_request = true self.token_lifespan = 2.weeks @@ -26,6 +27,7 @@ class Engine < ::Rails::Engine self.default_password_reset_url = nil self.redirect_whitelist = nil self.check_current_password_before_update = false + self.enable_standard_devise_support = false def self.setup(&block) yield self @@ -33,7 +35,7 @@ def self.setup(&block) Rails.application.config.after_initialize do if defined?(::OmniAuth) ::OmniAuth::config.path_prefix = Devise.omniauth_path_prefix = self.omniauth_prefix - + # Omniauth currently does not pass along omniauth.params upon failure redirect # see also: https://github.com/intridea/omniauth/issues/626 diff --git a/lib/generators/devise_token_auth/templates/devise_token_auth.rb b/lib/generators/devise_token_auth/templates/devise_token_auth.rb index e158e784f..6169a8bf7 100644 --- a/lib/generators/devise_token_auth/templates/devise_token_auth.rb +++ b/lib/generators/devise_token_auth/templates/devise_token_auth.rb @@ -3,26 +3,31 @@ # client is responsible for keeping track of the changing tokens. Change # this to false to prevent the Authorization header from changing after # each request. - #config.change_headers_on_each_request = true + # config.change_headers_on_each_request = true # By default, users will need to re-authenticate after 2 weeks. This setting # determines how long tokens will remain valid after they are issued. - #config.token_lifespan = 2.weeks + # config.token_lifespan = 2.weeks # Sometimes it's necessary to make several requests to the API at the same # time. In this case, each request in the batch will need to share the same # auth token. This setting determines how far apart the requests can be while # still using the same auth token. - #config.batch_request_buffer_throttle = 5.seconds + # config.batch_request_buffer_throttle = 5.seconds # This route will be the prefix for all oauth2 redirect callbacks. For # example, using the default '/omniauth', the github oauth2 provider will # redirect successful authentications to '/omniauth/github/callback' - #config.omniauth_prefix = "/omniauth" + # config.omniauth_prefix = "/omniauth" # By defult sending current password is not needed for the password update. # Uncomment to enforce current_password param to be checked before all # attribute updates. Set it to :password if you want it to be checked only if # password is updated. # config.check_current_password_before_update = :attributes -end + + # By default, only Bearer Token authentication is implemented out of the box. + # If, however, you wish to integrate with legacy Devise authentication, you can + # do so by enabling this flag. NOTE: This feature is highly experimental! + # enable_standard_devise_support = false +end \ No newline at end of file diff --git a/test/controllers/demo_user_controller_test.rb b/test/controllers/demo_user_controller_test.rb index df3dde9af..899d11a84 100644 --- a/test/controllers/demo_user_controller_test.rb +++ b/test/controllers/demo_user_controller_test.rb @@ -284,14 +284,25 @@ class DemoUserControllerTest < ActionDispatch::IntegrationTest end end - describe 'existing Warden authentication with ignored token data' do + end + + describe 'enable_standard_devise_support' do + + before do + @resource = users(:confirmed_email_user) + @auth_headers = @resource.create_new_auth_token + DeviseTokenAuth.enable_standard_devise_support = true + end + + describe 'Existing Warden authentication' do before do @resource = users(:second_confirmed_email_user) @resource.skip_confirmation! @resource.save! login_as( @resource, :scope => :user) - get '/demo/members_only', {}, @auth_headers + # no auth headers sent, testing that warden authenticates correctly. + get '/demo/members_only', {}, nil @resp_token = response.headers['access-token'] @resp_client_id = response.headers['client'] @@ -329,69 +340,69 @@ class DemoUserControllerTest < ActionDispatch::IntegrationTest assert @resp_client_id end - it "should not use the existing token's client" do - refute_equal @auth_headers['client'], @resp_client_id - end - it "should return the user's uid in the auth header" do assert @resp_uid end + end - it "should not return the token user's uid in the auth header" do - refute_equal @resp_uid, @auth_headers['uid'] + describe 'existing Warden authentication with ignored token data' do + before do + @resource = users(:second_confirmed_email_user) + @resource.skip_confirmation! + @resource.save! + login_as( @resource, :scope => :user) + + get '/demo/members_only', {}, @auth_headers + + @resp_token = response.headers['access-token'] + @resp_client_id = response.headers['client'] + @resp_expiry = response.headers['expiry'] + @resp_uid = response.headers['uid'] end - end - end - describe 'Existing Warden authentication' do - before do - @resource = users(:second_confirmed_email_user) - @resource.skip_confirmation! - @resource.save! - login_as( @resource, :scope => :user) + describe 'devise mappings' do + it 'should define current_user' do + assert_equal @resource, @controller.current_user + end - # no auth headers sent, testing that warden authenticates correctly. - get '/demo/members_only', {}, nil + it 'should define user_signed_in?' do + assert @controller.user_signed_in? + end - @resp_token = response.headers['access-token'] - @resp_client_id = response.headers['client'] - @resp_expiry = response.headers['expiry'] - @resp_uid = response.headers['uid'] - end + it 'should not define current_mang' do + refute_equal @resource, @controller.current_mang + end + end - describe 'devise mappings' do - it 'should define current_user' do - assert_equal @resource, @controller.current_user + it 'should return success status' do + assert_equal 200, response.status end - it 'should define user_signed_in?' do - assert @controller.user_signed_in? + it 'should receive new token after successful request' do + assert @resp_token end - it 'should not define current_mang' do - refute_equal @resource, @controller.current_mang + it 'should set the token expiry in the auth header' do + assert @resp_expiry end - end - it 'should return success status' do - assert_equal 200, response.status - end + it 'should return the client id in the auth header' do + assert @resp_client_id + end - it 'should receive new token after successful request' do - assert @resp_token - end + it "should not use the existing token's client" do + refute_equal @auth_headers['client'], @resp_client_id + end - it 'should set the token expiry in the auth header' do - assert @resp_expiry - end + it "should return the user's uid in the auth header" do + assert @resp_uid + end - it 'should return the client id in the auth header' do - assert @resp_client_id + it "should not return the token user's uid in the auth header" do + refute_equal @resp_uid, @auth_headers['uid'] + end end - it "should return the user's uid in the auth header" do - assert @resp_uid - end end end