security_spec.rb 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Manage > Settings > Security', type: :system do
  4. describe 'Manage Two-Factor Authentication' do
  5. before do
  6. visit '/#settings/security'
  7. within :active_content do
  8. click 'a[href="#two_factor_auth"]'
  9. end
  10. end
  11. shared_examples 'switching a method on and off' do |method|
  12. let(:method_setting) { "two_factor_authentication_method_#{method}" }
  13. let(:method_checkbox) { "setting-#{method_setting}" }
  14. it "switches #{method} method on and off" do
  15. expect(Setting.find_by(name: method_setting).state_current['value']).to be(false)
  16. click "label[for='#{method_checkbox}']"
  17. expect(Setting.find_by(name: method_setting).state_current['value']).to be(true)
  18. click "label[for='#{method_checkbox}']"
  19. expect(Setting.find_by(name: method_setting).state_current['value']).to be(false)
  20. end
  21. end
  22. shared_examples 'configuring a user role setting' do |setting|
  23. let(:setting_name) { "two_factor_authentication_#{setting}" }
  24. it "configures a user role setting #{setting}" do
  25. click "[data-attribute-name='#{setting_name}'] .columnSelect-column--sidebar .columnSelect-option", exact_text: 'Customer'
  26. click "##{setting_name} .btn--primary"
  27. expect(Setting.find_by(name: setting_name).state_current['value']).to include(
  28. Role.find_by(name: 'Customer').id.to_s
  29. )
  30. click "[data-attribute-name='#{setting_name}'] .columnSelect-column--selected .columnSelect-option", exact_text: 'Customer'
  31. click "##{setting_name} .btn--primary"
  32. expect(Setting.find_by(name: setting_name).state_current['value']).not_to include(
  33. Role.find_by(name: 'Customer').id.to_s
  34. )
  35. end
  36. end
  37. context 'with authenticator app method' do
  38. it_behaves_like 'switching a method on and off', 'authenticator_app'
  39. end
  40. context 'with recovery codes' do
  41. let(:method_setting) { 'two_factor_authentication_recovery_codes' }
  42. it 'allows to switch recovery codes on and off' do
  43. expect(Setting.find_by(name: method_setting).state_current['value']).to be(true)
  44. within "##{method_setting}" do
  45. select 'no', from: method_setting
  46. click_on 'Submit'
  47. end
  48. expect(Setting.find_by(name: method_setting).state_current['value']).to be(false)
  49. within "##{method_setting}" do
  50. select 'yes', from: method_setting
  51. click_on 'Submit'
  52. end
  53. expect(Setting.find_by(name: method_setting).state_current['value']).to be(true)
  54. end
  55. end
  56. context 'with enforcing setup to certain user roles' do
  57. it_behaves_like 'configuring a user role setting', 'enforce_role_ids'
  58. end
  59. end
  60. describe 'configure third-party applications' do
  61. shared_examples 'for third-party applications button in login page' do |**args|
  62. context "for third-party applications button in login page #{args.empty? ? '' : args.to_s}", authenticated_as: false do
  63. let(:display_name) { args[:display_name] || app_name }
  64. before do
  65. Setting.set("#{app_setting}_credentials", { display_name: args[:display_name] }) if args[:display_name]
  66. end
  67. context 'when feature is on' do
  68. before { Setting.set(app_setting, true) }
  69. it 'has authentication button in login page' do
  70. visit 'login'
  71. expect(page).to have_button(display_name)
  72. end
  73. end
  74. context 'when feature is off' do
  75. before { Setting.set(app_setting, false) }
  76. it 'does not have authentication button in login page' do
  77. visit 'login'
  78. expect(page).to have_no_button(display_name)
  79. end
  80. end
  81. end
  82. end
  83. shared_examples 'for third-party applications settings' do
  84. context 'for third-party applications settings', authenticated_as: true do
  85. let(:app_checkbox) { "setting-#{app_setting}" }
  86. context 'when app is turned on in setting page' do
  87. before do
  88. Setting.set(app_setting, false)
  89. visit '/#settings/security'
  90. within :active_content do
  91. click 'a[href="#third_party_auth"]'
  92. end
  93. check app_checkbox, allow_label_click: true
  94. await_empty_ajax_queue
  95. end
  96. it 'sets settings to be true' do
  97. expect(Setting.get(app_setting)).to be_truthy
  98. end
  99. end
  100. context 'when app is turned off in setting page' do
  101. before do
  102. Setting.set(app_setting, true)
  103. visit '/#settings/security'
  104. within :active_content do
  105. click 'a[href="#third_party_auth"]'
  106. end
  107. uncheck app_checkbox, allow_label_click: true
  108. await_empty_ajax_queue
  109. end
  110. it 'sets settings to be false' do
  111. expect(Setting.get(app_setting)).to be_falsey
  112. end
  113. end
  114. end
  115. end
  116. shared_examples 'Display callback urls for third-party applications #3622' do
  117. def callback_url
  118. page.evaluate_script("$('[data-name=#{app_setting}]').closest('.page-header').parent().find('[data-attribute-name=callback_url] input').val()")
  119. end
  120. context 'Display callback urls for third-party applications #3622', authenticated_as: true do
  121. before do
  122. visit '/#settings/security'
  123. within :active_content do
  124. click 'a[href="#third_party_auth"]'
  125. end
  126. end
  127. it 'does have a filled callback url' do
  128. expect(callback_url).to be_present
  129. end
  130. end
  131. end
  132. describe 'Authentication via Facebook' do
  133. let(:app_name) { 'Facebook' }
  134. let(:app_setting) { 'auth_facebook' }
  135. include_examples 'for third-party applications button in login page'
  136. include_examples 'for third-party applications settings'
  137. include_examples 'Display callback urls for third-party applications #3622'
  138. end
  139. describe 'Authentication via Github' do
  140. let(:app_name) { 'GitHub' }
  141. let(:app_setting) { 'auth_github' }
  142. include_examples 'for third-party applications button in login page'
  143. include_examples 'for third-party applications settings'
  144. include_examples 'Display callback urls for third-party applications #3622'
  145. end
  146. describe 'Authentication via GitLab' do
  147. let(:app_name) { 'GitLab' }
  148. let(:app_setting) { 'auth_gitlab' }
  149. include_examples 'for third-party applications button in login page'
  150. include_examples 'for third-party applications settings'
  151. include_examples 'Display callback urls for third-party applications #3622'
  152. end
  153. describe 'Authentication via Google' do
  154. let(:app_name) { 'Google' }
  155. let(:app_setting) { 'auth_google_oauth2' }
  156. include_examples 'for third-party applications button in login page'
  157. include_examples 'for third-party applications settings'
  158. include_examples 'Display callback urls for third-party applications #3622'
  159. end
  160. describe 'Authentication via LinkedIn' do
  161. let(:app_name) { 'LinkedIn' }
  162. let(:app_setting) { 'auth_linkedin' }
  163. include_examples 'for third-party applications button in login page'
  164. include_examples 'for third-party applications settings'
  165. include_examples 'Display callback urls for third-party applications #3622'
  166. end
  167. describe 'Authentication via Microsoft' do
  168. let(:app_name) { 'Microsoft' }
  169. let(:app_setting) { 'auth_microsoft_office365' }
  170. include_examples 'for third-party applications button in login page'
  171. include_examples 'for third-party applications settings'
  172. include_examples 'Display callback urls for third-party applications #3622'
  173. end
  174. describe 'Authentication via SAML' do
  175. let(:app_name) { 'SAML' }
  176. let(:app_setting) { 'auth_saml' }
  177. include_examples 'for third-party applications button in login page'
  178. include_examples 'for third-party applications button in login page', display_name: 'Security Assertion Markup Language'
  179. include_examples 'for third-party applications settings'
  180. include_examples 'Display callback urls for third-party applications #3622'
  181. end
  182. describe 'Authentication via SSO' do
  183. let(:app_name) { 'SSO' }
  184. let(:app_setting) { 'auth_sso' }
  185. include_examples 'for third-party applications button in login page'
  186. include_examples 'for third-party applications settings'
  187. end
  188. describe 'Authentication via Twitter' do
  189. let(:app_name) { 'Twitter' }
  190. let(:app_setting) { 'auth_twitter' }
  191. include_examples 'for third-party applications button in login page'
  192. include_examples 'for third-party applications settings'
  193. include_examples 'Display callback urls for third-party applications #3622'
  194. end
  195. describe 'Authentication via Weibo' do
  196. let(:app_name) { 'Weibo' }
  197. let(:app_setting) { 'auth_weibo' }
  198. include_examples 'for third-party applications button in login page'
  199. include_examples 'for third-party applications settings'
  200. include_examples 'Display callback urls for third-party applications #3622'
  201. end
  202. end
  203. end