How to prevent certain users from adding (for example, a Node) to bookmarks with Flag Module Flag Module >>> https://www.drupal.org/project/flag

How to disable/prevent some Users (NOT Roles) from adding (for example a Node) to bookmarks? Maybe showing a message after clicking on the Boomark button (You are not authorized to make this choice or something like that).
I assume you use Drupal 8:

Flag action handled by \Drupal\flag\Controller\ActionLinkController::flag so i think you should override this to check on your user and prevent to flag bookmarks nodes:


Override ActionLinkController controller using RouteSubscriber like the following:
Add the following to YOUR_MODULE_NAME.services.yml 




services:
  YOUR_MODULE_NAME.route_subscriber:
    class: Drupal\YOUR_MODULE_NAME\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }



Create YOUR_MODULE_NAME/src/Routing/RouteSubscriber.php

&lt;?php
namespace Drupal\YOUR_MODULE_NAME\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Change the route associated with /flag/flag/{flag}/{entity_id}.
    if ($route = $collection-&gt;get('flag.action_link_flag')) {
      $route-&gt;setDefault('_controller', '\Drupal\YOUR_MODULE_NAME\Controller\MyCustomActionLinkController::flag');
    }
  }

}



Create your new Controller YOUR_MODULE_NAME/src/Controller/MyCustomActionLinkController.php like the following:




namespace Drupal\YOUR_MODULE_NAME\Controller;

use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Entity\EntityInterface;
use Drupal\flag\Ajax\ActionLinkFlashCommand;
use Drupal\flag\Controller\ActionLinkController;
use Drupal\flag\FlagInterface;

class MyCustomActionLinkController extends ActionLinkController {

  /**
   * Performs a flagging when called via a route.
   *
   * @param \Drupal\flag\FlagInterface $flag
   *   The flag entity.
   * @param int $entity_id
   *   The flaggable entity ID.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse|null
   *   The response object, only if successful.
   *
   * @see \Drupal\flag\Plugin\Reload
   */
  public function flag(FlagInterface $flag, $entity_id) {
    /* @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $this->flagService->getFlaggableById($flag, $entity_id);
    $uid = \Drupal::currentUser()->id();
    // Do your check here i just test with the user admin.
    if ($uid == 1) {
      // Change the message you want to show 
      $flag->setFlagMessage("Sorry you don't have right to bookmark this");
      return $this->generateResponse($flag, $entity, $flag->getMessage('flag'));
    }
    else {
      try {
        $this->flagService->flag($flag, $entity);
      } catch (\LogicException $e) {
        // Fail silently so we return to the entity, which will show an updated
        // link for the existing state of the flag.
      }
      return $this->generateResponse($flag, $entity, $flag->getMessage('flag'));
    }
  }

  /**
   * Generates a response after the flag has been updated.
   *
   * @param \Drupal\flag\FlagInterface $flag
   *   The flag entity.
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity object.
   * @param string $message
   *   (optional) The message to flash.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   The response object.
   */
  private function generateResponse(FlagInterface $flag, EntityInterface $entity, $message) {
    // Create a new AJAX response.
    $response = new AjaxResponse();

    // Get the link type plugin.
    $link_type = $flag->getLinkTypePlugin();

    // Generate the link render array.
    $link = $link_type->getAsFlagLink($flag, $entity);

    // Generate a CSS selector to use in a JQuery Replace command.
    $selector = '.js-flag-' . Html::cleanCssIdentifier($flag->id()) . '-' . $entity->id();

    // Create a new JQuery Replace command to update the link display.
    $replace = new ReplaceCommand($selector, $this->renderer->renderPlain($link));
    $response->addCommand($replace);

    // Push a message pulsing command onto the stack.
    $pulse = new ActionLinkFlashCommand($selector, $message);
    $response->addCommand($pulse);

    return $response;
  }
}



Notes:


You may need to do the same the route flag.action_link_flag_nojs.
I reimplement the method generateResponse because it has a private visibility.