Skip to content

Commit

Permalink
Support evaluation of expression filters for entitlements in RBAC
Browse files Browse the repository at this point in the history
  • Loading branch information
imtayadeway committed Aug 7, 2017
1 parent 639ee18 commit 33a722b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/rbac/filterer.rb
Expand Up @@ -351,9 +351,11 @@ def get_self_service_objects(user, miq_group, klass)

def calc_filtered_ids(scope, user_filters, user, miq_group, scope_tenant_filter)
klass = scope.respond_to?(:klass) ? scope.klass : scope
expression = miq_group.try(:entitlement).try(:filter_expression)
expression.set_tagged_target(klass) if expression
u_filtered_ids = pluck_ids(get_self_service_objects(user, miq_group, klass))
b_filtered_ids = get_belongsto_filter_object_ids(klass, user_filters['belongsto'])
m_filtered_ids = pluck_ids(get_managed_filter_object_ids(scope, user_filters['managed']))
m_filtered_ids = pluck_ids(get_managed_filter_object_ids(scope, expression || user_filters['managed']))
d_filtered_ids = pluck_ids(matches_via_descendants(rbac_class(klass), user_filters['match_via_descendants'],
:user => user, :miq_group => miq_group))

Expand Down Expand Up @@ -417,6 +419,7 @@ def get_belongsto_filter_object_ids(klass, filter)
end

def get_managed_filter_object_ids(scope, filter)
return scope.where(filter.to_sql.first) if filter.kind_of?(MiqExpression)
klass = scope.respond_to?(:klass) ? scope.klass : scope
return nil if !TAGGABLE_FILTER_CLASSES.include?(safe_base_class(klass).name) || filter.blank?
scope.find_tags_by_grouping(filter, :ns => '*').reorder(nil)
Expand Down
50 changes: 50 additions & 0 deletions spec/lib/rbac/filterer_spec.rb
@@ -1,4 +1,54 @@
describe Rbac::Filterer do
describe "using expressions as managed filters" do
it "supports OR conditions across categories" do
filter = MiqExpression.new(
"OR" => [
{"CONTAINS" => {"tag" => "managed-environment", "value" => "prod"}},
{"CONTAINS" => {"tag" => "managed-location", "value" => "ny"}}
]
)
group = create_group_with_expression(filter)
user = FactoryGirl.create(:user, :miq_groups => [group])
vm1, vm2, _vm3 = FactoryGirl.create_list(:vm_vmware, 3)
vm1.tag_with("/managed/environment/prod", :ns => "*")
vm2.tag_with("/managed/location/ny", :ns => "*")

actual, = Rbac::Filterer.search(:targets => Vm, :user => user)

expected = [vm1, vm2]
expect(actual).to match(expected)
end

it "supports AND conditions within categories" do
filter = MiqExpression.new(
"AND" => [
{"CONTAINS" => {"tag" => "managed-environment", "value" => "prod"}},
{"CONTAINS" => {"tag" => "managed-environment", "value" => "test"}}
]
)
group = create_group_with_expression(filter)
user = FactoryGirl.create(:user, :miq_groups => [group])
vm1, vm2, vm3 = FactoryGirl.create_list(:vm_vmware, 3)
vm1.tag_with("/managed/environment/prod /managed/environment/test", :ns => "*")
vm2.tag_with("/managed/environment/prod", :ns => "*")
vm3.tag_with("/managed/environment/test", :ns => "*")

actual, = Rbac::Filterer.search(:targets => Vm, :user => user)

expected = [vm1]
expect(actual).to match(expected)
end

def create_group_with_expression(expression)
role = FactoryGirl.create(:miq_user_role)
group = FactoryGirl.create(:miq_group, :tenant => Tenant.root_tenant, :miq_user_role => role)
group.entitlement = Entitlement.new
group.entitlement.filter_expression = expression
group.save!
group
end
end

describe '.combine_filtered_ids' do
# Algorithm (from Rbac::Filterer.combine_filtered_ids):
# Algorithm: b_intersection_m = (b_filtered_ids INTERSECTION m_filtered_ids)
Expand Down

0 comments on commit 33a722b

Please sign in to comment.