Skip to content

Commit

Permalink
fixes #812 - new permissions model, user group role and nest support,…
Browse files Browse the repository at this point in the history
… role filters for better granularity

Contributions from:
* Daniel Lobato <[email protected]>
* Joseph Magen <[email protected]>
* Tom McKay <[email protected]>
* Greg Sutcliffe <[email protected]>
* Dominic Cleal <[email protected]>
  • Loading branch information
ares authored and Dominic Cleal committed Mar 3, 2014
1 parent 8cf1033 commit acfbc45
Show file tree
Hide file tree
Showing 329 changed files with 5,865 additions and 3,407 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ locale/*/LC_MESSAGES
coverage/
tags
_build
zeus.json
custom_plan.rb
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ gem 'rest-client', :require => 'rest_client'
gem "audited-activerecord", "3.0.0"
gem "will_paginate", "~> 3.0.2"
gem "ancestry", "~> 2.0"
gem 'scoped_search', '>= 2.5'
gem 'scoped_search', '>= 2.6.2'
gem 'net-ldap'
gem 'uuidtools'
gem "apipie-rails", "~> 0.0.23"
gem 'rabl', '>= 0.7.5', '<= 0.9.0'
gem 'oauth'
gem 'deep_cloneable'
gem 'foreigner', '~> 1.4.2'

if RUBY_VERSION =~ /^1\.8/
Expand Down
15 changes: 15 additions & 0 deletions app/assets/javascripts/filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
$(document).ready(function () {
$('#filter_resource_type').change(function () {
$.ajax({
url: $(this).data('url'),
data: {
resource_type: $('#filter_resource_type').val()
},
dataType: "script"
});
});

$('#filter_unlimited').change(function () {
$('#search').prop('disabled', $(this).prop('checked'));
});
});
4 changes: 2 additions & 2 deletions app/controllers/about_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ class AboutController < ApplicationController
skip_before_filter :authorize, :only => :index

def index
@proxies = SmartProxy.my_proxies.includes(:features)
@compute_resources = ComputeResource.my_compute_resources
@smart_proxies = SmartProxy.authorized(:view_smart_proxies).includes(:features)
@compute_resources = ComputeResource.authorized(:view_compute_resources)
@plugins = Foreman::Plugin.all
end

Expand Down
39 changes: 32 additions & 7 deletions app/controllers/api/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,15 @@ def resource_class
@resource_class ||= resource_name.classify.constantize
end

def resource_scope
@resource_scope ||= resource_class.scoped
def resource_scope(controller = controller_name)
@resource_scope ||= begin
scope = resource_class.scoped
if resource_class.respond_to?(:authorized)
scope.authorized("#{action_permission}_#{controller}", resource_class)
else
scope
end
end
end

def api_request?
Expand Down Expand Up @@ -138,14 +145,15 @@ def resource_identifying_attributes
#
# example:
# @host = Host.find_resource params[:id]
def find_resource
def find_resource(controller = controller_name)
resource = resource_identifying_attributes.find do |key|
next if key=='name' and (params[:id] =~ /\A\d+\z/)
method = "find_by_#{key}"
id = key=='id' ? params[:id].to_i : params[:id]
resource_scope.respond_to?(method) and
(resource = resource_scope.send method, id) and
break resource
scope = resource_scope(controller)
if scope.respond_to?(method)
(resource = scope.send method, id) and break resource
end
end

if resource
Expand Down Expand Up @@ -219,7 +227,10 @@ def find_nested_object
if allowed_nested_id.include?(param)
resource_identifying_attributes.each do |key|
find_method = "find_by_#{key}"
@nested_obj ||= md[1].classify.constantize.send(find_method, params[param])
model = md[1].classify.constantize
controller = "#{md[1].pluralize}_#{controller_name}"
authorized_scope = model.authorized("#{action_permission}_#{controller}")
@nested_obj ||= authorized_scope.send(find_method, params[param])
end
else
# there should be a route error before getting here, but just in case,
Expand Down Expand Up @@ -250,5 +261,19 @@ def skip_nested_id
[]
end

def action_permission
case params[:action]
when 'new', 'create'
'create'
when 'edit', 'update'
'edit'
when 'destroy'
'destroy'
when 'index', 'show', 'status'
'view'
else
raise ::Foreman::Exception.new(N_("unknown permission for %s"), "#{params[:controller]}##{params[:action]}")
end
end
end
end
4 changes: 3 additions & 1 deletion app/controllers/api/v1/architectures_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class ArchitecturesController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@architectures = Architecture.includes(:operatingsystems).
@architectures = Architecture.
authorized(:view_architectures).
includes(:operatingsystems).
search_for(*search_options).paginate(paginate_options)
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/api/v1/audits_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class AuditsController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
Audit.unscoped { @audits = Audit.search_for(*search_options).paginate(paginate_options) }
Audit.unscoped { @audits = Audit.authorized(:view_audit_logs).search_for(*search_options).paginate(paginate_options) }
end

api :GET, "/audits/:id/", "Show an audit"
Expand Down
7 changes: 5 additions & 2 deletions app/controllers/api/v1/common_parameters_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Api
module V1
class CommonParametersController < V1::BaseController
before_filter :find_resource, :only => [:show, :update, :destroy]
before_filter(:only => %w{show update destroy}) { find_resource('globals') }

api :GET, "/common_parameters/", "List all common parameters."
param :search, String, :desc => "filter results"
Expand All @@ -10,7 +10,10 @@ class CommonParametersController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@common_parameters = CommonParameter.search_for(*search_options).paginate(paginate_options)
@common_parameters = CommonParameter.
authorized(:view_globals).
search_for(*search_options).
paginate(paginate_options)
end

api :GET, "/common_parameters/:id/", "Show a common parameter."
Expand Down
8 changes: 3 additions & 5 deletions app/controllers/api/v1/compute_resources_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class ComputeResourcesController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@compute_resources = ComputeResource.my_compute_resources.search_for(*search_options).paginate(paginate_options)
@compute_resources = ComputeResource.
authorized(:view_compute_resources).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/compute_resources/:id/", "Show an compute resource."
Expand Down Expand Up @@ -66,10 +68,6 @@ def destroy
process_response @compute_resource.destroy
end

def resource_scope
resource_class.my_compute_resources
end

end
end
end
10 changes: 6 additions & 4 deletions app/controllers/api/v1/config_templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module V1
class ConfigTemplatesController < V1::BaseController
include Foreman::Renderer

before_filter :find_resource, :only => [:show, :update, :destroy]
before_filter(:only => %w{show update destroy}) { find_resource('templates') }
before_filter :handle_template_upload, :only => [:create, :update]
before_filter :process_template_kind, :only => [:create, :update]

Expand All @@ -14,7 +14,9 @@ class ConfigTemplatesController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@config_templates = ConfigTemplate.search_for(*search_options).paginate(paginate_options).
@config_templates = ConfigTemplate.
authorized(:view_templates).
search_for(*search_options).paginate(paginate_options).
includes(:operatingsystems, :template_combinations, :template_kind)
end

Expand Down Expand Up @@ -61,7 +63,7 @@ def update
param :version, String, :desc => "template version"

def revision
audit = Audit.find(params[:version])
audit = Audit.authorized(:view_audit_logs).find(params[:version])
render :json => audit.revision.template
end

Expand All @@ -75,7 +77,7 @@ def destroy
api :GET, "/config_templates/build_pxe_default", "Change the default PXE menu on all configured TFTP servers"

def build_pxe_default
status, msg = ConfigTemplate.build_pxe_default(self)
status, msg = ConfigTemplate.authorized(:deploy_templates).build_pxe_default(self)
render :json => msg, :status => status
end

Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v1/domains_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class DomainsController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@domains = Domain.search_for(*search_options).paginate(paginate_options)
@domains = Domain.
authorized(:view_domains).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/domains/:id/", "Show a domain."
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v1/environments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ class EnvironmentsController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@environments = Environment.search_for(*search_options).paginate(paginate_options)
@environments = Environment.
authorized(:view_environments).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/environments/:id/", "Show an environment."
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/api/v1/fact_values_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module Api
module V1
class FactValuesController < V1::BaseController
before_filter :find_resource, :only => %w{show update destroy}
before_filter :setup_search_options, :only => :index

api :GET, "/fact_values/", "List all fact values."
Expand All @@ -12,7 +11,10 @@ class FactValuesController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
values = FactValue.my_facts.no_timestamp_facts.
values = FactValue.
authorized(:view_facts).
my_facts.
no_timestamp_facts.
search_for(*search_options).paginate(paginate_options).
includes(:fact_name, :host)
render :json => FactValue.build_facts_hash(values.all)
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v1/hostgroups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class HostgroupsController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@hostgroups = Hostgroup.includes(:hostgroup_classes, :group_parameters).
@hostgroups = Hostgroup.
authorized(:view_hostgroups).
includes(:hostgroup_classes, :group_parameters).
search_for(*search_options).paginate(paginate_options)
end

Expand Down
13 changes: 7 additions & 6 deletions app/controllers/api/v1/hosts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class HostsController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@hosts = Host.my_hosts.search_for(*search_options).paginate(paginate_options)
@hosts = Host.
authorized(:view_hosts, Host).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/hosts/:id/", "Show a host."
Expand Down Expand Up @@ -121,13 +123,12 @@ def status
render :json => { :status => @host.host_status }.to_json if @host
end

# we need to limit resources for a current user
def resource_scope
resource_class.my_hosts
end

private

def resource_scope(controller = controller_name)
Host.authorized("#{action_permission}_#{controller}", Host)
end

# this is required for template generation (such as pxelinux) which is not done via a web request
def forward_request_url
@host.request_url = request.host_with_port if @host.respond_to?(:request_url)
Expand Down
7 changes: 5 additions & 2 deletions app/controllers/api/v1/images_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ class ImagesController < V1::BaseController
param :compute_resource_id, :identifier, :required => true

def index
@images = @compute_resource.images.search_for(*search_options).paginate(paginate_options)
@images = @compute_resource.
images.
authorized(:view_images).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/compute_resources/:compute_resource_id/images/:id/", "Show an image"
Expand Down Expand Up @@ -65,7 +68,7 @@ def destroy
private

def find_compute_resource
@compute_resource = ComputeResource.find(params[:compute_resource_id])
@compute_resource = ComputeResource.authorized(:view_compute_resources).find(params[:compute_resource_id])
end

end
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/api/v1/lookup_keys_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Api
module V1
class LookupKeysController < V1::BaseController
before_filter :find_resource, :only => %w{show update destroy}
before_filter(:only => %w{show update destroy}) { find_resource('external_variables') }
before_filter :setup_search_options, :only => :index

api :GET, "/lookup_keys/", "List all lookup_keys."
Expand All @@ -11,7 +11,9 @@ class LookupKeysController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@lookup_keys = LookupKey.search_for(*search_options).paginate(paginate_options)
@lookup_keys = LookupKey.
authorized(:view_external_variables).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/lookup_keys/:id/", "Show a lookup key."
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v1/media_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ class MediaController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@media = Medium.search_for(*search_options).paginate(paginate_options)
@media = Medium.
authorized(:view_media).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/media/:id/", "Show a medium."
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/api/v1/models_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ class ModelsController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@models = Model.search_for(*search_options).paginate(paginate_options)
@models = Model.
authorized(:view_models).
search_for(*search_options).
paginate(paginate_options)
end

api :GET, "/models/:id/", "Show a model."
Expand Down
5 changes: 3 additions & 2 deletions app/controllers/api/v1/operatingsystems_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class OperatingsystemsController < V1::BaseController

def index
@operatingsystems = Operatingsystem.
authorized(:view_operatingsystems).
includes(:media, :architectures, :ptables, :config_templates, :os_default_templates).
search_for(*search_options).paginate(paginate_options)
end
Expand Down Expand Up @@ -69,8 +70,8 @@ def destroy
param :architecture, String

def bootfiles
medium = Medium.find_by_name(params[:medium])
arch = Architecture.find_by_name(params[:architecture])
medium = Medium.authorized(:view_media).find_by_name(params[:medium])
arch = Architecture.authorized(:view_architectures).find_by_name(params[:architecture])
render :json => @operatingsystem.pxe_files(medium, arch)
rescue => e
render :json => e.to_s, :status => :unprocessable_entity
Expand Down
4 changes: 3 additions & 1 deletion app/controllers/api/v1/ptables_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ class PtablesController < V1::BaseController
param :per_page, String, :desc => "number of entries per request"

def index
@ptables = Ptable.search_for(*search_options).paginate(paginate_options)
@ptables = Ptable.
authorized(:view_ptables).
search_for(*search_options).paginate(paginate_options)
end

api :GET, "/ptables/:id/", "Show a ptable."
Expand Down
Loading

0 comments on commit acfbc45

Please sign in to comment.