diff --git a/app/policies/identity_provider_policy.rb b/app/policies/identity_provider_policy.rb index d34cdd5bdd43f095cc13722b4e1625a7f1c6ee0a..60fc6e9c337f61e2bf42aac2afd9d84cca70deb9 100644 --- a/app/policies/identity_provider_policy.rb +++ b/app/policies/identity_provider_policy.rb @@ -13,3 +13,5 @@ class IdentityProviderPolicy < BasePolicy rule { protected_provider }.prevent(:unlink) end + +IdentityProviderPolicy.prepend(EE::IdentityProviderPolicy) diff --git a/ee/app/models/ee/user.rb b/ee/app/models/ee/user.rb index da1be2653560e5bbbd1513e674bda48121c4168a..4210f9501eefa792883aa3a7bde7192ee79ce99f 100644 --- a/ee/app/models/ee/user.rb +++ b/ee/app/models/ee/user.rb @@ -246,6 +246,29 @@ def admin_unsubscribe! update_column :admin_email_unsubscribed_at, Time.now end + override :allow_password_authentication_for_web? + def allow_password_authentication_for_web?(*) + return false if group_managed_account? + + super + end + + override :allow_password_authentication_for_git? + def allow_password_authentication_for_git?(*) + return false if group_managed_account? + + super + end + + protected + + override :password_required? + def password_required?(*) + return false if group_managed_account? + + super + end + private def namespace_union(select = :id) diff --git a/ee/app/policies/ee/identity_provider_policy.rb b/ee/app/policies/ee/identity_provider_policy.rb new file mode 100644 index 0000000000000000000000000000000000000000..ae9c173abb88644faec2b6c55079e7e24b7a9942 --- /dev/null +++ b/ee/app/policies/ee/identity_provider_policy.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module EE + module IdentityProviderPolicy + extend ActiveSupport::Concern + + prepended do + desc "User account is managed by group SAML" + condition(:group_managed_account, scope: :user) { @user.group_managed_account? } + + rule { group_managed_account }.prevent_all + end + end +end diff --git a/ee/app/views/profiles/accounts/_group_saml_unlink_buttons.html.haml b/ee/app/views/profiles/accounts/_group_saml_unlink_buttons.html.haml index bd54d52441e278f147c03c8af6bb78bda7f6626a..6645c8840e71babf336b90311bd4554bbda0e4c9 100644 --- a/ee/app/views/profiles/accounts/_group_saml_unlink_buttons.html.haml +++ b/ee/app/views/profiles/accounts/_group_saml_unlink_buttons.html.haml @@ -3,5 +3,9 @@ .provider-btn-group .provider-btn-image = _("SAML for %{group_name}") % { group_name: group.name } - = link_to unlink_group_saml_providers_path(group), method: :delete, class: 'provider-btn' do - Disconnect + - if unlink_provider_allowed?(identity.saml_provider) + = link_to unlink_group_saml_providers_path(group), method: :delete, class: 'provider-btn' do + = s_('Profiles|Disconnect') + - else + %a.provider-btn + = s_('Profiles|Active') diff --git a/ee/spec/factories/users.rb b/ee/spec/factories/users.rb index 4af2347990769bf8406bb1d09edfc55b05086f00..872c43b977974180a2754672b75eec10b884e00c 100644 --- a/ee/spec/factories/users.rb +++ b/ee/spec/factories/users.rb @@ -5,6 +5,10 @@ trait :auditor do auditor true end + + trait :group_managed do + association :managing_group, factory: :group + end end factory :omniauth_user do diff --git a/ee/spec/models/ee/user_spec.rb b/ee/spec/models/ee/user_spec.rb index f2b24ba7affdcf33d0ce32dd6b8f2a5faa761d77..81148962414ed8fab724b6e16fe7a28c7e2bef05 100644 --- a/ee/spec/models/ee/user_spec.rb +++ b/ee/spec/models/ee/user_spec.rb @@ -380,16 +380,55 @@ end describe '#group_managed_account?' do + subject { user.group_managed_account? } + context 'when user has managing group linked' do before do - subject.managing_group = Group.new + user.managing_group = Group.new end - it { is_expected.to be_group_managed_account } + it { is_expected.to eq true } end context 'when user has no linked managing group' do - it { is_expected.not_to be_group_managed_account } + it { is_expected.to eq false } + end + end + + describe '#password_required?' do + context 'when user has managing group linked' do + before do + user.managing_group = Group.new + end + + it 'does not require password to be present' do + expect(user).not_to validate_presence_of(:password) + expect(user).not_to validate_presence_of(:password_confirmation) + end + end + end + + describe '#allow_password_authentication_for_web?' do + context 'when user has managing group linked' do + before do + user.managing_group = Group.new + end + + it 'is false' do + expect(user.allow_password_authentication_for_web?).to eq false + end + end + end + + describe '#allow_password_authentication_for_git?' do + context 'when user has managing group linked' do + before do + user.managing_group = Group.new + end + + it 'is false' do + expect(user.allow_password_authentication_for_git?).to eq false + end end end end diff --git a/ee/spec/policies/identity_provider_policy_spec.rb b/ee/spec/policies/identity_provider_policy_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..a4ecdc6c1ff9c9244f1b0e705faf1bcafcb8d1aa --- /dev/null +++ b/ee/spec/policies/identity_provider_policy_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +require 'spec_helper' + +describe IdentityProviderPolicy do + subject(:policy) { described_class.new(user, :a_provider) } + + describe '#rules' do + context 'when user is group managed' do + let(:user) { build_stubbed(:user, :group_managed) } + + it { is_expected.not_to be_allowed(:link) } + it { is_expected.not_to be_allowed(:unlink) } + end + end +end