Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #5535, adding permissions for host collections. #4076

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/controllers/katello/api/api_controller.rb
Expand Up @@ -54,6 +54,7 @@ def converted_controllers
'katello/api/v2/content_view_puppet_modules',
'katello/api/v2/content_view_versions',
'katello/api/v2/gpg_keys',
'katello/api/v2/host_collections',
'katello/api/v2/sync_plans',
'katello/api/v2/products',
'katello/api/v2/repositories',
Expand Down Expand Up @@ -138,12 +139,12 @@ def respond(options = {})
def format_bulk_action_messages(args = {})
models = args.fetch(:models)
authorized = args.fetch(:authorized)
messages = []
messages = {:success => [], :error => []}

unauthorized = models - authorized

messages << args.fetch(:success) % authorized.length if authorized.present?
messages << args.fetch(:error) % unauthorized if unauthorized.present?
messages[:success] << args.fetch(:success) % authorized.length if authorized.present?
messages[:error] << args.fetch(:error) % unauthorized if unauthorized.present?

messages
end
Expand Down
Expand Up @@ -71,7 +71,7 @@ def param_rules
def index
query_string = params[:search]

filters = [:terms => {:id => HostCollection.readable(@organization).pluck(:id)}]
filters = [:terms => {:id => HostCollection.readable.pluck(:id)}]
#downcase filtered analyzed field
filters << {:term => {:name => params[:name].downcase}} if params[:name]

Expand Down
Expand Up @@ -102,7 +102,7 @@ def show
param_group :search, Api::V2::ApiController
param :name, String, :desc => "host collection name to filter by"
def available_host_collections
filters = [:terms => {:id => HostCollection.readable(@activation_key.organization).pluck("#{Katello::HostCollection.table_name}.id") -
filters = [:terms => {:id => HostCollection.readable.pluck("#{Katello::HostCollection.table_name}.id") -
@activation_key.host_collections.pluck("#{Katello::HostCollection.table_name}.id")}]
filters << {:term => {:name => params[:name].downcase}} if params[:name]

Expand Down
55 changes: 27 additions & 28 deletions app/controllers/katello/api/v2/host_collections_controller.rb
Expand Up @@ -20,31 +20,10 @@ class Api::V2::HostCollectionsController < Api::V2::ApiController
before_filter :find_system
before_filter :find_optional_organization, :only => [:index]
before_filter :find_organization, :only => [:create]
before_filter :authorize
before_filter :load_search_service, :only => [:index, :systems]

wrap_parameters :include => (HostCollection.attribute_names + %w(system_ids))

def rules
any_readable = lambda { @organization && HostCollection.any_readable?(@organization) }
read_perm = lambda { @host_collection.readable? }
edit_perm = lambda { @host_collection.editable? }
create_perm = lambda { HostCollection.creatable?(@organization) }
destroy_perm = lambda { @host_collection.deletable? }
{ :index => any_readable,
:show => read_perm,
:systems => read_perm,
:create => create_perm,
:copy => create_perm,
:update => edit_perm,
:destroy => destroy_perm,
:add_systems => edit_perm,
:remove_systems => edit_perm,
:add_activation_keys => edit_perm,
:remove_activation_keys => edit_perm
}
end

def_param_group :host_collection do
param :name, String, :required => true, :desc => "Host Collection name"
param :system_ids, Array, :required => false, :desc => "List of system uuids to be in the host collection"
Expand Down Expand Up @@ -114,23 +93,43 @@ def systems
param :system_ids, Array, :desc => "Array of system ids"
def add_systems
ids = system_uuids_to_ids(params[:system_ids])
@systems = System.readable(@host_collection.organization).where(:id => ids)
@host_collection.system_ids = (@host_collection.system_ids + @systems.collect { |s| s.id }).uniq
@systems = System.where(:id => ids)
@editable_systems = @systems.editable
@host_collection.system_ids = (@host_collection.system_ids + @editable_systems.collect { |s| s.id }).uniq
@host_collection.save!
System.index.refresh
respond_for_index(:collection => @host_collection.systems, :template => :delta_systems)

messages = format_bulk_action_messages(
:success => _("Successfully added %s Content Host(s)."),
:error => _("You were not allowed to add %s"),
:models => @systems,
:authorized => @editable_systems
)

respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

api :PUT, "/host_collections/:id/remove_systems", "Remove systems from the host collection"
param :id, :identifier, :desc => "Id of the host collection", :required => true
param :system_ids, Array, :desc => "Array of system ids"
def remove_systems
ids = system_uuids_to_ids(params[:system_ids])
system_ids = System.readable(@host_collection.organization).where(:id => ids).collect { |s| s.id }
@host_collection.system_ids = (@host_collection.system_ids - system_ids).uniq
@systems = System.where(:id => ids)
@editable_systems = @systems.editable
@host_collection.system_ids = (@host_collection.system_ids - @editable_systems.collect { |s| s.id }).uniq
@host_collection.save!
System.index.refresh
respond_for_index(:collection => @host_collection.systems, :template => :delta_systems)

messages = format_bulk_action_messages(
:success => _("Successfully removed %s Content Host(s)."),
:error => _("You were not allowed to sync %s"),
:models => @systems,
:authorized => @editable_systems
)

respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

api :PUT, "/host_collections/:id/add_activation_keys", "Add activation keys to the host collection"
Expand Down Expand Up @@ -224,7 +223,7 @@ def filter_activation_key
end

def filter_organization
filters = [:terms => {:id => HostCollection.readable(@organization).pluck("#{Katello::HostCollection.table_name}.id")}]
filters = [:terms => {:id => HostCollection.readable.pluck("#{Katello::HostCollection.table_name}.id")}]
filters << {:term => {:name => params[:name].downcase}} if params[:name]

options = {
Expand Down
Expand Up @@ -28,7 +28,8 @@ def destroy_products
:authorized => deletable_products
)

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

api :PUT, "/products/bulk/sync", "Sync one or more products"
Expand All @@ -44,7 +45,8 @@ def sync_products
:authorized => syncable_products
)

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

api :PUT, "/products/bulk/sync_plan", "Sync one or more products"
Expand All @@ -64,7 +66,8 @@ def update_sync_plans
:authorized => editable_products
)

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

