Commit c62a65ec authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch '327020-saml-enforcement-by-default-if-enabled' into 'master'

Convert SAML setting toggles to checkboxes

See merge request gitlab-org/gitlab!59823
parents fd580d00 dedeb7cf
......@@ -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() {
this.updateSAMLSettings();
this.updateView();
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
= s_('GroupSAML|Before enforcing SSO, enable SAML authentication.')
.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
= 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?}" }
.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{ 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);
});
[groupSamlSetting, ...otherSettings] = samlSettingsForm.settings;
expect(otherSettings.every((s) => s.value)).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