Bug 1329487 - non-admin user seeing 500 error when reviewing their host's PXE configs
Summary: non-admin user seeing 500 error when reviewing their host's PXE configs
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat Satellite
Classification: Red Hat
Component: Hosts
Version: 6.1.8
Hardware: All
OS: Linux
high
high vote
Target Milestone: Unspecified
Assignee: satellite6-bugs
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-04-22 05:28 UTC by Neil Miao
Modified: 2019-09-26 18:42 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2016-12-06 12:55:35 UTC
Target Upstream Version:


Attachments (Terms of Use)

Description Neil Miao 2016-04-22 05:28:35 UTC
Description of problem:

Info:
* non-admin users are granted all possible permissions to create and manage host and provisioning templates in their own organization and locations
* all provisioning templates are assigned to the users' locations and organization
* users can see view and edit the templates just fine in https://satellite/config_templates
* users are able to provision hosts

Problem:
After the hosts are built, non-admin users cannot view the host's PXE config.
A 500 error page (we are sorry, but something went wrong) appears when the users go to https://satellite/unattended/PXELinux?hostname=_provisioned_host_

2016-04-22 04:41:55 [I] Completed 500 Internal Server Error in 331ms
2016-04-22 04:41:55 [F]
ArgumentError (There was no default layout for UnattendedController in #<ActionView::PathSet:0x0000000f3d06f8 @paths=[/usr/share/foreman/app/views, /opt/rh/ruby193/root/usr/share/gems/gems/foreman_
bootdisk-4.0.2.14/app/views, /opt/rh/ruby193/root/usr/share/gems/gems/redhat_access-0.2.5/app/views, /opt/rh/ruby193/root/usr/share/gems/gems/katello-2.2.0.85/app/views, /opt/rh/ruby193/root/usr/sh
are/gems/gems/bastion-0.3.0.10/app/views, /opt/rh/ruby193/root/usr/share/gems/gems/foreman-tasks-0.6.15.7/app/views, /opt/rh/ruby193/root/usr/share/gems/gems/foreman_discovery-2.0.0.23/app/views, /
opt/rh/ruby193/root/usr/share/gems/gems/foreman_docker-1.2.0.24/app/views, /opt/rh/ruby193/root/usr/share/gems/gems/apipie-rails-0.2.5/app/views]>):
  app/controllers/application_controller.rb:303:in `generic_exception'
  lib/middleware/catch_json_parse_errors.rb:9:in `call'
  app/controllers/application_controller.rb:221:in `block (2 levels) in render_403'
  app/controllers/application_controller.rb:220:in `render_403'
  app/controllers/application_controller.rb:59:in `deny_access'
  app/controllers/application_controller.rb:51:in `authorize'
  app/controllers/unattended_controller.rb:20:in `block (2 levels) in <class:UnattendedController>'
  app/models/concerns/foreman/thread_session.rb:33:in `clear_thread'


However, the provisioning config is visible just fine
https://satellite/unattended/provision?hostname=_provisioned_host_


Version-Release number of selected component (if applicable):
foreman-1.7.2.55-1.el7sat.noarch

How reproducible:
always

Steps to Reproduce:
1. grant manager role to a user (a.k.a user1)
2. provision a RHEL7(a.k.a host1) as the user using templates: (kickstart default pxe and satellite kickstart default)
3. verify both templates are viewable and editable by user1
4. https://satellite/unattended/provision?hostname=host1 returns the rendered KS file

Actual results:
https://satellite/unattended/PXELinux?hostname=host1 returns a 500 error page
https://satellite/unattended/iPXE?hostname=host1 returns a 500 error page
https://satellite/unattended/finish?hostname=host1 returns a 500 error page
https://satellite/unattended/user_data?hostname=host1 returns a 500 error page

Expected results:
the above urls should returns the rendered files

