Commit 79111c4c authored by Sanad Liaquat's avatar Sanad Liaquat

Merge branch 'qa-shl-group-managed-accounts-e2e-tests' into 'master'

Add group managed accounts spec

Closes gitlab-org/quality/nightly#140, #34434, and gitlab-org/quality/testcases#242

See merge request gitlab-org/gitlab!19449
parents ce529c00 0d175df3
...@@ -82,3 +82,4 @@ jsdoc/ ...@@ -82,3 +82,4 @@ jsdoc/
**/tmp/rubocop_cache/** **/tmp/rubocop_cache/**
.overcommit.yml .overcommit.yml
.projections.json .projections.json
/qa/.rakeTasks
...@@ -152,7 +152,7 @@ ...@@ -152,7 +152,7 @@
- email = " (#{@user.unconfirmed_email})" - email = " (#{@user.unconfirmed_email})"
%p This user has an unconfirmed email address#{email}. You may force a confirmation. %p This user has an unconfirmed email address#{email}. You may force a confirmation.
%br %br
= link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?' } = link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?', qa_selector: 'confirm_user_button' }
= render_if_exists 'admin/users/user_detail_note' = render_if_exists 'admin/users/user_detail_note'
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
- link_text = source.is_a?(Group) ? _('Leave group') : _('Leave project') - link_text = source.is_a?(Group) ? _('Leave group') : _('Leave project')
= link_to link_text, polymorphic_path([:leave, source, :members]), = link_to link_text, polymorphic_path([:leave, source, :members]),
method: :delete, method: :delete,
data: { confirm: leave_confirmation_message(source) }, data: { confirm: leave_confirmation_message(source), qa_selector: 'leave_group_link' },
class: 'access-request-link js-leave-link' class: 'access-request-link js-leave-link'
- elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord - elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord
= link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]), = link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
......
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
.form-group .form-group
%label.toggle-wrapper.mb-0.js-group-saml-enforced-sso-toggle-area %label.toggle-wrapper.mb-0.js-group-saml-enforced-sso-toggle-area
%button{ type: 'button', %button{ type: 'button',
class: "js-project-feature-toggle js-group-saml-enforced-sso-toggle project-feature-toggle d-inline qa-enforced-sso-toggle-button #{'is-checked' if saml_provider.enforced_sso?}", class: "js-project-feature-toggle js-group-saml-enforced-sso-toggle project-feature-toggle d-inline #{'is-checked' if saml_provider.enforced_sso?}",
data: { qa_selector: 'enforced_sso_toggle_button' },
"aria-label": s_("GroupSAML|Enforced SSO") } "aria-label": s_("GroupSAML|Enforced SSO") }
= f.hidden_field :enforced_sso, { class: 'js-group-saml-enforced-sso-input js-project-feature-toggle-input'} = f.hidden_field :enforced_sso, { class: 'js-group-saml-enforced-sso-input js-project-feature-toggle-input'}
%span.toggle-icon %span.toggle-icon
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
%label.toggle-wrapper.mb-0.js-group-saml-enforced-group-managed-accounts-toggle-area %label.toggle-wrapper.mb-0.js-group-saml-enforced-group-managed-accounts-toggle-area
%button{ type: 'button', %button{ type: 'button',
class: "js-project-feature-toggle js-group-saml-enforced-group-managed-accounts-toggle project-feature-toggle d-inline #{'is-checked' if saml_provider.enforced_group_managed_accounts?}", class: "js-project-feature-toggle js-group-saml-enforced-group-managed-accounts-toggle project-feature-toggle d-inline #{'is-checked' if saml_provider.enforced_group_managed_accounts?}",
data: { qa_selector: 'group_managed_accounts_toggle_button' },
"aria-label": s_("GroupSAML|Enforced SSO") } "aria-label": s_("GroupSAML|Enforced SSO") }
= f.hidden_field :enforced_group_managed_accounts, { class: 'js-group-saml-enforced-group-managed-accounts-input js-project-feature-toggle-input'} = f.hidden_field :enforced_group_managed_accounts, { class: 'js-group-saml-enforced-group-managed-accounts-input js-project-feature-toggle-input'}
%span.toggle-icon %span.toggle-icon
...@@ -45,18 +47,18 @@ ...@@ -45,18 +47,18 @@
.well-segment.borderless.mb-3.col-12.col-lg-9.p-0 .well-segment.borderless.mb-3.col-12.col-lg-9.p-0
= f.label :sso_url, class: 'label-bold' do = f.label :sso_url, class: 'label-bold' do
= s_('GroupSAML|Identity provider single sign on URL') = s_('GroupSAML|Identity provider single sign on URL')
= f.text_field :sso_url, placeholder: 'e.g. https://example.com/adfs/ls', class: 'form-control qa-identity-provider-sso-field' = f.text_field :sso_url, placeholder: 'e.g. https://example.com/adfs/ls', class: 'form-control', data: { qa_selector: 'identity_provider_sso_field' }
.form-text.text-muted .form-text.text-muted
= s_('GroupSAML|Members will be forwarded here when signing in to your group. Get this from your identity provider, where it can also be called "SSO Service Location", "SAML Token Issuance Endpoint", or "SAML 2.0/W-Federation URL".') = s_('GroupSAML|Members will be forwarded here when signing in to your group. Get this from your identity provider, where it can also be called "SSO Service Location", "SAML Token Issuance Endpoint", or "SAML 2.0/W-Federation URL".')
.well-segment.borderless.mb-3.col-12.col-lg-9.p-0 .well-segment.borderless.mb-3.col-12.col-lg-9.p-0
= f.label :certificate_fingerprint, class: 'label-bold' do = f.label :certificate_fingerprint, class: 'label-bold' do
= s_('GroupSAML|Certificate fingerprint') = s_('GroupSAML|Certificate fingerprint')
= f.text_field :certificate_fingerprint, placeholder: 'e.g. 0a:1b:2c:3d:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff', class: 'form-control qa-certificate-fingerprint-field' = f.text_field :certificate_fingerprint, placeholder: 'e.g. 0a:1b:2c:3d:00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff', class: 'form-control', data: { qa_selector: 'certificate_fingerprint_field' }
.form-text.text-muted .form-text.text-muted
= s_('GroupSAML|SHA1 fingerprint of the SAML token signing certificate. Get this from your identity provider, where it can also be called "Thumbprint".') = s_('GroupSAML|SHA1 fingerprint of the SAML token signing certificate. Get this from your identity provider, where it can also be called "Thumbprint".')
.mt-3 .mt-3
= f.submit _("Save changes"), class: 'btn btn-success qa-save-changes-button' = f.submit _("Save changes"), class: 'btn btn-success', data: { qa_selector: 'save_changes_button' }
#js-saml-test-button.has-tooltip.pull-right #js-saml-test-button.has-tooltip.pull-right
= render 'test_button', saml_provider: @saml_provider = render 'test_button', saml_provider: @saml_provider
...@@ -30,5 +30,5 @@ ...@@ -30,5 +30,5 @@
.well-segment.borderless .well-segment.borderless
%label= _("GitLab single sign on URL") %label= _("GitLab single sign on URL")
- user_login_url = sso_group_saml_providers_url(@group, token: @group.saml_discovery_token) - user_login_url = sso_group_saml_providers_url(@group, token: @group.saml_discovery_token)
%div= link_to user_login_url, user_login_url, class: "qa-user-login-url-link" %div= link_to user_login_url, user_login_url, data: { qa_selector: 'user_login_url_link' }
.form-text.text-muted= _("Used by members to sign in to your group in GitLab") .form-text.text-muted= _("Used by members to sign in to your group in GitLab")
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
= (_("Finish setting up your dedicated account for <strong>%{group_name}</strong>.") % { group_name: @group_name }).html_safe = (_("Finish setting up your dedicated account for <strong>%{group_name}</strong>.") % { group_name: @group_name }).html_safe
.form-group .form-group
= f.label :email, class: 'label-bold' = f.label :email, class: 'label-bold'
= f.email_field :email, class: "form-control qa-new-user-email", required: true, disabled: true = f.email_field :email, class: "form-control", required: true, disabled: true, data: { qa_selector: 'new_user_email_field' }
.name.form-group .name.form-group
= f.label :name, _('Full name'), class: 'label-bold' = f.label :name, _('Full name'), class: 'label-bold'
= f.text_field :name, class: "form-control top qa-new-user-name js-block-emoji", required: true, disabled: resource.name.present? = f.text_field :name, class: "form-control top js-block-emoji", required: true, data: { qa_selector: 'new_user_username_field' }, disabled: resource.name.present?
.username.form-group .username.form-group
= f.label :username, class: 'label-bold' = f.label :username, class: 'label-bold'
= f.text_field :username, class: "form-control qa-new-user-username js-block-emoji", pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.") = f.text_field :username, class: "form-control qa-new-user-username js-block-emoji", pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
.d-flex.justify-content-center .d-flex.justify-content-center
= render 'user_info' = render 'user_info'
.submit-container .submit-container
= f.submit _("Sign out & Register"), class: "btn-register btn qa-new-user-register-button" = f.submit _("Sign out & Register"), class: "btn-register btn qa-new-user-register-button", data: { qa_selector: 'sign_out_and_register_button' }
- else - else
.submit-container .submit-container
= f.submit _("Register"), class: "btn-register btn qa-new-user-register-button" = f.submit _("Register"), class: "btn-register btn qa-new-user-register-button"
...@@ -32,6 +32,7 @@ module QA ...@@ -32,6 +32,7 @@ module QA
module Group module Group
autoload :Menu, 'qa/ee/page/group/menu' autoload :Menu, 'qa/ee/page/group/menu'
autoload :SamlSSOSignIn, 'qa/ee/page/group/saml_sso_sign_in' autoload :SamlSSOSignIn, 'qa/ee/page/group/saml_sso_sign_in'
autoload :SamlSSOSignUp, 'qa/ee/page/group/saml_sso_sign_up'
autoload :Members, 'qa/ee/page/group/members' autoload :Members, 'qa/ee/page/group/members'
module Settings module Settings
......
...@@ -9,8 +9,11 @@ module QA ...@@ -9,8 +9,11 @@ module QA
element :saml_sso_signin_button element :saml_sso_signin_button
end end
def click_signin def click_sign_in
Support::Retrier.retry_until do
click_element :saml_sso_signin_button click_element :saml_sso_signin_button
!has_element?(:saml_sso_signin_button, wait: 0)
end
end end
end end
end end
......
# frozen_string_literal: true
module QA
module EE
module Page
module Group
class SamlSSOSignUp < QA::Page::Base
view 'ee/app/views/groups/sso/sign_up_form.html.haml' do
element :sign_out_and_register_button
element :new_user_email_field
element :new_user_username_field
end
def click_signout_and_register_button
click_element :sign_out_and_register_button
end
def current_email
find_element(:new_user_email_field)[:value]
end
def current_username
find_element(:new_user_username_field)[:value]
end
end
end
end
end
end
...@@ -10,6 +10,7 @@ module QA ...@@ -10,6 +10,7 @@ module QA
element :identity_provider_sso_field element :identity_provider_sso_field
element :certificate_fingerprint_field element :certificate_fingerprint_field
element :enforced_sso_toggle_button element :enforced_sso_toggle_button
element :group_managed_accounts_toggle_button
element :save_changes_button element :save_changes_button
end end
...@@ -30,7 +31,31 @@ module QA ...@@ -30,7 +31,31 @@ module QA
end end
def enforce_sso def enforce_sso
Support::Retrier.retry_until do
click_element :enforced_sso_toggle_button unless find_element(:enforced_sso_toggle_button)[:class].include?('is-checked') click_element :enforced_sso_toggle_button unless find_element(:enforced_sso_toggle_button)[:class].include?('is-checked')
find_element(:enforced_sso_toggle_button)[:class].include?('is-checked')
end
end
def disable_enforce_sso
Support::Retrier.retry_until do
click_element :enforced_sso_toggle_button if find_element(:enforced_sso_toggle_button)[:class].include?('is-checked')
!find_element(:enforced_sso_toggle_button)[:class].include?('is-checked')
end
end
def enable_group_managed_accounts
Support::Retrier.retry_until do
click_element :group_managed_accounts_toggle_button unless find_element(:group_managed_accounts_toggle_button)[:class].include?('is-checked')
find_element(:group_managed_accounts_toggle_button)[:class].include?('is-checked')
end
end
def disable_group_managed_accounts
Support::Retrier.retry_until do
click_element :group_managed_accounts_toggle_button if find_element(:group_managed_accounts_toggle_button)[:class].include?('is-checked')
!find_element(:group_managed_accounts_toggle_button)[:class].include?('is-checked')
end
end end
def click_save_changes def click_save_changes
...@@ -44,6 +69,10 @@ module QA ...@@ -44,6 +69,10 @@ module QA
def click_user_login_url_link def click_user_login_url_link
click_element :user_login_url_link click_element :user_login_url_link
end end
def user_login_url_link_text
find_element(:user_login_url_link).text
end
end end
end end
end end
......
...@@ -10,9 +10,19 @@ module QA ...@@ -10,9 +10,19 @@ module QA
element :impersonate_user_link element :impersonate_user_link
end end
view 'app/views/admin/users/show.html.haml' do
element :confirm_user_button
end
def click_impersonate_user def click_impersonate_user
click_element(:impersonate_user_link) click_element(:impersonate_user_link)
end end
def confirm_user
accept_confirm do
click_element :confirm_user_button
end
end
end end
end end
end end
......
...@@ -18,6 +18,10 @@ module QA ...@@ -18,6 +18,10 @@ module QA
element :no_result_text, 'No groups or projects matched your search' # rubocop:disable QA/ElementWithPattern element :no_result_text, 'No groups or projects matched your search' # rubocop:disable QA/ElementWithPattern
end end
view 'app/views/shared/members/_access_request_links.html.haml' do
element :leave_group_link
end
def click_subgroup(name) def click_subgroup(name)
click_link name click_link name
end end
...@@ -42,6 +46,12 @@ module QA ...@@ -42,6 +46,12 @@ module QA
click_element :new_in_group_button click_element :new_in_group_button
end end
def leave_group
accept_alert do
click_element :leave_group_link
end
end
private private
def select_kind(kind) def select_kind(kind)
......
...@@ -64,12 +64,11 @@ module QA ...@@ -64,12 +64,11 @@ module QA
end end
def visit! def visit!
Runtime::Logger.debug("Visiting #{web_url}") Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"]) if Runtime::Env.debug?
Support::Retrier.retry_until do Support::Retrier.retry_until do
visit(web_url) visit(web_url)
wait { current_url.include?(URI.parse(web_url).path.split('/').last || web_url) }
wait { current_url == web_url }
end end
end end
......
...@@ -11,6 +11,10 @@ module QA ...@@ -11,6 +11,10 @@ module QA
post Runtime::API::Request.new(api_client, api_members_path).url, { user_id: user.id, access_level: access_level } post Runtime::API::Request.new(api_client, api_members_path).url, { user_id: user.id, access_level: access_level }
end end
def list_members
JSON.parse(get(Runtime::API::Request.new(api_client, api_members_path).url).body)
end
def api_members_path def api_members_path
"#{api_get_path}/members" "#{api_get_path}/members"
end end
......
...@@ -7,6 +7,8 @@ module QA ...@@ -7,6 +7,8 @@ module QA
# creating it if it doesn't yet exist. # creating it if it doesn't yet exist.
# #
class Sandbox < Base class Sandbox < Base
include Members
attr_accessor :path attr_accessor :path
attribute :id attribute :id
......
...@@ -19,6 +19,28 @@ module QA ...@@ -19,6 +19,28 @@ module QA
set_feature(key, false) set_feature(key, false)
end end
def remove(key)
request = Runtime::API::Request.new(api_client, "/features/#{key}")
response = delete(request.url)
unless response.code == QA::Support::Api::HTTP_STATUS_NO_CONTENT
raise SetFeatureError, "Deleting feature flag #{key} failed with `#{response}`."
end
end
def enable_and_verify(key)
Support::Retrier.retry_on_exception(sleep_interval: 2) do
enable(key)
is_enabled = false
QA::Support::Waiter.wait(interval: 1) do
is_enabled = enabled?(key)
end
raise SetFeatureError, "#{key} was not enabled!" unless is_enabled
end
end
def enabled?(key) def enabled?(key)
feature = JSON.parse(get_features).find { |flag| flag["name"] == key } feature = JSON.parse(get_features).find { |flag| flag["name"] == key }
feature && feature["state"] == "on" feature && feature["state"] == "on"
......
...@@ -8,7 +8,9 @@ module QA ...@@ -8,7 +8,9 @@ module QA
Page::Main::Login.perform(&:sign_in_with_saml) Page::Main::Login.perform(&:sign_in_with_saml)
Vendor::SAMLIdp::Page::Login.perform(&:login) Vendor::SAMLIdp::Page::Login.perform do |login_page|
login_page.login('user1', 'user1pass')
end
expect(page).to have_content('Welcome to GitLab') expect(page).to have_content('Welcome to GitLab')
end end
......
# frozen_string_literal: true # frozen_string_literal: true
module QA module QA
context 'Manage', :orchestrated, :group_saml do context 'Manage', :group_saml, :orchestrated, :requires_admin do
describe 'Group SAML SSO' do describe 'Group SAML SSO' do
include Support::Api include Support::Api
before(:all) do before(:all) do
@group = Resource::Sandbox.fabricate! @group = Resource::Sandbox.fabricate_via_api!
@api_client = Runtime::API::Client.new(:gitlab, personal_access_token: Runtime::Env.admin_personal_access_token)
end end
before do before do
unless Page::Main::Menu.perform(&:has_personal_area?) reset_idp_session
Runtime::Browser.visit(:gitlab, Page::Main::Login) page.visit Runtime::Scenario.gitlab_address
Page::Main::Login.perform(&:sign_in_using_credentials)
end Page::Main::Login.perform(&:sign_in_using_credentials) unless Page::Main::Menu.perform(&:signed_in?)
@group.visit! @group.visit!
end end
context 'Non enforced SSO' do
it 'User logs in to group with SAML SSO' do it 'User logs in to group with SAML SSO' do
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings) Page::Group::Menu.perform(&:go_to_saml_sso_group_settings)
EE::Page::Group::Settings::SamlSSO.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName managed_group_url = EE::Page::Group::Settings::SamlSSO.perform do |saml_sso|
page.set_id_provider_sso_url(QA::EE::Runtime::Saml.idp_sso_url) saml_sso.set_id_provider_sso_url(EE::Runtime::Saml.idp_sso_url)
page.set_cert_fingerprint(QA::EE::Runtime::Saml.idp_certificate_fingerprint) saml_sso.set_cert_fingerprint(EE::Runtime::Saml.idp_certificate_fingerprint)
page.click_save_changes saml_sso.click_save_changes
page.click_user_login_url_link saml_sso.user_login_url_link_text
end end
EE::Page::Group::SamlSSOSignIn.perform(&:click_signin) page.visit managed_group_url
login_to_idp_if_required_and_expect_success EE::Page::Group::SamlSSOSignIn.perform(&:click_sign_in)
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings) login_to_idp_if_required_and_expect_success
EE::Page::Group::Settings::SamlSSO.perform(&:click_user_login_url_link) page.visit managed_group_url
EE::Page::Group::SamlSSOSignIn.perform(&:click_signin) EE::Page::Group::SamlSSOSignIn.perform(&:click_sign_in)
expect(page).to have_content("Already signed in with SAML for #{Runtime::Env.sandbox_name}") expect(page).to have_content("Already signed in with SAML for #{Runtime::Namespace.sandbox_name}")
end end
it 'Lets group admin test settings' do it 'Lets group admin test settings' do
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings) Page::Group::Menu.perform(&:go_to_saml_sso_group_settings)
EE::Page::Group::Settings::SamlSSO.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName EE::Page::Group::Settings::SamlSSO.perform do |saml_sso|
page.set_id_provider_sso_url(QA::EE::Runtime::Saml.idp_sso_url) saml_sso.set_id_provider_sso_url(EE::Runtime::Saml.idp_sso_url)
page.set_cert_fingerprint(QA::EE::Runtime::Saml.idp_certificate_fingerprint) saml_sso.set_cert_fingerprint(EE::Runtime::Saml.idp_certificate_fingerprint)
page.click_save_changes saml_sso.click_save_changes
page.click_test_button saml_sso.click_test_button
end end
login_to_idp_if_required_and_expect_success login_to_idp_if_required_and_expect_success
expect(page).to have_content("Test SAML SSO") expect(page).to have_content("Test SAML SSO")
end end
end
context 'Enforced SSO' do context 'Enforced SSO' do
let(:user) { Resource::User.fabricate_via_api! }
before do before do
%w[enforced_sso enforced_sso_requires_session].each do |flag| %w[enforced_sso enforced_sso_requires_session].each do |flag|
QA::Support::Retrier.retry_until(exit_on_failure: true) do Runtime::Feature.enable_and_verify(flag)
Runtime::Feature.enable(flag)
Runtime::Feature.enabled?(flag)
end
end end
@group.add_member(user)
end end
it 'user clones and pushes to project within a group using Git HTTP' do it 'user clones and pushes to project within a group using Git HTTP' do
branch_name = "new_branch" setup_and_enable_enforce_sso
user = Resource::User.new.tap do |user| @project = Resource::Project.fabricate! do |project|
user.name = 'SAML Developer' project.name = 'project-in-saml-enforced-group'
user.username = 'saml_dev' project.description = 'project in SAML enforced gorup for git clone test'
project.group = @group
project.initialize_with_readme = true
end end
create_user_via_api(user) @project.visit!
add_user_to_group_via_api(user.username, @group, '30') expect do
Resource::Repository::ProjectPush.fabricate! do |project_push|
project_push.project = @project
project_push.branch_name = "new_branch"
project_push.user = user
end
end.not_to raise_error
end
@group.visit! context 'Group managed accounts' do
before do
%w[enforced_sso enforced_sso_requires_session group_managed_accounts sign_up_on_sso group_scim].each do |flag|
Runtime::Feature.enable_and_verify(flag)
end
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings) @managed_group_url = setup_and_enable_group_managed_accounts
end
EE::Page::Group::Settings::SamlSSO.perform do |page| # rubocop:disable QA/AmbiguousPageObjectName it 'removes existing users from the group, forces existing users to create a new account and allows to leave group' do
page.enforce_sso expect(@group.list_members.map { |item| item["username"] }).not_to include(user.username)
page.set_id_provider_sso_url(QA::EE::Runtime::Saml.idp_sso_url)
page.set_cert_fingerprint(QA::EE::Runtime::Saml.idp_certificate_fingerprint)
page.click_save_changes visit_managed_group_url
end
@project = Resource::Project.fabricate! do |project| EE::Page::Group::SamlSSOSignIn.perform(&:click_sign_in)
project.name = 'project-in-saml-enforced-group'
project.description = 'project in SAML enforced gorup for git clone test'
project.group = @group
project.initialize_with_readme = true
end
@project.visit! Vendor::SAMLIdp::Page::Login.perform { |login_page| login_page.login_if_required('user2', 'user2pass') }
expect(page).to have_text("uses group managed accounts. You need to create a new GitLab account which will be managed by")
@idp_user_email = EE::Page::Group::SamlSSOSignUp.perform(&:current_email)
remove_user_if_exists(@idp_user_email)
new_username = EE::Page::Group::SamlSSOSignUp.perform(&:current_username)
EE::Page::Group::SamlSSOSignUp.perform(&:click_signout_and_register_button)
expect(page).to have_text("Sign up was successful! Please confirm your email to sign in.")
confirm_user(new_username)
visit_managed_group_url
Resource::Repository::ProjectPush.fabricate! do |push| EE::Page::Group::SamlSSOSignIn.perform(&:click_sign_in)
push.project = @project
push.branch_name = branch_name expect(page).to have_text("Signed in with SAML")
push.user = user
Page::Group::Show.perform(&:leave_group)
expect(page).to have_text("You left")
Page::Main::Menu.perform(&:sign_out)
visit_managed_group_url
EE::Page::Group::SamlSSOSignIn.perform(&:click_sign_in)
expect(page).to have_text("uses group managed accounts. You need to create a new GitLab account which will be managed by")
end
after do
remove_user_if_exists(@idp_user_email)
end end
end end
after do
disable_enforce_sso_and_group_managed_account
remove_user_if_exists(user.email)
end
end end
after(:all) do after(:all) do
remove_group(@group) unless @group.nil? remove_group(@group) unless @group.nil?
%w[enforced_sso enforced_sso_requires_session group_managed_accounts sign_up_on_sso group_scim].each do |flag|
Runtime::Feature.remove(flag)
end
end end
end end
def login_to_idp_if_required_and_expect_success def login_to_idp_if_required_and_expect_success
Vendor::SAMLIdp::Page::Login.perform { |login_page| login_page.login_if_required } Vendor::SAMLIdp::Page::Login.perform { |login_page| login_page.login_if_required('user1', 'user1pass') }
expect(page).to have_content("SAML for #{Runtime::Env.sandbox_name} was added to your connected accounts") expect(page).to have_content("SAML for #{Runtime::Env.sandbox_name} was added to your connected accounts")
.or have_content("Already signed in with SAML for #{Runtime::Env.sandbox_name}") .or have_content("Already signed in with SAML for #{Runtime::Env.sandbox_name}")
end end
def remove_group(group) def remove_group(group)
api_client = Runtime::API::Client.new(:gitlab) delete Runtime::API::Request.new(@api_client, "/groups/#{group.path}").url
delete Runtime::API::Request.new(api_client, "/groups/#{group.path}").url end
def confirm_user(name)
page.visit Runtime::Scenario.gitlab_address
Page::Main::Menu.perform(&:sign_out_if_signed_in)
Page::Main::Login.perform(&:sign_in_using_admin_credentials)
Page::Main::Menu.perform(&:click_admin_area)
Page::Admin::Menu.perform(&:go_to_users_overview)
Page::Admin::Overview::Users::Index.perform do |index|
index.search_user(name)
index.click_user(name)
end
Page::Admin::Overview::Users::Show.perform(&:confirm_user)
Page::Main::Menu.perform(&:sign_out)
end
def setup_and_enable_enforce_sso
Page::Main::Login.perform(&:sign_in_using_credentials) unless Page::Main::Menu.perform(&:signed_in?)
Support::Retrier.retry_on_exception do
@group.visit!
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings)
EE::Page::Group::Settings::SamlSSO.perform do |saml_sso|
saml_sso.enforce_sso
saml_sso.set_id_provider_sso_url(EE::Runtime::Saml.idp_sso_url)
saml_sso.set_cert_fingerprint(EE::Runtime::Saml.idp_certificate_fingerprint)
saml_sso.click_save_changes
end
end
end
def setup_and_enable_group_managed_accounts
Page::Main::Login.perform(&:sign_in_using_credentials) unless Page::Main::Menu.perform(&:signed_in?)
Support::Retrier.retry_on_exception do
@group.visit!
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings)
EE::Page::Group::Settings::SamlSSO.perform do |saml_sso|
saml_sso.enforce_sso
saml_sso.enable_group_managed_accounts
saml_sso.set_id_provider_sso_url(EE::Runtime::Saml.idp_sso_url)
saml_sso.set_cert_fingerprint(EE::Runtime::Saml.idp_certificate_fingerprint)
saml_sso.click_save_changes
# To work around a bug (https://gitlab.com/gitlab-org/gitlab/issues/35365),
# we need to disable group managed accounts and enable it again in order for
# any existing non-owner users to be removed from the group.
# This should be updated once the bug is fixed.
saml_sso.disable_group_managed_accounts
saml_sso.click_save_changes
saml_sso.enable_group_managed_accounts
saml_sso.click_save_changes
saml_sso.user_login_url_link_text
end
end
end
def remove_user_if_exists(username_or_email)
response = parse_body(get Runtime::API::Request.new(@api_client, "/users?search=#{username_or_email}").url)
delete Runtime::API::Request.new(@api_client, "/users/#{response.first[:id]}").url if response.any?
end
def create_a_user_via_api
Resource::User.fabricate_via_api!
end end
def create_user_via_api(user) def reset_idp_session
Resource::User.fabricate_via_api! do |resource| Runtime::Logger.debug(%Q[Visiting IDP url at "#{EE::Runtime::Saml.idp_sso_url}"]) if Runtime::Env.debug?
resource.username = user.username
resource.name = user.name page.visit EE::Runtime::Saml.idp_sso_url
resource.email = user.email Support::Waiter.wait { current_url == EE::Runtime::Saml.idp_sso_url }
resource.password = user.password
Capybara.current_session.reset!
end end
def visit_managed_group_url
Runtime::Logger.debug(%Q[Visiting managed_group_url at "#{@managed_group_url}"]) if Runtime::Env.debug?
page.visit @managed_group_url
Support::Waiter.wait { current_url == @managed_group_url }
end end
def add_user_to_group_via_api(username, group, access_level) def disable_enforce_sso_and_group_managed_account
api_client = Runtime::API::Client.new(:gitlab) Runtime::Logger.info('Disabling enforce sso and group managed account')
response = get Runtime::API::Request.new(api_client, "/users?username=#{username}").url
post Runtime::API::Request.new(api_client, group.api_members_path).url, { user_id: parse_body(response).first[:id], access_level: access_level } page.visit Runtime::Scenario.gitlab_address
Page::Main::Menu.perform(&:sign_out_if_signed_in)
Page::Main::Login.perform(&:sign_in_using_admin_credentials)
@group.visit!
Page::Group::Menu.perform(&:go_to_saml_sso_group_settings)
EE::Page::Group::Settings::SamlSSO.perform do |saml_sso|
saml_sso.disable_enforce_sso if Runtime::Feature.enabled?('enforced_sso')
saml_sso.disable_group_managed_accounts if Runtime::Feature.enabled?('group_managed_accounts')
saml_sso.click_save_changes
end
end end
end end
end end
...@@ -7,18 +7,22 @@ module QA ...@@ -7,18 +7,22 @@ module QA
module SAMLIdp module SAMLIdp
module Page module Page
class Login < Page::Base class Login < Page::Base
def login def login(username, password)
fill_in 'username', with: 'user1' QA::Runtime::Logger.debug("Logging into SAMLIdp with username: #{username} and password:#{password}") if QA::Runtime::Env.debug?
fill_in 'password', with: 'user1pass'
fill_in 'username', with: username
fill_in 'password', with: password
click_on 'Login' click_on 'Login'
end end
def login_if_required def login_if_required(username, password)
login if login_required? login(username, password) if login_required?
end end
def login_required? def login_required?
page.has_text?('Enter your username and password') login_required = page.has_text?('Enter your username and password')
QA::Runtime::Logger.debug("login_required: #{login_required}") if QA::Runtime::Env.debug?
login_required
end end
end end
end end
......
...@@ -20,7 +20,7 @@ RSpec.configure do |config| ...@@ -20,7 +20,7 @@ RSpec.configure do |config|
QA::Specs::Helpers::Quarantine.configure_rspec QA::Specs::Helpers::Quarantine.configure_rspec
config.before do |example| config.before do |example|
QA::Runtime::Logger.debug("Starting test: #{example.full_description}") if QA::Runtime::Env.debug? QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n") if QA::Runtime::Env.debug?
end end
config.after(:context) do config.after(:context) do
......
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