0

We have a Drupal 7 site that uses a bespoke login module for ordinary users. Certain (administrative) user rôles, however, must use the core login form at /user to log in, as they have escalated privileges. Regular users get a login form at / (redirected from any URL when not logged in) and cannot log in at /user; administrative users cannot log in at /, but must use the form at /user — these two forms ask different login questions.

We would like to be able to restrict the /user login form to a whitelist of IP addresses, so that only users coming from known IPs can use this form to log in. This would seem simple, at a first glance, as we could use Apache to reject requests for ^/user$ coming from non-whitelisted IPs, except that Drupal also uses /user as a redirect to the currently-logged-in users's profile page and this link appears in a handful of locations in our site.

Now I don't want to go hacking through Core, but I can't see how I can enforce the whitelist for anonymous users, whilst allowing any authenticated user to access their own profile page on the URL /user.

Should I go through everywhere that we link to /user (including the menu block) to substitute in the user's profile ID, or is there some more-elegant solution that I'm just not seeing?

All suggestions gratefully received :o)

2

I'm not sure this is necessarily the 'best' way to handle this but you could override the access callback for the user and user/login paths in a custom module and do your whitelist check in there:

function MYMODULE_menu_alter(&$items) {
  $items['user']['access callback'] = 'MYMODULE_access_callback';
  $items['user/login']['access callback'] = 'MYMODULE_access_callback';
}

function MYMODULE_access_callback() {
  global $user;

  if ($user->uid) {
    // If a logged in user is trying to access the login page, deny access
    if (arg(0) == 'user' && arg(1) == 'login') {
      return FALSE;
    }

    // Otherwise let the user see their page
    return TRUE;
  }

  // If we've got this far the user is not logged in and the access
  // is based on the whitelist
  $whitelist = get_whitelist_array();
  if (in_array(ip_address(), $whitelist)) {
    return TRUE;
  }

  return FALSE;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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