You are here

class OAuthServer in OAuth 1.0 7.3

Same name and namespace in other branches
  1. 6.3 lib/OAuth.php \OAuthServer
  2. 6 OAuth.php \OAuthServer

Hierarchy

Expanded class hierarchy of OAuthServer

File

lib/OAuth.php, line 509
OAuth 1.0 server and client library.

View source
class OAuthServer {
  protected $timestamp_threshold = 300;

  // in seconds, five minutes
  protected $version = '1.0';

  // hi blaine
  protected $signature_methods = array();
  protected $data_store;
  function __construct($data_store) {
    $this->data_store = $data_store;
  }
  public function add_signature_method($signature_method) {
    $this->signature_methods[$signature_method
      ->get_name()] = $signature_method;
  }

  // high level functions

  /**
   * process a request_token request
   * returns the request token on success
   */
  public function fetch_request_token(&$request) {
    $this
      ->get_version($request);
    $consumer = $this
      ->get_consumer($request);

    // no token required for the initial token request
    $token = NULL;
    $this
      ->check_signature($request, $consumer, $token);

    // Rev A change
    $callback = $request
      ->get_parameter('oauth_callback');
    $new_token = $this->data_store
      ->new_request_token($consumer, $callback);
    return $new_token;
  }

  /**
   * process an access_token request
   * returns the access token on success
   */
  public function fetch_access_token(&$request) {
    $this
      ->get_version($request);
    $consumer = $this
      ->get_consumer($request);

    // requires authorized request token
    $token = $this
      ->get_token($request, $consumer, "request");
    $this
      ->check_signature($request, $consumer, $token);

    // Rev A change
    $verifier = $request
      ->get_parameter('oauth_verifier');
    $new_token = $this->data_store
      ->new_access_token($token, $consumer, $verifier);
    return $new_token;
  }

  /**
   * verify an api call, checks all the parameters
   */
  public function verify_request(&$request) {
    $this
      ->get_version($request);
    $consumer = $this
      ->get_consumer($request);
    $token = $this
      ->get_token($request, $consumer, "access");
    $this
      ->check_signature($request, $consumer, $token);
    return array(
      $consumer,
      $token,
    );
  }

  // Internals from here

  /**
   * version 1
   */
  private function get_version(&$request) {
    $version = $request
      ->get_parameter("oauth_version");
    if (!$version) {

      // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
      // Chapter 7.0 ("Accessing Protected Ressources")
      $version = '1.0';
    }
    if ($version !== $this->version) {
      throw new OAuthException("OAuth version '{$version}' not supported");
    }
    return $version;
  }

  /**
   * figure out the signature with some defaults
   */
  private function get_signature_method($request) {
    $signature_method = $request instanceof OAuthRequest ? $request
      ->get_parameter("oauth_signature_method") : NULL;
    if (!$signature_method) {

      // According to chapter 7 ("Accessing Protected Ressources") the signature-method
      // parameter is required, and we can't just fallback to PLAINTEXT
      throw new OAuthException('No signature method parameter. This parameter is required');
    }
    if (!in_array($signature_method, array_keys($this->signature_methods))) {
      throw new OAuthException("Signature method '{$signature_method}' not supported " . "try one of the following: " . implode(", ", array_keys($this->signature_methods)));
    }
    return $this->signature_methods[$signature_method];
  }

  /**
   * try to find the consumer for the provided request's consumer key
   */
  private function get_consumer($request) {
    $consumer_key = $request instanceof OAuthRequest ? $request
      ->get_parameter("oauth_consumer_key") : NULL;
    if (!$consumer_key) {
      throw new OAuthException("Invalid consumer key");
    }
    $consumer = $this->data_store
      ->lookup_consumer($consumer_key);
    if (!$consumer) {
      throw new OAuthException("Invalid consumer");
    }
    return $consumer;
  }

  /**
   * try to find the token for the provided request's token key
   */
  private function get_token($request, $consumer, $token_type = "access") {
    $token_field = $request instanceof OAuthRequest ? $request
      ->get_parameter('oauth_token') : NULL;
    if (!empty($token_field)) {
      $token = $this->data_store
        ->lookup_token($consumer, $token_type, $token_field);
      if (!$token) {
        throw new OAuthException("Invalid {$token_type} token: {$token_field}");
      }
    }
    else {
      $token = new OAuthToken('', '');
    }
    return $token;
  }

  /**
   * all-in-one function to check the signature on a request
   * should guess the signature method appropriately
   */
  private function check_signature($request, $consumer, $token) {

    // this should probably be in a different method
    $timestamp = $request instanceof OAuthRequest ? $request
      ->get_parameter('oauth_timestamp') : NULL;
    $nonce = $request instanceof OAuthRequest ? $request
      ->get_parameter('oauth_nonce') : NULL;
    $this
      ->check_timestamp($timestamp);
    $this
      ->check_nonce($consumer, $token, $nonce, $timestamp);
    $signature_method = $this
      ->get_signature_method($request);
    $signature = $request
      ->get_parameter('oauth_signature');
    $valid_sig = $signature_method
      ->check_signature($request, $consumer, $token, $signature);
    if (!$valid_sig) {
      throw new OAuthException("Invalid signature");
    }
  }

  /**
   * check that the timestamp is new enough
   */
  private function check_timestamp($timestamp) {
    if (!$timestamp) {
      throw new OAuthException('Missing timestamp parameter. The parameter is required');
    }

    // verify that timestamp is recentish
    $now = time();
    if (abs($now - $timestamp) > $this->timestamp_threshold) {
      throw new OAuthException("Expired timestamp, yours {$timestamp}, ours {$now}");
    }
  }

  /**
   * check that the nonce is not repeated
   */
  private function check_nonce($consumer, $token, $nonce, $timestamp) {
    if (!$nonce) {
      throw new OAuthException('Missing nonce parameter. The parameter is required');
    }

    // verify that the nonce is uniqueish
    $found = $this->data_store
      ->lookup_nonce($consumer, $token, $nonce, $timestamp);
    if ($found) {
      throw new OAuthException("Nonce already used: {$nonce}");
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
OAuthServer::$data_store protected property
OAuthServer::$signature_methods protected property
OAuthServer::$timestamp_threshold protected property
OAuthServer::$version protected property
OAuthServer::add_signature_method public function
OAuthServer::check_nonce private function check that the nonce is not repeated
OAuthServer::check_signature private function all-in-one function to check the signature on a request should guess the signature method appropriately
OAuthServer::check_timestamp private function check that the timestamp is new enough
OAuthServer::fetch_access_token public function process an access_token request returns the access token on success
OAuthServer::fetch_request_token public function process a request_token request returns the request token on success
OAuthServer::get_consumer private function try to find the consumer for the provided request's consumer key
OAuthServer::get_signature_method private function figure out the signature with some defaults
OAuthServer::get_token private function try to find the token for the provided request's token key
OAuthServer::get_version private function version 1
OAuthServer::verify_request public function verify an api call, checks all the parameters
OAuthServer::__construct function 1