Skip to content

Commit

Permalink
use features to check if a role is an admin role
Browse files Browse the repository at this point in the history
the role name used to determine if it were

https://bugzilla.redhat.com/show_bug.cgi?id=1090627
  • Loading branch information
kbrock committed May 17, 2018
1 parent cf89dca commit c3e49cc
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 19 deletions.
7 changes: 5 additions & 2 deletions app/models/miq_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ def settings=(new_settings)
super(indifferent_settings)
end

def self.with_roles_excluding(disallowed_roles)
includes(:miq_user_role).where.not(:miq_user_roles => {:name => disallowed_roles})
def self.with_roles_excluding(identifier)
where.not(:id => MiqGroup.joins(:miq_product_features)
.where(:miq_product_features => {:identifier => identifier})
.select(:id)
)
end

def self.next_sequence
Expand Down
4 changes: 3 additions & 1 deletion app/models/miq_product_feature.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
class MiqProductFeature < ApplicationRecord
SUPER_ADMIN_FEATURE = "everything"
ADMIN_FEATURE = "admin"
acts_as_tree

has_and_belongs_to_many :miq_user_roles, :join_table => :miq_roles_features
Expand Down Expand Up @@ -107,7 +109,7 @@ def self.seed_features(path = FIXTURE_PATH)
features = all.to_a.index_by(&:identifier)
seen = seed_from_hash(YAML.load_file(fixture_yaml), seen, nil, features)

root_feature = MiqProductFeature.find_by(:identifier => 'everything')
root_feature = MiqProductFeature.find_by(:identifier => SUPER_ADMIN_FEATURE)
Dir.glob(path.join("*.yml")).each do |fixture|
seed_from_hash(YAML.load_file(fixture), seen, root_feature)
end
Expand Down
13 changes: 7 additions & 6 deletions app/models/miq_user_role.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
class MiqUserRole < ApplicationRecord
SUPER_ADMIN_ROLE_NAME = "EvmRole-super_administrator"
ADMIN_ROLE_NAME = "EvmRole-administrator"
DEFAULT_TENANT_ROLE_NAME = "EvmRole-tenant_administrator"

has_many :entitlements, :dependent => :restrict_with_exception
Expand Down Expand Up @@ -64,8 +62,11 @@ def limited_self_service?
(settings || {}).fetch_path(:restrictions, :vms) == :user
end

def self.with_roles_excluding(disallowed_roles)
where.not(:name => disallowed_roles)
def self.with_roles_excluding(identifier)
where.not(:id => MiqUserRole.joins(:miq_product_features)
.where(:miq_product_features => {:identifier => identifier})
.select(:id)
)
end

def self.seed
Expand Down Expand Up @@ -103,11 +104,11 @@ def vm_restriction
end

def super_admin_user?
name == SUPER_ADMIN_ROLE_NAME
allows?(:identifier => MiqProductFeature::SUPER_ADMIN_FEATURE)
end

def admin_user?
name == SUPER_ADMIN_ROLE_NAME || name == ADMIN_ROLE_NAME
allows_any?(:identifiers => [MiqProductFeature::SUPER_ADMIN_FEATURE, MiqProductFeature::ADMIN_FEATURE])
end

def self.default_tenant_role
Expand Down
10 changes: 7 additions & 3 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class User < ApplicationRecord
belongs_to :current_group, :class_name => "MiqGroup"
has_and_belongs_to_many :miq_groups
scope :superadmins, lambda {
joins(:miq_groups => :miq_user_role).where(:miq_user_roles => {:name => MiqUserRole::SUPER_ADMIN_ROLE_NAME })
joins(:miq_groups => {:miq_user_role => :miq_product_features})
.where(:miq_product_features => {:identifier => MiqProductFeature::SUPER_ADMIN_FEATURE })
}

virtual_has_many :active_vms, :class_name => "VmOrTemplate"
Expand All @@ -50,8 +51,11 @@ class User < ApplicationRecord

scope :with_same_userid, ->(id) { where(:userid => User.find(id).userid) }

def self.with_roles_excluding(disallowed_roles)
includes(:miq_groups => :miq_user_role).where.not(:miq_user_roles => {:name => disallowed_roles})
def self.with_roles_excluding(identifier)
where.not(:id => User.joins(:miq_groups => :miq_product_features)
.where(:miq_product_features => {:identifier => identifier})
.select(:id)
)
end

def self.scope_by_tenant?
Expand Down
6 changes: 6 additions & 0 deletions db/fixtures/miq_product_features.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
:identifier: everything
:children:

# Special Admin Functionality
- :name: Admin
:description: Special Admin Functionality
:feature_type: admin
:identifier: admin

# Workloads Explorer
- :name: Workloads
:description: Workloads Views
Expand Down
1 change: 1 addition & 0 deletions db/fixtures/miq_user_roles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
:read_only: true
:miq_product_feature_identifiers:
- about
- admin
- all_vm_rules
- automation_manager
- embedded_automation_manager
Expand Down
12 changes: 7 additions & 5 deletions lib/rbac/filterer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -514,17 +514,19 @@ def scope_for_user_role_group(klass, scope, miq_group, user, managed_filters)
if user_or_group.try!(:self_service?) && MiqUserRole != klass
scope.where(:id => klass == User ? user.id : miq_group.id)
else
if user_or_group.miq_user_role_name == 'EvmRole-tenant_administrator'
scope = scope.with_roles_excluding(%w(EvmRole-super_administrator EvmRole-administrator))
# hide creating admin group / roles from tenant administrators
if !user_or_group.miq_user_role&.admin_user?
scope = scope.with_roles_excluding([MiqProductFeature::SUPER_ADMIN_FEATURE, MiqProductFeature::ADMIN_FEATURE])
end

if MiqUserRole != klass
if MiqUserRole == klass
scope
else
filtered_ids = pluck_ids(get_managed_filter_object_ids(scope, managed_filters))
# Non admins can only see their own groups
scope = scope.with_groups(user.miq_group_ids) if !user_or_group.miq_user_role&.admin_user?
scope_by_ids(scope, filtered_ids)
end

scope_by_ids(scope, filtered_ids)
end
end

Expand Down
13 changes: 11 additions & 2 deletions spec/factories/miq_user_role.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
name { |ur| ur.role ? "EvmRole-#{ur.role}" : generate(:miq_user_role_name) }

after(:build) do |user, evaluator|
e_features = evaluator.features
if evaluator.role.present?
@system_roles ||= YAML.load_file(MiqUserRole::FIXTURE_YAML)
seeded_role = @system_roles.detect { |role| role[:name] == "EvmRole-#{evaluator.role}" }
Expand All @@ -20,10 +21,18 @@
user.read_only = seeded_role[:read_only]
user.settings = seeded_role[:settings]
end
if e_features.blank?
# admins now using a feature instead of a roll
if evaluator.role == "super_administrator"
e_features = MiqProductFeature::SUPER_ADMIN_FEATURE
elsif evaluator.role == "administrator"
e_features = MiqProductFeature::ADMIN_FEATURE
end
end
end

if evaluator.features.present?
user.miq_product_features = Array.wrap(evaluator.features).map do |f|
if e_features.present?
user.miq_product_features = Array.wrap(e_features).map do |f|
if f.kind_of?(MiqProductFeature) # TODO: remove class reference
f
else
Expand Down

0 comments on commit c3e49cc

Please sign in to comment.