login_spec.rb 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Login', authenticated_as: false, type: :system do
  4. context 'with standard authentication' do
  5. before do
  6. visit '/'
  7. end
  8. it 'fqdn is visible on login page' do
  9. expect(page).to have_css('.login p', text: Setting.get('fqdn'))
  10. end
  11. it 'Login with wrong credentials' do
  12. within('#login') do
  13. fill_in 'username', with: 'admin@example.com'
  14. fill_in 'password', with: 'wrong'
  15. click_on('Sign in')
  16. end
  17. expect(page).to have_css('#login .alert')
  18. end
  19. end
  20. context 'with enabled two factor authentication' do
  21. let(:user) { User.find_by(login: 'admin@example.com') }
  22. before do
  23. Setting.set('two_factor_authentication_method_security_keys', true)
  24. Setting.set('two_factor_authentication_method_authenticator_app', true)
  25. end
  26. context 'with security keys method' do
  27. before do
  28. skip('Mocking of Web Authentication API is currently supported only in Chrome.') if Capybara.current_driver != :zammad_chrome
  29. stub_const('Auth::BRUTE_FORCE_SLEEP', 0)
  30. visit '/'
  31. # We can only mock the security key within the loaded app.
  32. two_factor_pref
  33. refresh
  34. within('#login') do
  35. fill_in 'username', with: 'admin@example.com'
  36. fill_in 'password', with: 'test'
  37. click_on('Sign in')
  38. end
  39. end
  40. context 'with the configured security key present' do
  41. let(:two_factor_pref) { create(:user_two_factor_preference, :mocked_security_keys, user: user, page: page) }
  42. it 'signs in with the correct security key present' do
  43. expect(page).to have_no_selector('#login')
  44. end
  45. end
  46. context 'with the incorrect security key present' do
  47. let(:two_factor_pref) { create(:user_two_factor_preference, :mocked_security_keys, user: user, page: page, wrong_key: true) }
  48. it 'shows error and retry button' do
  49. expect(page).to have_css('#login .alert')
  50. expect(page).to have_css('.js-retry')
  51. end
  52. end
  53. end
  54. context 'with authenticator app method' do
  55. let(:token) { two_factor_pref.configuration[:code] }
  56. let!(:two_factor_pref) { create(:user_two_factor_preference, :authenticator_app, user: user) }
  57. before do
  58. stub_const('Auth::BRUTE_FORCE_SLEEP', 0)
  59. visit '/'
  60. within('#login') do
  61. fill_in 'username', with: 'admin@example.com'
  62. fill_in 'password', with: 'test'
  63. click_on('Sign in')
  64. end
  65. end
  66. it 'login with correct payload' do
  67. within('#login') do
  68. fill_in 'security_code', with: token
  69. click_on('Sign in')
  70. end
  71. expect(page).to have_no_selector('#login')
  72. end
  73. it 'login with wrong payload' do
  74. within('#login') do
  75. fill_in 'security_code', with: 'asd'
  76. click_on('Sign in')
  77. end
  78. expect(page).to have_css('#login .alert')
  79. end
  80. end
  81. context 'with recovery code' do
  82. let(:token) { 'token' }
  83. let(:two_factor_pref) { create(:user_two_factor_preference, :authenticator_app, user: user) }
  84. let(:recovery_2fa) { create(:user_two_factor_preference, :recovery_codes, recovery_code: token, user: user) }
  85. before do
  86. two_factor_pref && recovery_2fa
  87. Setting.set('two_factor_authentication_recovery_codes', recovery_codes_enabled)
  88. visit '/'
  89. within('#login') do
  90. fill_in 'username', with: 'admin@example.com'
  91. fill_in 'password', with: 'test'
  92. click_on('Sign in')
  93. end
  94. end
  95. context 'when recovery code is enabled' do
  96. let(:recovery_codes_enabled) { true }
  97. before do
  98. click_on 'Try another method'
  99. click_on 'recovery codes'
  100. end
  101. it 'login with correct payload' do
  102. within('#login') do
  103. fill_in 'security_code', with: token
  104. click_on('Sign in')
  105. end
  106. expect(page).to have_no_selector('#login')
  107. end
  108. it 'login with wrong payload' do
  109. within('#login') do
  110. fill_in 'security_code', with: 'wrong token'
  111. click_on('Sign in')
  112. end
  113. expect(page).to have_css('#login .alert')
  114. end
  115. end
  116. context 'when recovery code is disabled' do
  117. let(:recovery_codes_enabled) { false }
  118. it 'recovery code link is hidden' do
  119. expect(page).to have_no_text 'Try another method'
  120. end
  121. end
  122. end
  123. end
  124. end