devise_token_auth 0.1.28 → 0.1.29.beta1
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 +4 -4
- data/README.md +61 -1
- data/app/controllers/devise_token_auth/{auth_controller.rb → omniauth_callbacks_controller.rb} +22 -33
- data/app/controllers/devise_token_auth/registrations_controller.rb +2 -0
- data/app/controllers/devise_token_auth/sessions_controller.rb +1 -1
- data/app/controllers/devise_token_auth/token_validations_controller.rb +23 -0
- data/app/models/devise_token_auth/concerns/user.rb +1 -3
- data/config/initializers/devise.rb +0 -9
- data/config/routes.rb +12 -1
- data/lib/devise_token_auth/engine.rb +8 -0
- data/lib/devise_token_auth/rails/routes.rb +30 -9
- data/lib/devise_token_auth/version.rb +1 -1
- data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +0 -2
- data/test/controllers/devise_token_auth/{auth_controller_test.rb → omniauth_callbacks_controller_test.rb} +4 -4
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +6 -0
- data/test/controllers/overrides/confirmations_controller_test.rb +44 -0
- data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +44 -0
- data/test/controllers/overrides/passwords_controller_test.rb +62 -0
- data/test/controllers/overrides/registrations_controller_test.rb +40 -0
- data/test/controllers/overrides/sessions_controller_test.rb +33 -0
- data/test/controllers/overrides/token_validations_controller_test.rb +38 -0
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +32 -0
- data/test/dummy/app/controllers/overrides/omniauth_callbacks_controller.rb +14 -0
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +39 -0
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +27 -0
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +43 -0
- data/test/dummy/app/controllers/overrides/token_validations_controller.rb +23 -0
- data/test/dummy/{tmp/generators/app/models/mang.rb → app/models/evil_user.rb} +1 -1
- data/test/dummy/config/routes.rb +9 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/{tmp/generators/db/migrate/20140924174608_devise_token_auth_create_mangs.rb → db/migrate/20140928231203_devise_token_auth_create_evil_users.rb} +10 -9
- data/test/dummy/db/schema.rb +33 -1
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +437 -0
- data/test/dummy/log/test.log +72703 -0
- data/test/dummy/tmp/generators/config/routes.rb +0 -5
- data/test/dummy/tmp/generators/db/migrate/{20140924174608_devise_token_auth_create_users.rb → 20140930001137_devise_token_auth_create_users.rb} +0 -2
- data/test/fixtures/evil_users.yml +29 -0
- data/test/fixtures/mangs.yml +0 -2
- data/test/fixtures/users.yml +0 -2
- metadata +40 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27aae401ac1cd56896e88990fafd43722ae0874d
|
4
|
+
data.tar.gz: 641556555fefe2509adf75b29125a94abb9ca14a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a439fc3a695c0aeec35b4a15b9c5da795fa66ceffe917d03a3b9da79ebe713b59a742af02911f0bd0d301a79f6c5785c101dda0ea15fc93dc44b7614e556fb76
|
7
|
+
data.tar.gz: f6e51f041bee6233ffa21a92888fc62fcd1be9fd871bc233c946e2735b3745e3f0a0d640ba7eb26ab486eea759d49acdf8ab108e6b268412bcbf73b10826d581
|
data/README.md
CHANGED
@@ -42,6 +42,7 @@ The fully configured api used in the demo can be found [here](https://github.com
|
|
42
42
|
* [Controller Integration](#controller-concerns)
|
43
43
|
* [Model Integration](#model-concerns)
|
44
44
|
* [Using Multiple User Classes](#using-multiple-models)
|
45
|
+
* [Custom Controller Overrides](#custom-controller-overrides)
|
45
46
|
* [Conceptual Diagrams](#conceptual)
|
46
47
|
* [Token Management](#about-token-management)
|
47
48
|
* [Batch Requests](#about-batch-requests)
|
@@ -75,12 +76,18 @@ You will need to create a [user model](#model-concerns), [define routes](#mounti
|
|
75
76
|
rails g devise_token_auth:install [USER_CLASS] [MOUNT_PATH]
|
76
77
|
~~~
|
77
78
|
|
79
|
+
**Example**:
|
80
|
+
|
81
|
+
~~~bash
|
82
|
+
rails g devise_token_auth:install User /auth
|
83
|
+
~~~
|
84
|
+
|
78
85
|
This generator accepts the following optional arguments:
|
79
86
|
|
80
87
|
| Argument | Default | Description |
|
81
88
|
|---|---|---|
|
82
89
|
| USER_CLASS | `User` | The name of the class to use for user authentication. |
|
83
|
-
| MOUNT_PATH |
|
90
|
+
| MOUNT_PATH | `/auth` | The path at which to mount the authentication routes. [Read more](#usage). |
|
84
91
|
|
85
92
|
The following events will take place when using the install generator:
|
86
93
|
|
@@ -498,6 +505,59 @@ In the above example, the following methods will be available (in addition to `c
|
|
498
505
|
* `current_member`
|
499
506
|
* `member_signed_in?`
|
500
507
|
|
508
|
+
## Custom Controller Overrides
|
509
|
+
|
510
|
+
The built-in controllers can be overridden with your own custom controllers.
|
511
|
+
|
512
|
+
For example, the default behavior of the [`validate_token`](https://github.com/lynndylanhurley/devise_token_auth/blob/8a33d25deaedb4809b219e557e82ec7ec61bf940/app/controllers/devise_token_auth/token_validations_controller.rb#L6) method of the [`TokenValidationController`](https://github.com/lynndylanhurley/devise_token_auth/blob/8a33d25deaedb4809b219e557e82ec7ec61bf940/app/controllers/devise_token_auth/token_validations_controller.rb) is to return the `User` object as json (sans password and token data). The following example shows how to override the `validate_token` action to include a model method as well.
|
513
|
+
|
514
|
+
##### Example: controller overrides
|
515
|
+
|
516
|
+
~~~ruby
|
517
|
+
# config/routes.rb
|
518
|
+
Rails.application.routes.draw do
|
519
|
+
...
|
520
|
+
mount_devise_token_auth_for 'User', at: '/auth', controllers: {
|
521
|
+
token_validations: 'overrides/token_validations'
|
522
|
+
}
|
523
|
+
end
|
524
|
+
|
525
|
+
# app/controllers/overrides/token_validations_controller.rb
|
526
|
+
module Overrides
|
527
|
+
class TokenValidationsController < DeviseTokenAuth::TokenValidationsController
|
528
|
+
|
529
|
+
def validate_token
|
530
|
+
# @user will have been set by set_user_by_token concern
|
531
|
+
if @user
|
532
|
+
render json: {
|
533
|
+
data: @user.as_json(methods: :calculate_operating_thetan)
|
534
|
+
}
|
535
|
+
else
|
536
|
+
render json: {
|
537
|
+
success: false,
|
538
|
+
errors: ["Invalid login credentials"]
|
539
|
+
}, status: 401
|
540
|
+
end
|
541
|
+
end
|
542
|
+
end
|
543
|
+
end
|
544
|
+
~~~
|
545
|
+
|
546
|
+
##### Example: all :controller options with default settings:
|
547
|
+
|
548
|
+
~~~ruby
|
549
|
+
mount_devise_token_auth_for 'User', at: '/auth', controllers: {
|
550
|
+
confirmations: 'devise_token_auth/confirmations',
|
551
|
+
passwords: 'devise_token_auth/passwords',
|
552
|
+
omniauth_callbacks: 'devise_token_auth/omniauth_callbacks',
|
553
|
+
registrations: 'devise_token_auth/registrations',
|
554
|
+
sessions: 'devise_token_auth/sessions',
|
555
|
+
token_validations: 'devise_token_auth/token_validations'
|
556
|
+
}
|
557
|
+
~~~
|
558
|
+
|
559
|
+
**Note:** Controller overrides must implement the expected actions of the controllers that they replace.
|
560
|
+
|
501
561
|
# Conceptual
|
502
562
|
|
503
563
|
None of the following information is required to use this gem, but read on if you're curious.
|
data/app/controllers/devise_token_auth/{auth_controller.rb → omniauth_callbacks_controller.rb}
RENAMED
@@ -1,25 +1,6 @@
|
|
1
1
|
module DeviseTokenAuth
|
2
|
-
class
|
2
|
+
class OmniauthCallbacksController < DeviseTokenAuth::ApplicationController
|
3
3
|
skip_after_filter :update_auth_header, :only => [:omniauth_success, :omniauth_failure]
|
4
|
-
skip_before_filter :assert_is_devise_resource!, :only => [:validate_token]
|
5
|
-
before_filter :set_user_by_token, :only => [:validate_token]
|
6
|
-
|
7
|
-
def validate_token
|
8
|
-
# @user will have been set by set_user_token concern
|
9
|
-
if @user
|
10
|
-
render json: {
|
11
|
-
success: true,
|
12
|
-
data: @user.as_json(except: [
|
13
|
-
:tokens, :confirm_success_url, :reset_password_redirect_url, :created_at, :updated_at
|
14
|
-
])
|
15
|
-
}
|
16
|
-
else
|
17
|
-
render json: {
|
18
|
-
success: false,
|
19
|
-
errors: ["Invalid login credentials"]
|
20
|
-
}, status: 401
|
21
|
-
end
|
22
|
-
end
|
23
4
|
|
24
5
|
def omniauth_success
|
25
6
|
# find or create user by provider and provider uid
|
@@ -32,7 +13,7 @@ module DeviseTokenAuth
|
|
32
13
|
@client_id = SecureRandom.urlsafe_base64(nil, false)
|
33
14
|
@token = SecureRandom.urlsafe_base64(nil, false)
|
34
15
|
|
35
|
-
@auth_origin_url = generate_url(
|
16
|
+
@auth_origin_url = generate_url(auth_params['auth_origin_url'], {
|
36
17
|
token: @token,
|
37
18
|
client_id: @client_id,
|
38
19
|
uid: @user.uid
|
@@ -52,12 +33,7 @@ module DeviseTokenAuth
|
|
52
33
|
}
|
53
34
|
|
54
35
|
# sync user info with provider, update/generate auth token
|
55
|
-
@user
|
56
|
-
nickname: auth_hash['info']['nickname'],
|
57
|
-
name: auth_hash['info']['name'],
|
58
|
-
image: auth_hash['info']['image'],
|
59
|
-
email: auth_hash['info']['email']
|
60
|
-
})
|
36
|
+
assign_provider_attrs(@user, auth_hash)
|
61
37
|
|
62
38
|
# assign any additional (whitelisted) attributes
|
63
39
|
extra_params = whitelisted_params
|
@@ -74,6 +50,15 @@ module DeviseTokenAuth
|
|
74
50
|
end
|
75
51
|
end
|
76
52
|
|
53
|
+
def assign_provider_attrs(user, auth_hash)
|
54
|
+
user.assign_attributes({
|
55
|
+
nickname: auth_hash['info']['nickname'],
|
56
|
+
name: auth_hash['info']['name'],
|
57
|
+
image: auth_hash['info']['image'],
|
58
|
+
email: auth_hash['info']['email']
|
59
|
+
})
|
60
|
+
end
|
61
|
+
|
77
62
|
def omniauth_failure
|
78
63
|
@error = params[:message]
|
79
64
|
|
@@ -83,14 +68,18 @@ module DeviseTokenAuth
|
|
83
68
|
end
|
84
69
|
|
85
70
|
def auth_hash
|
86
|
-
|
71
|
+
params["auth_hash"]
|
72
|
+
end
|
73
|
+
|
74
|
+
def auth_params
|
75
|
+
params["auth_params"]
|
87
76
|
end
|
88
77
|
|
89
78
|
def whitelisted_params
|
90
79
|
whitelist = devise_parameter_sanitizer.for(:sign_up)
|
91
80
|
|
92
81
|
whitelist.inject({}){|coll, key|
|
93
|
-
param =
|
82
|
+
param = auth_params[key.to_s]
|
94
83
|
if param
|
95
84
|
coll[key] = param
|
96
85
|
end
|
@@ -104,8 +93,8 @@ module DeviseTokenAuth
|
|
104
93
|
|
105
94
|
# pull resource class from omniauth return
|
106
95
|
def resource_name
|
107
|
-
if
|
108
|
-
|
96
|
+
if auth_params
|
97
|
+
auth_params['resource_class'].constantize
|
109
98
|
else
|
110
99
|
super
|
111
100
|
end
|
@@ -113,8 +102,8 @@ module DeviseTokenAuth
|
|
113
102
|
|
114
103
|
# necessary for access to devise_parameter_sanitizers
|
115
104
|
def devise_mapping
|
116
|
-
if
|
117
|
-
Devise.mappings[
|
105
|
+
if auth_params
|
106
|
+
Devise.mappings[auth_params['resource_class'].underscore.to_sym]
|
118
107
|
else
|
119
108
|
request.env['devise.mapping']
|
120
109
|
end
|
@@ -20,6 +20,8 @@ module DeviseTokenAuth
|
|
20
20
|
end
|
21
21
|
|
22
22
|
begin
|
23
|
+
# override email confirmation, must be sent manually from ctrl
|
24
|
+
User.skip_callback("create", :after, :send_on_create_confirmation_instructions)
|
23
25
|
if @resource.save
|
24
26
|
@resource.send_confirmation_instructions({
|
25
27
|
client_config: params[:config_name],
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DeviseTokenAuth
|
2
|
+
class TokenValidationsController < DeviseTokenAuth::ApplicationController
|
3
|
+
skip_before_filter :assert_is_devise_resource!, :only => [:validate_token]
|
4
|
+
before_filter :set_user_by_token, :only => [:validate_token]
|
5
|
+
|
6
|
+
def validate_token
|
7
|
+
# @user will have been set by set_user_token concern
|
8
|
+
if @user
|
9
|
+
render json: {
|
10
|
+
success: true,
|
11
|
+
data: @user.as_json(except: [
|
12
|
+
:tokens, :created_at, :updated_at
|
13
|
+
])
|
14
|
+
}
|
15
|
+
else
|
16
|
+
render json: {
|
17
|
+
success: false,
|
18
|
+
errors: ["Invalid login credentials"]
|
19
|
+
}, status: 401
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -6,7 +6,7 @@ module DeviseTokenAuth::Concerns::User
|
|
6
6
|
# :confirmable, :lockable, :timeoutable and :omniauthable
|
7
7
|
devise :database_authenticatable, :registerable,
|
8
8
|
:recoverable, :rememberable, :trackable, :validatable,
|
9
|
-
:confirmable
|
9
|
+
:confirmable, :omniauthable
|
10
10
|
|
11
11
|
serialize :tokens, JSON
|
12
12
|
|
@@ -48,7 +48,6 @@ module DeviseTokenAuth::Concerns::User
|
|
48
48
|
send_devise_notification(:confirmation_instructions, @raw_confirmation_token, opts)
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
51
|
# override devise method to include additional info as opts hash
|
53
52
|
def send_reset_password_instructions(opts=nil)
|
54
53
|
token = set_reset_password_token
|
@@ -71,7 +70,6 @@ module DeviseTokenAuth::Concerns::User
|
|
71
70
|
end
|
72
71
|
|
73
72
|
|
74
|
-
|
75
73
|
def valid_token?(token, client_id='default')
|
76
74
|
client_id ||= 'default'
|
77
75
|
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
2
|
if defined?(::OmniAuth)
|
3
|
-
|
3
|
+
match "#{::OmniAuth::config.path_prefix}/:provider/callback", to: redirect {|params, request|
|
4
|
+
devise_mapping = request.env['omniauth.params']['resource_class'].underscore.to_sym
|
5
|
+
mount_point = Devise.mappings[devise_mapping].as_json["path_prefix"]
|
6
|
+
|
7
|
+
qs = {
|
8
|
+
auth_hash: request.env['omniauth.auth'],
|
9
|
+
auth_params: request.env['omniauth.params']
|
10
|
+
}.to_query
|
11
|
+
|
12
|
+
"#{mount_point}/#{params[:provider]}/callback?#{qs}"
|
13
|
+
}, via: :all
|
4
14
|
end
|
15
|
+
|
5
16
|
end
|
@@ -7,6 +7,14 @@ module DeviseTokenAuth
|
|
7
7
|
initializer "devise_token_auth.url_helpers" do
|
8
8
|
Devise.helpers << DeviseTokenAuth::Controllers::Helpers
|
9
9
|
end
|
10
|
+
|
11
|
+
initializer "devise_token_auth.omniauth_strategy" do
|
12
|
+
if defined?(::OmniAuth)
|
13
|
+
Devise.with_options model: true do |d|
|
14
|
+
d.add_module(:dta_omniauthable, controller: :omniauth_callbacks, route: :omniauth_callbacks)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
10
18
|
end
|
11
19
|
|
12
20
|
mattr_accessor :change_headers_on_each_request,
|
@@ -1,22 +1,43 @@
|
|
1
1
|
module ActionDispatch::Routing
|
2
2
|
class Mapper
|
3
3
|
def mount_devise_token_auth_for(resource, opts)
|
4
|
+
# ensure objects exist to simplify attr checks
|
5
|
+
opts[:controllers] ||= {}
|
6
|
+
opts[:skip] ||= []
|
7
|
+
|
8
|
+
# check for ctrl overrides, fall back to defaults
|
9
|
+
sessions_ctrl = opts[:controllers][:sessions] || "devise_token_auth/sessions"
|
10
|
+
registrations_ctrl = opts[:controllers][:registrations] || "devise_token_auth/registrations"
|
11
|
+
passwords_ctrl = opts[:controllers][:passwords] || "devise_token_auth/passwords"
|
12
|
+
confirmations_ctrl = opts[:controllers][:confirmations] || "devise_token_auth/confirmations"
|
13
|
+
token_validations_ctrl = opts[:controllers][:token_validations] || "devise_token_auth/token_validations"
|
14
|
+
omniauth_ctrl = opts[:controllers][:omniauth_callbacks] || "devise_token_auth/omniauth_callbacks"
|
15
|
+
|
16
|
+
# define devise controller mappings
|
17
|
+
controllers = {:sessions => sessions_ctrl,
|
18
|
+
:registrations => registrations_ctrl,
|
19
|
+
:passwords => passwords_ctrl,
|
20
|
+
:confirmations => confirmations_ctrl,
|
21
|
+
:omniauth_callbacks => omniauth_ctrl}
|
22
|
+
|
23
|
+
# remove any unwanted devise modules
|
24
|
+
opts[:skip].each{|item| controllers.delete(item)}
|
25
|
+
|
4
26
|
scope opts[:at] do
|
5
27
|
devise_for resource.pluralize.underscore.to_sym,
|
6
28
|
:class_name => resource,
|
7
29
|
:module => :devise,
|
8
30
|
:path => "",
|
9
|
-
:controllers =>
|
10
|
-
:registrations => "devise_token_auth/registrations",
|
11
|
-
:passwords => "devise_token_auth/passwords",
|
12
|
-
:confirmations => "devise_token_auth/confirmations"}
|
31
|
+
:controllers => controllers
|
13
32
|
|
14
33
|
devise_scope resource.underscore.to_sym do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
34
|
+
# path to verify token validity
|
35
|
+
get "validate_token", to: "#{token_validations_ctrl}#validate_token"
|
36
|
+
|
37
|
+
# omniauth routes. only define if omniauth is installed and not skipped.
|
38
|
+
if defined?(::OmniAuth) and not opts[:skip].include?(:omniauth_callbacks)
|
39
|
+
get "failure", to: "#{omniauth_ctrl}#omniauth_failure"
|
40
|
+
get ":provider/callback", to: "#{omniauth_ctrl}#omniauth_success"
|
20
41
|
|
21
42
|
# preserve the resource class thru oauth authentication by setting name of
|
22
43
|
# resource as "resource_class" param
|
@@ -8,7 +8,6 @@ class DeviseTokenAuthCreate<%= user_class.pluralize %> < ActiveRecord::Migration
|
|
8
8
|
## Recoverable
|
9
9
|
t.string :reset_password_token
|
10
10
|
t.datetime :reset_password_sent_at
|
11
|
-
t.string :reset_password_redirect_url
|
12
11
|
|
13
12
|
## Rememberable
|
14
13
|
t.datetime :remember_created_at
|
@@ -24,7 +23,6 @@ class DeviseTokenAuthCreate<%= user_class.pluralize %> < ActiveRecord::Migration
|
|
24
23
|
t.string :confirmation_token
|
25
24
|
t.datetime :confirmed_at
|
26
25
|
t.datetime :confirmation_sent_at
|
27
|
-
t.string :confirm_success_url
|
28
26
|
t.string :unconfirmed_email # Only if using reconfirmable
|
29
27
|
|
30
28
|
## Lockable
|
@@ -38,11 +38,11 @@ class OmniauthTest < ActionDispatch::IntegrationTest
|
|
38
38
|
end
|
39
39
|
|
40
40
|
test 'request should determine the correct resource_class' do
|
41
|
-
assert_equal 'User',
|
41
|
+
assert_equal 'User', controller.auth_params['resource_class']
|
42
42
|
end
|
43
43
|
|
44
44
|
test 'request should pass correct redirect_url' do
|
45
|
-
assert_equal @redirect_url,
|
45
|
+
assert_equal @redirect_url, controller.auth_params['auth_origin_url']
|
46
46
|
end
|
47
47
|
|
48
48
|
test 'user should have been created' do
|
@@ -116,11 +116,11 @@ class OmniauthTest < ActionDispatch::IntegrationTest
|
|
116
116
|
end
|
117
117
|
|
118
118
|
test 'request should determine the correct resource_class' do
|
119
|
-
assert_equal 'Mang',
|
119
|
+
assert_equal 'Mang', controller.auth_params['resource_class']
|
120
120
|
end
|
121
121
|
|
122
122
|
test 'request should pass correct redirect_url' do
|
123
|
-
assert_equal @redirect_url,
|
123
|
+
assert_equal @redirect_url, controller.auth_params['auth_origin_url']
|
124
124
|
end
|
125
125
|
|
126
126
|
test 'user should have been created' do
|
@@ -10,6 +10,8 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionController::TestCase
|
|
10
10
|
describe DeviseTokenAuth::RegistrationsController do
|
11
11
|
describe "Successful registration" do
|
12
12
|
before do
|
13
|
+
@mails_sent = ActionMailer::Base.deliveries.count
|
14
|
+
|
13
15
|
xhr :post, :create, {
|
14
16
|
email: Faker::Internet.email,
|
15
17
|
password: "secret123",
|
@@ -46,6 +48,10 @@ class DeviseTokenAuth::RegistrationsControllerTest < ActionController::TestCase
|
|
46
48
|
test "new user password should not be returned" do
|
47
49
|
assert_nil @data['data']['password']
|
48
50
|
end
|
51
|
+
|
52
|
+
test "only one email was sent" do
|
53
|
+
assert_equal @mails_sent + 1, ActionMailer::Base.deliveries.count
|
54
|
+
end
|
49
55
|
end
|
50
56
|
|
51
57
|
describe "Adding extra params" do
|