Merge upstream tag 'v3.5.2'

This commit is contained in:
Mike Barnes 2022-05-23 19:28:18 +10:00
commit d161ca885c
2205 changed files with 91260 additions and 41616 deletions

View file

@ -37,8 +37,11 @@ RSpec.describe Auth::SessionsController, type: :controller do
end
context 'with a suspended user' do
before do
user.account.suspend!
end
it 'redirects to home after sign out' do
Fabricate(:account, user: user, suspended: true)
sign_in(user, scope: :user)
delete :destroy
@ -69,7 +72,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
end
it 'shows a login error' do
expect(flash[:alert]).to match I18n.t('devise.failure.invalid', authentication_keys: 'Email')
expect(flash[:alert]).to match I18n.t('devise.failure.invalid', authentication_keys: I18n.t('activerecord.attributes.user.email'))
end
it "doesn't log the user in" do
@ -78,8 +81,8 @@ RSpec.describe Auth::SessionsController, type: :controller do
end
context 'using a valid email and existing user' do
let(:user) do
account = Fabricate.build(:account, username: 'pam_user1')
let!(:user) do
account = Fabricate.build(:account, username: 'pam_user1', user: nil)
account.save!(validate: false)
user = Fabricate(:user, email: 'pam@example.com', password: nil, account: account, external: true)
user
@ -136,7 +139,7 @@ RSpec.describe Auth::SessionsController, type: :controller do
end
it 'shows a login error' do
expect(flash[:alert]).to match I18n.t('devise.failure.invalid', authentication_keys: 'Email')
expect(flash[:alert]).to match I18n.t('devise.failure.invalid', authentication_keys: I18n.t('activerecord.attributes.user.email'))
end
it "doesn't log the user in" do
@ -222,22 +225,6 @@ RSpec.describe Auth::SessionsController, type: :controller do
end
end
context 'using email and password after an unfinished log-in attempt with a sign-in token challenge' do
let!(:other_user) do
Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: false, current_sign_in_at: 1.month.ago)
end
before do
post :create, params: { user: { email: other_user.email, password: other_user.password } }
post :create, params: { user: { email: user.email, password: user.password } }
end
it 'renders two factor authentication page' do
expect(controller).to render_template("two_factor")
expect(controller).to render_template(partial: "_otp_authentication_form")
end
end
context 'using upcase email and password' do
before do
post :create, params: { user: { email: user.email.upcase, password: user.password } }
@ -398,124 +385,33 @@ RSpec.describe Auth::SessionsController, type: :controller do
end
end
end
end
context 'when 2FA is disabled and IP is unfamiliar' do
let!(:user) { Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', current_sign_in_at: 3.weeks.ago, current_sign_in_ip: '0.0.0.0') }
describe 'GET #webauthn_options' do
context 'with WebAuthn and OTP enabled as second factor' do
let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http' }://#{Rails.configuration.x.web_domain}" }
let(:fake_client) { WebAuthn::FakeClient.new(domain) }
let!(:user) do
Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32))
end
before do
request.remote_ip = '10.10.10.10'
request.user_agent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0'
allow(UserMailer).to receive(:sign_in_token).and_return(double('email', deliver_later!: nil))
user.update(webauthn_id: WebAuthn.generate_user_id)
public_key_credential = WebAuthn::Credential.from_create(fake_client.create)
user.webauthn_credentials.create(
nickname: 'SecurityKeyNickname',
external_id: public_key_credential.id,
public_key: public_key_credential.public_key,
sign_count: '1000'
)
post :create, params: { user: { email: user.email, password: user.password } }
end
context 'using email and password' do
before do
post :create, params: { user: { email: user.email, password: user.password } }
end
it 'renders sign in token authentication page' do
expect(controller).to render_template("sign_in_token")
end
it 'generates sign in token' do
expect(user.reload.sign_in_token).to_not be_nil
end
it 'sends sign in token e-mail' do
expect(UserMailer).to have_received(:sign_in_token)
end
end
context 'using email and password after an unfinished log-in attempt to a 2FA-protected account' do
let!(:other_user) do
Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32))
end
before do
post :create, params: { user: { email: other_user.email, password: other_user.password } }
post :create, params: { user: { email: user.email, password: user.password } }
end
it 'renders sign in token authentication page' do
expect(controller).to render_template("sign_in_token")
end
it 'generates sign in token' do
expect(user.reload.sign_in_token).to_not be_nil
end
it 'sends sign in token e-mail' do
expect(UserMailer).to have_received(:sign_in_token)
end
end
context 'using email and password after an unfinished log-in attempt with a sign-in token challenge' do
let!(:other_user) do
Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: false, current_sign_in_at: 1.month.ago)
end
before do
post :create, params: { user: { email: other_user.email, password: other_user.password } }
post :create, params: { user: { email: user.email, password: user.password } }
end
it 'renders sign in token authentication page' do
expect(controller).to render_template("sign_in_token")
end
it 'generates sign in token' do
expect(user.reload.sign_in_token).to_not be_nil
end
it 'sends sign in token e-mail' do
expect(UserMailer).to have_received(:sign_in_token).with(user, any_args)
end
end
context 'using a valid sign in token' do
before do
user.generate_sign_in_token && user.save
post :create, params: { user: { sign_in_token_attempt: user.sign_in_token } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
it 'redirects to home' do
expect(response).to redirect_to(root_path)
end
it 'logs the user in' do
expect(controller.current_user).to eq user
end
end
context 'using a valid sign in token, attempting to leverage previous half-login to bypass password auth' do
let!(:other_user) do
Fabricate(:user, email: 'z@y.com', password: 'abcdefgh', otp_required_for_login: false, current_sign_in_at: 1.month.ago)
end
before do
user.generate_sign_in_token && user.save
post :create, params: { user: { email: other_user.email, password: other_user.password } }
post :create, params: { user: { email: user.email, sign_in_token_attempt: user.sign_in_token } }, session: { attempt_user_updated_at: user.updated_at.to_s }
end
it "doesn't log the user in" do
expect(controller.current_user).to be_nil
end
end
context 'using an invalid sign in token' do
before do
post :create, params: { user: { sign_in_token_attempt: 'wrongotp' } }, session: { attempt_user_id: user.id, attempt_user_updated_at: user.updated_at.to_s }
end
it 'shows a login error' do
expect(flash[:alert]).to match I18n.t('users.invalid_sign_in_token')
end
it "doesn't log the user in" do
expect(controller.current_user).to be_nil
end
it 'returns http success' do
get :webauthn_options
expect(response).to have_http_status :ok
end
end
end