Commit dedeb7cf authored by Peter Hegman's avatar Peter Hegman Committed by Enrique Alcántara

Convert SAML settings fields from toggles to checkboxes

Toggles should not be used for these kind of controls. Also refactor
to using `~/dirty_submit/dirty_submit_factory`
parent ba710a0d
......@@ -82,10 +82,10 @@ After you set up your identity provider to work with GitLab, you must configure
1. Find the SSO URL from your identity provider and enter it the **Identity provider single sign-on URL** field.
1. Find and enter the fingerprint for the SAML token signing certificate in the **Certificate** field.
1. Select the access level to be applied to newly added users in the **Default membership role** field. The default access level is 'Guest'.
1. Select the **Enable SAML authentication for this group** toggle switch.
1. Select the **Enable SAML authentication for this group** checkbox.
1. Select the **Save changes** button.
![Group SAML Settings for GitLab.com](img/group_saml_settings_v13_3.png)
![Group SAML Settings for GitLab.com](img/group_saml_settings_v13_12.png)
NOTE:
Please note that the certificate [fingerprint algorithm](../../../integration/saml.md#notes-on-configuring-your-identity-provider) must be in SHA1. When configuring the identity provider, use a secure signature algorithm.
......
export default class DirtyFormChecker {
constructor(formSelector, onChange) {
this.form = document.querySelector(formSelector);
this.onChange = onChange;
this.isDirty = false;
this.editableInputs = Array.from(this.form.querySelectorAll('input[name]')).filter(
(el) =>
(el.type !== 'submit' && el.type !== 'hidden') ||
el.classList.contains('js-project-feature-toggle-input'),
);
this.startingStates = {};
this.editableInputs.forEach((input) => {
this.startingStates[input.name] = input.value;
});
}
init() {
this.form.addEventListener('input', (event) => {
if (event.target.matches('input[name]')) {
this.recalculate();
}
});
}
recalculate() {
const wasDirty = this.isDirty;
this.isDirty = this.editableInputs.some((input) => {
const currentValue = input.value;
const startValue = this.startingStates[input.name];
return currentValue !== startValue;
});
if (this.isDirty !== wasDirty) {
this.onChange();
}
}
}
import $ from 'jquery';
import { parseBoolean } from '~/lib/utils/common_utils';
import dirtySubmitFactory from '~/dirty_submit/dirty_submit_factory';
import { __ } from '~/locale';
import setupToggleButtons from '~/toggle_buttons';
import { fixTitle } from '~/tooltips';
import DirtyFormChecker from './dirty_form_checker';
const CALLOUT_SELECTOR = '.js-callout';
const HELPER_SELECTOR = '.js-helper-text';
const TOGGLE_SELECTOR = '.js-project-feature-toggle';
function getHelperText(el) {
return el.parentNode.querySelector(HELPER_SELECTOR);
}
function getCallout(el) {
return el.parentNode.querySelector(CALLOUT_SELECTOR);
return el.closest('.form-group').querySelector(CALLOUT_SELECTOR);
}
function getToggle(el) {
return el.querySelector(TOGGLE_SELECTOR);
function toggleElementVisibility(el, show) {
if (show) {
el.classList.remove('gl-display-none');
} else {
el.classList.add('gl-display-none');
}
}
export default class SamlSettingsForm {
......@@ -27,47 +28,50 @@ export default class SamlSettingsForm {
this.settings = [
{
name: 'group-saml',
el: this.form.querySelector('.js-group-saml-enabled-toggle-area'),
el: this.form.querySelector('.js-group-saml-enabled-input'),
},
{
name: 'enforced-sso',
el: this.form.querySelector('.js-group-saml-enforced-sso-toggle-area'),
el: this.form.querySelector('.js-group-saml-enforced-sso-input'),
dependsOn: 'group-saml',
},
{
name: 'enforced-group-managed-accounts',
el: this.form.querySelector('.js-group-saml-enforced-group-managed-accounts-toggle-area'),
el: this.form.querySelector('.js-group-saml-enforced-group-managed-accounts-input'),
dependsOn: 'enforced-sso',
},
{
name: 'enforced-git-activity-check',
el: this.form.querySelector('.js-group-saml-enforced-git-check-toggle-area'),
el: this.form.querySelector('.js-group-saml-enforced-git-check-input'),
dependsOn: 'enforced-sso',
},
{
name: 'prohibited-outer-forks',
el: this.form.querySelector('.js-group-saml-prohibited-outer-forks-toggle-area'),
el: this.form.querySelector('.js-group-saml-prohibited-outer-forks-input'),
dependsOn: 'enforced-group-managed-accounts',
},
]
.filter((s) => s.el)
.map((setting) => ({
...setting,
toggle: getToggle(setting.el),
helperText: getHelperText(setting.el),
callout: getCallout(setting.el),
input: setting.el.querySelector('input'),
}));
this.testButtonTooltipWrapper = this.form.querySelector('#js-saml-test-button');
this.testButton = this.testButtonTooltipWrapper.querySelector('a');
this.dirtyFormChecker = new DirtyFormChecker(formSelector, () => this.updateView());
this.dirtyFormChecker = dirtySubmitFactory(this.form);
this.form.addEventListener('change', this.handleChangeEvent);
}
findSetting(name) {
return this.settings.find((s) => s.name === name);
}
settingIsDefined(el) {
return this.settings.some((setting) => setting.el.isSameNode(el));
}
getValueWithDeps(name) {
const setting = this.findSetting(name);
let currentDependsOn = setting.dependsOn;
......@@ -85,21 +89,25 @@ export default class SamlSettingsForm {
init() {
this.dirtyFormChecker.init();
setupToggleButtons(this.form);
$(this.form).on('trigger-change', () => this.onEnableToggle());
this.updateSAMLSettings();
this.updateView();
}
onEnableToggle() {
handleChangeEvent = (event) => {
if (this.settingIsDefined(event.target)) {
this.updateSAMLSettings();
this.updateView();
}
};
isFormDirty() {
return this.dirtyFormChecker.dirtyInputs.length;
}
updateSAMLSettings() {
this.settings = this.settings.map((setting) => ({
...setting,
value: parseBoolean(setting.el.querySelector('input').value),
value: setting.el.checked,
}));
}
......@@ -108,40 +116,40 @@ export default class SamlSettingsForm {
return __('Group SAML must be enabled to test');
}
if (this.dirtyFormChecker.isDirty) {
if (this.isFormDirty()) {
return __('Save changes before testing');
}
return __('Redirect to SAML provider to test configuration');
}
updateToggles() {
updateCheckboxes() {
this.settings
.filter((setting) => setting.dependsOn)
.forEach((setting) => {
const { helperText, callout, toggle } = setting;
const { helperText, callout, el } = setting;
const isRelatedToggleOn = this.getValueWithDeps(setting.dependsOn);
if (helperText) {
helperText.style.display = isRelatedToggleOn ? 'none' : 'block';
toggleElementVisibility(helperText, !isRelatedToggleOn);
}
toggle.classList.toggle('is-disabled', !isRelatedToggleOn);
toggle.disabled = !isRelatedToggleOn;
el.disabled = !isRelatedToggleOn;
if (callout) {
callout.style.display = setting.value && isRelatedToggleOn ? 'block' : 'none';
toggleElementVisibility(callout, setting.value && isRelatedToggleOn);
}
});
}
updateView() {
if (this.getValueWithDeps('group-saml') && !this.dirtyFormChecker.isDirty) {
if (this.getValueWithDeps('group-saml') && !this.isFormDirty()) {
this.testButton.removeAttribute('disabled');
} else {
this.testButton.setAttribute('disabled', true);
}
this.updateToggles();
this.updateCheckboxes();
// Update tooltip using wrapper so it works when input disabled
this.testButtonTooltipWrapper.setAttribute('title', this.testButtonTooltip());
......
%section.saml_provider#js-saml-settings-form.gl-mt-3
= form_for [group, saml_provider], url: group_saml_providers_path do |f|
%section.saml_provider.gl-mt-5
= form_for [group, saml_provider], url: group_saml_providers_path, html: { id: 'js-saml-settings-form' } do |f|
.form-group
= form_errors(saml_provider)
%label.gl-mt-2.mb-0.js-group-saml-enabled-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: saml_provider.enabled?, label: s_("GroupSAML|Toggle SAML authentication"), class_list: "js-project-feature-toggle project-feature-toggle d-inline" do
= f.hidden_field :enabled, { class: 'js-group-saml-enabled-input js-project-feature-toggle-input'}
%span.d-inline.font-weight-normal.align-text-bottom.ml-3= s_('GroupSAML|Enable SAML authentication for this group.')
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :enabled, { class: 'custom-control-input js-group-saml-enabled-input' }
= f.label :enabled, { class: 'custom-control-label' } do
= s_('GroupSAML|Enable SAML authentication for this group')
.form-group
%label.gl-mt-2.mb-0.js-group-saml-enforced-sso-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: saml_provider.enforced_sso, disabled: !saml_provider.enabled?, label: s_("GroupSAML|Enforced SSO"), class_list: "js-project-feature-toggle js-group-saml-enforced-sso-toggle project-feature-toggle d-inline", data: { qa_selector: 'enforced_sso_toggle_button' } do
= f.hidden_field :enforced_sso, { class: 'js-group-saml-enforced-sso-input js-project-feature-toggle-input'}
%span.form-text.d-inline.font-weight-normal.align-text-bottom.ml-3= s_('GroupSAML|Enforce SSO-only authentication for web activity for this group.')
.form-text.text-muted.js-helper-text{ style: "display: #{'none' if saml_provider.enabled?} #{'block' unless saml_provider.enabled?}" }
%span
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :enforced_sso, { class: 'custom-control-input js-group-saml-enforced-sso-input', data: { qa_selector: 'enforced_sso_checkbox' } }
= f.label :enforced_sso, { class: 'custom-control-label' } do
= s_('GroupSAML|Enforce SSO-only authentication for web activity for this group')
%p.help-text.js-helper-text{ class: saml_provider.enabled? && 'gl-display-none' }
= s_('GroupSAML|Before enforcing SSO, enable SAML authentication.')
.form-group
%label.gl-mt-2.mb-0.js-group-saml-enforced-git-check-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: saml_provider.git_check_enforced, disabled: !saml_provider.enabled?, label: s_("GroupSAML|Check SSO on git activity"), class_list: "js-project-feature-toggle js-group-saml-enforced-git-check-toggle-area project-feature-toggle d-inline", data: { qa_selector: 'git_activity_check_toggle_button' } do
= f.hidden_field :git_check_enforced, { class: 'js-group-enforced-git-check-input js-project-feature-toggle-input'}
%span.form-text.d-inline.font-weight-normal.align-text-bottom.ml-3= s_('GroupSAML|Enforce SSO-access for Git in this group.')
.form-text.text-muted.js-helper-text{ style: "display: #{saml_provider.enabled? ? 'none' : 'block'}" }
%span
= s_('GroupSAML|Before enforcing SSO-access for Git, enable SSO-only authentication for web activity.')
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :git_check_enforced, { class: 'custom-control-input js-group-saml-enforced-git-check-input' }
= f.label :git_check_enforced, { class: 'custom-control-label' } do
= s_('GroupSAML|Enforce SSO-only authentication for Git activity for this group')
%p.help-text.js-helper-text{ class: saml_provider.enabled? && 'gl-display-none' }
= s_('GroupSAML|Before enforcing SSO-only authentication for Git activity, enable SSO-only authentication for web activity.')
- if Feature.enabled?(:group_managed_accounts, group)
.form-group
%label.gl-mt-2.mb-0.js-group-saml-enforced-group-managed-accounts-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: saml_provider.enforced_group_managed_accounts, disabled: !saml_provider.enforced_sso?, label: s_("GroupSAML|Enforced SSO"), class_list: "js-project-feature-toggle js-group-saml-enforced-group-managed-accounts-toggle project-feature-toggle d-inline", data: { qa_selector: 'group_managed_accounts_toggle_button' } do
= f.hidden_field :enforced_group_managed_accounts, { class: 'js-group-saml-enforced-group-managed-accounts-input js-project-feature-toggle-input'}
%span.form-text.d-inline.font-weight-normal.align-text-bottom.ml-3= s_('GroupSAML|Enforce users to have dedicated group managed accounts for this group.')
.form-text.text-muted.js-helper-text{ style: "display: #{'none' if saml_provider.enforced_sso?} #{'block' unless saml_provider.enforced_sso?}" }
%span
= s_('GroupSAML|To be able to enable group managed accounts, you first need to enable enforced SSO.')
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :enforced_group_managed_accounts, { class: 'custom-control-input js-group-saml-enforced-group-managed-accounts-input', data: { qa_selector: 'group_managed_accounts_checkbox' } }
= f.label :enforced_group_managed_accounts, { class: 'custom-control-label' } do
= s_('GroupSAML|Enforce users to have dedicated group-managed accounts for this group')
%p.help-text.js-helper-text{ class: saml_provider.enforced_sso? && 'gl-display-none' }
= s_('GroupSAML|To be able to enable group-managed accounts, you first need to enable enforced SSO.')
.form-group
%label.gl-mt-2.mb-0.js-group-saml-prohibited-outer-forks-toggle-area
= render "shared/buttons/project_feature_toggle", is_checked: saml_provider.prohibited_outer_forks, disabled: !saml_provider.enforced_group_managed_accounts?, label: s_("GroupSAML|Prohibit outer forks"), class_list: "js-project-feature-toggle js-group-saml-prohibited-outer-forks-toggle project-feature-toggle d-inline", data: { qa_selector: 'prohibited_outer_forks_toggle_button' } do
= f.hidden_field :prohibited_outer_forks, { class: 'js-group-saml-prohibited-outer-forks-input js-project-feature-toggle-input'}
%span.form-text.d-inline.font-weight-normal.align-text-bottom.ml-3= s_('GroupSAML|Prohibit outer forks for this group.')
.form-text.text-muted.js-helper-text{ style: "display: #{'none' if saml_provider.enforced_group_managed_accounts?} #{'block' unless saml_provider.enforced_group_managed_accounts?}" }
%span
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :prohibited_outer_forks, { class: 'custom-control-input js-group-saml-prohibited-outer-forks-input' }
= f.label :prohibited_outer_forks, { class: 'custom-control-label' } do
= s_('GroupSAML|Prohibit outer forks for this group')
%p.help-text.js-helper-text{ class: saml_provider.enforced_group_managed_accounts? && 'gl-display-none' }
= s_('GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts.')
.bs-callout.bs-callout-info.js-callout{ style: "display: #{'block' if saml_provider.enforced_group_managed_accounts?} #{'none' unless saml_provider.enforced_group_managed_accounts?}" }
.bs-callout.bs-callout-info.js-callout{ class: !saml_provider.enforced_group_managed_accounts? && 'gl-display-none' }
= s_('GroupSAML|With prohibit outer forks flag enabled group members will be able to fork project only inside your group.')
.well-segment.borderless.mb-3.col-12.col-lg-9.p-0
= f.label :sso_url, class: 'label-bold' do
......
---
title: Convert SAML setting toggles to checkboxes and update UI text
merge_request: 59823
author:
type: changed
......@@ -80,7 +80,7 @@ RSpec.describe 'SAML provider settings' do
it 'allows provider to be disabled', :js do
visit group_saml_providers_path(group)
find('.js-group-saml-enabled-toggle-area button').click
uncheck 'Enable SAML authentication for this group'
expect { submit }.to change { saml_provider.reload.enabled }.to false
end
......@@ -97,7 +97,7 @@ RSpec.describe 'SAML provider settings' do
it 'updates the enforced sso setting', :js do
visit group_saml_providers_path(group)
find('.js-group-saml-enforced-sso-toggle').click
check 'Enforce SSO-only authentication for web activity for this group'
expect { submit }.to change { saml_provider.reload.enforced_sso }.to(true)
end
......@@ -111,8 +111,8 @@ RSpec.describe 'SAML provider settings' do
it 'updates the enforced_group_managed_accounts flag' do
visit group_saml_providers_path(group)
find('.js-group-saml-enforced-sso-toggle').click
find('.js-group-saml-enforced-group-managed-accounts-toggle').click
check 'Enforce SSO-only authentication for web activity for this group'
check 'Enforce users to have dedicated group-managed accounts for this group'
expect { submit }.to change { saml_provider.reload.enforced_group_managed_accounts }.to(true)
end
......@@ -120,9 +120,9 @@ RSpec.describe 'SAML provider settings' do
it 'updates the prohibited_outer_forks flag' do
visit group_saml_providers_path(group)
find('.js-group-saml-enforced-sso-toggle').click
find('.js-group-saml-enforced-group-managed-accounts-toggle').click
find('.js-group-saml-prohibited-outer-forks-toggle').click
check 'Enforce SSO-only authentication for web activity for this group'
check 'Enforce users to have dedicated group-managed accounts for this group'
check 'Prohibit outer forks for this group'
expect { submit }.to change { saml_provider.reload.prohibited_outer_forks }.to(true)
end
......@@ -134,8 +134,8 @@ RSpec.describe 'SAML provider settings' do
visit group_saml_providers_path(group)
expect(page).not_to have_selector('.js-group-saml-enforced-group-managed-accounts-toggle')
expect(page).not_to have_selector('.js-group-saml-prohibited-outer-forks-toggle')
expect(page).not_to have_field('Enforce users to have dedicated group-managed accounts for this group')
expect(page).not_to have_field('Prohibit outer forks for this group')
end
end
end
......
import DirtyFormChecker from 'ee/saml_providers/dirty_form_checker';
describe('DirtyFormChecker', () => {
const FIXTURE = 'groups/saml_providers/show.html';
beforeEach(() => {
loadFixtures(FIXTURE);
});
describe('constructor', () => {
let dirtyFormChecker;
beforeEach(() => {
dirtyFormChecker = new DirtyFormChecker('#js-saml-settings-form');
});
it('finds editable inputs', () => {
const editableInputs = dirtyFormChecker.editableInputs.map((input) => input.name);
expect(editableInputs).toContain('saml_provider[sso_url]');
expect(editableInputs).not.toContain('authenticity_token');
});
it('tracks starting states for editable inputs', () => {
const enabledStartState = dirtyFormChecker.startingStates['saml_provider[enabled]'];
expect(enabledStartState).toEqual('true');
});
});
describe('recalculate', () => {
let dirtyFormChecker;
let onChangeCallback;
beforeEach(() => {
onChangeCallback = jest.fn();
dirtyFormChecker = new DirtyFormChecker('#js-saml-settings-form', onChangeCallback);
});
it('does not trigger callback when nothing changes', () => {
dirtyFormChecker.recalculate();
expect(onChangeCallback).not.toHaveBeenCalled();
});
it('triggers callback when form becomes dirty', () => {
dirtyFormChecker.startingStates['saml_provider[sso_url]'] = 'https://old.value';
dirtyFormChecker.recalculate();
expect(dirtyFormChecker.isDirty).toEqual(true);
expect(onChangeCallback).toHaveBeenCalled();
});
it('triggers callback when form returns to original state', () => {
dirtyFormChecker.isDirty = true;
dirtyFormChecker.recalculate();
expect(onChangeCallback).toHaveBeenCalled();
});
});
});
......@@ -11,9 +11,14 @@ describe('SamlSettingsForm', () => {
samlSettingsForm.init();
});
const findEnforcedGroupManagedAccountSetting = () =>
samlSettingsForm.settings.find((s) => s.name === 'enforced-group-managed-accounts');
const findProhibitForksSetting = () =>
samlSettingsForm.settings.find((s) => s.name === 'prohibited-outer-forks');
describe('updateView', () => {
it('disables Test button when form has changes', () => {
samlSettingsForm.dirtyFormChecker.isDirty = true;
samlSettingsForm.dirtyFormChecker.dirtyInputs = [findEnforcedGroupManagedAccountSetting().el];
expect(samlSettingsForm.testButton.hasAttribute('disabled')).toBe(false);
......@@ -40,35 +45,30 @@ describe('SamlSettingsForm', () => {
});
});
it('correctly disables dependent toggle', () => {
it('correctly disables dependent toggle and shows helper text', () => {
samlSettingsForm.settings.forEach((s) => {
const { input } = s;
input.value = true;
const { el } = s;
el.checked = true;
});
const findEnforcedGroupManagedAccountSetting = () =>
samlSettingsForm.settings.find((s) => s.name === 'enforced-group-managed-accounts');
const findProhibitForksSetting = () =>
samlSettingsForm.settings.find((s) => s.name === 'prohibited-outer-forks');
samlSettingsForm.updateSAMLSettings();
samlSettingsForm.updateView();
expect(findProhibitForksSetting().toggle.hasAttribute('disabled')).toBe(false);
expect(findProhibitForksSetting().toggle.classList.contains('is-disabled')).toBe(false);
expect(findProhibitForksSetting().el.hasAttribute('disabled')).toBe(false);
expect(findProhibitForksSetting().helperText.classList.contains('gl-display-none')).toBe(true);
findEnforcedGroupManagedAccountSetting().input.value = false;
findEnforcedGroupManagedAccountSetting().el.checked = false;
samlSettingsForm.updateSAMLSettings();
samlSettingsForm.updateView();
expect(findProhibitForksSetting().toggle.hasAttribute('disabled')).toBe(true);
expect(findProhibitForksSetting().toggle.classList.contains('is-disabled')).toBe(true);
expect(findProhibitForksSetting().el.hasAttribute('disabled')).toBe(true);
expect(findProhibitForksSetting().helperText.classList.contains('gl-display-none')).toBe(false);
expect(findProhibitForksSetting().value).toBe(true);
});
it('correctly disables multiple dependent toggles', () => {
samlSettingsForm.settings.forEach((s) => {
const { input } = s;
input.value = true;
const { el } = s;
el.checked = true;
});
let groupSamlSetting;
......@@ -78,16 +78,14 @@ describe('SamlSettingsForm', () => {
samlSettingsForm.updateView();
[groupSamlSetting, ...otherSettings] = samlSettingsForm.settings;
expect(samlSettingsForm.settings.every((s) => s.value)).toBe(true);
expect(samlSettingsForm.settings.some((s) => s.toggle.hasAttribute('disabled'))).toBe(false);
expect(samlSettingsForm.settings.some((s) => s.el.hasAttribute('disabled'))).toBe(false);
groupSamlSetting.input.value = false;
groupSamlSetting.el.checked = false;
samlSettingsForm.updateSAMLSettings();
samlSettingsForm.updateView();
return new Promise(window.requestAnimationFrame).then(() => {
[groupSamlSetting, ...otherSettings] = samlSettingsForm.settings;
expect(otherSettings.every((s) => s.value)).toBe(true);
expect(otherSettings.every((s) => s.toggle.hasAttribute('disabled'))).toBe(true);
});
expect(otherSettings.every((s) => s.el.hasAttribute('disabled'))).toBe(true);
});
});
......@@ -15555,15 +15555,12 @@ msgstr ""
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
msgid "GroupSAML|Before enforcing SSO-access for Git, enable SSO-only authentication for web activity."
msgid "GroupSAML|Before enforcing SSO-only authentication for Git activity, enable SSO-only authentication for web activity."
msgstr ""
msgid "GroupSAML|Certificate fingerprint"
msgstr ""
msgid "GroupSAML|Check SSO on git activity"
msgstr ""
msgid "GroupSAML|Configuration"
msgstr ""
......@@ -15576,19 +15573,16 @@ msgstr ""
msgid "GroupSAML|Default membership role"
msgstr ""
msgid "GroupSAML|Enable SAML authentication for this group."
msgstr ""
msgid "GroupSAML|Enforce SSO-access for Git in this group."
msgid "GroupSAML|Enable SAML authentication for this group"
msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group."
msgid "GroupSAML|Enforce SSO-only authentication for Git activity for this group"
msgstr ""
msgid "GroupSAML|Enforce users to have dedicated group managed accounts for this group."
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
msgstr ""
msgid "GroupSAML|Enforced SSO"
msgid "GroupSAML|Enforce users to have dedicated group-managed accounts for this group"
msgstr ""
msgid "GroupSAML|Generate a SCIM token"
......@@ -15627,10 +15621,7 @@ msgstr ""
msgid "GroupSAML|No active SAML group links"
msgstr ""
msgid "GroupSAML|Prohibit outer forks"
msgstr ""
msgid "GroupSAML|Prohibit outer forks for this group."
msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
msgid "GroupSAML|Role to assign members of this SAML group."
......@@ -15678,15 +15669,12 @@ msgstr ""
msgid "GroupSAML|This will be set as the access level of users added to the group."
msgstr ""
msgid "GroupSAML|To be able to enable group managed accounts, you first need to enable enforced SSO."
msgid "GroupSAML|To be able to enable group-managed accounts, you first need to enable enforced SSO."
msgstr ""
msgid "GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts."
msgstr ""
msgid "GroupSAML|Toggle SAML authentication"
msgstr ""
msgid "GroupSAML|Valid SAML Response"
msgstr ""
......
......@@ -10,8 +10,8 @@ module QA
element :identity_provider_sso_field
element :certificate_fingerprint_field
element :default_membership_role_dropdown
element :enforced_sso_toggle_button
element :group_managed_accounts_toggle_button
element :enforced_sso_checkbox
element :group_managed_accounts_checkbox
element :save_changes_button
end
......@@ -35,43 +35,43 @@ module QA
select_element(:default_membership_role_dropdown, role)
end
def has_enforced_sso_button?
has_button = has_element?(:enforced_sso_toggle_button, wait: 5)
QA::Runtime::Logger.debug "has_enforced_sso_button?: #{has_button}"
has_button
def has_enforced_sso_checkbox?
has_checkbox = has_element?(:enforced_sso_checkbox, visible: false, wait: 5)
QA::Runtime::Logger.debug "has_enforced_sso_checkbox?: #{has_checkbox}"
has_checkbox
end
def enforce_sso_enabled?
enabled = has_enforced_sso_button? && find_element(:enforced_sso_toggle_button).find('input', visible: :all)[:value] == 'true'
enabled = has_enforced_sso_checkbox? && find_element(:enforced_sso_checkbox, visible: false).checked?
QA::Runtime::Logger.debug "enforce_sso_enabled?: #{enabled}"
enabled
end
def enforce_sso
click_element :enforced_sso_toggle_button unless enforce_sso_enabled?
check_element(:enforced_sso_checkbox, true) unless enforce_sso_enabled?
Support::Waiter.wait_until(raise_on_failure: true) { enforce_sso_enabled? }
end
def disable_enforced_sso
click_element :enforced_sso_toggle_button if enforce_sso_enabled?
uncheck_element(:enforced_sso_checkbox, true) if enforce_sso_enabled?
Support::Waiter.wait_until(raise_on_failure: true) { !enforce_sso_enabled? }
end
def has_group_managed_accounts_button?
has_element?(:group_managed_accounts_toggle_button, wait: 5)
def has_group_managed_accounts_checkbox?
has_element?(:group_managed_accounts_checkbox, wait: 5)
end
def group_managed_accounts_enabled?
enforce_sso_enabled? && has_group_managed_accounts_button? && find_element(:group_managed_accounts_toggle_button).find('input', visible: :all)[:value] == 'true'
enforce_sso_enabled? && has_group_managed_accounts_checkbox? && find_element(:group_managed_accounts_checkbox).checked?
end
def enable_group_managed_accounts
click_element :group_managed_accounts_toggle_button unless group_managed_accounts_enabled?
check_element(:group_managed_accounts_checkbox, true) unless group_managed_accounts_enabled?
Support::Waiter.wait_until { group_managed_accounts_enabled? }
end
def disable_group_managed_accounts
click_element :group_managed_accounts_toggle_button if group_managed_accounts_enabled?
uncheck_element(:group_managed_accounts_checkbox, true) if group_managed_accounts_enabled?
Support::Waiter.wait_until { !group_managed_accounts_enabled? }
end
......
......@@ -227,10 +227,12 @@ module QA
wait = kwargs.delete(:wait) || Capybara.default_max_wait_time
text = kwargs.delete(:text)
klass = kwargs.delete(:class)
visible = kwargs.delete(:visible)
visible = visible.nil? && true
try_find_element = ->(wait) do
if disabled.nil?
has_css?(element_selector_css(name, kwargs), text: text, wait: wait, class: klass)
has_css?(element_selector_css(name, kwargs), text: text, wait: wait, class: klass, visible: visible)
else
find_element(name, original_kwargs).disabled? == disabled
end
......
......@@ -72,7 +72,7 @@ module QA
Support::Retrier.retry_on_exception do
Flow::Saml.visit_saml_sso_settings(@group)
ensure_enforced_sso_button_shown
ensure_enforced_sso_checkbox_shown
managed_group_url = EE::Page::Group::Settings::SamlSSO.perform do |saml_sso|
saml_sso.enforce_sso
......@@ -86,7 +86,7 @@ module QA
end
Flow::Saml.visit_saml_sso_settings(@group, direct: true)
ensure_enforced_sso_button_shown
ensure_enforced_sso_checkbox_shown
unless EE::Page::Group::Settings::SamlSSO.perform(&:enforce_sso_enabled?)
QA::Runtime::Logger.debug "Enforced SSO not setup correctly. About to raise failure."
......@@ -100,12 +100,12 @@ module QA
end
end
def ensure_enforced_sso_button_shown
# Sometimes, the toggle button for SAML SSO does not appear and only appears after a refresh
def ensure_enforced_sso_checkbox_shown
# Sometimes, the checkbox for SAML SSO does not appear and only appears after a refresh
# This issue can only be reproduced manually if you are too quick to go to the group setting page
# after enabling the feature flags.
Support::Retrier.retry_until(sleep_interval: 1, raise_on_failure: true) do
condition_met = EE::Page::Group::Settings::SamlSSO.perform(&:has_enforced_sso_button?)
condition_met = EE::Page::Group::Settings::SamlSSO.perform(&:has_enforced_sso_checkbox?)
page.refresh unless condition_met
condition_met
end
......
......@@ -152,7 +152,7 @@ module QA
# Once the feature flags are enabled, it takes some time for the toggle buttons to show on the UI.
# This issue does not happen manually. Only happens with the test as they are too fast.
Support::Retrier.retry_until(sleep_interval: 1, raise_on_failure: true) do
condition_met = saml_sso.has_enforced_sso_button? && saml_sso.has_group_managed_accounts_button?
condition_met = saml_sso.has_enforced_sso_checkbox? && saml_sso.has_group_managed_accounts_checkbox?
page.refresh unless condition_met
condition_met
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment