Merge upstream tag 'v3.5.2'
This commit is contained in:
commit
d161ca885c
2205 changed files with 91260 additions and 41616 deletions
|
|
@ -32,6 +32,52 @@ describe Auth::ConfirmationsController, type: :controller do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when user is unconfirmed and unapproved' do
|
||||
let!(:user) { Fabricate(:user, confirmation_token: 'foobar', confirmed_at: nil, approved: false) }
|
||||
|
||||
before do
|
||||
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||
@request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
get :show, params: { confirmation_token: 'foobar' }
|
||||
end
|
||||
|
||||
it 'redirects to login' do
|
||||
expect(response).to redirect_to(new_user_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is already confirmed' do
|
||||
let!(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||
@request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
sign_in(user, scope: :user)
|
||||
get :show, params: { confirmation_token: 'foobar' }
|
||||
end
|
||||
|
||||
it 'redirects to root path' do
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is already confirmed but unapproved' do
|
||||
let!(:user) { Fabricate(:user, approved: false) }
|
||||
|
||||
before do
|
||||
allow(BootstrapTimelineWorker).to receive(:perform_async)
|
||||
@request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
user.approved = false
|
||||
user.save!
|
||||
sign_in(user, scope: :user)
|
||||
get :show, params: { confirmation_token: 'foobar' }
|
||||
end
|
||||
|
||||
it 'redirects to settings' do
|
||||
expect(response).to redirect_to(edit_user_registration_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is updating email' do
|
||||
let!(:user) { Fabricate(:user, confirmation_token: 'foobar', unconfirmed_email: 'new-email@example.com') }
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
|
|||
end
|
||||
|
||||
it 'does nothing if user already exists' do
|
||||
Fabricate(:user, account: Fabricate(:account, username: 'test'))
|
||||
Fabricate(:account, username: 'test')
|
||||
subject
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -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