private
Expand Down
Expand Up @@ -31,7 +31,8 @@ def destroy_repositories
:authorized => deletable_repositories
)

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

api :POST, "/repositories/bulk/sync", "Synchronise repository"
Expand All @@ -47,7 +48,8 @@ def sync_repositories
:authorized => syncable_repositories
)

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => messages }
end

private
Expand Down
Expand Up @@ -70,7 +70,8 @@ def bulk_add_host_collections
end
end

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => display_messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => display_messages }
end

api :PUT, "/systems/bulk/remove_host_collections",
Expand All @@ -92,7 +93,8 @@ def bulk_remove_host_collections
end
end

respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => display_messages }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => display_messages }
end

api :POST, "/systems/bulk/applicable_errata",
Expand Down Expand Up @@ -143,7 +145,8 @@ def remove_content
def destroy_systems
@systems.each{ |system| system.destroy }
display_message = _("Successfully removed %s content host(s)") % @systems.length
respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => [display_message] }
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => [display_message] }
end

api :PUT, "/systems/bulk/environment_content_view", "Assign the environment and content view to one or more systems"
Expand All @@ -158,7 +161,8 @@ def environment_content_view
end
display_message = _("Successfully reassigned %{count} content host(s) to %{cv} in %{env}.") %
{:count => @systems.length, :cv => @view.name, :env => @environment.name}
respond_for_show :template => 'bulk_action', :resource => { 'displayMessages' => [display_message]}
respond_for_show :template => 'bulk_action', :resource_name => 'common',
:resource => { 'displayMessages' => [display_message] }
end

private
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/katello/api/v2/systems_controller.rb
Expand Up @@ -66,8 +66,8 @@ def organization_id_keys
def index
filters = []

uuids = System.readable.pluck(:uuid)
filters << {:terms => {:uuid => uuids}}
#uuids = System.readable.pluck(:uuid)
#filters << {:terms => {:uuid => uuids}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These not needed anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Good catch, forgot I commented those out, will fix.


if params[:environment_id]
filters << {:terms => {:environment_id => [params[:environment_id]] }}
Expand Down Expand Up @@ -145,7 +145,7 @@ def show
param_group :search, Api::V2::ApiController
param :name, String, :desc => "host collection name to filter by"
def available_host_collections
filters = [:terms => {:id => HostCollection.readable(@system.organization).pluck("#{Katello::HostCollection.table_name}.id") - @system.host_collection_ids}]
filters = [:terms => {:id => HostCollection.readable.pluck("#{Katello::HostCollection.table_name}.id") - @system.host_collection_ids}]
filters << {:term => {:name => params[:name].downcase}} if params[:name]

