Add e-mail-based sign in challenge for users with disabled 2FA (#14013)

This commit is contained in:
Eugen Rochko
2020-06-09 10:23:06 +02:00
committed by GitHub
parent 8b6d97fb7c
commit 72a7cfaa39
14 changed files with 368 additions and 51 deletions

View File

@ -38,6 +38,8 @@
# chosen_languages :string is an Array
# created_by_application_id :bigint(8)
# approved :boolean default(TRUE), not null
# sign_in_token :string
# sign_in_token_sent_at :datetime
#
class User < ApplicationRecord
@ -113,7 +115,7 @@ class User < ApplicationRecord
:advanced_layout, :use_blurhash, :use_pending_items, :trends, :crop_images,
to: :settings, prefix: :setting, allow_nil: false
attr_reader :invite_code
attr_reader :invite_code, :sign_in_token_attempt
attr_writer :external
def confirmed?
@ -167,6 +169,10 @@ class User < ApplicationRecord
true
end
def suspicious_sign_in?(ip)
!otp_required_for_login? && current_sign_in_at.present? && current_sign_in_at < 2.weeks.ago && !recent_ip?(ip)
end
def functional?
confirmed? && approved? && !disabled? && !account.suspended? && account.moved_to_account_id.nil?
end
@ -269,6 +275,13 @@ class User < ApplicationRecord
super
end
def external_or_valid_password?(compare_password)
# If encrypted_password is blank, we got the user from LDAP or PAM,
# so credentials are already valid
encrypted_password.blank? || valid_password?(compare_password)
end
def send_reset_password_instructions
return false if encrypted_password.blank?
@ -304,6 +317,15 @@ class User < ApplicationRecord
end
end
def sign_in_token_expired?
sign_in_token_sent_at.nil? || sign_in_token_sent_at < 5.minutes.ago
end
def generate_sign_in_token
self.sign_in_token = Devise.friendly_token(6)
self.sign_in_token_sent_at = Time.now.utc
end
protected
def send_devise_notification(notification, *args)
@ -320,6 +342,10 @@ class User < ApplicationRecord
private
def recent_ip?(ip)
recent_ips.any? { |(_, recent_ip)| recent_ip == ip }
end
def send_pending_devise_notifications
pending_devise_notifications.each do |notification, args|
render_and_send_devise_message(notification, *args)