0

This is a follow up to drupal.stackexchange.com/q/228722/9921

I have an api that I creates that I would like to restrict access to users with administrator role. But for some reason the 'administrator permission' is not working. And the api returns an error when I add this restriction. To clearify the use of language here:

    User : admin 
    Role : Administrator 
if you go to people permissions, Administrator has a permission of type administer permissions

I am 100% certain the user is an administrator

function mymodule_menu() {
/**
 * Create api callback to return list of users in a give site
*/
  $items['api/v1/userslist'] = array(
    'type' => MENU_CALLBACK,
    'page callback' => 'mymodule_api_userslist',
    //'access callback' => array('administer permissions'), // tried both and they don't work
    'access arguments' => array('administer permissions'),
    'delivery callback' => 'mymodule_json',
  );
  return $items;
}

function mymodule_api_userslist() {
  // code not included since I know it works if the permission are just all permisions
  $data = Do an entityfieldquery to fetch users and return them
  return $data;
}

function mymodule_json($data) {
  if (is_int($data)) { 
    drupal_add_http_header('Status', '400 Bad Request');
  }

  echo drupal_json_output($data);
}

The above code is being called via

  $users = drupal_http_request('http://'.$domain.'/api/v1/userslist');

Any ideas?

____EDIT

<?php

/**
 * Implements hook_menu().
 *
 * */
function data_export_menu() {
/**
 * Create api callback to return list of users in a give site
*/
  $items['api/v1/userslist'] = array(
    'type' => MENU_CALLBACK,
    'page callback' => 'data_export_api_userslist',
    'access arguments' => TRUE,
    'delivery callback' => 'data_export_json',
  );
  return $items;
}

function data_export_api_userslist() {

  $data = data_export_process_users();
  // Do an entityfieldquery (or some other query) to fetch users and return them
  // as an array, not HTML or json. Json encoding will happen in the delivery callback.
  return $data;
}

/**
 * Delivers JSON. Used as a deliver callback for api menu items.
 *
 * @param array $data
 *   An array to be encoded as json.
 */
function data_export_json($data) {
  if (is_int($data)) { //https://api.drupal.org/api/drupal/includes!common.inc/function/drupal_deliver_html_page/7.x
    drupal_add_http_header('Status', '400 Bad Request');
  }

  echo drupal_json_output($data);
}

function data_export_process_users () {

  $results = array();

  $query = new EntityFieldQuery();
  $query
    ->entityCondition('entity_type', 'user')
    ->addTag('role_filter');

  $results = $query->execute();

  $users_node_list = entity_load('user', array_keys($results['user']));

  $return_results = array();

  foreach ($users_node_list as $key => $value) {
    $output = array();
    $output['name'] = $value->name;
    $output['email'] = $value->mail;
    $output['init'] = $value->init;
    $output['role'] = array_slice($value->roles, 1, 1)[0];
    $output['status'] = ($value->status) ? 'active' : 'blocked';
    $output['last_access'] = format_date($value->access,'small');
    $return_results[] = $output;
  }

  return $return_results;
}

function data_export_query_role_filter_alter(QueryAlterableInterface $query) {
  $query->innerJoin('users_roles', 'ur', 'users.uid = ur.uid');  
  $query->innerJoin('role', 'r', 'r.rid = ur.rid');
  $query->condition('r.name', ['administrator', 'contributor', 'publisher'], 'IN');
  $query->condition('users.init', '', '<>');
}
0

Your latest edit clears up where the problem is likely to be:

The above code is being called via

$users = drupal_http_request('http://'.$domain.'/api/v1/userslist');

You're probably under the impression that the active user session from the calling site will somehow be passed through to and become valid for the API site? That won't happen, even if it's the same site - you're making a completely new request which doesn't share anything with the request you're making it from.

If you're building a secured API, you need to provide an authentication method that integrates with Drupal's login system, while still handling tokens etc for the API communication itself. That can be a fair amount of work, so people tend to use existing solutions like the Services module.

That module has an authentication layer for the core Drupal user login built in, and provides hooks for you to register your own resources. It will probably take less time to build your API using Services than building and testing your own authentication, so it's worth a look.

| improve this answer | |

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.