Move Direct File Upload access control to the routing layer

Created on 2 August 2023, over 1 year ago
Updated 30 August 2023, over 1 year ago

Problem/Motivation

In πŸ“Œ [META] Modernise file upload logic Active we want to unify the file upload logic. Currently REST and JSON API do access checking directly in the controller.

I think we should explore moving the access to routing, just to confirm it can be done.

Steps to reproduce

Proposed resolution

Move access checking for direct api file uploads to the routing layer.

πŸ“Œ Task
Status

Needs work

Version

11.0 πŸ”₯

Component
File moduleΒ  β†’

Last updated 6 days ago

Created by

πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

Live updates comments and jobs are added and updated live.
  • Needs architectural review

    The issue is available for high level reviews only. If there is a patch or MR it is not to be set to 'Needs work' for coding standards, minor or nit-pick changes.

Sign in to follow issues

Comments & Activities

  • Issue created by @kim.pepper
  • last update over 1 year ago
    29,951 pass, 2 fail
  • @kimpepper opened merge request.
  • Status changed to Needs review over 1 year ago
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    Added the access check.

    Remaining tasks

    • work out how to wire it up with REST and JSON API routing.
    • Consider using a param converter for entity type instead of passing the $entity_type_id
  • last update over 1 year ago
    29,963 pass
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    Looking at how to extract the path parameters for JSON API and REST.

    REST uses:

    "/file/upload/{entity_type_id}/{bundle}/{field_name}"

    JSON API adds Routes like:

    new Route("/{$path}/{file_field_name}");
    

    Where {$path} is 'resource_type/bundle' and isn't set as a URL parameter.

    We may need to have a separate access check for JSON API that extracts those values.

  • last update over 1 year ago
    29,963 pass
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    We should be able to add the access check to the REST route via an route alter event subscriber.

  • last update over 1 year ago
    29,902 pass, 9 fail
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    This is what our JSON API route definition looks like now:

    name: jsonapi.user--user.file_upload.existing_resource
    path: '/jsonapi/user/user/{entity}/{file_field_name}'
    defaults:
      _controller: 'jsonapi.file_upload:handleFileUploadForExistingResource'
      entity_type_id: user
      bundle: user
      field_name: '{file_field_name}'
      resource_type: user--user
      _is_jsonapi: true
    requirements:
      _csrf_request_header_token: 'TRUE'
      _file_upload_access: 'TRUE'
      _content_type_format: bin
      _format: api_json
    options:
      parameters:
        entity:
          type: 'entity:user'
          converter: paramconverter.jsonapi.entity_uuid
        resource_type:
          type: jsonapi_resource_type
          converter: paramconverter.jsonapi.resource_type
      _auth:
        - cookie
      _access_checks:
        - file.upload_access_check
        - access_check.header.csrf
    
    
  • last update over 1 year ago
    29,914 pass, 6 fail
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    Here's the new route definition for REST

    name: rest.file.upload.POST
    path: '/file/upload/{entity_type_id}/{bundle}/{field_name}'
    defaults:
      _controller: 'Drupal\rest\RequestHandler::handleRaw'
      _rest_resource_config: file.upload
    requirements:
      _access: 'TRUE'
      _content_type_format: bin
      _csrf_request_header_token: 'TRUE'
      _format: json
      _file_upload_access: 'TRUE'
    options:
      _auth:
        - cookie
      parameters:
        _rest_resource_config:
          type: 'entity:rest_resource_config'
          converter: paramconverter.entity
      _access_checks:
        - access_check.default
        - file.upload_access_check
        - access_check.header.csrf
    
  • last update over 1 year ago
    29,936 pass, 3 fail
  • last update over 1 year ago
    29,923 pass, 4 fail
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    Looking at the test fails, I'm not sure what we should be doing.

    JSON API expects a 404 Not Found when an entity or field doesn't exist. However this is being forbidden by our access checker.

    I'm trying to understand how entity field access works.

    If we return Neutral when our entity or field doesn't exist, that still won't Allow access, right? as this happens in the routing layer.

  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia

    Answering my own question here...

    Looking at how other access checks work, we only need to check for access if we do have an entity and the field exists. Otherwise we defer access to another checker.

    This should me we return neutral for those conditions in #8.

    That is:

  • last update over 1 year ago
    29,923 pass, 4 fail
  • πŸ‡¦πŸ‡ΊAustralia kim.pepper πŸ„β€β™‚οΈπŸ‡¦πŸ‡ΊSydney, Australia
  • Status changed to Needs work over 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Seems to have open threads and test failures. Moving to NW for those.

Production build 0.71.5 2024