devise_token_auth 0.1.30.beta3 → 0.1.30.beta4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -2
- data/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +9 -9
- data/app/controllers/devise_token_auth/confirmations_controller.rb +5 -5
- data/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +10 -10
- data/app/controllers/devise_token_auth/passwords_controller.rb +34 -23
- data/app/controllers/devise_token_auth/registrations_controller.rb +10 -11
- data/app/controllers/devise_token_auth/sessions_controller.rb +23 -8
- data/app/controllers/devise_token_auth/token_validations_controller.rb +3 -3
- data/app/models/devise_token_auth/concerns/user.rb +1 -0
- data/app/views/devise_token_auth/omniauth_success.html.erb +1 -1
- data/lib/devise_token_auth/version.rb +1 -1
- data/lib/generators/devise_token_auth/templates/devise_token_auth_create_users.rb.erb +6 -6
- data/test/controllers/demo_group_controller_test.rb +14 -14
- data/test/controllers/demo_mang_controller_test.rb +25 -25
- data/test/controllers/demo_user_controller_test.rb +25 -25
- data/test/controllers/devise_token_auth/confirmations_controller_test.rb +6 -6
- data/test/controllers/devise_token_auth/omniauth_callbacks_controller_test.rb +11 -11
- data/test/controllers/devise_token_auth/passwords_controller_test.rb +110 -84
- data/test/controllers/devise_token_auth/registrations_controller_test.rb +23 -23
- data/test/controllers/devise_token_auth/sessions_controller_test.rb +68 -5
- data/test/controllers/overrides/omniauth_callbacks_controller_test.rb +3 -3
- data/test/controllers/overrides/passwords_controller_test.rb +4 -4
- data/test/controllers/overrides/sessions_controller_test.rb +1 -1
- data/test/controllers/overrides/token_validations_controller_test.rb +5 -5
- data/test/dummy/app/controllers/demo_mang_controller.rb +2 -2
- data/test/dummy/app/controllers/demo_user_controller.rb +2 -2
- data/test/dummy/app/controllers/overrides/confirmations_controller.rb +5 -5
- data/test/dummy/app/controllers/overrides/passwords_controller.rb +6 -6
- data/test/dummy/app/controllers/overrides/registrations_controller.rb +4 -4
- data/test/dummy/app/controllers/overrides/sessions_controller.rb +7 -7
- data/test/dummy/app/controllers/overrides/token_validations_controller.rb +3 -3
- data/test/dummy/config/application.yml +8 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20140715061447_devise_token_auth_create_users.rb +2 -2
- data/test/dummy/db/migrate/20140715061805_devise_token_auth_create_mangs.rb +2 -2
- data/test/dummy/db/migrate/20140928231203_devise_token_auth_create_evil_users.rb +2 -2
- data/test/dummy/db/schema.rb +12 -9
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +1979 -0
- data/test/dummy/log/test.log +183708 -0
- data/test/dummy/tmp/generators/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/test/dummy/tmp/generators/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/test/models/user_test.rb +37 -27
- metadata +10 -10
- data/test/dummy/tmp/generators/app/models/user.rb +0 -7
- data/test/dummy/tmp/generators/config/initializers/devise_token_auth.rb +0 -22
- data/test/dummy/tmp/generators/db/migrate/20141028214843_devise_token_auth_create_users.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b53b78fa871bf37ca5f3b9b0bf81b51a811eaa61
|
4
|
+
data.tar.gz: e5c001234e39914f312c192362f4430747dc6f5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c02997a4d6df1d85cad79c559931f19e3b1222ecd175e4cac7b0c9ecc1156de1a02630c48a2167429df2c42e028842d99ca1754a100c21d229c29c8e2003c4ab
|
7
|
+
data.tar.gz: 738bb86d30c28f52d6b591a62629e3cf621fa4af2b4ce520d727b0faf2d9ec3620c04768d7c191ffd513038e3019f007d1a2c6a15bdce8954b05e5aa068f82e2
|
data/README.md
CHANGED
@@ -666,9 +666,23 @@ But the most important step is to use HTTPS. You are on the hook for that.
|
|
666
666
|
|
667
667
|
|
668
668
|
# Contributing
|
669
|
-
Just send a pull request. I will grant you commit access if you send quality pull requests.
|
670
669
|
|
671
|
-
|
670
|
+
1. Create a feature branch with your changes.
|
671
|
+
2. Write some test cases.
|
672
|
+
3. Make all the tests pass.
|
673
|
+
4. Issue a pull request.
|
674
|
+
|
675
|
+
I will grant you commit access if you send quality pull requests.
|
676
|
+
|
677
|
+
To run the test suite do the following:
|
678
|
+
|
679
|
+
1. Clone this repo
|
680
|
+
2. Run `bundle install`
|
681
|
+
3. Run `rake db:migrate`
|
682
|
+
4. Run `RAILS_ENV=test rake db:migrate`
|
683
|
+
5. Run `guard`.
|
684
|
+
|
685
|
+
The last command will open the [guard](https://github.com/guard/guard) test-runner. Guard will re-run each test suite when changes are made to its corresponding files.
|
672
686
|
|
673
687
|
# License
|
674
688
|
This project uses the WTFPL
|
@@ -22,7 +22,7 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
22
22
|
return unless rc
|
23
23
|
|
24
24
|
# user has already been found and authenticated
|
25
|
-
return @
|
25
|
+
return @resource if @resource and @resource.class == rc
|
26
26
|
|
27
27
|
# parse header for values necessary for authentication
|
28
28
|
uid = request.headers['uid']
|
@@ -39,10 +39,10 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
39
39
|
|
40
40
|
if user && user.valid_token?(@token, @client_id)
|
41
41
|
sign_in(:user, user, store: false, bypass: true)
|
42
|
-
return @
|
42
|
+
return @resource = user
|
43
43
|
else
|
44
44
|
# zero all values previously set values
|
45
|
-
return @
|
45
|
+
return @resource = nil
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -50,20 +50,20 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
50
50
|
def update_auth_header
|
51
51
|
|
52
52
|
# cannot save object if model has invalid params
|
53
|
-
return unless @
|
53
|
+
return unless @resource and @resource.valid? and @client_id
|
54
54
|
|
55
55
|
# Lock the user record during any auth_header updates to ensure
|
56
56
|
# we don't have write contention from multiple threads
|
57
|
-
@
|
57
|
+
@resource.with_lock do
|
58
58
|
|
59
59
|
# determine batch request status after request processing, in case
|
60
60
|
# another processes has updated it during that processing
|
61
|
-
@is_batch_request = is_batch_request?(@
|
61
|
+
@is_batch_request = is_batch_request?(@resource, @client_id)
|
62
62
|
|
63
63
|
auth_header = {}
|
64
64
|
|
65
65
|
if not DeviseTokenAuth.change_headers_on_each_request
|
66
|
-
auth_header = @
|
66
|
+
auth_header = @resource.build_auth_header(@token, @client_id)
|
67
67
|
|
68
68
|
# update the response header
|
69
69
|
response.headers.merge!(auth_header)
|
@@ -71,11 +71,11 @@ module DeviseTokenAuth::Concerns::SetUserByToken
|
|
71
71
|
# extend expiration of batch buffer to account for the duration of
|
72
72
|
# this request
|
73
73
|
elsif @is_batch_request
|
74
|
-
auth_header = @
|
74
|
+
auth_header = @resource.extend_batch_buffer(@token, @client_id)
|
75
75
|
|
76
76
|
# update Authorization response header with new token
|
77
77
|
else
|
78
|
-
auth_header = @
|
78
|
+
auth_header = @resource.create_new_auth_token(@client_id)
|
79
79
|
|
80
80
|
# update the response header
|
81
81
|
response.headers.merge!(auth_header)
|
@@ -1,23 +1,23 @@
|
|
1
1
|
module DeviseTokenAuth
|
2
2
|
class ConfirmationsController < DeviseTokenAuth::ApplicationController
|
3
3
|
def show
|
4
|
-
@
|
4
|
+
@resource = resource_class.confirm_by_token(params[:confirmation_token])
|
5
5
|
|
6
|
-
if @
|
6
|
+
if @resource and @resource.id
|
7
7
|
# create client id
|
8
8
|
client_id = SecureRandom.urlsafe_base64(nil, false)
|
9
9
|
token = SecureRandom.urlsafe_base64(nil, false)
|
10
10
|
token_hash = BCrypt::Password.create(token)
|
11
11
|
expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
12
12
|
|
13
|
-
@
|
13
|
+
@resource.tokens[client_id] = {
|
14
14
|
token: token_hash,
|
15
15
|
expiry: expiry
|
16
16
|
}
|
17
17
|
|
18
|
-
@
|
18
|
+
@resource.save!
|
19
19
|
|
20
|
-
redirect_to(@
|
20
|
+
redirect_to(@resource.build_auth_url(params[:redirect_url], {
|
21
21
|
token: token,
|
22
22
|
client_id: client_id,
|
23
23
|
account_confirmation_success: true,
|
@@ -20,7 +20,7 @@ module DeviseTokenAuth
|
|
20
20
|
|
21
21
|
def omniauth_success
|
22
22
|
# find or create user by provider and provider uid
|
23
|
-
@
|
23
|
+
@resource = resource_class.where({
|
24
24
|
uid: auth_hash['uid'],
|
25
25
|
provider: auth_hash['provider']
|
26
26
|
}).first_or_initialize
|
@@ -33,34 +33,34 @@ module DeviseTokenAuth
|
|
33
33
|
@auth_origin_url = generate_url(omniauth_params['auth_origin_url'], {
|
34
34
|
token: @token,
|
35
35
|
client_id: @client_id,
|
36
|
-
uid: @
|
36
|
+
uid: @resource.uid,
|
37
37
|
expiry: @expiry
|
38
38
|
})
|
39
39
|
|
40
40
|
# set crazy password for new oauth users. this is only used to prevent
|
41
41
|
# access via email sign-in.
|
42
|
-
unless @
|
42
|
+
unless @resource.id
|
43
43
|
p = SecureRandom.urlsafe_base64(nil, false)
|
44
|
-
@
|
45
|
-
@
|
44
|
+
@resource.password = p
|
45
|
+
@resource.password_confirmation = p
|
46
46
|
end
|
47
47
|
|
48
|
-
@
|
48
|
+
@resource.tokens[@client_id] = {
|
49
49
|
token: BCrypt::Password.create(@token),
|
50
50
|
expiry: @expiry
|
51
51
|
}
|
52
52
|
|
53
53
|
# sync user info with provider, update/generate auth token
|
54
|
-
assign_provider_attrs(@
|
54
|
+
assign_provider_attrs(@resource, auth_hash)
|
55
55
|
|
56
56
|
# assign any additional (whitelisted) attributes
|
57
57
|
extra_params = whitelisted_params
|
58
|
-
@
|
58
|
+
@resource.assign_attributes(extra_params) if extra_params
|
59
59
|
|
60
60
|
# don't send confirmation email!!!
|
61
|
-
@
|
61
|
+
@resource.skip_confirmation!
|
62
62
|
|
63
|
-
@
|
63
|
+
@resource.save!
|
64
64
|
|
65
65
|
# render user info to javascript postMessage communication window
|
66
66
|
respond_to do |format|
|
@@ -20,32 +20,43 @@ module DeviseTokenAuth
|
|
20
20
|
}, status: 401
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
# honor devise configuration for case_insensitive_keys
|
24
|
+
if resource_class.case_insensitive_keys.include?(:email)
|
25
|
+
email = resource_params[:email].downcase
|
26
|
+
else
|
27
|
+
email = resource_params[:email]
|
28
|
+
end
|
29
|
+
|
30
|
+
q = "uid='#{email}' AND provider='email'"
|
31
|
+
|
32
|
+
# fix for mysql default case insensitivity
|
33
|
+
if ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'
|
34
|
+
q = "BINARY uid='#{email}' AND provider='email'"
|
35
|
+
end
|
36
|
+
|
37
|
+
@resource = resource_class.where(q).first
|
27
38
|
|
28
39
|
errors = nil
|
29
40
|
|
30
|
-
if @
|
31
|
-
@
|
32
|
-
email:
|
41
|
+
if @resource
|
42
|
+
@resource.send_reset_password_instructions({
|
43
|
+
email: email,
|
33
44
|
provider: 'email',
|
34
45
|
redirect_url: params[:redirect_url],
|
35
46
|
client_config: params[:config_name]
|
36
47
|
})
|
37
48
|
|
38
|
-
if @
|
49
|
+
if @resource.errors.empty?
|
39
50
|
render json: {
|
40
51
|
success: true,
|
41
|
-
message: "An email has been sent to #{
|
52
|
+
message: "An email has been sent to #{email} containing "+
|
42
53
|
"instructions for resetting your password."
|
43
54
|
}
|
44
55
|
else
|
45
|
-
errors = @
|
56
|
+
errors = @resource.errors
|
46
57
|
end
|
47
58
|
else
|
48
|
-
errors = ["Unable to find user with email '#{
|
59
|
+
errors = ["Unable to find user with email '#{email}'."]
|
49
60
|
end
|
50
61
|
|
51
62
|
if errors
|
@@ -59,27 +70,27 @@ module DeviseTokenAuth
|
|
59
70
|
|
60
71
|
# this is where users arrive after visiting the email confirmation link
|
61
72
|
def edit
|
62
|
-
@
|
73
|
+
@resource = resource_class.reset_password_by_token({
|
63
74
|
reset_password_token: resource_params[:reset_password_token]
|
64
75
|
})
|
65
76
|
|
66
|
-
if @
|
77
|
+
if @resource and @resource.id
|
67
78
|
client_id = SecureRandom.urlsafe_base64(nil, false)
|
68
79
|
token = SecureRandom.urlsafe_base64(nil, false)
|
69
80
|
token_hash = BCrypt::Password.create(token)
|
70
81
|
expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
71
82
|
|
72
|
-
@
|
83
|
+
@resource.tokens[client_id] = {
|
73
84
|
token: token_hash,
|
74
85
|
expiry: expiry
|
75
86
|
}
|
76
87
|
|
77
88
|
# ensure that user is confirmed
|
78
|
-
@
|
89
|
+
@resource.skip_confirmation! unless @resource.confirmed_at
|
79
90
|
|
80
|
-
@
|
91
|
+
@resource.save!
|
81
92
|
|
82
|
-
redirect_to(@
|
93
|
+
redirect_to(@resource.build_auth_url(params[:redirect_url], {
|
83
94
|
token: token,
|
84
95
|
client_id: client_id,
|
85
96
|
reset_password: true,
|
@@ -92,7 +103,7 @@ module DeviseTokenAuth
|
|
92
103
|
|
93
104
|
def update
|
94
105
|
# make sure user is authorized
|
95
|
-
unless @
|
106
|
+
unless @resource
|
96
107
|
return render json: {
|
97
108
|
success: false,
|
98
109
|
errors: ['Unauthorized']
|
@@ -100,11 +111,11 @@ module DeviseTokenAuth
|
|
100
111
|
end
|
101
112
|
|
102
113
|
# make sure account doesn't use oauth2 provider
|
103
|
-
unless @
|
114
|
+
unless @resource.provider == 'email'
|
104
115
|
return render json: {
|
105
116
|
success: false,
|
106
117
|
errors: ["This account does not require a password. Sign in using "+
|
107
|
-
"your #{@
|
118
|
+
"your #{@resource.provider.humanize} account instead."]
|
108
119
|
}, status: 422
|
109
120
|
end
|
110
121
|
|
@@ -116,18 +127,18 @@ module DeviseTokenAuth
|
|
116
127
|
}, status: 422
|
117
128
|
end
|
118
129
|
|
119
|
-
if @
|
130
|
+
if @resource.update_attributes(password_resource_params)
|
120
131
|
return render json: {
|
121
132
|
success: true,
|
122
133
|
data: {
|
123
|
-
user: @
|
134
|
+
user: @resource,
|
124
135
|
message: "Your password has been successfully updated."
|
125
136
|
}
|
126
137
|
}
|
127
138
|
else
|
128
139
|
return render json: {
|
129
140
|
success: false,
|
130
|
-
errors: @
|
141
|
+
errors: @resource.errors
|
131
142
|
}, status: 422
|
132
143
|
end
|
133
144
|
end
|
@@ -21,7 +21,7 @@ module DeviseTokenAuth
|
|
21
21
|
|
22
22
|
begin
|
23
23
|
# override email confirmation, must be sent manually from ctrl
|
24
|
-
|
24
|
+
resource_class.skip_callback("create", :after, :send_on_create_confirmation_instructions)
|
25
25
|
if @resource.save
|
26
26
|
|
27
27
|
unless @resource.confirmed?
|
@@ -33,16 +33,15 @@ module DeviseTokenAuth
|
|
33
33
|
|
34
34
|
else
|
35
35
|
# email auth has been bypassed, authenticate user
|
36
|
-
@user = @resource
|
37
36
|
@client_id = SecureRandom.urlsafe_base64(nil, false)
|
38
37
|
@token = SecureRandom.urlsafe_base64(nil, false)
|
39
38
|
|
40
|
-
@
|
39
|
+
@resource.tokens[@client_id] = {
|
41
40
|
token: BCrypt::Password.create(@token),
|
42
41
|
expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
43
42
|
}
|
44
43
|
|
45
|
-
@
|
44
|
+
@resource.save!
|
46
45
|
|
47
46
|
update_auth_header
|
48
47
|
end
|
@@ -70,16 +69,16 @@ module DeviseTokenAuth
|
|
70
69
|
end
|
71
70
|
|
72
71
|
def update
|
73
|
-
if @
|
74
|
-
if @
|
72
|
+
if @resource
|
73
|
+
if @resource.update_attributes(account_update_params)
|
75
74
|
render json: {
|
76
75
|
status: 'success',
|
77
|
-
data: @
|
76
|
+
data: @resource.as_json
|
78
77
|
}
|
79
78
|
else
|
80
79
|
render json: {
|
81
80
|
status: 'error',
|
82
|
-
errors: @
|
81
|
+
errors: @resource.errors
|
83
82
|
}, status: 403
|
84
83
|
end
|
85
84
|
else
|
@@ -91,12 +90,12 @@ module DeviseTokenAuth
|
|
91
90
|
end
|
92
91
|
|
93
92
|
def destroy
|
94
|
-
if @
|
95
|
-
@
|
93
|
+
if @resource
|
94
|
+
@resource.destroy
|
96
95
|
|
97
96
|
render json: {
|
98
97
|
status: 'success',
|
99
|
-
message: "Account with uid #{@
|
98
|
+
message: "Account with uid #{@resource.uid} has been destroyed."
|
100
99
|
}
|
101
100
|
else
|
102
101
|
render json: {
|
@@ -4,30 +4,45 @@ module DeviseTokenAuth
|
|
4
4
|
before_filter :set_user_by_token, :only => [:destroy]
|
5
5
|
|
6
6
|
def create
|
7
|
-
|
7
|
+
# honor devise configuration for case_insensitive_keys
|
8
|
+
if resource_class.case_insensitive_keys.include?(:email)
|
9
|
+
email = resource_params[:email].downcase
|
10
|
+
else
|
11
|
+
email = resource_params[:email]
|
12
|
+
end
|
8
13
|
|
9
|
-
|
14
|
+
q = "uid='#{email}' AND provider='email'"
|
15
|
+
|
16
|
+
if ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'
|
17
|
+
q = "BINARY uid='#{email}' AND provider='email'"
|
18
|
+
end
|
19
|
+
|
20
|
+
@resource = resource_class.where(q).first
|
21
|
+
|
22
|
+
if @resource and valid_params? and @resource.valid_password?(resource_params[:password]) and @resource.confirmed?
|
10
23
|
# create client id
|
11
24
|
@client_id = SecureRandom.urlsafe_base64(nil, false)
|
12
25
|
@token = SecureRandom.urlsafe_base64(nil, false)
|
13
26
|
|
14
|
-
@
|
27
|
+
@resource.tokens[@client_id] = {
|
15
28
|
token: BCrypt::Password.create(@token),
|
16
29
|
expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
17
30
|
}
|
18
|
-
@
|
31
|
+
@resource.save
|
32
|
+
|
33
|
+
sign_in(:user, @resource, store: false, bypass: false)
|
19
34
|
|
20
35
|
render json: {
|
21
|
-
data: @
|
36
|
+
data: @resource.as_json(except: [
|
22
37
|
:tokens, :created_at, :updated_at
|
23
38
|
])
|
24
39
|
}
|
25
40
|
|
26
|
-
elsif @
|
41
|
+
elsif @resource and not @resource.confirmed?
|
27
42
|
render json: {
|
28
43
|
success: false,
|
29
44
|
errors: [
|
30
|
-
"A confirmation email was sent to your account at #{@
|
45
|
+
"A confirmation email was sent to your account at #{@resource.email}. "+
|
31
46
|
"You must follow the instructions in the email before your account "+
|
32
47
|
"can be activated"
|
33
48
|
]
|
@@ -42,7 +57,7 @@ module DeviseTokenAuth
|
|
42
57
|
|
43
58
|
def destroy
|
44
59
|
# remove auth instance variables so that after_filter does not run
|
45
|
-
user = remove_instance_variable(:@
|
60
|
+
user = remove_instance_variable(:@resource) if @resource
|
46
61
|
client_id = remove_instance_variable(:@client_id) if @client_id
|
47
62
|
remove_instance_variable(:@token) if @token
|
48
63
|
|
@@ -4,11 +4,11 @@ module DeviseTokenAuth
|
|
4
4
|
before_filter :set_user_by_token, :only => [:validate_token]
|
5
5
|
|
6
6
|
def validate_token
|
7
|
-
# @
|
8
|
-
if @
|
7
|
+
# @resource will have been set by set_user_token concern
|
8
|
+
if @resource
|
9
9
|
render json: {
|
10
10
|
success: true,
|
11
|
-
data: @
|
11
|
+
data: @resource.as_json(except: [
|
12
12
|
:tokens, :created_at, :updated_at
|
13
13
|
])
|
14
14
|
}
|