options = {
Expand Down
2 changes: 1 addition & 1 deletion app/lib/katello/dashboard/host_collections_widget.rb
Expand Up @@ -15,7 +15,7 @@ class Dashboard::HostCollectionsWidget < Dashboard::Widget

def accessible?
Katello.config.katello? && current_organization &&
HostCollection.any_readable?(current_organization)
HostCollection.readable
end

def title
Expand Down
122 changes: 28 additions & 94 deletions app/models/katello/authorization/host_collection.rb
Expand Up @@ -11,114 +11,48 @@
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.

module Katello
module Authorization::HostCollection
extend ActiveSupport::Concern
module Authorization::HostCollection
extend ActiveSupport::Concern

READ_PERM_VERBS = [:create, :read, :update, :delete, :read_content_hosts, :update_content_hosts, :delete_content_hosts]
SYSTEM_READ_PERMS = [:read_content_hosts, :update_content_hosts, :delete_content_hosts]

module ClassMethods
def readable(org)
items(org, READ_PERM_VERBS)
end

def editable(org)
items(org, [:update])
end

def content_hosts_readable(org)
items(org, SYSTEM_READ_PERMS)
end

def content_hosts_editable(org)
items(org, [:update_content_hosts])
end

def content_hosts_deletable(org)
items(org, [:delete_content_hosts])
end

def assert_editable(host_collections)
invalid_perms = host_collections.select{ |host_collection| !host_collection.editable? }.collect{ |host_collection| host_collection.name }

unless invalid_perms.empty?
fail Errors::SecurityViolation, _("Collection membership modification is not allowed for host collections(s): %s") % invalid_perms.join(', ')
module ClassMethods
def readable
authorized(:view_host_collections)
end
true
end

def creatable?(org)
::User.allowed_to?([:create], :host_collections, nil, org)
end

def any_readable?(org)
::User.allowed_to?(READ_PERM_VERBS, :host_collections, nil, org)
end

def list_tags(org_id)
HostCollection.select('id,name').where(:organization_id => org_id).collect { |m| VirtualTag.new(m.id, m.name) }
end
def creatable
authorized(:create_host_collections)
end

def tags(ids)
select('id,name').where(:id => ids).collect { |m| VirtualTag.new(m.id, m.name) }
end
def editable
authorized(:update_host_collections)
end

def list_verbs(global = false)
{
:create => _("Administer Host Collections"),
:read => _("Read Host Collection"),
:update => _("Modify Host Collection details and content host membership"),
:delete => _("Delete Host Collection"),
:read_content_hosts => _("Read Content Hoss in Host Collection"),
:update_content_hosts => _("Modify Content Hosts in Host Collection"),
:delete_content_hosts => _("Delete Content Hosts in Host Collection")
}.with_indifferent_access
end
def deletable
authorized(:destroy_host_collections)
end

def read_verbs
[:read]
end

def no_tag_verbs
[:create]
end
included do
include Authorizable
include Katello::Authorization

def items(org, verbs)
fail "scope requires an organization" if org.nil?
resource = :host_collections
if ::User.allowed_all_tags?(verbs, resource, org)
where(:organization_id => org)
else
where("#{HostCollection.table_name}.id in (#{::User.allowed_tags_sql(verbs, resource, org)})")
def readable?
authorized?(:view_host_collections)
end
end
end

included do
def content_hosts_readable?
::User.allowed_to?(SYSTEM_READ_PERMS, :host_collections, self.id, self.organization)
end

def content_hosts_deletable?
::User.allowed_to?([:delete_content_hosts], :host_collections, self.id, self.organization)
end

def content_hosts_editable?
::User.allowed_to?([:update_content_hosts], :host_collections, self.id, self.organization)
end
def creatable?
authorized?(:create_host_collections)
end

def readable?
::User.allowed_to?(READ_PERM_VERBS, :host_collections, self.id, self.organization)
end
def editable?
authorized?(:update_host_collections)
end

def editable?
::User.allowed_to?([:update, :create], :host_collections, self.id, self.organization)
def deletable?
authorized?(:destroy_host_collections)
end
end

def deletable?
::User.allowed_to?([:delete, :create], :host_collections, self.id, self.organization)
end
end

end
end