devise-suspicious_login 0.1.1
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 +7 -0
- data/.gitignore +10 -0
- data/Gemfile +2 -0
- data/README.md +111 -0
- data/Rakefile +36 -0
- data/app/views/devise/mailer/suspicious_login_instructions.html.erb +7 -0
- data/bin/test +7 -0
- data/config/locales/en.yml +10 -0
- data/devise-suspicious_login.gemspec +26 -0
- data/lib/generators/active_record/suspicious_login_generator.rb +97 -0
- data/lib/generators/active_record/templates/migration.rb +11 -0
- data/lib/generators/active_record/templates/migration_existing.rb +13 -0
- data/lib/generators/suspicious_login/install_generator.rb +23 -0
- data/lib/generators/suspicious_login/orm_helpers.rb +56 -0
- data/lib/generators/templates/suspicious_login.rb +26 -0
- data/lib/suspicious_login.rb +38 -0
- data/lib/suspicious_login/controllers/helpers.rb +6 -0
- data/lib/suspicious_login/hooks/suspicious_login.rb +8 -0
- data/lib/suspicious_login/mailer.rb +11 -0
- data/lib/suspicious_login/model.rb +79 -0
- data/lib/suspicious_login/patches.rb +12 -0
- data/lib/suspicious_login/rails.rb +9 -0
- data/lib/suspicious_login/schema.rb +19 -0
- data/lib/suspicious_login/strategies/token.rb +54 -0
- data/lib/suspicious_login/version.rb +3 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/home_controller.rb +5 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/application_record.rb +3 -0
- data/test/dummy/app/models/user.rb +9 -0
- data/test/dummy/app/views/home/index.html +0 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +38 -0
- data/test/dummy/bin/update +29 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +17 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +21 -0
- data/test/dummy/config/environment.rb +2 -0
- data/test/dummy/config/environments/test.rb +19 -0
- data/test/dummy/config/initializers/devise.rb +13 -0
- data/test/dummy/config/locales/devise.en.yml +12 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +5 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/migrate/20180910092425_create_tables.rb +16 -0
- data/test/dummy/db/migrate/20180910094718_add_login_token_columns.rb +8 -0
- data/test/dummy/db/migrate/20180910104707_add_trackable_columns.rb +11 -0
- data/test/dummy/db/migrate/20180919081730_add_recoverable_columns.rb +8 -0
- data/test/dummy/db/schema.rb +38 -0
- data/test/dummy/log/.keep +0 -0
- data/test/factories.rb +47 -0
- data/test/generators/active_record_generator_test.rb +40 -0
- data/test/generators/install_generator_test.rb +15 -0
- data/test/support/helpers.rb +16 -0
- data/test/suspicious_acceptance_test.rb +269 -0
- data/test/suspicious_login_test.rb +38 -0
- data/test/test_helper.rb +37 -0
- metadata +245 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Rails.application.configure do
|
|
2
|
+
config.cache_classes = true
|
|
3
|
+
config.eager_load = false
|
|
4
|
+
|
|
5
|
+
config.public_file_server.enabled = true
|
|
6
|
+
config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" }
|
|
7
|
+
|
|
8
|
+
config.consider_all_requests_local = true
|
|
9
|
+
config.action_controller.perform_caching = false
|
|
10
|
+
|
|
11
|
+
config.action_dispatch.show_exceptions = false
|
|
12
|
+
|
|
13
|
+
config.action_controller.allow_forgery_protection = false
|
|
14
|
+
config.action_mailer.perform_caching = false
|
|
15
|
+
|
|
16
|
+
config.action_mailer.delivery_method = :test
|
|
17
|
+
|
|
18
|
+
config.active_support.deprecation = :stderr
|
|
19
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Devise.setup do |config|
|
|
2
|
+
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
|
|
3
|
+
require 'devise/orm/active_record'
|
|
4
|
+
|
|
5
|
+
config.case_insensitive_keys = [:email]
|
|
6
|
+
config.strip_whitespace_keys = [:email]
|
|
7
|
+
config.skip_session_storage = [:http_auth]
|
|
8
|
+
config.stretches = Rails.env.test? ? 1 : 11
|
|
9
|
+
|
|
10
|
+
config.warden do |config|
|
|
11
|
+
config.default_strategies(:scope => :user).unshift :suspicious_login_token
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
en:
|
|
2
|
+
devise:
|
|
3
|
+
failure:
|
|
4
|
+
already_authenticated: ""
|
|
5
|
+
inactive: ""
|
|
6
|
+
invalid: "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in."
|
|
7
|
+
locked: "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in."
|
|
8
|
+
last_attempt: "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in."
|
|
9
|
+
not_found_in_database: "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in."
|
|
10
|
+
timeout: "Your session expired. Please log in again to continue."
|
|
11
|
+
unauthenticated: "You need to log in or sign up before continuing."
|
|
12
|
+
unconfirmed: ""
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class CreateTables < ActiveRecord::Migration[5.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :users do |t|
|
|
4
|
+
t.string :unique_session_id, :limit => 20
|
|
5
|
+
|
|
6
|
+
## Database authenticatable
|
|
7
|
+
t.string :email, null: false, default: ''
|
|
8
|
+
t.string :encrypted_password, null: false, default: ''
|
|
9
|
+
|
|
10
|
+
t.datetime :password_changed_at
|
|
11
|
+
t.timestamps null: false
|
|
12
|
+
end
|
|
13
|
+
add_index :users, :password_changed_at
|
|
14
|
+
add_index :users, :email
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class AddTrackableColumns < ActiveRecord::Migration[5.1]
|
|
2
|
+
def change
|
|
3
|
+
change_table :users do |t|
|
|
4
|
+
add_column :users, :last_sign_in_at, :datetime
|
|
5
|
+
add_column :users, :current_sign_in_at, :datetime
|
|
6
|
+
add_column :users, :current_sign_in_ip, :string
|
|
7
|
+
add_column :users, :last_sign_in_ip, :string
|
|
8
|
+
add_column :users, :sign_in_count, :integer, default: 0, null: false
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
|
4
|
+
#
|
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
|
6
|
+
# database schema. If you need to create the application database on another
|
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
|
10
|
+
#
|
|
11
|
+
# It's strongly recommended that you check this file into your version control system.
|
|
12
|
+
|
|
13
|
+
ActiveRecord::Schema.define(version: 2018_09_24_105700) do
|
|
14
|
+
|
|
15
|
+
create_table "users", force: :cascade do |t|
|
|
16
|
+
t.string "unique_session_id", limit: 20
|
|
17
|
+
t.string "email", default: "", null: false
|
|
18
|
+
t.string "encrypted_password", default: "", null: false
|
|
19
|
+
t.datetime "password_changed_at"
|
|
20
|
+
t.datetime "created_at", null: false
|
|
21
|
+
t.datetime "updated_at", null: false
|
|
22
|
+
t.string "login_token"
|
|
23
|
+
t.datetime "login_token_sent_at"
|
|
24
|
+
t.datetime "last_sign_in_at"
|
|
25
|
+
t.datetime "current_sign_in_at"
|
|
26
|
+
t.string "current_sign_in_ip"
|
|
27
|
+
t.string "last_sign_in_ip"
|
|
28
|
+
t.integer "sign_in_count", default: 0, null: false
|
|
29
|
+
t.string "reset_password_token"
|
|
30
|
+
t.datetime "reset_password_sent_at"
|
|
31
|
+
t.string "authentication_token"
|
|
32
|
+
t.datetime "authentication_token_created_at"
|
|
33
|
+
t.index ["authentication_token"], name: "index_users_on_authentication_token", unique: true
|
|
34
|
+
t.index ["email"], name: "index_users_on_email"
|
|
35
|
+
t.index ["password_changed_at"], name: "index_users_on_password_changed_at"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
File without changes
|
data/test/factories.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
FactoryBot.define do
|
|
2
|
+
sequence :email do |n|
|
|
3
|
+
"email#{n}@example.com"
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
sequence :uid do |n|
|
|
7
|
+
"12345#{n}"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
factory :user, aliases: [:new_user] do
|
|
11
|
+
email
|
|
12
|
+
password { 'password' }
|
|
13
|
+
created_at { Time.now.utc }
|
|
14
|
+
updated_at { Time.now.utc }
|
|
15
|
+
last_sign_in_ip { '127.0.0.1' }
|
|
16
|
+
current_sign_in_ip { '127.0.0.2' }
|
|
17
|
+
|
|
18
|
+
factory :user_with_honest_login do
|
|
19
|
+
last_sign_in_at { 2.days.ago.utc }
|
|
20
|
+
current_sign_in_at { 1.day.ago.utc }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
factory :user_with_dormant_login do
|
|
24
|
+
last_sign_in_at { 1.year.ago.utc }
|
|
25
|
+
current_sign_in_at { 6.months.ago.utc }
|
|
26
|
+
|
|
27
|
+
factory :user_with_dormant_login_and_recently_sent_login_token do
|
|
28
|
+
login_token_sent_at { Time.now.utc }
|
|
29
|
+
login_token { "TOKEN" }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
factory :user_with_suspicious_login do
|
|
34
|
+
email { 'suspicious@example.org' }
|
|
35
|
+
|
|
36
|
+
factory :user_with_suspicious_login_and_recently_sent_login_token do
|
|
37
|
+
login_token_sent_at { Time.now.utc }
|
|
38
|
+
login_token { "TOKEN" }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
factory :user_with_suspicious_login_and_ancient_login_token do
|
|
42
|
+
login_token_sent_at { 1.day.ago.utc }
|
|
43
|
+
login_token { "TOKEN" }
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require_relative '../test_helper.rb'
|
|
2
|
+
|
|
3
|
+
if DEVISE_ORM == :active_record
|
|
4
|
+
require 'generators/active_record/suspicious_login_generator'
|
|
5
|
+
|
|
6
|
+
class ActiveRecordGeneratorTest < Rails::Generators::TestCase
|
|
7
|
+
tests ActiveRecord::Generators::SuspiciousLoginGenerator
|
|
8
|
+
destination File.expand_path('../../tmp', __FILE__)
|
|
9
|
+
setup :prepare_destination
|
|
10
|
+
|
|
11
|
+
test "update model migration when model exists in test mode" do
|
|
12
|
+
run_generator %w(foo)
|
|
13
|
+
assert_file "app/models/foo.rb"
|
|
14
|
+
run_generator %w(foo)
|
|
15
|
+
assert_migration "db/migrate/add_devise_suspicious_login_to_foos.rb", /#{Devise.token_field_name}/
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
test "raise error if model is not present when not in test mode" do
|
|
19
|
+
Rails.env = 'prod'
|
|
20
|
+
assert_raise SuspiciousLogin::MissingModelError do
|
|
21
|
+
run_generator %w(foo)
|
|
22
|
+
end
|
|
23
|
+
Rails.env = 'test'
|
|
24
|
+
assert_no_file "app/models/foo.rb"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
test "append warden strategy to model" do
|
|
28
|
+
run_generator %w(foo)
|
|
29
|
+
assert_file "config/initializers/suspicious_login.rb", /manager\.default_strategies\(:scope => :foo\)\.unshift :suspicious_login_token/
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
test "all files are deleted except the model" do
|
|
33
|
+
run_generator %w(foo)
|
|
34
|
+
run_generator %w(foo)
|
|
35
|
+
assert_migration "db/migrate/add_devise_suspicious_login_to_foos.rb"
|
|
36
|
+
run_generator %w(foo), behavior: :revoke
|
|
37
|
+
assert_no_migration "db/migrate/add_devise_suspicious_login_to_foos.rb"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require_relative '../test_helper.rb'
|
|
2
|
+
require 'generators/suspicious_login/install_generator'
|
|
3
|
+
|
|
4
|
+
class InstallGeneratorTest < Rails::Generators::TestCase
|
|
5
|
+
tests SuspiciousLogin::Generators::InstallGenerator
|
|
6
|
+
destination File.expand_path("../../tmp", __FILE__)
|
|
7
|
+
setup :prepare_destination
|
|
8
|
+
|
|
9
|
+
test "assert all files created" do
|
|
10
|
+
run_generator
|
|
11
|
+
assert_file "config/initializers/suspicious_login.rb", /config\.warden do \|manager\|\n/
|
|
12
|
+
assert_file "config/locales/suspicious_login.en.yml", /missing_modules:/
|
|
13
|
+
assert_file "config/application.rb", /require 'suspicious_login'/
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'active_support/test_case'
|
|
2
|
+
|
|
3
|
+
@@default_ip = '127.0.0.4'
|
|
4
|
+
|
|
5
|
+
class ActiveSupport::TestCase
|
|
6
|
+
def setup_mailer
|
|
7
|
+
Devise.mailer = Devise::Mailer
|
|
8
|
+
ActionMailer::Base.deliveries = []
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class ActionDispatch::Request
|
|
13
|
+
def remote_ip
|
|
14
|
+
@@default_ip
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
class SuspiciousMailTest < ActionDispatch::IntegrationTest
|
|
2
|
+
def setup
|
|
3
|
+
setup_mailer
|
|
4
|
+
Devise.mailer = Devise::Mailer
|
|
5
|
+
Devise.mailer_sender = 'test@example.com'
|
|
6
|
+
Devise.clear_token_on_login = true
|
|
7
|
+
@@default_ip = '127.0.0.4'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def mail
|
|
11
|
+
@mail ||= begin
|
|
12
|
+
ActionMailer::Base.deliveries.first
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test 'new user' do
|
|
17
|
+
user = create(:new_user)
|
|
18
|
+
|
|
19
|
+
params = {
|
|
20
|
+
user: {
|
|
21
|
+
email: user.email,
|
|
22
|
+
password: "password"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
post user_session_path, params: params
|
|
27
|
+
assert_redirected_to root_path
|
|
28
|
+
assert_nil mail
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
test 'user with honest login' do
|
|
32
|
+
user = create(:user_with_honest_login)
|
|
33
|
+
|
|
34
|
+
params = {
|
|
35
|
+
user: {
|
|
36
|
+
email: user.email,
|
|
37
|
+
password: "password"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
post user_session_path, params: params
|
|
42
|
+
assert_redirected_to root_path
|
|
43
|
+
assert_nil mail
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
test 'user with dormant login from same ip' do
|
|
47
|
+
user = create(:user_with_dormant_login)
|
|
48
|
+
|
|
49
|
+
@@default_ip = '127.0.0.1'
|
|
50
|
+
params = {
|
|
51
|
+
user: {
|
|
52
|
+
email: user.email,
|
|
53
|
+
password: "password"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
post user_session_path, params: params
|
|
58
|
+
assert_redirected_to root_path
|
|
59
|
+
assert_nil mail
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
test 'user with dormant login from different ip' do
|
|
63
|
+
user = create(:user_with_dormant_login)
|
|
64
|
+
|
|
65
|
+
params = {
|
|
66
|
+
user: {
|
|
67
|
+
email: user.email,
|
|
68
|
+
password: "password"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
post user_session_path, params: params
|
|
73
|
+
assert_redirected_to new_user_session_path
|
|
74
|
+
assert_not_nil mail
|
|
75
|
+
assert_equal "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in.", flash[:alert]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
test 'user with suspicious login' do
|
|
79
|
+
user = create(:user_with_suspicious_login)
|
|
80
|
+
|
|
81
|
+
params = {
|
|
82
|
+
user: {
|
|
83
|
+
email: user.email,
|
|
84
|
+
password: "password"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
post user_session_path, params: params
|
|
89
|
+
assert_redirected_to new_user_session_path
|
|
90
|
+
assert_not_nil mail
|
|
91
|
+
assert_equal "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in.", flash[:alert]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
test 'user with dormant login from different ip and recently sent login token' do
|
|
95
|
+
user = create(:user_with_dormant_login_and_recently_sent_login_token)
|
|
96
|
+
|
|
97
|
+
params = {
|
|
98
|
+
user: {
|
|
99
|
+
email: user.email,
|
|
100
|
+
password: "password"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
post user_session_path, params: params
|
|
105
|
+
assert_redirected_to new_user_session_path
|
|
106
|
+
assert_nil mail
|
|
107
|
+
assert_equal "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in.", flash[:alert]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
test 'user with suspicious login and recently sent login token' do
|
|
111
|
+
user = create(:user_with_suspicious_login_and_recently_sent_login_token)
|
|
112
|
+
|
|
113
|
+
params = {
|
|
114
|
+
user: {
|
|
115
|
+
email: user.email,
|
|
116
|
+
password: "password"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
post user_session_path, params: params
|
|
121
|
+
assert_redirected_to new_user_session_path
|
|
122
|
+
assert_nil mail
|
|
123
|
+
assert_equal "Your email or password are invalid, OR we need to verify your sign in. If you have received an email from us, please follow the instructions to complete your sign in.", flash[:alert]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
test 'user with suspicious login and no token' do
|
|
127
|
+
user = create(:user_with_suspicious_login_and_recently_sent_login_token)
|
|
128
|
+
|
|
129
|
+
get root_path
|
|
130
|
+
assert_redirected_to new_user_session_path
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
test 'user with suspicious login and valid token and config.clear_token_on_login=true' do
|
|
134
|
+
Devise.clear_token_on_login = true
|
|
135
|
+
|
|
136
|
+
user = create(:user_with_suspicious_login_and_recently_sent_login_token)
|
|
137
|
+
params = {
|
|
138
|
+
login_token: "TOKEN",
|
|
139
|
+
email: user.email
|
|
140
|
+
}
|
|
141
|
+
get root_path(params)
|
|
142
|
+
assert_response :success
|
|
143
|
+
|
|
144
|
+
user = User.find(user.id)
|
|
145
|
+
assert_nil user[Devise.token_field_name]
|
|
146
|
+
assert_nil user[Devise.token_created_at_field_name]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
test 'user with suspicious login and valid token and config.clear_token_on_login=false' do
|
|
150
|
+
Devise.clear_token_on_login = false
|
|
151
|
+
|
|
152
|
+
user = create(:user_with_suspicious_login_and_recently_sent_login_token)
|
|
153
|
+
params = {
|
|
154
|
+
login_token: "TOKEN",
|
|
155
|
+
email: user.email
|
|
156
|
+
}
|
|
157
|
+
get root_path(params)
|
|
158
|
+
assert_response :success
|
|
159
|
+
|
|
160
|
+
user = User.find(user.id)
|
|
161
|
+
assert_equal user[Devise.token_field_name], "TOKEN"
|
|
162
|
+
assert_not_nil user[Devise.token_created_at_field_name]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
test 'user with suspicious login and valid but expired token' do
|
|
166
|
+
Devise.clear_token_on_login = false
|
|
167
|
+
|
|
168
|
+
user = create(:user_with_suspicious_login_and_ancient_login_token)
|
|
169
|
+
params = {
|
|
170
|
+
login_token: "TOKEN",
|
|
171
|
+
email: user.email
|
|
172
|
+
}
|
|
173
|
+
get root_path(params)
|
|
174
|
+
assert_redirected_to new_user_session_path
|
|
175
|
+
|
|
176
|
+
user = User.find(user.id)
|
|
177
|
+
assert_equal user[Devise.token_field_name], "TOKEN"
|
|
178
|
+
assert_not_nil user[Devise.token_created_at_field_name]
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
test 'user with suspicious login and invalid token and config.clear_token_on_login=true' do
|
|
182
|
+
Devise.clear_token_on_login = true
|
|
183
|
+
|
|
184
|
+
user = create(:user_with_suspicious_login_and_recently_sent_login_token)
|
|
185
|
+
params = {
|
|
186
|
+
login_token: "WRONG TOKEN",
|
|
187
|
+
email: user.email
|
|
188
|
+
}
|
|
189
|
+
get root_path(params)
|
|
190
|
+
assert_redirected_to new_user_session_path
|
|
191
|
+
|
|
192
|
+
user = User.find(user.id)
|
|
193
|
+
assert_equal user[Devise.token_field_name], "TOKEN"
|
|
194
|
+
assert_not_nil user[Devise.token_created_at_field_name]
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
test 'user with suspicious login and invalid token and config.clear_token_on_login=false' do
|
|
198
|
+
Devise.clear_token_on_login = false
|
|
199
|
+
|
|
200
|
+
user = create(:user_with_suspicious_login_and_recently_sent_login_token)
|
|
201
|
+
params = {
|
|
202
|
+
login_token: "WRONG TOKEN",
|
|
203
|
+
email: user.email
|
|
204
|
+
}
|
|
205
|
+
get root_path(params)
|
|
206
|
+
assert_redirected_to new_user_session_path
|
|
207
|
+
|
|
208
|
+
user = User.find(user.id)
|
|
209
|
+
assert_equal user[Devise.token_field_name], "TOKEN"
|
|
210
|
+
assert_not_nil user[Devise.token_created_at_field_name]
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
test 'multiple failed signins does not update trackable data' do
|
|
214
|
+
user = create(:user_with_dormant_login)
|
|
215
|
+
|
|
216
|
+
params = {
|
|
217
|
+
user: {
|
|
218
|
+
email: user.email,
|
|
219
|
+
password: "password"
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
last_sign_in_at = user.last_sign_in_at
|
|
224
|
+
current_sign_in_at = user.current_sign_in_at
|
|
225
|
+
last_sign_in_ip = user.last_sign_in_ip
|
|
226
|
+
current_sign_in_ip = user.current_sign_in_ip
|
|
227
|
+
|
|
228
|
+
post user_session_path, params: params
|
|
229
|
+
assert_redirected_to new_user_session_path
|
|
230
|
+
user.reload
|
|
231
|
+
assert_equal user.last_sign_in_at, last_sign_in_at
|
|
232
|
+
assert_equal user.current_sign_in_at, current_sign_in_at
|
|
233
|
+
assert_equal user.last_sign_in_ip, last_sign_in_ip
|
|
234
|
+
assert_equal user.current_sign_in_ip, current_sign_in_ip
|
|
235
|
+
|
|
236
|
+
post user_session_path, params: params
|
|
237
|
+
assert_redirected_to new_user_session_path
|
|
238
|
+
user.reload
|
|
239
|
+
assert_equal user.last_sign_in_at, last_sign_in_at
|
|
240
|
+
assert_equal user.current_sign_in_at, current_sign_in_at
|
|
241
|
+
assert_equal user.last_sign_in_ip, last_sign_in_ip
|
|
242
|
+
assert_equal user.current_sign_in_ip, current_sign_in_ip
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
test 'successful login updates trackable fields correctly' do
|
|
246
|
+
user = create(:user_with_honest_login)
|
|
247
|
+
|
|
248
|
+
params = {
|
|
249
|
+
user: {
|
|
250
|
+
email: user.email,
|
|
251
|
+
password: "password"
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
last_sign_in_at = user.last_sign_in_at
|
|
256
|
+
current_sign_in_at = user.current_sign_in_at
|
|
257
|
+
last_sign_in_ip = user.last_sign_in_ip
|
|
258
|
+
current_sign_in_ip = user.current_sign_in_ip
|
|
259
|
+
|
|
260
|
+
post user_session_path, params: params
|
|
261
|
+
assert_redirected_to root_path
|
|
262
|
+
|
|
263
|
+
user.reload
|
|
264
|
+
assert_equal user.last_sign_in_at, current_sign_in_at
|
|
265
|
+
assert user.current_sign_in_at > current_sign_in_at
|
|
266
|
+
assert_equal user.last_sign_in_ip, current_sign_in_ip
|
|
267
|
+
assert_equal user.current_sign_in_ip, '127.0.0.4'
|
|
268
|
+
end
|
|
269
|
+
end
|