From d174d12c831989bf1d5d3ca54d4f26d28c2c8925 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 21 Jun 2021 17:07:30 +0200 Subject: Add authentication history (#16408) --- .../auth/omniauth_callbacks_controller.rb | 9 +++++ app/controllers/auth/sessions_controller.rb | 44 ++++++++++++++++++---- .../sign_in_token_authentication_concern.rb | 5 +-- .../concerns/two_factor_authentication_concern.rb | 10 ++--- .../settings/login_activities_controller.rb | 7 ++++ 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 app/controllers/settings/login_activities_controller.rb (limited to 'app/controllers') diff --git a/app/controllers/auth/omniauth_callbacks_controller.rb b/app/controllers/auth/omniauth_callbacks_controller.rb index 682c77016..7925e23cb 100644 --- a/app/controllers/auth/omniauth_callbacks_controller.rb +++ b/app/controllers/auth/omniauth_callbacks_controller.rb @@ -10,6 +10,15 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController @user = User.find_for_oauth(request.env['omniauth.auth'], current_user) if @user.persisted? + LoginActivity.create( + user: user, + success: true, + authentication_method: :omniauth, + provider: provider, + ip: request.remote_ip, + user_agent: request.user_agent + ) + sign_in_and_redirect @user, event: :authentication set_flash_message(:notice, :success, kind: provider_id.capitalize) if is_navigational_format? else diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index 13d158c67..9c73b39e2 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -25,9 +25,11 @@ class Auth::SessionsController < Devise::SessionsController def create super do |resource| - resource.update_sign_in!(request, new_sign_in: true) - remember_me(resource) - flash.delete(:notice) + # We only need to call this if this hasn't already been + # called from one of the two-factor or sign-in token + # authentication methods + + on_authentication_success(resource, :password) unless @on_authentication_success_called end end @@ -42,10 +44,8 @@ class Auth::SessionsController < Devise::SessionsController def webauthn_options user = find_user - if user.webauthn_enabled? - options_for_get = WebAuthn::Credential.options_for_get( - allow: user.webauthn_credentials.pluck(:external_id) - ) + if user&.webauthn_enabled? + options_for_get = WebAuthn::Credential.options_for_get(allow: user.webauthn_credentials.pluck(:external_id)) session[:webauthn_challenge] = options_for_get.challenge @@ -136,4 +136,34 @@ class Auth::SessionsController < Devise::SessionsController session.delete(:attempt_user_id) session.delete(:attempt_user_updated_at) end + + def on_authentication_success(user, security_measure) + @on_authentication_success_called = true + + clear_attempt_from_session + + user.update_sign_in!(request, new_sign_in: true) + remember_me(user) + sign_in(user) + flash.delete(:notice) + + LoginActivity.create( + user: user, + success: true, + authentication_method: security_measure, + ip: request.remote_ip, + user_agent: request.user_agent + ) + end + + def on_authentication_failure(user, security_measure, failure_reason) + LoginActivity.create( + user: user, + success: false, + authentication_method: security_measure, + failure_reason: failure_reason, + ip: request.remote_ip, + user_agent: request.user_agent + ) + end end diff --git a/app/controllers/concerns/sign_in_token_authentication_concern.rb b/app/controllers/concerns/sign_in_token_authentication_concern.rb index 3c95a4afd..cbee84569 100644 --- a/app/controllers/concerns/sign_in_token_authentication_concern.rb +++ b/app/controllers/concerns/sign_in_token_authentication_concern.rb @@ -29,10 +29,9 @@ module SignInTokenAuthenticationConcern def authenticate_with_sign_in_token_attempt(user) if valid_sign_in_token_attempt?(user) - clear_attempt_from_session - remember_me(user) - sign_in(user) + on_authentication_success(user, :sign_in_token) else + on_authentication_failure(user, :sign_in_token, :invalid_sign_in_token) flash.now[:alert] = I18n.t('users.invalid_sign_in_token') prompt_for_sign_in_token(user) end diff --git a/app/controllers/concerns/two_factor_authentication_concern.rb b/app/controllers/concerns/two_factor_authentication_concern.rb index 4d4ccf49c..909ab7717 100644 --- a/app/controllers/concerns/two_factor_authentication_concern.rb +++ b/app/controllers/concerns/two_factor_authentication_concern.rb @@ -52,21 +52,19 @@ module TwoFactorAuthenticationConcern webauthn_credential = WebAuthn::Credential.from_get(user_params[:credential]) if valid_webauthn_credential?(user, webauthn_credential) - clear_attempt_from_session - remember_me(user) - sign_in(user) + on_authentication_success(user, :webauthn) render json: { redirect_path: root_path }, status: :ok else + on_authentication_failure(user, :webauthn, :invalid_credential) render json: { error: t('webauthn_credentials.invalid_credential') }, status: :unprocessable_entity end end def authenticate_with_two_factor_via_otp(user) if valid_otp_attempt?(user) - clear_attempt_from_session - remember_me(user) - sign_in(user) + on_authentication_success(user, :otp) else + on_authentication_failure(user, :otp, :invalid_otp_token) flash.now[:alert] = I18n.t('users.invalid_otp_token') prompt_for_two_factor(user) end diff --git a/app/controllers/settings/login_activities_controller.rb b/app/controllers/settings/login_activities_controller.rb new file mode 100644 index 000000000..57fa6aef0 --- /dev/null +++ b/app/controllers/settings/login_activities_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Settings::LoginActivitiesController < Settings::BaseController + def index + @login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page]) + end +end -- cgit From 63b807cffcba0579efdf2f4ed4a2deb93af4850b Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 21 Jun 2021 20:14:47 +0200 Subject: Fix serialization of followers/following counts when user hides their network (#16418) * Add tests * Fix serialization of followers/following counts when user hides their network Fixes #16382 Signed-off-by: Claire --- app/controllers/follower_accounts_controller.rb | 2 +- app/controllers/following_accounts_controller.rb | 2 +- spec/controllers/follower_accounts_controller_spec.rb | 19 ++++++++++++++++++- .../controllers/following_accounts_controller_spec.rb | 19 ++++++++++++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) (limited to 'app/controllers') diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index ff4df2adf..b3589a39f 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -85,7 +85,7 @@ class FollowerAccountsController < ApplicationController if page_requested? || !@account.user_hides_network? # Return all fields else - %i(id type totalItems) + %i(id type total_items) end end end diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 6bb95c454..8a72dc475 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -85,7 +85,7 @@ class FollowingAccountsController < ApplicationController if page_requested? || !@account.user_hides_network? # Return all fields else - %i(id type totalItems) + %i(id type total_items) end end end diff --git a/spec/controllers/follower_accounts_controller_spec.rb b/spec/controllers/follower_accounts_controller_spec.rb index f6d55f693..006274169 100644 --- a/spec/controllers/follower_accounts_controller_spec.rb +++ b/spec/controllers/follower_accounts_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe FollowerAccountsController do render_views - let(:alice) { Fabricate(:account, username: 'alice') } + let(:alice) { Fabricate(:user).account } let(:follower0) { Fabricate(:account) } let(:follower1) { Fabricate(:account) } @@ -101,6 +101,23 @@ describe FollowerAccountsController do expect(body['partOf']).to be_blank end + context 'when account hides their network' do + before do + alice.user.settings.hide_network = true + end + + it 'returns followers count' do + expect(body['totalItems']).to eq 2 + end + + it 'does not return items' do + expect(body['items']).to be_blank + expect(body['orderedItems']).to be_blank + expect(body['first']).to be_blank + expect(body['last']).to be_blank + end + end + context 'when account is permanently suspended' do before do alice.suspend! diff --git a/spec/controllers/following_accounts_controller_spec.rb b/spec/controllers/following_accounts_controller_spec.rb index 0fc0967a6..7ec0e3d06 100644 --- a/spec/controllers/following_accounts_controller_spec.rb +++ b/spec/controllers/following_accounts_controller_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe FollowingAccountsController do render_views - let(:alice) { Fabricate(:account, username: 'alice') } + let(:alice) { Fabricate(:user).account } let(:followee0) { Fabricate(:account) } let(:followee1) { Fabricate(:account) } @@ -101,6 +101,23 @@ describe FollowingAccountsController do expect(body['partOf']).to be_blank end + context 'when account hides their network' do + before do + alice.user.settings.hide_network = true + end + + it 'returns followers count' do + expect(body['totalItems']).to eq 2 + end + + it 'does not return items' do + expect(body['items']).to be_blank + expect(body['orderedItems']).to be_blank + expect(body['first']).to be_blank + expect(body['last']).to be_blank + end + end + context 'when account is permanently suspended' do before do alice.suspend! -- cgit From 979059fbc93664b38b720b369b31beaa89457879 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 23 Jun 2021 12:21:40 +0200 Subject: Fix login date not showing up in login history by using “public” pack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/settings/login_activities_controller.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'app/controllers') diff --git a/app/controllers/settings/login_activities_controller.rb b/app/controllers/settings/login_activities_controller.rb index 57fa6aef0..ee77524b1 100644 --- a/app/controllers/settings/login_activities_controller.rb +++ b/app/controllers/settings/login_activities_controller.rb @@ -4,4 +4,10 @@ class Settings::LoginActivitiesController < Settings::BaseController def index @login_activities = LoginActivity.where(user: current_user).order(id: :desc).page(params[:page]) end + + private + + def set_pack + use_pack 'settings' + end end -- cgit