You are here

function apigee_edge_apiproduct_rbac_api_product_access in Apigee Edge 8

Implements hook_ENTITY_TYPE_access().

Supported operations: view, view label, assign.

See also

apigee_edge_api_product_access()

File

modules/apigee_edge_apiproduct_rbac/apigee_edge_apiproduct_rbac.module, line 56
Copyright 2018 Google Inc.

Code

function apigee_edge_apiproduct_rbac_api_product_access(EntityInterface $entity, $operation, AccountInterface $account) {

  /** @var \Drupal\apigee_edge\Entity\ApiProductInterface $entity */
  if (!in_array($operation, [
    'view',
    'view label',
    'assign',
  ])) {
    return AccessResult::neutral(sprintf('%s is not supported by %s.', $operation, __FUNCTION__));
  }
  $result = AccessResult::allowedIfHasPermission($account, 'bypass api product access control');
  if ($result
    ->isNeutral()) {
    $config = \Drupal::config(APIGEE_EDGE_APIPRODUCT_RBAC_CONFIG_SETTINGS);
    $rbac_attribute_name = $config
      ->get('attribute_name');
    if (empty($entity
      ->getAttributeValue($rbac_attribute_name))) {
      if ('assign' === $operation) {
        $result = AccessResult::neutral("{$operation} is not allowed on {$entity->label()} API product.");
      }
      elseif ($config
        ->get('grant_access_if_attribute_missing')) {
        $result = AccessResult::allowed();
      }
      else {
        $result = _apigee_edge_user_has_an_app_with_product($entity
          ->id(), $account, TRUE);
        if (!$result
          ->isAllowed()) {
          $result = AccessResult::neutral("{$rbac_attribute_name} attribute on the API product is missing or empty.");
        }
      }
    }
    else {
      $roles = explode(APIGEE_EDGE_APIPRODUCT_RBAC_ATTRIBUTE_VALUE_DELIMITER, $entity
        ->getAttributeValue($rbac_attribute_name));

      // A user may not have access to this API product based on the current
      // access control attribute value but we should still grant access
      // if they have a developer app in association with this API product.
      // We should not provide access if operation is "assign" just
      // because they have an app with the API product.
      // Displaying these products should be solved on the form level always.
      if (empty(array_intersect($roles, $account
        ->getRoles()))) {
        if ('assign' === $operation) {
          $result = AccessResult::neutral("{$operation} is not allowed on {$entity->label()} API product.");
        }
        else {
          $result = _apigee_edge_user_has_an_app_with_product($entity
            ->id(), $account, TRUE);
          if (!$result
            ->isAllowed()) {
            $result = AccessResult::neutral(sprintf('%s user neither has any of %s roles nor an app with %s API product.', $account
              ->getEmail(), rtrim(implode(APIGEE_EDGE_APIPRODUCT_RBAC_ATTRIBUTE_VALUE_DELIMITER, $roles)), $entity
              ->label()));
          }
        }
      }
      else {
        $result = AccessResult::allowed();
      }
    }
  }
  return $result
    ->addCacheableDependency($entity)
    ->cachePerUser()
    ->addCacheTags([
    'config:' . APIGEE_EDGE_APIPRODUCT_RBAC_CONFIG_SETTINGS,
  ]);
}