Skip to content

Commit

Permalink
Include tenants from other regions in RBAC
Browse files Browse the repository at this point in the history
accessible_tenant_ids are tenant ids determined
for selection of resources by certain tenant strategy.

This update extend tenant ids about tenant ids from
other regions. This tenant ids are determined by
finding tenant with same name as we have in other
regions and tenant is used to get tenant ids
by certaion tenant strategy.
  • Loading branch information
lpichler committed Dec 11, 2018
1 parent 363d6a9 commit 81f2d38
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
10 changes: 9 additions & 1 deletion app/models/tenant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,16 @@ def all_subprojects
self.class.descendants_of(self).where(:divisible => false)
end

def regional_tenants
self.class.regional_tenants(self)
end

def self.regional_tenants(tenant)
where(arel_table.grouping(Arel::Nodes::NamedFunction.new("LOWER", [arel_attribute(:name)]).eq(tenant.name.downcase)))
end

def accessible_tenant_ids(strategy = nil)
(strategy ? send(strategy) : []).append(id)
(strategy ? regional_tenants.map(&strategy.to_sym).flatten : []) + regional_tenants.ids
end

def name
Expand Down
55 changes: 55 additions & 0 deletions spec/lib/rbac/filterer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2501,6 +2501,61 @@ def get_rbac_results_for_and_expect_objects(klass, expected_objects)
end
end

context "multi regional environment(global region)" do
# 3 regions - default - 2 remotes
# create service template in one region
# user in remote region - tenant - in other region

let(:common_t2_name) { "Tenant 2" }
# global(default) region
# T1 -> T2 -> T3
let(:t1) { FactoryGirl.create(:tenant) }
let(:t2) { FactoryGirl.create(:tenant, :parent => t1, :name => common_t2_name.upcase) }
let(:t3) { FactoryGirl.create(:tenant, :parent => t2) }

# user with T2
#
let(:group_t2) { FactoryGirl.create(:miq_group, :tenant => t2) }
let(:user_t2) { FactoryGirl.create(:user, :miq_groups => [group_t2]) }

# in other region
#
#
let(:other_region) { FactoryGirl.create(:miq_region) }

def id_for_model_in_region(model, other_region)
model.id_in_region(model.count + 1_000_000, other_region.region)
end

#
# T1 -> T2 -> T3
let(:t1_other_region) { FactoryGirl.create(:tenant, :id => id_for_model_in_region(Tenant, other_region)) }
let(:t2_other_region) { FactoryGirl.create(:tenant, :parent => t1_other_region, :id => id_for_model_in_region(Tenant, other_region), :name => common_t2_name) }
let(:t3_other_region) { FactoryGirl.create(:tenant, :parent => t2_other_region, :id => id_for_model_in_region(Tenant, other_region)) }

#
# user with T2
#
let(:group_t2_other_region) { FactoryGirl.create(:miq_group, :tenant => t2_other_region, :id => id_for_model_in_region(MiqGroup, other_region)) }
let(:user_t2_other_region) { FactoryGirl.create(:user, :miq_groups => [group_t2_other_region], :id => id_for_model_in_region(User, other_region)) }
let!(:service_template_other_region) { FactoryGirl.create(:service_template, :tenant => t2_other_region, :id => id_for_model_in_region(ServiceTemplate, other_region)) }

let!(:vm_other_region) { FactoryGirl.create(:vm, :tenant => t2_other_region, :id => id_for_model_in_region(Vm, other_region)) }

it "finds also service templates from other region" do
expect(ServiceTemplate.count).to eq(1)
result = described_class.filtered(ServiceTemplate, :user => user_t2_other_region)
expect(result).to eq([service_template_other_region])

# on global region
result = described_class.filtered(ServiceTemplate, :user => user_t2)
expect(result).to eq([service_template_other_region])

result = described_class.filtered(Vm, :user => user_t2)
expect(result).to eq([vm_other_region])
end
end

private

# separate them to match easier for failures
Expand Down

0 comments on commit 81f2d38

Please sign in to comment.