From 72a7cfaa395bbddabd0f0a712165fd7babf5d58c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 9 Jun 2020 10:23:06 +0200 Subject: Add e-mail-based sign in challenge for users with disabled 2FA (#14013) --- app/models/user.rb | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/user.rb b/app/models/user.rb index ae0cdf29d..306e2d435 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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) -- cgit