diff --git a/app/decorators/include_space_decorator.rb b/app/decorators/include_space_decorator.rb index a60d966f1c6..19959a6eb5a 100644 --- a/app/decorators/include_space_decorator.rb +++ b/app/decorators/include_space_decorator.rb @@ -8,12 +8,24 @@ def match?(include) def decorate(hash, resources) hash[:included] ||= {} space_guids = resources.map(&:space_guid).uniq - spaces = Space.where(guid: space_guids).order(:created_at). - eager(Presenters::V3::SpacePresenter.associated_resources).all + spaces_query = Space.where(guid: space_guids).order(:created_at). + eager(Presenters::V3::SpacePresenter.associated_resources) + spaces_query = with_readable_space_guids(spaces_query) - hash[:included][:spaces] = spaces.map { |space| Presenters::V3::SpacePresenter.new(space).to_hash } + hash[:included][:spaces] = spaces_query.all.map { |space| Presenters::V3::SpacePresenter.new(space).to_hash } hash end + + private + + # This method is used to filter out spaces that the user does not have read access to. + # An org_auditor can read routes in a space, but not the space itself. + def with_readable_space_guids(spaces_query) + permission_queryer = Permissions.new(SecurityContext.current_user) + return spaces_query if permission_queryer.can_read_globally? + + spaces_query.where(guid: permission_queryer.readable_space_guids_query) + end end end end diff --git a/spec/request/routes_spec.rb b/spec/request/routes_spec.rb index 473bfe1d128..02645c60480 100644 --- a/spec/request/routes_spec.rb +++ b/spec/request/routes_spec.rb @@ -1092,6 +1092,21 @@ ] ) end + + context 'user is org_auditor' do + let(:user_header) { set_user_with_header_as_role(user: user, role: 'org_auditor', org: org) } + + it 'includes the unique organizations for the routes, but no spaces' do + get "/v3/routes/#{route.guid}?include=space,space.organization", nil, user_header + expect(last_response).to have_status_code(200) + expect(parsed_response['included']).to match_json_response( + 'spaces' => [], + 'organizations' => [ + org_json_generator.call(org) + ] + ) + end + end end end end diff --git a/spec/unit/decorators/include_space_decorator_spec.rb b/spec/unit/decorators/include_space_decorator_spec.rb index 02478804fe4..8abe68676a8 100644 --- a/spec/unit/decorators/include_space_decorator_spec.rb +++ b/spec/unit/decorators/include_space_decorator_spec.rb @@ -7,6 +7,10 @@ module VCAP::CloudController let(:space2) { Space.make(name: 'second-space') } let(:apps) { [AppModel.make(space: space1), AppModel.make(space: space2), AppModel.make(space: space1)] } + before do + allow(Permissions).to receive(:new).and_return(double(can_read_globally?: true)) + end + it 'decorates the given hash with spaces from apps' do undecorated_hash = { foo: 'bar' } hash = subject.decorate(undecorated_hash, apps)