Additional info:
ACL is the culprit, as always ...

  app/controllers/application_controller.rb:221:in `block (2 levels) in render_403'
  app/controllers/application_controller.rb:220:in `render_403'
  app/controllers/application_controller.rb:59:in `deny_access'
  app/controllers/application_controller.rb:51:in `authorize'
  app/controllers/unattended_controller.rb:20:in `block (2 levels) in <class:UnattendedController>'

-- snip --
  def authorize
    (render :json => { :error => "Authentication error" }, :status => :unauthorized and return) unless User.current.present?
    authorized ? true : deny_access
  end
-- snip --

For some reason 'authorized' returns false, which triggers the code to try render a 403 page within the unattended controller, which end up throwing 500 since unattended controller doesn't know how to render a 403 page. 

It took me a while to found the reason why authorized == false.

By adding additional logging in these places:

app/controllers/concerns/foreman/controller/authentication.rb
  def authorized
logger.debug(params.to_yaml)
    User.current.allowed_to?(params.slice(:controller, :action, :id))
  end

app/models/role.rb
  def allowed_to?(action)
logger.debug('XXX')
    if action.is_a? Hash
      action[:controller] = action[:controller][1..-1] if action[:controller].starts_with?('/')
logger.debug(allowed_actions.to_yaml)
logger.debug(action.to_yaml)
      allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
    else
logger.debug(allowed_permissions.to_yaml)
logger.debug(action.to_yaml)
      allowed_permissions.include? action
    end
  end

I realized the manager role is blocked by ACL from reaching any actions other than 'provision' and 'template' in 'unattended' controller, even though all host/template permissions are already granted to role.

All allowed permissions debug log:
2016-04-22 03:29:47 [D]   Permission Load (1.9ms)  SELECT "permissions".* FROM "permissions" INNER JOIN "filterings" ON "permissions"."id" = "filterings"."permission_id" INNER JOIN "filters" ON "filterings"."filter_id" = "filters"."id" WHERE "filters"."role_id" = 21 ORDER BY role_id, filters.id
2016-04-22 03:29:47 [D] ---
- architectures/index
- architectures/show
- architectures/auto_complete_search
- api/v1/architectures/index
- api/v1/architectures/show
- api/v2/architectures/index
- api/v2/architectures/show
...
- unattended/template
- unattended/provision
...

2016-04-22 03:29:47 [D] --- !ruby/hash:ActionController::Parameters
controller: unattended
action: PXELinux

Apparently, the action is blocked since its not available in the allowed permissions list.

It seems the permissions for unattended controller is not configurable in GUI and no unattended related entry found in the db table 'permissions' as well. 

Turns out they are hard-coded in 'services/foreman/access_permissions.rb'

-- snip --
map.permission :view_hosts,    {:hosts => [:index, :show, :errors, :active, :out_of_sync, :disabled, :pending, :vm,
                                      :externalNodes, :pxe_config, :storeconfig_klasses, :auto_complete_search, :bmc,
                                      :runtime, :resources, :templates, :overview],
                                    :dashboard => [:OutOfSync, :errors, :active],
                                    :unattended => [:template, :provision],
                                     :"api/v1/hosts" => [:index, :show, :status],
                                     :"api/v2/hosts" => [:index, :show, :status],
                                     :"api/v2/interfaces" => [:index, :show],
                                     :locations =>  [:mismatches],
                                     :organizations =>  [:mismatches]
-- snip --
As soon as ':PXELinux' and the other template types are added into ':unattached', the issue is gone.

The fact that ':template' lists in there means at some point the unattended templates are all rendered via the unattended/template action, which will work just fine. But someone later change that behavior in the unattended_controller.rb, without changing the access_permissions.rb to match it...

Are we suppose to have some unit-test/functional-test to cover this sort of things??

Anyway, I was determined to get to the bottom of this POS and it does take me a few hours to track it down. (shows that I am not quite familiar with the foreman code base and the code is really not the easiest code in the world to follow)

Adding all those template types in access_permissions.rb stinks, hopefully someone finds a better way to fix it. 

Again, satellite 6 developers, PLEASE put in some effect to close the testing gap!!!
Bugs like these should never even reaches end users like me.

Comment 2 Tomer Brisker 2016-12-06 12:55:35 UTC
This seems to have been fixed in 6.2 as far as I can tell. 
Closing, feel free to reopen if issue still persists.


Note You need to log in before you can comment on or make changes to this bug.