devise_token_auth 0.1.28 → 0.1.29.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class Overrides::ConfirmationsControllerTest < ActionDispatch::IntegrationTest
|
10
|
+
describe Overrides::ConfirmationsController do
|
11
|
+
before do
|
12
|
+
@redirect_url = Faker::Internet.url
|
13
|
+
@new_user = evil_users(:unconfirmed_email_user)
|
14
|
+
|
15
|
+
# generate + send email
|
16
|
+
@new_user.send_confirmation_instructions({
|
17
|
+
redirect_url: @redirect_url
|
18
|
+
})
|
19
|
+
|
20
|
+
@mail = ActionMailer::Base.deliveries.last
|
21
|
+
@confirmation_path = @mail.body.match(/localhost([^\"]*)\"/)[1]
|
22
|
+
|
23
|
+
# visit confirmation link
|
24
|
+
get @confirmation_path
|
25
|
+
|
26
|
+
# reload user from db
|
27
|
+
@new_user.reload
|
28
|
+
end
|
29
|
+
|
30
|
+
test "user is confirmed" do
|
31
|
+
assert @new_user.confirmed?
|
32
|
+
end
|
33
|
+
|
34
|
+
test "user can be authenticated via confirmation link" do
|
35
|
+
# hard coded in override controller
|
36
|
+
override_proof_str = "(^^,)"
|
37
|
+
|
38
|
+
# ensure present in redirect URL
|
39
|
+
override_proof_param = URI.unescape(response.headers["Location"].match(/override_proof=([^&]*)&/)[1])
|
40
|
+
|
41
|
+
assert_equal override_proof_str, override_proof_param
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class Overrides::OmniauthCallbacksControllerTest < ActionDispatch::IntegrationTest
|
10
|
+
describe Overrides::OmniauthCallbacksController do
|
11
|
+
setup do
|
12
|
+
OmniAuth.config.test_mode = true
|
13
|
+
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
|
14
|
+
:provider => 'facebook',
|
15
|
+
:uid => '123545',
|
16
|
+
:info => {
|
17
|
+
name: 'chong',
|
18
|
+
email: 'chongbong@aol.com'
|
19
|
+
}
|
20
|
+
})
|
21
|
+
|
22
|
+
@favorite_color = "gray"
|
23
|
+
|
24
|
+
get_via_redirect '/evil_user_auth/facebook', {
|
25
|
+
auth_origin_url: Faker::Internet.url,
|
26
|
+
favorite_color: @favorite_color
|
27
|
+
}
|
28
|
+
|
29
|
+
@user = assigns(:user)
|
30
|
+
end
|
31
|
+
|
32
|
+
test 'request is successful' do
|
33
|
+
assert_equal 200, response.status
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'controller was overridden' do
|
37
|
+
assert_equal @user.nickname, Overrides::OmniauthCallbacksController::DEFAULT_NICKNAME
|
38
|
+
end
|
39
|
+
|
40
|
+
test 'whitelisted param was allowed' do
|
41
|
+
assert_equal @favorite_color, @user.favorite_color
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class Overrides::PasswordsControllerTest < ActionDispatch::IntegrationTest
|
10
|
+
describe Overrides::PasswordsController do
|
11
|
+
before do
|
12
|
+
@user = evil_users(:confirmed_email_user)
|
13
|
+
@redirect_url = Faker::Internet.url
|
14
|
+
|
15
|
+
post "/evil_user_auth/password", {
|
16
|
+
email: @user.email,
|
17
|
+
redirect_url: @redirect_url
|
18
|
+
}
|
19
|
+
|
20
|
+
@mail = ActionMailer::Base.deliveries.last
|
21
|
+
@user.reload
|
22
|
+
|
23
|
+
@mail_config_name = CGI.unescape(@mail.body.match(/config=([^&]*)&/)[1])
|
24
|
+
@mail_redirect_url = CGI.unescape(@mail.body.match(/redirect_url=([^&]*)&/)[1])
|
25
|
+
@mail_reset_token = @mail.body.match(/reset_password_token=(.*)\"/)[1]
|
26
|
+
|
27
|
+
get '/evil_user_auth/password/edit', {
|
28
|
+
reset_password_token: @mail_reset_token,
|
29
|
+
redirect_url: @mail_redirect_url
|
30
|
+
}
|
31
|
+
|
32
|
+
@user.reload
|
33
|
+
|
34
|
+
raw_qs = response.location.split('?')[1]
|
35
|
+
@qs = Rack::Utils.parse_nested_query(raw_qs)
|
36
|
+
|
37
|
+
@client_id = @qs["client_id"]
|
38
|
+
@expiry = @qs["expiry"]
|
39
|
+
@reset_password = @qs["reset_password"]
|
40
|
+
@token = @qs["token"]
|
41
|
+
@uid = @qs["uid"]
|
42
|
+
@override_proof = @qs["override_proof"]
|
43
|
+
end
|
44
|
+
|
45
|
+
test 'respones should have success redirect status' do
|
46
|
+
assert_equal 302, response.status
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'response should contain auth params + override proof' do
|
50
|
+
assert @client_id
|
51
|
+
assert @expiry
|
52
|
+
assert @reset_password
|
53
|
+
assert @token
|
54
|
+
assert @uid
|
55
|
+
assert @override_proof
|
56
|
+
end
|
57
|
+
|
58
|
+
test 'override proof is correct' do
|
59
|
+
assert_equal @override_proof, Overrides::PasswordsController::OVERRIDE_PROOF
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class Overrides::RegistrationsControllerTest < ActionDispatch::IntegrationTest
|
10
|
+
describe Overrides::RegistrationsController do
|
11
|
+
setup do
|
12
|
+
@existing_user = evil_users(:confirmed_email_user)
|
13
|
+
@auth_headers = @existing_user.create_new_auth_token
|
14
|
+
@client_id = @auth_headers['client']
|
15
|
+
@favorite_color = "pink"
|
16
|
+
|
17
|
+
|
18
|
+
# ensure request is not treated as batch request
|
19
|
+
age_token(@existing_user, @client_id)
|
20
|
+
|
21
|
+
# test valid update param
|
22
|
+
@new_operating_thetan = 1000000
|
23
|
+
|
24
|
+
put '/evil_user_auth', {
|
25
|
+
favorite_color: @favorite_color
|
26
|
+
}, @auth_headers
|
27
|
+
|
28
|
+
@data = JSON.parse(response.body)
|
29
|
+
@existing_user.reload
|
30
|
+
end
|
31
|
+
|
32
|
+
test 'user was updated' do
|
33
|
+
assert_equal @favorite_color, @existing_user.favorite_color
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'controller was overridden' do
|
37
|
+
assert_equal Overrides::RegistrationsController::OVERRIDE_PROOF, @data["override_proof"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class Overrides::RegistrationsControllerTest < ActionDispatch::IntegrationTest
|
10
|
+
describe Overrides::RegistrationsController do
|
11
|
+
before do
|
12
|
+
@existing_user = evil_users(:confirmed_email_user)
|
13
|
+
@existing_user.skip_confirmation!
|
14
|
+
@existing_user.save!
|
15
|
+
|
16
|
+
post '/evil_user_auth/sign_in', {
|
17
|
+
email: @existing_user.email,
|
18
|
+
password: 'secret123'
|
19
|
+
}
|
20
|
+
|
21
|
+
@user = assigns(:user)
|
22
|
+
@data = JSON.parse(response.body)
|
23
|
+
end
|
24
|
+
|
25
|
+
test "request should succeed" do
|
26
|
+
assert_equal 200, response.status
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'controller was overridden' do
|
30
|
+
assert_equal Overrides::RegistrationsController::OVERRIDE_PROOF, @data['override_proof']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# was the web request successful?
|
4
|
+
# was the user redirected to the right page?
|
5
|
+
# was the user successfully authenticated?
|
6
|
+
# was the correct object stored in the response?
|
7
|
+
# was the appropriate message delivered in the json payload?
|
8
|
+
|
9
|
+
class Overrides::TokenValidationsControllerTest < ActionDispatch::IntegrationTest
|
10
|
+
describe Overrides::TokenValidationsController do
|
11
|
+
before do
|
12
|
+
@user = evil_users(:confirmed_email_user)
|
13
|
+
@user.skip_confirmation!
|
14
|
+
@user.save!
|
15
|
+
|
16
|
+
@auth_headers = @user.create_new_auth_token
|
17
|
+
|
18
|
+
@token = @auth_headers['access-token']
|
19
|
+
@client_id = @auth_headers['client']
|
20
|
+
@expiry = @auth_headers['expiry']
|
21
|
+
|
22
|
+
# ensure that request is not treated as batch request
|
23
|
+
age_token(@user, @client_id)
|
24
|
+
|
25
|
+
get '/evil_user_auth/validate_token', {}, @auth_headers
|
26
|
+
|
27
|
+
@resp = JSON.parse(response.body)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "token valid" do
|
31
|
+
assert_equal 200, response.status
|
32
|
+
end
|
33
|
+
|
34
|
+
test "controller was overridden" do
|
35
|
+
assert_equal Overrides::TokenValidationsController::OVERRIDE_PROOF, @resp["override_proof"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Overrides
|
2
|
+
class ConfirmationsController < DeviseTokenAuth::ConfirmationsController
|
3
|
+
def show
|
4
|
+
@user = resource_class.confirm_by_token(params[:confirmation_token])
|
5
|
+
|
6
|
+
if @user and @user.id
|
7
|
+
# create client id
|
8
|
+
client_id = SecureRandom.urlsafe_base64(nil, false)
|
9
|
+
token = SecureRandom.urlsafe_base64(nil, false)
|
10
|
+
token_hash = BCrypt::Password.create(token)
|
11
|
+
expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
12
|
+
|
13
|
+
@user.tokens[client_id] = {
|
14
|
+
token: token_hash,
|
15
|
+
expiry: expiry
|
16
|
+
}
|
17
|
+
|
18
|
+
@user.save!
|
19
|
+
|
20
|
+
redirect_to(@user.build_auth_url(params[:redirect_url], {
|
21
|
+
token: token,
|
22
|
+
client_id: client_id,
|
23
|
+
account_confirmation_success: true,
|
24
|
+
config: params[:config],
|
25
|
+
override_proof: "(^^,)"
|
26
|
+
}))
|
27
|
+
else
|
28
|
+
raise ActionController::RoutingError.new('Not Found')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Overrides
|
2
|
+
class OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
|
3
|
+
DEFAULT_NICKNAME = "stimpy"
|
4
|
+
|
5
|
+
def assign_provider_attrs(user, auth_hash)
|
6
|
+
user.assign_attributes({
|
7
|
+
nickname: DEFAULT_NICKNAME,
|
8
|
+
name: auth_hash['info']['name'],
|
9
|
+
image: auth_hash['info']['image'],
|
10
|
+
email: auth_hash['info']['email']
|
11
|
+
})
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Overrides
|
2
|
+
class PasswordsController < DeviseTokenAuth::PasswordsController
|
3
|
+
OVERRIDE_PROOF = "(^^,)"
|
4
|
+
|
5
|
+
# this is where users arrive after visiting the email confirmation link
|
6
|
+
def edit
|
7
|
+
@user = resource_class.reset_password_by_token({
|
8
|
+
reset_password_token: resource_params[:reset_password_token]
|
9
|
+
})
|
10
|
+
|
11
|
+
if @user and @user.id
|
12
|
+
client_id = SecureRandom.urlsafe_base64(nil, false)
|
13
|
+
token = SecureRandom.urlsafe_base64(nil, false)
|
14
|
+
token_hash = BCrypt::Password.create(token)
|
15
|
+
expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
16
|
+
|
17
|
+
@user.tokens[client_id] = {
|
18
|
+
token: token_hash,
|
19
|
+
expiry: expiry
|
20
|
+
}
|
21
|
+
|
22
|
+
# ensure that user is confirmed
|
23
|
+
@user.skip_confirmation! unless @user.confirmed_at
|
24
|
+
|
25
|
+
@user.save!
|
26
|
+
|
27
|
+
redirect_to(@user.build_auth_url(params[:redirect_url], {
|
28
|
+
token: token,
|
29
|
+
client_id: client_id,
|
30
|
+
reset_password: true,
|
31
|
+
config: params[:config],
|
32
|
+
override_proof: OVERRIDE_PROOF
|
33
|
+
}))
|
34
|
+
else
|
35
|
+
raise ActionController::RoutingError.new('Not Found')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Overrides
|
2
|
+
class RegistrationsController < DeviseTokenAuth::RegistrationsController
|
3
|
+
OVERRIDE_PROOF = "(^^,)"
|
4
|
+
|
5
|
+
def update
|
6
|
+
if @user
|
7
|
+
if @user.update_attributes(account_update_params)
|
8
|
+
render json: {
|
9
|
+
status: 'success',
|
10
|
+
data: @user.as_json,
|
11
|
+
override_proof: OVERRIDE_PROOF
|
12
|
+
}
|
13
|
+
else
|
14
|
+
render json: {
|
15
|
+
status: 'error',
|
16
|
+
errors: @user.errors
|
17
|
+
}, status: 403
|
18
|
+
end
|
19
|
+
else
|
20
|
+
render json: {
|
21
|
+
status: 'error',
|
22
|
+
errors: ["User not found."]
|
23
|
+
}, status: 404
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Overrides
|
2
|
+
class SessionsController < DeviseTokenAuth::SessionsController
|
3
|
+
OVERRIDE_PROOF = "(^^,)"
|
4
|
+
|
5
|
+
def create
|
6
|
+
@user = resource_class.find_by_email(resource_params[:email])
|
7
|
+
|
8
|
+
if @user and valid_params? and @user.valid_password?(resource_params[:password]) and @user.confirmed?
|
9
|
+
# create client id
|
10
|
+
@client_id = SecureRandom.urlsafe_base64(nil, false)
|
11
|
+
@token = SecureRandom.urlsafe_base64(nil, false)
|
12
|
+
|
13
|
+
@user.tokens[@client_id] = {
|
14
|
+
token: BCrypt::Password.create(@token),
|
15
|
+
expiry: (Time.now + DeviseTokenAuth.token_lifespan).to_i
|
16
|
+
}
|
17
|
+
@user.save
|
18
|
+
|
19
|
+
render json: {
|
20
|
+
data: @user.as_json(except: [
|
21
|
+
:tokens, :created_at, :updated_at
|
22
|
+
]),
|
23
|
+
override_proof: OVERRIDE_PROOF
|
24
|
+
}
|
25
|
+
|
26
|
+
elsif @user and not @user.confirmed?
|
27
|
+
render json: {
|
28
|
+
success: false,
|
29
|
+
errors: [
|
30
|
+
"A confirmation email was sent to your account at #{@user.email}. "+
|
31
|
+
"You must follow the instructions in the email before your account "+
|
32
|
+
"can be activated"
|
33
|
+
]
|
34
|
+
}, status: 401
|
35
|
+
|
36
|
+
else
|
37
|
+
render json: {
|
38
|
+
errors: ["Invalid login credentials. Please try again."]
|
39
|
+
}, status: 401
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Overrides
|
2
|
+
class TokenValidationsController < DeviseTokenAuth::TokenValidationsController
|
3
|
+
OVERRIDE_PROOF = '(^^,)'
|
4
|
+
|
5
|
+
def validate_token
|
6
|
+
# @user will have been set by set_user_by_token concern
|
7
|
+
if @user
|
8
|
+
render json: {
|
9
|
+
success: true,
|
10
|
+
data: @user.as_json(except: [
|
11
|
+
:tokens, :created_at, :updated_at
|
12
|
+
]),
|
13
|
+
override_proof: OVERRIDE_PROOF
|
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
|