Skip to content

Commit

Permalink
feat(enable-standard-devise): allow configurable support of legacy De…
Browse files Browse the repository at this point in the history
…vise authentication. update default to disabled.
  • Loading branch information
booleanbetrayal committed Oct 30, 2015
1 parent 073f711 commit ee7e3f6
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 62 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.


<a name="0.1.36"></a>
# 0.1.36 (2015-10-13)

Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,3 @@ DEPENDENCIES
rack-cors
sqlite3 (~> 1.3)
thor

BUNDLED WITH
1.10.5
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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

Expand Down
14 changes: 8 additions & 6 deletions app/controllers/devise_token_auth/concerns/set_user_by_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions lib/devise_token_auth/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -26,14 +27,15 @@ 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

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
Expand Down
15 changes: 10 additions & 5 deletions lib/generators/devise_token_auth/templates/devise_token_auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
101 changes: 56 additions & 45 deletions test/controllers/demo_user_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit ee7e3f6

Please sign in to comment.