You are here

function apigee_edge_apiproduct_rbac_form_apigee_edge_api_product_access_control_form_alter in Apigee Edge 8

Implements hook_form_FORM_ID_alter().

Adds RBAC settings to the API product access control form.

File

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

Code

function apigee_edge_apiproduct_rbac_form_apigee_edge_api_product_access_control_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $config = \Drupal::config(APIGEE_EDGE_APIPRODUCT_RBAC_CONFIG_SETTINGS);
  $current_rbac_attr_name = $config
    ->get('attribute_name');
  $api_product_storage = \Drupal::entityTypeManager()
    ->getStorage('api_product');

  // Parent form has already calculated these for us.
  $role_names = $form['access']['role_names']['#value'];
  $roles_with_bypass_perm = $form['access']['roles_with_bypass']['#value'];
  $form['access']['rbac-warning'] = [
    '#theme' => 'status_messages',
    '#message_list' => [
      'warning' => [
        t('Access by visibility is disabled by the <em>Apigee Edge API Product RBAC</em> module.'),
      ],
    ],
    '#weight' => -100,
  ];
  $form['access']['#open'] = FALSE;
  $form['access']['visibility']['#access'] = FALSE;
  $form['rbac'] = [
    '#type' => 'details',
    '#title' => t('Access by API product'),
    '#description' => t('Allows to grant view access to an API product only to certain roles.'),
    '#open' => TRUE,
    '#tree' => TRUE,
  ];
  $form['rbac']['attribute_name'] = [
    '#type' => 'textfield',
    '#title' => t('Attribute name'),
    '#description' => t('Name of the attribute on API products that stores role assignments.'),
    '#default_value' => $config
      ->get('attribute_name'),
    '#required' => TRUE,
  ];
  $form['rbac']['original_attribute_name'] = [
    '#type' => 'value',
    '#value' => $config
      ->get('attribute_name'),
  ];
  $form['rbac']['grant_access_if_attribute_missing'] = [
    '#type' => 'checkbox',
    '#title' => t('Show API products with missing or empty attribute to everyone'),
    '#description' => t('If this checkbox is disabled only users with <em>Bypass API product access control</em> permission can view and assign an API product with missing or empty attribute to a developer app.'),
    '#default_value' => $config
      ->get('grant_access_if_attribute_missing'),
  ];

  // Store $role_names for use when saving the data.
  $form['rbac']['role_names'] = $form['access']['role_names'];

  // Store $rolesWithBypassPerm for use when saving the data.
  $form['rbac']['roles_with_bypass'] = $form['access']['roles_with_bypass'];
  $form['rbac']['api_products'] = [
    '#type' => 'table',
    '#header' => [
      t('API products'),
    ],
    '#id' => 'rbac-settings',
    '#attributes' => [
      'class' => [
        'rbac-settings',
        'js-rbac-settings',
      ],
    ],
    '#sticky' => TRUE,
  ];
  foreach ($role_names as $rid => $name) {
    $form['rbac']['api_products']['#header'][] = [
      'data' => "{$name} ({$rid})",
      'class' => [
        'checkbox',
      ],
    ];
  }

  /** @var \Drupal\apigee_edge\Entity\ApiProductInterface[] $api_products */
  $api_products = $api_product_storage
    ->loadMultiple();

  // Sort products alphabetically (display name is an attribute so sorting in
  // the query level does not work).
  uasort($api_products, function (ApiProductInterface $a, ApiProductInterface $b) {

    // Ignore case and malicious characters.
    return strcmp(mb_strtolower(Xss::filter($a
      ->getDisplayName())), mb_strtolower(Xss::filter($b
      ->getDisplayName())));
  });
  $product_names = [];
  foreach ($api_products as $product_name => $product) {
    $product_names[$product_name] = $product
      ->getDisplayName();
    $form['rbac']['api_products'][$product_name]['name'] = [
      '#type' => 'html_tag',
      '#tag' => 'span',
      '#value' => $product
        ->getDisplayName(),
      '#attributes' => [
        'class' => 'api-product-name',
      ],
    ];

    // Fetch role names for API Product.
    $selectedRoles = [];
    if (!empty($product
      ->getAttributeValue($current_rbac_attr_name))) {
      $selectedRoles = explode(APIGEE_EDGE_APIPRODUCT_RBAC_ATTRIBUTE_VALUE_DELIMITER, $product
        ->getAttributeValue($current_rbac_attr_name));
    }
    foreach ($role_names as $rid => $name) {
      $form['rbac']['api_products'][$product_name][$rid] = [
        '#title' => $product
          ->getDisplayName(),
        '#title_display' => 'invisible',
        '#wrapper_attributes' => [
          'class' => [
            'checkbox',
          ],
        ],
        '#type' => 'checkbox',
        '#default_value' => in_array($rid, $selectedRoles) ? 1 : 0,
        '#attributes' => [
          'class' => [
            'rid-' . $rid,
            'js-rid-' . $rid,
          ],
        ],
        '#parents' => [
          'rbac',
          $rid,
          $product_name,
        ],
      ];

      // Show a column of disabled but checked checkboxes.
      if ($roles_with_bypass_perm[$rid]) {
        $form['rbac']['api_products'][$product_name][$rid]['#disabled'] = TRUE;
        $form['rbac']['api_products'][$product_name][$rid]['#default_value'] = TRUE;
        $form['rbac']['api_products'][$product_name][$rid]['#attributes']['title'] = t('This checkbox is disabled because this role has "Bypass API product access control" permission.');
      }
    }
  }

  // Store name => display name mapping for use when saving the data.
  $form['rbac']['api_products']['product_names'] = [
    '#type' => 'value',
    '#value' => $product_names,
  ];
  $form['#attached']['library'][] = 'apigee_edge_apiproduct_rbac/admin';
  $form['#submit'][] = 'apigee_edge_apiproduct_rbac_form_apigee_edge_api_product_access_control_form_submit';
}