Project

General

Profile

Download (5.24 KB) Statistics
| Branch: | Tag: | Revision:
module Foreman
class Plugin
class RbacSupport
# These plugins can be extended by plugins through plugin API
AUTO_EXTENDED_ROLES = [ Role::VIEWER, Role::MANAGER, Role::ORG_ADMIN ]

def add_all_permissions_to_default_roles(all_permissions)
view_permissions = all_permissions.where("name LIKE :name", :name => "view_%")
org_admin_permissions = all_permissions.where('resource_type <> :resource_type OR resource_type IS NULL', { :resource_type => "Organization" })
Role.transaction do
add_all_permissions_to_role(Role::MANAGER, all_permissions)
add_all_permissions_to_role(Role::ORG_ADMIN, org_admin_permissions)
add_all_permissions_to_role(Role::VIEWER, view_permissions)
end
rescue ActiveRecord::StatementInvalid => e
Foreman::Logging.exception _("Could not add permissions to Manager and Viewer roles: %s") % e.message, e, :level => :debug
end

def add_resource_permissions_to_default_roles(resources, opts = {})
# to get early warnings on typos
resources.map(&:constantize)
Role.without_auditing do
Role.transaction do
add_resource_permissions_to_viewer(resources, opts.dup)
add_resource_permissions_to_manager(resources, opts.dup)
add_resource_permissions_to_organization_admin(resources, opts.dup)
end
end
end

def add_permissions_to_default_roles(roles)
roles.each do |role_name, permissions|
check_role_name_before_extending role_name
role = Role.find_by :name => role_name
next unless role
include_permissions_for_role(role, permissions)
end
end

def check_role_name_before_extending(role_name)
msg = "Invalid role name, only '#{AUTO_EXTENDED_ROLES.map {|r| "'#{r}'"}.join(', ')}' is allowed to be extended from a plugin"
raise Foreman::Exception.new msg unless AUTO_EXTENDED_ROLES.include?(role_name)
end

def add_resource_permissions_to_manager(resources, opts)
manager = Role.find_by :name => Role::MANAGER
return if !manager || resources.empty?
include_permissions manager, resources, opts
rescue ActiveRecord::StatementInvalid => e
Foreman::Logging.exception _("Could not add permissions to Manager role: %s") % e.message, e, :level => :debug
end

def add_resource_permissions_to_viewer(resources, opts)
viewer = Role.find_by :name => Role::VIEWER
opts[:condition] = "name LIKE :name"
opts[:condition_hash] = { :name => "view_%" }
return if !viewer || resources.empty?
include_permissions viewer, resources, opts
rescue ActiveRecord::StatementInvalid => e
Foreman::Logging.exception _("Could not add permissions to Viewer role: %s") % e.message, e, :level => :debug
end

def add_resource_permissions_to_organization_admin(resources, opts)
organization_admin = Role.find_by :name => Role::ORG_ADMIN
opts[:condition] = "resource_type <> :not_resource_type"
opts[:condition_hash] = { :not_resource_type => "Organization" }
return if !organization_admin || resources.empty?
include_permissions organization_admin, resources, opts
rescue ActiveRecord::StatementInvalid => e
Foreman::Logging.exception _("Could not add permissions to Organization admin role: %s") % e.message, e, :level => :debug
end

def include_permissions(role, resources, opts)
to_add = resources.flat_map { |resource| new_permissions_for role, resource, opts }.map(&:name)
role.ignore_locking do |this_role|
this_role.add_permissions! to_add if to_add.any?
end
end

def new_permissions_for(role, resource, opts)
condition_hash = { :resource_type => resource }
condition_hash.merge! opts[:condition_hash] if opts[:condition_hash]
conditions = "resource_type = :resource_type"
conditions << (" AND " + opts[:condition]) if opts[:condition]
all_permissions = Permission.where(conditions, condition_hash)
all_permissions.reject do |permission|
permission_already_included? role, permission, opts
end
end

def permission_already_included?(role, permission, opts)
opts[:except] ||= []
opts[:except].include?(permission.name.to_sym) || role.permissions.where(:name => permission.name).any?
end

def include_permissions_for_role(role, permission_names)
role.ignore_locking do |this_role|
Role.without_auditing do
existing_permissions = this_role.permissions.where(:name => permission_names).pluck(:name)
to_add = permission_names.select { |name| !existing_permissions.include?(name) }
this_role.add_permissions! to_add if to_add.any?
end
end
end

def add_all_permissions_to_role(role_name, permissions)
role = Role.find_by :name => role_name
return unless role
include_permissions_for_role role, permissions.map(&:name)
rescue ActiveRecord::StatementInvalid => e
Foreman::Logging.exception _("Could not extend role '%{name}': %{message}") % {:name => role_name, :message => e.message}, e, :level => :debug
end
end
end
end
(4-4/8)