2

I am using Views Access Callback module to set my custom callback access check. I have written a custom module and implemented the hook provided by this module. I have added a condition to return TRUE and FALSE. But the access callback get cached.

/**
 * Implements hook_views_access_callbacks().
 */
function my_custom_views_access_callbacks() {
  return array('my_custom_module_access' => t('Allow my views access.'));
}
function my_custom_module_access() {
  $password = \Drupal::config('my_custom.settings')->get('my_custom.pass');
  if (isset($_SESSION['my_custom_pass']) && $_SESSION['my_custom_pass'] == Crypt::hashBase64($password)) {
    return TRUE;
  }
  return FALSE; 
}

I have added callback like above. So when I drush cr from command line it will return FALSE because there is no session in terminal. So when I access the view in browser it still shows access denied because of cache I guess.

My question is how to handle this callback without being cached?

4
  • 1
    Sounds like the module is flawed, it needs to allow to return an access result object to add cacheablity metadata. Implementing your own access plugin isn't that hard, try doing that.
    – Berdir
    Commented Aug 16, 2016 at 19:52
  • Actually I have ported the module. According the views access plugin in core, like Permission access plugin, we have to return true or false and not the access result object. class ViewsAccessCallback extends AccessPluginBase Commented Aug 17, 2016 at 6:05
  • Yes, I think there is an open bug report about this in core, right...
    – Berdir
    Commented Aug 17, 2016 at 8:15
  • Oh ok. Thanks. Will need to try another solution then. :) Commented Aug 17, 2016 at 8:30

2 Answers 2

1

I did this using following way :

function my_custom_preprocess_page(&$variables) {
  $url = Drupal\Core\Url::fromRoute('<current>');
  if ($url->getInternalPath() == 'my-view-page') {
    $password = \Drupal::config('my_custom.settings')->get('my_custom.pass');
    if (!isset($_SESSION['my_custom_pass']) || (isset($_SESSION['my_custom_pass']) && $_SESSION['my_custom_pass'] != Crypt::hashBase64($password))) {
      throw new AccessDeniedHttpException();
    }
  }
}

Edit: We can add our dependency to access object in our access hook.

/**
 * Implements hook_node_access().
 */
function my_custom_node_access(NodeInterface $node, $operation, AccountInterface $account) {
  $access = new AccessResultNeutral();
  $password = \Drupal::config('my_custom.settings')->get('my_custom.pass');
  if (!isset($_SESSION['my_custom_pass']) || (isset($_SESSION['my_custom_pass']) && $_SESSION['my_custom_pass'] != Crypt::hashBase64($password))) {
    $access = new AccessResultForbidden();
  }
  $access->addCacheableDependency($_SESSION);
  return $access;
}
0

The hook_ENTITY_TYPE_access() should return \Drupal\Core\Access\AccessResultInterface type. This is missing here, try

use Drupal\Core\Access\AccessResult;
    function my_custom_school_access() {
        $password = \Drupal::config('my_custom.settings')->get('my_custom.pass');
        if (isset($_SESSION['my_custom_pass']) && $_SESSION['my_custom_pass'] == Crypt::hashBase64($password)) {
           return AccessResult::allowed();
        }
        return AccessResult::forbidden();
    }
2
  • Thanks but Its not hook_ENTITY_TYPE_access, its the access callback used for module. See module's API.php file. Commented Aug 16, 2016 at 14:46
  • Updated my question. Please check. Commented Aug 16, 2016 at 14:52

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.