You are here

function oa_core_file_entity_access in Open Atrium Core 7.2

Implements hook_file_entity_access().

Check permissions of private files based upon the node they are attached to

File

includes/oa_core.access.inc, line 373
Code for Access Control functions for OpenAtrium spaces

Code

function oa_core_file_entity_access($op, $file, $account) {
  if (is_object($file) && in_array($op, array(
    'view',
    'download',
  ))) {
    $scheme = file_uri_scheme($file->uri);
    $wrapper = file_entity_get_stream_wrapper($scheme);
    if (!empty($wrapper['private'])) {
      $query = db_select('node', 'n');
      if (user_access('view revisions')) {
        $query
          ->join('field_revision_field_oa_media', 'f', "n.nid = f.entity_id AND f.entity_type = 'node'");
      }
      else {
        $query
          ->join('field_data_field_oa_media', 'f', "n.nid = f.entity_id AND f.entity_type = 'node'");
      }
      $nids = $query
        ->fields('n', array(
        'nid',
      ))
        ->condition('f.field_oa_media_fid', $file->fid)
        ->addTag('node_access')
        ->execute()
        ->fetchCol(0);

      // add paragraph references
      if (module_exists('paragraphs')) {
        $query = db_select('node', 'n');
        if (user_access('view revisions')) {
          $query
            ->join('field_revision_field_oa_related', 'r', "n.nid = r.entity_id AND r.entity_type = 'node'");
          $query
            ->join('field_revision_field_oa_media', 'f', "r.field_oa_related_value = f.entity_id AND f.entity_type = 'paragraphs_item'");
        }
        else {
          $query
            ->join('field_data_field_oa_related', 'r', "n.nid = r.entity_id AND r.entity_type = 'node'");
          $query
            ->join('field_data_field_oa_media', 'f', "r.field_oa_related_value = f.entity_id AND f.entity_type = 'paragraphs_item'");
        }
        $related_nids = $query
          ->fields('n', array(
          'nid',
        ))
          ->condition('f.field_oa_media_fid', $file->fid)
          ->addTag('node_access')
          ->execute()
          ->fetchCol(0);
        $nids = array_merge($nids, $related_nids);
      }
      if (!empty($nids)) {
        $nids = array_unique($nids);

        // Ensure the user *really* has access to the nodes
        // since addTag('node_access') doesn't call node_access hooks.
        // Since the number of nodes the file is attached to is small, this
        // shouldn't be a performance issue.
        if (user_access('view files', $account)) {
          foreach ($nids as $nid) {
            if (($node = node_load($nid)) && node_access('view', $node, $account)) {
              return FILE_ENTITY_ACCESS_ALLOW;
            }
          }
        }

        // Otherwise, file is attached to nodes we don't have access to
        // so deny access.
        return FILE_ENTITY_ACCESS_DENY;
      }
      else {

        // File is not attached to a node we have specific node grants for
        // so now check if file is attached to ANY other revision.
        $query = db_select('node', 'n');
        $query
          ->join('field_revision_field_oa_media', 'f', "n.nid = f.entity_id AND f.entity_type = 'node'");
        $nids = $query
          ->fields('n', array(
          'nid',
        ))
          ->condition('f.field_oa_media_fid', $file->fid)
          ->execute()
          ->fetchCol(0);

        // add paragraph references
        if (module_exists('paragraphs')) {
          $query = db_select('node', 'n');
          $query
            ->join('field_data_field_oa_related', 'r', "n.nid = r.entity_id AND r.entity_type = 'node'");
          $query
            ->join('field_data_field_oa_media', 'f', "r.field_oa_related_value = f.entity_id AND f.entity_type = 'paragraphs_item'");
          $related_nids = $query
            ->fields('n', array(
            'nid',
          ))
            ->condition('f.field_oa_media_fid', $file->fid)
            ->execute()
            ->fetchCol(0);
          $nids = array_merge($nids, $related_nids);
        }
        if (empty($nids)) {

          // File is not referenced by any node revision, so allow it if they can access content
          // Open Atrium treats unattached files as public since everything is
          // stored in the private file system.
          if (user_access('access content', $account) && user_access('view files', $account) && !user_access('view private files', $account)) {

            // Default Open Atrium permissions are set, so allow access.
            return FILE_ENTITY_ACCESS_ALLOW;
          }
          else {
            return FILE_ENTITY_ACCESS_IGNORE;
          }
        }
        else {

          // File is referenced by node that we don't have access to, so deny.
          return FILE_ENTITY_ACCESS_DENY;
        }
      }
    }
  }
  return FILE_ENTITY_ACCESS_IGNORE;
}