Merge upstream tag 'v3.5.2'
This commit is contained in:
commit
d161ca885c
2205 changed files with 91260 additions and 41616 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue