1

I am trying to do the following thing:

-> Authenticate a user against Drupal. -> Get all information about user (including email address!)

So far I have tried to use the Drupal module services for this. I created a new service 'system' and activated the resource 'login','index' and 'retrieve'. I create a new admin user 'servicesAdmin' and gave him all the permissions (on Drupal side) there are available for the 'Services' module.

I created this little standalone PHP script to test my new service. It basically does three things:

STEP1 Login of test user 'tom'. This returns everything about Tom, but NOT the email Address:

STEP2 Login of the user 'servicesAdmin'. This returns the necessary session name, session id etc.

STEP3 Retrieving all information about user 'tom'. And here is the problem: If user 'servicesAdmin' has full admin rights, STEP3 will return the email address, if not it will only return all the fields but NOT the email address?

What can I do get email address without making the user 'serviceAmdin' to be a full administrator?

Thanks, Uwe Here is the code

$curl_options_post = array
(
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HEADER         => false,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_ENCODING       => "gzip,deflate",
  CURLOPT_USERAGENT      => "login", // who am i
  CURLOPT_AUTOREFERER    => true,     // set referer on redirect
  CURLOPT_CONNECTTIMEOUT => 0,      // timeout on connect
  CURLOPT_TIMEOUT        => 80,      // timeout on response
  CURLOPT_MAXREDIRS      => 10,       // stop after 10 redirects
  CURLOPT_POST            =>true
);
$curl_options_get = array
(
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HEADER         => false,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_USERAGENT      => "login"
  CURLOPT_AUTOREFERER    => true
  CURLOPT_CONNECTTIMEOUT => 0,
  CURLOPT_TIMEOUT        => 80,
  CURLOPT_MAXREDIRS      => 10, 
  CURLOPT_POST     =>false
);
//STEP1: login - authenticating user against Drupal portal.
$data = array('username'=>'tom','password'=>'password');
$url = '/portal.localhost/services/system/user/login.json';

$ch = curl_init($url);
curl_setopt_array( $ch, $curl_options_post);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $data); 
curl_response = curl_exec($ch);
curl_close($ch);
$user_login= json_decode($curl_response);
$uid = $user_login->user->uid;


//STEP2: Login 'servicesAdmin'
$data = array('username'=>'servicesAdmin','password'=>'password2');
$url = 'http://portal.localhost/services/system/user/login.json';
$ch = curl_init($url);
curl_setopt_array( $ch, $curl_options_post);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $data);
$curl_response = curl_exec($ch);
curl_close($ch);
$admin_login= json_decode($curl_response);



//STEP3: Retrieve all information about user with '$uid'

$url = 'http://portal.localhost/services/system/user/'.$uid.'.json?parameters[field]=mail,uid';
$ch = curl_init($url); 

$header = array
(
  'Connection: keep-alive',
  'Keep-Alive: 10000',
  'Cookie:'.$admin_login->session_name . '=' . $admin_login->sessid
);
curl_setopt ( $ch, CURLOPT_HTTPHEADER,$header);
curl_setopt_array($ch, $curl_options_get);
$curl_response = curl_exec($ch);

print_r (json_decode($curl_response));

The url in STEP1 is the way it is only for 'stackexchange' as it would allow me to save this post otherwise

I am not allowed to answer my own question (yet). Anyway, here is the answer to my own question: The 'problem'? lies within the file services.module in line 751

function services_remove_user_data(&$account) 
{
  // Remove the users password from the account object.
  unset($account->pass);
  if (!user_access('administer users')) 
  {
    unset($account->mail);
    unset($account->init);
  }
  drupal_alter('services_account_object', $account);
}

This function gets called in user_resource.inc after the user objects got put together. From the code you can clearly see that 'mail' gets 'unset' if the call is not authenticated as 'administers users'.

Why? I can not explain, it seems random to me.

1 Answer 1

3

Had the same issue and it's something that I was banging my head against the wall why an authenticated user can't see his own email!

Here's the solution:

/**
 * Implements hook_services_account_object_alter().
 */
function HOOK_services_account_object_alter(&$account) {
  $account->mail = db_query('SELECT mail FROM {users} WHERE uid = :uid', array(':uid' => $account->uid))->fetchField();;
}

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.