Skip to content

Commit

Permalink
Merge pull request #18654 from NickLaMuro/fix-container-group-entitle…
Browse files Browse the repository at this point in the history
…ment-filtering-in-rbac

Fix Container* belongsto filter in Rbac::Filterer

(cherry picked from commit 171c281)

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1702076
  • Loading branch information
kbrock authored and simaishi committed Apr 22, 2019
1 parent 0f52970 commit 9abba2b
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 2 deletions.
46 changes: 44 additions & 2 deletions lib/rbac/filterer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ class Filterer
).freeze

BELONGSTO_FILTER_CLASSES = %w(
Container
ContainerBuild
ContainerGroup
ContainerImage
ContainerImageRegistry
ContainerNode
ContainerProject
ContainerReplicator
ContainerRoute
ContainerService
ContainerTemplate
ContainerVolume
EmsCluster
EmsFolder
ExtManagementSystem
Expand Down Expand Up @@ -713,15 +725,45 @@ def get_belongsto_matches(blist, klass)
# typically, this is the only one we want:
vcmeta = vcmeta_list.last

if ([ExtManagementSystem, Host].any? { |x| vcmeta.kind_of?(x) } && klass <= VmOrTemplate) ||
(vcmeta.kind_of?(ManageIQ::Providers::NetworkManager) && NETWORK_MODELS_FOR_BELONGSTO_FILTER.any? { |association_class| klass <= association_class.safe_constantize })
if belongsto_association_filtered?(vcmeta, klass)
vcmeta.send(association_name).to_a
else
vcmeta_list.grep(klass) + vcmeta.descendants.grep(klass)
end
end.uniq
end

def belongsto_association_filtered?(vcmeta, klass)
if [ExtManagementSystem, Host].any? { |x| vcmeta.kind_of?(x) }
# Eject early if true
return true if associated_belongsto_models.any? { |associated| klass <= associated }
end

if vcmeta.kind_of?(ManageIQ::Providers::NetworkManager)
NETWORK_MODELS_FOR_BELONGSTO_FILTER.any? do |association_class|
klass <= association_class.safe_constantize
end
end
end

def associated_belongsto_models
[
VmOrTemplate,
Container,
ContainerBuild,
ContainerGroup,
ContainerImage,
ContainerImageRegistry,
ContainerNode,
ContainerProject,
ContainerReplicator,
ContainerRoute,
ContainerService,
ContainerTemplate,
ContainerVolume
]
end

def get_belongsto_matches_for_host(blist)
clusters = []
hosts = []
Expand Down
73 changes: 73 additions & 0 deletions spec/lib/rbac/filterer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,79 @@ def combine_filtered_ids(user_filtered_ids, belongsto_filtered_ids, managed_filt
end
end

context "with ContainerManagers with user roles" do
let(:owned_ems) { FactoryBot.create(:ems_openshift) }
let(:other_ems) { FactoryBot.create(:ems_openshift) }

before do
filters = ["/belongsto/ExtManagementSystem|#{owned_ems.name}"]

owner_group.entitlement = Entitlement.new
owner_group.entitlement.set_managed_filters([])
owner_group.entitlement.set_belongsto_filters(filters)
owner_group.save!
end

%w[
Container
ContainerBuild
ContainerGroup
ContainerImage
ContainerImageRegistry
ContainerNode
ContainerProject
ContainerReplicator
ContainerRoute
ContainerService
ContainerTemplate
].each do |object_klass|
context "with #{object_klass}s" do
let(:subklass) { owned_ems.class.const_get(object_klass) }
let!(:object1) { subklass.create(:ems_id => owned_ems.id) }
let!(:object2) { subklass.create(:ems_id => owned_ems.id) }
let!(:object3) { subklass.create(:ems_id => other_ems.id) }
let!(:object4) { subklass.create(:ems_id => other_ems.id) }

it "properly filters" do
search_opts = {
:targets => subklass,
:userid => owner_user.userid
}
results = described_class.search(search_opts)
objects = results.first

expect(objects.length).to eq(2)
expect(objects.to_a).to match_array([object1, object2])
end
end
end

# ContainerVolumes are the only class that has a `has_many :through`
# relationship with EMS.
context "with ContainerVolumes" do
let(:subklass) { owned_ems.class.const_get(:ContainerGroup) }
let(:volume_klass) { owned_ems.class.const_get(:ContainerVolume) }
let!(:group1) { subklass.create(:ems_id => owned_ems.id) }
let!(:group2) { subklass.create(:ems_id => other_ems.id) }
let!(:volume1) { volume_klass.create(:parent => group1) }
let!(:volume2) { volume_klass.create(:parent => group1) }
let!(:volume3) { volume_klass.create(:parent => group2) }
let!(:volume4) { volume_klass.create(:parent => group2) }

it "properly filters" do
search_opts = {
:targets => volume_klass,
:userid => owner_user.userid
}
results = described_class.search(search_opts)
objects = results.first

expect(objects.length).to eq(2)
expect(objects.to_a).to match_array([volume1, volume2])
end
end
end

context 'when class does not participate in RBAC' do
before do
@vm = FactoryGirl.create(:vm_vmware, :name => "VM1", :host => @host1, :ext_management_system => @ems)
Expand Down

0 comments on commit 9abba2b

Please sign in to comment.