1

I am trying to create a module with custom access checks.

I would like to know what additional features does implementing AccessInterface provide.

For example I can check access within the controller using access method.

But there is also a way to create a separate access checker file as below.

My Code is as follows what difference does both have.

access_check_examples.routing.yml

access_check_examples.build:
  path: '/examples-codes/access-check-examples/build'
  defaults:
    _title: 'Access Check Build Controller'
    _controller: '\Drupal\access_check_examples\Controller\AccessCheckController::build'
  requirements:
    _custom_access: '\Drupal\access_check_examples\Controller\AccessCheckController::access'

access_check_examples.info:
  path: '/examples-codes/access-check-examples/info'
  defaults:
    _title: 'Access Check Info Controller'
    _controller: '\Drupal\access_check_examples\Controller\AccessCheckController::info'
  requirements:
    _custom_role_access_check: 'TRUE'

AccessCheckController.php

namespace Drupal\access_check_examples\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Session\AccountInterface;

/**
 * Returns responses for Access Check routes.
 */
class AccessCheckController extends ControllerBase {

  /**
   * Builds the response.
   */
  public function build() {

    $build['content'] = [
      '#type' => 'item',
      '#markup' => $this->t('It works!'),
    ];

    return $build;
  }

  /**
   * Builds the response.
   */
  public function info() {

    $build['content'] = [
      '#type' => 'item',
      '#markup' => $this->t('It works!'),
    ];

    return $build;
  }


  /**
   * Checks access for a specific request.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Run access checks for this account.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(AccountInterface $account) {

    $uid = $account->id();
    return AccessResult::allowedIf($account->hasPermission('administer access check examples configuration') && $uid == 1);
  }

}

access_check_examples.services.yml

services:
  access_check.access_check_examples.custom_role_access_check:
    class: Drupal\access_check_examples\Access\CustomRoleAccessCheck
    arguments: ['@database','@messenger','@logger.factory','@date.formatter']
    tags:
      - { name: access_check, applies_to: _custom_role_access_check }

CustomRoleAccessCheck.php

namespace Drupal\access_check_examples\Access;

use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Symfony\Component\Routing\Route;
use Drupal\Core\Database\Connection;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Session\AccountInterface;


/**
 * Checks if the route has required permission.
 *
 */
class CustomRoleAccessCheck implements AccessInterface {

    /**
   * Database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * Date formatter.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * The Messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * Logger service.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $logger;

  /**
   * UserLoginSubscriber constructor.
   *
   * @param \Drupal\Core\Database\Connection $database
   *   The database service.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger
   *   The logger service.
   * @param \Drupal\Core\Datetime\DateFormatter $date_formatter
   *   The date formatter service.
   */
  public function __construct(Connection $database, MessengerInterface $messenger, LoggerChannelFactoryInterface $logger, DateFormatter $date_formatter) {
    $this->database = $database;
    $this->messenger = $messenger;
    $this->logger = $logger->get('access_check_examples');
    $this->dateFormatter = $date_formatter;

  }

  /**
   * A custom access check.
   *
   * @param \Symfony\Component\Routing\Route $route
   *   The route to check against.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Run access checks for this account.
   *
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
   */
  public function access(Route $route,AccountInterface $account) {

    if (!$route->hasRequirement('_custom_role_access_check')) {
      return AccessResult::neutral();
    }

    $uid = $account->id();
     $this->messenger->addMessage(t('Your UID is :  %uid', ['%uid' => $uid]), 'notice');

    $this->logger->notice('Your UID is :  @uid', ['@uid' => $uid]);

    return AccessResult::allowedIf(!$account->hasPermission('administer access check examples configuration') && $uid == 1)->addCacheContexts(['route']);
  }


}

There is a similar question in regards but can not get required info from there. Can anyone please provide the differences between both.

6
  • 2
    Access checks are always placed in tagged services. Drupal core provides CustomAccessCheck, which is tagged the same way, for convenient reasons so that a simple module is able to provide content and access checks in a single controller class. See drupal.stackexchange.com/questions/221891/…
    – 4uk4
    Jun 11, 2020 at 18:10
  • I can't tell what you're asking. You seem to be asking what a custom access controller is, but you've already created one, so I can't understand why you wouldn't know what that is.
    – Jaypan
    Jun 12, 2020 at 13:43
  • Hi @Jaypan , I wanted to know why there are two ways to implement access check and what is difference between the both. Jun 12, 2020 at 14:12
  • Hi @4k4 , Thank you for the response, so basically controller has access method for convenient purpose but actually it is also a derivative of tagged service right ? Jun 12, 2020 at 14:15
  • Yes, exactly, the service CustomAccessCheck you call through _custom_access has no access method of its own but instantiates the controller to run the access method you have specified.
    – 4uk4
    Jun 12, 2020 at 14:34

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.