diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2019-07-22 10:48:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-22 10:48:50 +0200 |
commit | 964ae8eee593687f922c873fa7b378bb6e3e39bb (patch) | |
tree | eb67d6521d6cecc6679e75800c4d170ea5883fa0 /app/controllers | |
parent | fea903f574cd59e6938c775427727337d7f929c3 (diff) |
Change unconfirmed user login behaviour (#11375)
Allow access to account settings, 2FA, authorized applications, and account deletions to unconfirmed and pending users, as well as users who had their accounts disabled. Suspended users cannot update their e-mail or password or delete their account. Display account status on account settings page, for example, when an account is frozen, limited, unconfirmed or pending review. After sign up, login users straight away and show a simple page that tells them the status of their account with links to account settings and logout, to reduce onboarding friction and allow users to correct wrongly typed e-mail addresses. Move the final sign-up step of SSO integrations to be the same as above to reduce code duplication.
Diffstat (limited to 'app/controllers')
14 files changed, 93 insertions, 28 deletions
diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb index 33bac9bbc..31cf17710 100644 --- a/app/controllers/about_controller.rb +++ b/app/controllers/about_controller.rb @@ -7,7 +7,7 @@ class AboutController < ApplicationController before_action :set_instance_presenter before_action :set_expires_in - skip_before_action :check_user_permissions, only: [:more, :terms] + skip_before_action :require_functional!, only: [:more, :terms] def show; end diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index eca558f42..6f33a1ea9 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -7,7 +7,7 @@ class Api::BaseController < ApplicationController include RateLimitHeaders skip_before_action :store_current_location - skip_before_action :check_user_permissions + skip_before_action :require_functional! before_action :set_cache_headers diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b8a1faf77..41ce1a0ca 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -25,7 +25,7 @@ class ApplicationController < ActionController::Base rescue_from Mastodon::NotPermittedError, with: :forbidden before_action :store_current_location, except: :raise_not_found, unless: :devise_controller? - before_action :check_user_permissions, if: :user_signed_in? + before_action :require_functional!, if: :user_signed_in? def raise_not_found raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}" @@ -57,8 +57,8 @@ class ApplicationController < ActionController::Base forbidden unless current_user&.staff? end - def check_user_permissions - forbidden if current_user.disabled? || current_user.account.suspended? + def require_functional! + redirect_to edit_user_registration_path unless current_user.functional? end def after_sign_out_path_for(_resource_or_scope) diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index c28c7471c..0d7c6e7c2 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -4,34 +4,15 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController layout 'auth' before_action :set_body_classes - before_action :set_user, only: [:finish_signup] - def finish_signup - return unless request.patch? && params[:user] - - if @user.update(user_params) - @user.skip_reconfirmation! - bypass_sign_in(@user) - redirect_to root_path, notice: I18n.t('devise.confirmations.send_instructions') - else - @show_errors = true - end - end + skip_before_action :require_functional! private - def set_user - @user = current_user - end - def set_body_classes @body_classes = 'lighter' end - def user_params - params.require(:user).permit(:email) - end - def after_confirmation_path_for(_resource_name, user) if user.created_by_application && truthy_param?(:redirect_to_app) user.created_by_application.redirect_uri diff --git a/app/controllers/auth/omniauth_callbacks_controller.rb b/app/controllers/auth/omniauth_callbacks_controller.rb index bbf63bed3..682c77016 100644 --- a/app/controllers/auth/omniauth_callbacks_controller.rb +++ b/app/controllers/auth/omniauth_callbacks_controller.rb @@ -27,7 +27,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController if resource.email_verified? root_path else - finish_signup_path + auth_setup_path(missing_email: '1') end end end diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 83797cf1f..019caf9c1 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -9,6 +9,9 @@ class Auth::RegistrationsController < Devise::RegistrationsController before_action :set_sessions, only: [:edit, :update] before_action :set_instance_presenter, only: [:new, :create, :update] before_action :set_body_classes, only: [:new, :create, :edit, :update] + before_action :require_not_suspended!, only: [:update] + + skip_before_action :require_functional!, only: [:edit, :update] def new super(&:build_invite_request) @@ -43,7 +46,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def after_sign_up_path_for(_resource) - new_user_session_path + auth_setup_path end def after_sign_in_path_for(_resource) @@ -102,4 +105,8 @@ class Auth::RegistrationsController < Devise::RegistrationsController def set_sessions @sessions = current_user.session_activations end + + def require_not_suspended! + forbidden if current_account.suspended? + end end diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index fb8615c31..7e6dbf19e 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -6,8 +6,10 @@ class Auth::SessionsController < Devise::SessionsController layout 'auth' skip_before_action :require_no_authentication, only: [:create] - skip_before_action :check_user_permissions, only: [:destroy] + skip_before_action :require_functional! + prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] + before_action :set_instance_presenter, only: [:new] before_action :set_body_classes diff --git a/app/controllers/auth/setup_controller.rb b/app/controllers/auth/setup_controller.rb new file mode 100644 index 000000000..46c5f2958 --- /dev/null +++ b/app/controllers/auth/setup_controller.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +class Auth::SetupController < ApplicationController + layout 'auth' + + before_action :authenticate_user! + before_action :require_unconfirmed_or_pending! + before_action :set_body_classes + before_action :set_user + + skip_before_action :require_functional! + + def show + flash.now[:notice] = begin + if @user.pending? + I18n.t('devise.registrations.signed_up_but_pending') + else + I18n.t('devise.registrations.signed_up_but_unconfirmed') + end + end + end + + def update + # This allows updating the e-mail without entering a password as is required + # on the account settings page; however, we only allow this for accounts + # that were not confirmed yet + + if @user.update(user_params) + redirect_to auth_setup_path, notice: I18n.t('devise.confirmations.send_instructions') + else + render :show + end + end + + helper_method :missing_email? + + private + + def require_unconfirmed_or_pending! + redirect_to root_path if current_user.confirmed? && current_user.approved? + end + + def set_user + @user = current_user + end + + def set_body_classes + @body_classes = 'lighter' + end + + def user_params + params.require(:user).permit(:email) + end + + def missing_email? + truthy_param?(:missing_email) + end +end diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb index f3d235366..fb8389034 100644 --- a/app/controllers/oauth/authorized_applications_controller.rb +++ b/app/controllers/oauth/authorized_applications_controller.rb @@ -7,6 +7,8 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio before_action :authenticate_resource_owner! before_action :set_body_classes + skip_before_action :require_functional! + include Localized def destroy diff --git a/app/controllers/settings/deletes_controller.rb b/app/controllers/settings/deletes_controller.rb index dd19aadf6..97fe4d328 100644 --- a/app/controllers/settings/deletes_controller.rb +++ b/app/controllers/settings/deletes_controller.rb @@ -5,6 +5,9 @@ class Settings::DeletesController < Settings::BaseController before_action :check_enabled_deletion before_action :authenticate_user! + before_action :require_not_suspended! + + skip_before_action :require_functional! def show @confirmation = Form::DeleteConfirmation.new @@ -29,4 +32,8 @@ class Settings::DeletesController < Settings::BaseController def delete_params params.require(:form_delete_confirmation).permit(:password) end + + def require_not_suspended! + forbidden if current_account.suspended? + end end diff --git a/app/controllers/settings/sessions_controller.rb b/app/controllers/settings/sessions_controller.rb index 84ebb21f2..df5ace803 100644 --- a/app/controllers/settings/sessions_controller.rb +++ b/app/controllers/settings/sessions_controller.rb @@ -4,6 +4,8 @@ class Settings::SessionsController < Settings::BaseController before_action :authenticate_user! before_action :set_session, only: :destroy + skip_before_action :require_functional! + def destroy @session.destroy! flash[:notice] = I18n.t('sessions.revoke_success') diff --git a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb index 02652a36c..3145e092d 100644 --- a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb +++ b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb @@ -8,6 +8,8 @@ module Settings before_action :authenticate_user! before_action :ensure_otp_secret + skip_before_action :require_functional! + def new prepare_two_factor_form end diff --git a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb index 874bf532b..09a759860 100644 --- a/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb +++ b/app/controllers/settings/two_factor_authentication/recovery_codes_controller.rb @@ -7,6 +7,8 @@ module Settings before_action :authenticate_user! + skip_before_action :require_functional! + def create @recovery_codes = current_user.generate_otp_backup_codes! current_user.save! diff --git a/app/controllers/settings/two_factor_authentications_controller.rb b/app/controllers/settings/two_factor_authentications_controller.rb index e12c43074..6904076e4 100644 --- a/app/controllers/settings/two_factor_authentications_controller.rb +++ b/app/controllers/settings/two_factor_authentications_controller.rb @@ -7,6 +7,8 @@ module Settings before_action :authenticate_user! before_action :verify_otp_required, only: [:create] + skip_before_action :require_functional! + def show @confirmation = Form::TwoFactorConfirmation.new end |