diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 259883f..b225f1d 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -35,6 +35,10 @@ module Api @resource_class ||= resource_name.camelize.constantize end + def resource_scope + @resource_scope ||= resource_class.scoped + end + protected def process_resource_error(options = { }) @@ -110,8 +114,8 @@ module Api resource = resource_identifying_attributes.find do |key| next if key=='id' and params[:id].to_i == 0 method = "find_by_#{key}" - resource_class.respond_to?(method) and - (resource = resource_class.send method, params[:id]) and + resource_scope.respond_to?(method) and + (resource = resource_scope.send method, params[:id]) and break resource end diff --git a/app/controllers/api/v1/compute_resources_controller.rb b/app/controllers/api/v1/compute_resources_controller.rb index 93d3c67..a956319 100644 --- a/app/controllers/api/v1/compute_resources_controller.rb +++ b/app/controllers/api/v1/compute_resources_controller.rb @@ -66,6 +66,10 @@ module Api process_response @compute_resource.destroy end + def resource_scope + resource_class.my_compute_resources + end + end end end diff --git a/app/controllers/api/v1/hosts_controller.rb b/app/controllers/api/v1/hosts_controller.rb index d02d6d1..9f4c6f7 100644 --- a/app/controllers/api/v1/hosts_controller.rb +++ b/app/controllers/api/v1/hosts_controller.rb @@ -101,13 +101,17 @@ Return value may either be one of the following: 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 # 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) end - end end end diff --git a/test/fixtures/compute_resources.yml b/test/fixtures/compute_resources.yml index 31cb468..26ed7b3 100644 --- a/test/fixtures/compute_resources.yml +++ b/test/fixtures/compute_resources.yml @@ -26,3 +26,4 @@ yourcompute: password: MyString uuid: yourcompute type: Foreman::Model::Libvirt + users: restricted diff --git a/test/fixtures/hosts.yml b/test/fixtures/hosts.yml index 870bd1d..c83637e 100644 --- a/test/fixtures/hosts.yml +++ b/test/fixtures/hosts.yml @@ -196,3 +196,22 @@ db_host: managed: true compute_resource: one hostgroup: db + +owned_by_restricted: + type: Host::Managed + name: owned_by_restricted.mydomain.net + ip: "2.3.4.155" + mac: deadbeeffeed + environment: production + architecture: x86_64 + operatingsystem: redhat + ptable: one + subnet: one + domain: mydomain + puppet_proxy: puppetmaster + managed: true + compute_resource: one + location: location1 + organization: organization1 + owner: restricted + owner_type: User diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml index c231919..35278a4 100644 --- a/test/fixtures/roles.yml +++ b/test/fixtures/roles.yml @@ -197,3 +197,24 @@ none_compute_resources: permissions: | --- +manage_compute_resources: + name: View compute resources + id: "11" + builtin: "0" + permissions: | + --- + - :view_compute_resources + - :create_compute_resources + - :edit_compute_resources + - :destroy_compute_resources + +manage_hosts: + name: CRUD hosts + id: "12" + builtin: "0" + permissions: | + --- + - :create_hosts + - :edit_hosts + - :destroy_hosts + - :view_hosts diff --git a/test/fixtures/user_roles.yml b/test/fixtures/user_roles.yml new file mode 100644 index 0000000..d4a9f75 --- /dev/null +++ b/test/fixtures/user_roles.yml @@ -0,0 +1,15 @@ +user_restricted_viewer_role: + user: restricted + role_id: 5 + +user_restricted_anonymous_role: + user: restricted + role_id: 7 + +user_restricted_manage_hosts_role: + user: restricted + role_id: 12 + +user_restricted_manage_compute_resources: + user: restricted + role_id: 11 diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 20fb7bb..3e51fd8 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -18,6 +18,16 @@ two: last_login_on: 2009-10-12 21:50:04 auth_source: one +restricted: + login: restricted + firstname: Restricted + lastname: User + mail: userrestricted@someware.com + admin: false + last_login_on: 2009-10-12 21:50:04 + auth_source: one + filter_on_owner: true + admin: login: admin firstname: Admin @@ -49,4 +59,4 @@ apiadmin: last_login_on: 2009-10-12 21:50:04 auth_source: internal password_hash: 02d7ff9921071af778ff4f8608579dcd6d80dfba - password_salt: 80a167f1effbd82c2485ed81c3cfd68b11bc40dc \ No newline at end of file + password_salt: 80a167f1effbd82c2485ed81c3cfd68b11bc40dc diff --git a/test/functional/api/v1/compute_resources_controller_test.rb b/test/functional/api/v1/compute_resources_controller_test.rb index 17516e2..68755ed 100644 --- a/test/functional/api/v1/compute_resources_controller_test.rb +++ b/test/functional/api/v1/compute_resources_controller_test.rb @@ -47,4 +47,61 @@ class Api::V1::ComputeResourcesControllerTest < ActionController::TestCase assert_response :success end + test "should get index of owned" do + as_user(:restricted) do + get :index, {} + end + assert_response :success + assert_not_nil assigns(:compute_resources) + compute_resources = ActiveSupport::JSON.decode(@response.body) + ids = compute_resources.map { |hash| hash['compute_resource']['id'] } + assert !ids.include?(compute_resources(:mycompute).id) + assert ids.include?(compute_resources(:yourcompute).id) + end + + test "should allow access to a compute resource for owner" do + as_user(:restricted) do + get :show, { :id => compute_resources(:yourcompute).to_param } + end + assert_response :success + end + + test "should update compute resource for owner" do + as_user(:restricted) do + put :update, { :id => compute_resources(:yourcompute).to_param, :compute_resource => { :description => "new_description" } } + end + assert_equal "new_description", ComputeResource.find_by_name('yourcompute').description + assert_response :success + end + + test "should destroy compute resource for owner" do + assert_difference('ComputeResource.count', -1) do + as_user(:restricted) do + delete :destroy, { :id => compute_resources(:yourcompute).id } + end + end + assert_response :success + end + + test "should not allow access to a compute resource out of users compute resources scope" do + as_user(:restricted) do + get :show, { :id => compute_resources(:one).to_param } + end + assert_response :not_found + end + + test "should not update compute resource for restricted" do + as_user(:restricted) do + put :update, { :id => compute_resources(:mycompute).to_param, :compute_resource => { :description => "new_description" } } + end + assert_response :not_found + end + + test "should not destroy compute resource for restricted" do + as_user(:restricted) do + delete :destroy, { :id => compute_resources(:mycompute).id } + end + assert_response :not_found + end + end diff --git a/test/functional/api/v1/hosts_controller_test.rb b/test/functional/api/v1/hosts_controller_test.rb index a1131f9..9496084 100644 --- a/test/functional/api/v1/hosts_controller_test.rb +++ b/test/functional/api/v1/hosts_controller_test.rb @@ -63,4 +63,81 @@ class Api::V1::HostsControllerTest < ActionController::TestCase assert_response :success end + test "should be able to create hosts even when restricted" do + disable_orchestration + assert_difference('Host.count') do + post :create, { :host => valid_attrs } + end + assert_response :success + end + + test "should allow access to restricted user who owns the host" do + as_user :restricted do + get :show, { :id => hosts(:owned_by_restricted).to_param } + end + assert_response :success + end + + test "should allow to update for restricted user who owns the host" do + disable_orchestration + as_user :restricted do + put :update, { :id => hosts(:owned_by_restricted).to_param, :host => {} } + end + assert_response :success + end + + test "should allow destroy for restricted user who owns the hosts" do + assert_difference('Host.count', -1) do + as_user :restricted do + delete :destroy, { :id => hosts(:owned_by_restricted).to_param } + end + end + assert_response :success + end + + test "should allow show status for restricted user who owns the hosts" do + as_user :restricted do + get :status, { :id => hosts(:owned_by_restricted).to_param } + end + assert_response :success + end + + test "should not allow access to a host out of users hosts scope" do + as_user :restricted do + get :show, { :id => hosts(:one).to_param } + end + assert_response :not_found + end + + test "should not list a host out of users hosts scope" do + as_user :restricted do + get :index, {} + end + assert_response :success + hosts = ActiveSupport::JSON.decode(@response.body) + ids = hosts.map { |hash| hash['host']['id'] } + assert !ids.include?(hosts(:one).id) + assert ids.include?(hosts(:owned_by_restricted).id) + end + + test "should not update host out of users hosts scope" do + as_user :restricted do + put :update, { :id => hosts(:one).to_param } + end + assert_response :not_found + end + + test "should not delete hosts out of users hosts scope" do + as_user :restricted do + delete :destroy, { :id => hosts(:one).to_param } + end + assert_response :not_found + end + + test "should not show status of hosts out of users hosts scope" do + as_user :restricted do + get :status, { :id => hosts(:one).to_param } + end + assert_response :not_found + end end