diff --git a/app/models/miq_product_feature.rb b/app/models/miq_product_feature.rb index 8bc974fa23f..a13d1179953 100644 --- a/app/models/miq_product_feature.rb +++ b/app/models/miq_product_feature.rb @@ -1,6 +1,8 @@ class MiqProductFeature < ApplicationRecord SUPER_ADMIN_FEATURE = "everything".freeze - ADMIN_FEATURE = "miq_report_superadmin".freeze + REPORT_ADMIN_FEATURE = "miq_report_superadmin".freeze + REQUEST_ADMIN_FEATURE = "miq_request_superadmin".freeze + ADMIN_FEATURE = REPORT_ADMIN_FEATURE acts_as_tree has_and_belongs_to_many :miq_user_roles, :join_table => :miq_roles_features diff --git a/app/models/miq_report.rb b/app/models/miq_report.rb index 79caf84230f..76c8a24e8b6 100644 --- a/app/models/miq_report.rb +++ b/app/models/miq_report.rb @@ -55,7 +55,7 @@ class MiqReport < ApplicationRecord IMPORT_CLASS_NAMES = %w(MiqReport).freeze scope :for_user, lambda { |user| - if user.admin_user? + if user.report_admin_user? all else where( diff --git a/app/models/miq_report/import_export.rb b/app/models/miq_report/import_export.rb index dd2f8bda012..c52809279c8 100644 --- a/app/models/miq_report/import_export.rb +++ b/app/models/miq_report/import_export.rb @@ -44,7 +44,7 @@ def import_from_hash(report, options = nil) # if report exists if options[:overwrite] # if report exists delete and create new - if user.admin_user? || user.current_group_id == rep.miq_group_id + if user.report_admin_user? || user.current_group_id == rep.miq_group_id msg = "Overwriting Report: [#{report["name"]}]" rep.attributes = report result = {:message => "Replaced Report: [#{report["name"]}]", :level => :info, :status => :update} diff --git a/app/models/miq_report_result.rb b/app/models/miq_report_result.rb index 858381de739..32d7181898f 100644 --- a/app/models/miq_report_result.rb +++ b/app/models/miq_report_result.rb @@ -24,7 +24,7 @@ class MiqReportResult < ApplicationRecord end } scope :for_user, lambda { |user| - for_groups(user.admin_user? ? nil : user.miq_group_ids) + for_groups(user.report_admin_user? ? nil : user.miq_group_ids) } before_save do @@ -329,7 +329,7 @@ def self.with_report(report_id = nil) def self.with_current_user_groups current_user = User.current_user - current_user.admin_user? ? all : where(:miq_group_id => current_user.miq_group_ids) + current_user.report_admin_user? ? all : where(:miq_group_id => current_user.miq_group_ids) end def self.with_chargeback diff --git a/app/models/miq_user_role.rb b/app/models/miq_user_role.rb index 746458cacab..afa8dd66278 100644 --- a/app/models/miq_user_role.rb +++ b/app/models/miq_user_role.rb @@ -106,8 +106,14 @@ def super_admin_user? allows?(:identifier => MiqProductFeature::SUPER_ADMIN_FEATURE) end - def admin_user? - allows_any?(:identifiers => [MiqProductFeature::SUPER_ADMIN_FEATURE, MiqProductFeature::ADMIN_FEATURE]) + def report_admin_user? + allows_any?(:identifiers => [MiqProductFeature::SUPER_ADMIN_FEATURE, MiqProductFeature::REPORT_ADMIN_FEATURE]) + end + + alias admin_user? report_admin_user? + + def request_admin_user? + allows_any?(:identifiers => [MiqProductFeature::SUPER_ADMIN_FEATURE, MiqProductFeature::REQUEST_ADMIN_FEATURE]) end def self.default_tenant_role diff --git a/app/models/user.rb b/app/models/user.rb index b264b21df9e..57bff1eb00d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -33,7 +33,7 @@ class User < ApplicationRecord delegate :miq_user_role, :current_tenant, :get_filters, :has_filters?, :get_managed_filters, :get_belongsto_filters, :to => :current_group, :allow_nil => true - delegate :super_admin_user?, :admin_user?, :self_service?, :limited_self_service?, + delegate :super_admin_user?, :admin_user?, :self_service?, :limited_self_service?, :report_admin_user?, :to => :miq_user_role, :allow_nil => true validates_presence_of :name, :userid diff --git a/db/fixtures/miq_product_features.yml b/db/fixtures/miq_product_features.yml index 6433b384dc4..2fdd81d5b60 100644 --- a/db/fixtures/miq_product_features.yml +++ b/db/fixtures/miq_product_features.yml @@ -180,6 +180,10 @@ :description: Edit a Request :feature_type: admin :identifier: miq_request_edit + - :name: Request Admin + :description: Edit other user's requests + :feature_type: admin + :identifier: miq_request_superadmin # Catalog Items - :name: Catalogs Explorer @@ -1599,8 +1603,8 @@ :feature_type: node :identifier: miq_report_menu_editor # Special Admin Functionality - - :name: Admin - :description: Special Admin Functionality + - :name: Report Admin + :description: See other user's reports :feature_type: admin :identifier: miq_report_superadmin - :name: Import / Export diff --git a/db/fixtures/miq_user_roles.yml b/db/fixtures/miq_user_roles.yml index 623ab8c9acf..8f537b6d06a 100644 --- a/db/fixtures/miq_user_roles.yml +++ b/db/fixtures/miq_user_roles.yml @@ -65,6 +65,7 @@ - miq_report - miq_report_superadmin - miq_request + - miq_request_superadmin - miq_template - orchestration_stack - physical_rack diff --git a/lib/rbac/filterer.rb b/lib/rbac/filterer.rb index 85d48dffef8..b48ebb7e7ba 100644 --- a/lib/rbac/filterer.rb +++ b/lib/rbac/filterer.rb @@ -514,15 +514,15 @@ 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 - # hide creating admin group / roles from tenant administrators - unless user_or_group.miq_user_role&.admin_user? - scope = scope.with_roles_excluding([MiqProductFeature::SUPER_ADMIN_FEATURE, MiqProductFeature::ADMIN_FEATURE]) + # hide creating admin group / roles from non-super administrators + unless user_or_group.miq_user_role&.super_admin_user? + scope = scope.with_roles_excluding(MiqProductFeature::SUPER_ADMIN_FEATURE) end if MiqUserRole != klass 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) unless user_or_group.miq_user_role&.admin_user? + scope = scope.with_groups(user.miq_group_ids) unless user_or_group.miq_user_role&.super_admin_user? end scope_by_ids(scope, filtered_ids) diff --git a/spec/lib/rbac/filterer_spec.rb b/spec/lib/rbac/filterer_spec.rb index b04d515b264..556cc2c94ff 100644 --- a/spec/lib/rbac/filterer_spec.rb +++ b/spec/lib/rbac/filterer_spec.rb @@ -897,7 +897,7 @@ def get_rbac_results_for_and_expect_objects(klass, expected_objects) it 'can see all roles expect to EvmRole-super_administrator' do expect(MiqUserRole.count).to eq(3) - get_rbac_results_for_and_expect_objects(MiqUserRole, [tenant_administrator_user_role]) + get_rbac_results_for_and_expect_objects(MiqUserRole, [tenant_administrator_user_role, administrator_user_role]) end it 'can see all groups expect to group with role EvmRole-super_administrator' do diff --git a/spec/models/miq_user_role_spec.rb b/spec/models/miq_user_role_spec.rb index fbd48c40347..4341d171d67 100644 --- a/spec/models/miq_user_role_spec.rb +++ b/spec/models/miq_user_role_spec.rb @@ -172,31 +172,39 @@ expect(MiqUserRole.count).to eq(1) end + let(:super_admin_role) { FactoryGirl.create(:miq_user_role, :features => MiqProductFeature::SUPER_ADMIN_FEATURE) } + let(:report_admin_role) { FactoryGirl.create(:miq_user_role, :features => MiqProductFeature::REPORT_ADMIN_FEATURE) } + let(:request_admin_role) { FactoryGirl.create(:miq_user_role, :features => MiqProductFeature::REQUEST_ADMIN_FEATURE) } + let(:regular_role) { FactoryGirl.create(:miq_user_role) } + describe "#super_admin_user?" do it "detects super admin" do - expect(FactoryGirl.create(:miq_user_role, :role => "super_administrator")).to be_super_admin_user + expect(super_admin_role).to be_super_admin_user end it "detects admin" do - expect(FactoryGirl.create(:miq_user_role, :role => "administrator")).not_to be_super_admin_user + expect(report_admin_role).not_to be_super_admin_user end it "detects non-admin" do - expect(FactoryGirl.create(:miq_user_role)).not_to be_super_admin_user + expect(regular_role).not_to be_super_admin_user end end - describe "#admin_user?" do + describe "#admin_user?", "#report_admin_user?" do it "detects super admin" do - expect(FactoryGirl.create(:miq_user_role, :role => "super_administrator")).to be_admin_user + expect(super_admin_role).to be_admin_user + expect(super_admin_role).to be_report_admin_user end it "detects admin" do - expect(FactoryGirl.create(:miq_user_role, :role => "administrator")).to be_admin_user + expect(report_admin_role).to be_admin_user + expect(report_admin_role).to be_report_admin_user end it "detects non-admin" do - expect(FactoryGirl.create(:miq_user_role)).not_to be_admin_user + expect(regular_role).not_to be_admin_user + expect(regular_role).not_to be_report_admin_user end end