Add ability to skip sign-in token authentication for specific users (#16427)
Remove "active within last two weeks" exception for sign in token requirement Change admin reset password to lock access until the password is reset
This commit is contained in:
parent
2e0eac71dd
commit
771c9d4ba8
14 changed files with 160 additions and 32 deletions
|
@ -6,9 +6,9 @@ module Admin
|
|||
|
||||
def create
|
||||
authorize @user, :reset_password?
|
||||
@user.send_reset_password_instructions
|
||||
@user.reset_password!
|
||||
log_action :reset_password, @user
|
||||
redirect_to admin_accounts_path
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class SignInTokenAuthenticationsController < BaseController
|
||||
before_action :set_target_user
|
||||
|
||||
def create
|
||||
authorize @user, :enable_sign_in_token_auth?
|
||||
@user.update(skip_sign_in_token: false)
|
||||
log_action :enable_sign_in_token_auth, @user
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @user, :disable_sign_in_token_auth?
|
||||
@user.update(skip_sign_in_token: true)
|
||||
log_action :disable_sign_in_token_auth, @user
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_target_user
|
||||
@user = User.find(params[:user_id])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -9,7 +9,7 @@ module Admin
|
|||
@user.disable_two_factor!
|
||||
log_action :disable_2fa, @user
|
||||
UserMailer.two_factor_disabled(@user).deliver_later!
|
||||
redirect_to admin_accounts_path
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
# sign_in_token_sent_at :datetime
|
||||
# webauthn_id :string
|
||||
# sign_up_ip :inet
|
||||
# skip_sign_in_token :boolean
|
||||
#
|
||||
|
||||
class User < ApplicationRecord
|
||||
|
@ -200,7 +201,7 @@ class User < ApplicationRecord
|
|||
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)
|
||||
!otp_required_for_login? && !skip_sign_in_token? && current_sign_in_at.present? && !recent_ip?(ip)
|
||||
end
|
||||
|
||||
def functional?
|
||||
|
@ -329,12 +330,32 @@ class User < ApplicationRecord
|
|||
super
|
||||
end
|
||||
|
||||
def reset_password!(new_password, new_password_confirmation)
|
||||
def reset_password(new_password, new_password_confirmation)
|
||||
return false if encrypted_password.blank?
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def reset_password!
|
||||
# First, change password to something random, invalidate the remember-me token,
|
||||
# and deactivate all sessions
|
||||
transaction do
|
||||
update(remember_token: nil, remember_created_at: nil, password: SecureRandom.hex)
|
||||
session_activations.destroy_all
|
||||
end
|
||||
|
||||
# Then, remove all authorized applications and connected push subscriptions
|
||||
Doorkeeper::AccessGrant.by_resource_owner(self).in_batches.update_all(revoked_at: Time.now.utc)
|
||||
|
||||
Doorkeeper::AccessToken.by_resource_owner(self).in_batches do |batch|
|
||||
batch.update_all(revoked_at: Time.now.utc)
|
||||
Web::PushSubscription.where(access_token_id: batch).delete_all
|
||||
end
|
||||
|
||||
# Finally, send a reset password prompt to the user
|
||||
send_reset_password_instructions
|
||||
end
|
||||
|
||||
def show_all_media?
|
||||
setting_display_media == 'show_all'
|
||||
end
|
||||
|
|
|
@ -13,6 +13,14 @@ class UserPolicy < ApplicationPolicy
|
|||
admin? && !record.staff?
|
||||
end
|
||||
|
||||
def disable_sign_in_token_auth?
|
||||
staff?
|
||||
end
|
||||
|
||||
def enable_sign_in_token_auth?
|
||||
staff?
|
||||
end
|
||||
|
||||
def confirm?
|
||||
staff? && !record.confirmed?
|
||||
end
|
||||
|
|
|
@ -129,6 +129,27 @@
|
|||
- else
|
||||
= t('admin.accounts.confirming')
|
||||
%td= table_link_to 'refresh', t('admin.accounts.resend_confirmation.send'), resend_admin_account_confirmation_path(@account.id), method: :post if can?(:confirm, @account.user)
|
||||
%tr
|
||||
%th{ rowspan: can?(:reset_password, @account.user) ? 2 : 1 }= t('admin.accounts.security')
|
||||
%td{ rowspan: can?(:reset_password, @account.user) ? 2 : 1 }
|
||||
- if @account.user&.two_factor_enabled?
|
||||
= t 'admin.accounts.security_measures.password_and_2fa'
|
||||
- elsif @account.user&.skip_sign_in_token?
|
||||
= t 'admin.accounts.security_measures.only_password'
|
||||
- else
|
||||
= t 'admin.accounts.security_measures.password_and_sign_in_token'
|
||||
%td
|
||||
- if @account.user&.two_factor_enabled?
|
||||
= table_link_to 'unlock', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete if can?(:disable_2fa, @account.user)
|
||||
- elsif @account.user&.skip_sign_in_token?
|
||||
= table_link_to 'lock', t('admin.accounts.enable_sign_in_token_auth'), admin_user_sign_in_token_authentication_path(@account.user.id), method: :post if can?(:enable_sign_in_token_auth, @account.user)
|
||||
- else
|
||||
= table_link_to 'unlock', t('admin.accounts.disable_sign_in_token_auth'), admin_user_sign_in_token_authentication_path(@account.user.id), method: :delete if can?(:disable_sign_in_token_auth, @account.user)
|
||||
|
||||
- if can?(:reset_password, @account.user)
|
||||
%tr
|
||||
%td
|
||||
= table_link_to 'key', t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, data: { confirm: t('admin.accounts.are_you_sure') }
|
||||
|
||||
%tr
|
||||
%th= t('simple_form.labels.defaults.locale')
|
||||
|
@ -221,9 +242,6 @@
|
|||
|
||||
%div
|
||||
- if @account.local?
|
||||
= link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button' if can?(:reset_password, @account.user)
|
||||
- if @account.user&.otp_required_for_login?
|
||||
= link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button' if can?(:disable_2fa, @account.user)
|
||||
- if !@account.memorial? && @account.user_approved?
|
||||
= link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, @account)
|
||||
- else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue