You are here

function _services_keyauth_authenticate_call in Services 7

Same name and namespace in other branches
  1. 6.2 auth/services_keyauth/services_keyauth.inc \_services_keyauth_authenticate_call()
1 string reference to '_services_keyauth_authenticate_call'
services_keyauth_authentication_info in auth/services_keyauth/services_keyauth.module
Implements hook_authentication_info().

File

auth/services_keyauth/services_keyauth.inc, line 144
The implementation of the key authentication scheme

Code

function _services_keyauth_authenticate_call($method, $method_name, &$args) {
  if ($method['#key'] && variable_get('services_use_key', TRUE)) {
    $hash = array_shift($args);
    $domain = array_shift($args);
    $timestamp = array_shift($args);
    $nonce = array_shift($args);
    $expiry_time = $timestamp + variable_get('services_key_expiry', 30);
    if ($expiry_time < REQUEST_TIME) {
      return services_error(t('Token has expired.'), 401);
    }
    $has_rows = (bool) db_query_range("SELECT 1 FROM {services_timestamp_nonce} WHERE domain = :domain AND nonce = :nonce", 0, 1, array(
      ':domain' => $domain,
      ':nonce' => $nonce,
    ))
      ->fetchField();

    // Still in time but has it been used before
    if ($has_rows) {
      return services_error(t('Token has been used previously for a request. Re-try with another nonce key.', 401));
    }
    else {
      db_insert('services_timestamp_nonce')
        ->fields(array(
        'domain',
        'timestamp',
        'nonce',
      ))
        ->values(array(
        'domain' => $domain,
        'timestamp' => $timestamp,
        'nonce' => $nonce,
      ))
        ->execute();
    }
    $api_key = db_query("SELECT kid FROM {services_keys} WHERE domain = :key", array(
      ':key' => $domain,
    ))
      ->fetchField('kid');

    //if (!services_keyauth_validate_key($api_key, $timestamp, $domain, $nonce, $method_name, $hash_parameters, $hash)) {
    if ($hash != services_get_hash($timestamp, $domain, $nonce, $method, $args)) {
      return services_error(t('Invalid API key.'), 401);
    }
    $has_rows = (bool) db_query_range("SELECT 1 FROM {services_key_permissions} WHERE kid = :kid AND method = :method", 0, 1, array(
      ':kid' => $api_key,
      ':method' => $method_name,
    ))
      ->fetchField();
    if (!$has_rows) {
      return services_error(t('Access denied.'), 401);
    }
  }

  // Add additonal processing for methods requiring session
  $session_backup = NULL;
  if ($method['#auth'] && variable_get('services_use_sessid', TRUE)) {
    $sessid = array_shift($args);
    if (empty($sessid)) {
      return t('Invalid sessid.');
    }
    $session_backup = services_session_load($sessid);
  }
}