Drupal - Prevent users from editing or viewing their own profile

Add this to a custom module:

function MYMODULE_menu_alter(&$items) {
  $items['user/%user']['access arguments'] = array('access user profiles');
  $items['user/%user']['access callback'] = 'user_access';
  $items['user/%user/edit']['access arguments'] = array('administer users');
  $items['user/%user/edit']['access callback'] = 'user_access';
}

This will put the user profile view under 'View user profiles' permission and edit under 'Administer users'.


Since the question doesn't seem to be specific for Drupal 7, here's how you do it in Drupal 8. hook_menu_alter is no more, now you use a RouteSubscriber. You can see how this works here: https://www.drupal.org/docs/8/api/routing-system/altering-existing-routes-and-adding-new-routes-based-on-dynamic-ones

The RouteSubscriber would look like this:

<?php

namespace Drupal\my_module\Services;

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) {

    // Edit user
    if ($route = $collection->get('entity.user.edit_form')) {
      $route->setRequirement('_permission', 'administer users');
    }

    // View user
    if ($route = $collection->get('entity.user.canonical')) {
      $route->setRequirement('_permission', 'administer users');
    }
  }
}

The route names are taken from the core user module. In "setRequirement" you can do everything you can do in the normal route config. Note that setRequirement adds a permission (or role etc), but the ["_entity_access"] => "user.update" requirement is also still part of the route.

Then you need to register the service in your module's service yaml file:

services:
  my_module.route_subscriber:
    class: Drupal\my_module\Services\RouteSubscriber
    tags:
      - { name: event_subscriber }

Tags:

Users

7