Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

simpler oAuth

  • Loading branch information...
commit 4b440780574ee3603b7412775fe023eeda666831 1 parent 2fd13ef
@codepo8 authored
View
7 filter.php
@@ -7,6 +7,13 @@
Code licensed under the BSD License:
http://wait-till-i.com/license.txt
*/
+ include_once('keys.php');
+ require_once('lib/OAuth/OAuth.php');
+ require_once('lib/Yahoo/YahooOAuthApplication.class.php');
+ $oauthapp = new YahooOAuthApplication($CONSUMER_KEY, $CONSUMER_SECRET, '');
+ include_once('sources.php');
+ include_once('renderers.php');
+
$offset = isset($_POST['offset']) ? $_POST['offset'] : 0;
$args = array(
'sent' => FILTER_SANITIZE_SPECIAL_CHARS,
View
11 index.php
@@ -6,18 +6,7 @@
Code licensed under the BSD License:
http://wait-till-i.com/license.txt
*/
- include_once('keys.php');
- include_once('lib/Yahoo.inc');
- YahooLogger::setDebug(true);
- $yahoo_session = YahooSession::requireSession(
- CONSUMER_KEY, CONSUMER_SECRET
- );
- if ($yahoo_session == NULL) {
- die('Session error :(');
- }
include_once('filter.php');
- include_once('sources.php');
- include_once('renderers.php');
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
View
5 keys.php
@@ -9,7 +9,6 @@
*/
// Get your own key and secret at http://developer.yahoo.com
-define('CONSUMER_KEY', '');
-define('CONSUMER_SECRET','');
-
+$CONSUMER_KEY = '';
+$CONSUMER_SECRET = '';
?>
View
22 lib/OAuth/LICENSE
@@ -0,0 +1,22 @@
+The MIT License
+
+Copyright (c) 2007 Andy Smith
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
View
805 lib/OAuth/OAuth.php
@@ -0,0 +1,805 @@
+<?php
+
+/**
+ *
+ * @package OAuth
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ *
+ * The MIT License
+ *
+ * Copyright (c) 2007 Andy Smith
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Generic exception class
+ */
+if(!class_exists('OAuthException')) // php oauth extension support - php.net/oauth
+{
+ class OAuthException extends Exception {
+ // pass
+ }
+}
+
+class OAuthConsumer {
+ public $key;
+ public $secret;
+
+ function __construct($key, $secret, $callback_url=NULL) {
+ $this->key = $key;
+ $this->secret = $secret;
+ $this->callback_url = $callback_url;
+ }
+
+ function __toString() {
+ return "OAuthConsumer[key=$this->key,secret=$this->secret]";
+ }
+}
+
+class OAuthToken {
+ // access tokens and request tokens
+ public $key;
+ public $secret;
+
+ /**
+ * key = the token
+ * secret = the token secret
+ */
+ function __construct($key, $secret) {
+ $this->key = $key;
+ $this->secret = $secret;
+ }
+
+ /**
+ * generates the basic string serialization of a token that a server
+ * would respond to request_token and access_token calls with
+ */
+ function to_string() {
+ return "oauth_token=" .
+ OAuthUtil::urlencode_rfc3986($this->key) .
+ "&oauth_token_secret=" .
+ OAuthUtil::urlencode_rfc3986($this->secret);
+ }
+
+ function __toString() {
+ return $this->to_string();
+ }
+}
+
+class OAuthSignatureMethod {
+ public function check_signature(&$request, $consumer, $token, $signature) {
+ $built = $this->build_signature($request, $consumer, $token);
+ return $built == $signature;
+ }
+}
+
+class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
+ function get_name() {
+ return "HMAC-SHA1";
+ }
+
+ public function build_signature($request, $consumer, $token) {
+ $base_string = $request->get_signature_base_string();
+ $request->base_string = $base_string;
+
+ $key_parts = array(
+ $consumer->secret,
+ ($token) ? $token->secret : ""
+ );
+
+ $key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
+ $key = implode('&', $key_parts);
+
+ return base64_encode(hash_hmac('sha1', $base_string, $key, true));
+ }
+}
+
+class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
+ public function get_name() {
+ return "PLAINTEXT";
+ }
+
+ public function build_signature($request, $consumer, $token) {
+ $sig = array(
+ OAuthUtil::urlencode_rfc3986($consumer->secret)
+ );
+
+ if ($token) {
+ array_push($sig, OAuthUtil::urlencode_rfc3986($token->secret));
+ } else {
+ array_push($sig, '');
+ }
+
+ $raw = implode("&", $sig);
+ // for debug purposes
+ $request->base_string = $raw;
+
+ return OAuthUtil::urlencode_rfc3986($raw);
+ }
+}
+
+class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
+ public function get_name() {
+ return "RSA-SHA1";
+ }
+
+ protected function fetch_public_cert(&$request) {
+ // not implemented yet, ideas are:
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
+ // (2) fetch via http using a url provided by the requester
+ // (3) some sort of specific discovery code based on request
+ //
+ // either way should return a string representation of the certificate
+ throw Exception("fetch_public_cert not implemented");
+ }
+
+ protected function fetch_private_cert(&$request) {
+ // not implemented yet, ideas are:
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
+ //
+ // either way should return a string representation of the certificate
+ throw Exception("fetch_private_cert not implemented");
+ }
+
+ public function build_signature(&$request, $consumer, $token) {
+ $base_string = $request->get_signature_base_string();
+ $request->base_string = $base_string;
+
+ // Fetch the private key cert based on the request
+ $cert = $this->fetch_private_cert($request);
+
+ // Pull the private key ID from the certificate
+ $privatekeyid = openssl_get_privatekey($cert);
+
+ // Sign using the key
+ $ok = openssl_sign($base_string, $signature, $privatekeyid);
+
+ // Release the key resource
+ openssl_free_key($privatekeyid);
+
+ return base64_encode($signature);
+ }
+
+ public function check_signature(&$request, $consumer, $token, $signature) {
+ $decoded_sig = base64_decode($signature);
+
+ $base_string = $request->get_signature_base_string();
+
+ // Fetch the public key cert based on the request
+ $cert = $this->fetch_public_cert($request);
+
+ // Pull the public key ID from the certificate
+ $publickeyid = openssl_get_publickey($cert);
+
+ // Check the computed signature against the one passed in the query
+ $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
+
+ // Release the key resource
+ openssl_free_key($publickeyid);
+
+ return $ok == 1;
+ }
+}
+
+class OAuthRequest {
+ public $parameters;
+ public $http_method;
+ public $http_url;
+ // for debug purposes
+ public $base_string;
+ public static $version = '1.0';
+ public static $POST_INPUT = 'php://input';
+
+ function __construct($http_method, $http_url, $parameters=NULL) {
+ @$parameters or $parameters = array();
+ $this->parameters = $parameters;
+ $this->http_method = $http_method;
+ $this->http_url = $http_url;
+ }
+
+
+ /**
+ * attempt to build up a request from what was passed to the server
+ */
+ public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
+ $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
+ ? 'http'
+ : 'https';
+ @$http_url or $http_url = $scheme .
+ '://' . $_SERVER['HTTP_HOST'] .
+ ':' .
+ $_SERVER['SERVER_PORT'] .
+ $_SERVER['REQUEST_URI'];
+ @$http_method or $http_method = $_SERVER['REQUEST_METHOD'];
+
+ // We weren't handed any parameters, so let's find the ones relevant to
+ // this request.
+ // If you run XML-RPC or similar you should use this to provide your own
+ // parsed parameter-list
+ if (!$parameters) {
+ // Find request headers
+ $request_headers = OAuthUtil::get_headers();
+
+ // Parse the query-string to find GET parameters
+ $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
+
+ // It's a POST request of the proper content-type, so parse POST
+ // parameters and add those overriding any duplicates from GET
+ if ($http_method == "POST"
+ && @strstr($request_headers["Content-Type"],
+ "application/x-www-form-urlencoded")
+ ) {
+ $post_data = OAuthUtil::parse_parameters(
+ file_get_contents(self::$POST_INPUT)
+ );
+ $parameters = array_merge($parameters, $post_data);
+ }
+
+ // We have a Authorization-header with OAuth data. Parse the header
+ // and add those overriding any duplicates from GET or POST
+ if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") {
+ $header_parameters = OAuthUtil::split_header(
+ $request_headers['Authorization']
+ );
+ $parameters = array_merge($parameters, $header_parameters);
+ }
+
+ }
+
+ return new OAuthRequest($http_method, $http_url, $parameters);
+ }
+
+ /**
+ * pretty much a helper function to set up the request
+ */
+ public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
+ @$parameters or $parameters = array();
+ $defaults = array("oauth_version" => OAuthRequest::$version,
+ "oauth_nonce" => OAuthRequest::generate_nonce(),
+ "oauth_timestamp" => OAuthRequest::generate_timestamp(),
+ "oauth_consumer_key" => $consumer->key);
+ if ($token)
+ $defaults['oauth_token'] = $token->key;
+
+ $parameters = array_merge($defaults, $parameters);
+
+ return new OAuthRequest($http_method, $http_url, $parameters);
+ }
+
+ public function set_parameter($name, $value, $allow_duplicates = true) {
+ if ($allow_duplicates && isset($this->parameters[$name])) {
+ // We have already added parameter(s) with this name, so add to the list
+ if (is_scalar($this->parameters[$name])) {
+ // This is the first duplicate, so transform scalar (string)
+ // into an array so we can add the duplicates
+ $this->parameters[$name] = array($this->parameters[$name]);
+ }
+
+ $this->parameters[$name][] = $value;
+ } else {
+ $this->parameters[$name] = $value;
+ }
+ }
+
+ public function get_parameter($name) {
+ return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
+ }
+
+ public function get_parameters() {
+ return $this->parameters;
+ }
+
+ public function unset_parameter($name) {
+ unset($this->parameters[$name]);
+ }
+
+ /**
+ * The request parameters, sorted and concatenated into a normalized string.
+ * @return string
+ */
+ public function get_signable_parameters() {
+ // Grab all parameters
+ $params = $this->parameters;
+
+ // Remove oauth_signature if present
+ // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
+ if (isset($params['oauth_signature'])) {
+ unset($params['oauth_signature']);
+ }
+
+ return OAuthUtil::build_http_query($params);
+ }
+
+ /**
+ * Returns the base string of this request
+ *
+ * The base string defined as the method, the url
+ * and the parameters (normalized), each urlencoded
+ * and the concated with &.
+ */
+ public function get_signature_base_string() {
+ $parts = array(
+ $this->get_normalized_http_method(),
+ $this->get_normalized_http_url(),
+ $this->get_signable_parameters()
+ );
+
+ $parts = OAuthUtil::urlencode_rfc3986($parts);
+
+ return implode('&', $parts);
+ }
+
+ /**
+ * just uppercases the http method
+ */
+ public function get_normalized_http_method() {
+ return strtoupper($this->http_method);
+ }
+
+ /**
+ * parses the url and rebuilds it to be
+ * scheme://host/path
+ */
+ public function get_normalized_http_url() {
+ $parts = parse_url($this->http_url);
+
+ $port = @$parts['port'];
+ $scheme = $parts['scheme'];
+ $host = $parts['host'];
+ $path = @$parts['path'];
+
+ $port or $port = ($scheme == 'https') ? '443' : '80';
+
+ if (($scheme == 'https' && $port != '443')
+ || ($scheme == 'http' && $port != '80')) {
+ $host = "$host:$port";
+ }
+ return "$scheme://$host$path";
+ }
+
+ /**
+ * builds a url usable for a GET request
+ */
+ public function to_url() {
+ $post_data = $this->to_postdata();
+ $out = $this->get_normalized_http_url();
+ if ($post_data) {
+ $out .= '?'.$post_data;
+ }
+ return $out;
+ }
+
+ /**
+ * builds the data one would send in a POST request
+ */
+ public function to_postdata() {
+ return OAuthUtil::build_http_query($this->parameters);
+ }
+
+ /**
+ * builds the Authorization: header
+ */
+ public function to_header() {
+ $out ='Authorization: OAuth realm="yahooapis.com"';
+ $total = array();
+ foreach ($this->parameters as $k => $v) {
+ if (substr($k, 0, 5) != "oauth") continue;
+ if (is_array($v)) {
+ throw new OAuthException('Arrays not supported in headers');
+ }
+ $out .= ',' .
+ OAuthUtil::urlencode_rfc3986($k) .
+ '="' .
+ OAuthUtil::urlencode_rfc3986($v) .
+ '"';
+ }
+ return $out;
+ }
+
+ public function __toString() {
+ return $this->to_url();
+ }
+
+
+ public function sign_request($signature_method, $consumer, $token) {
+ $this->set_parameter(
+ "oauth_signature_method",
+ $signature_method->get_name(),
+ false
+ );
+ $signature = $this->build_signature($signature_method, $consumer, $token);
+ $this->set_parameter("oauth_signature", $signature, false);
+ }
+
+ public function build_signature($signature_method, $consumer, $token) {
+ $signature = $signature_method->build_signature($this, $consumer, $token);
+ return $signature;
+ }
+
+ /**
+ * util function: current timestamp
+ */
+ private static function generate_timestamp() {
+ return time();
+ }
+
+ /**
+ * util function: current nonce
+ */
+ private static function generate_nonce() {
+ $mt = microtime();
+ $rand = mt_rand();
+
+ return md5($mt . $rand); // md5s look nicer than numbers
+ }
+}
+
+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);
+
+ $new_token = $this->data_store->new_request_token($consumer);
+
+ 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);
+
+ $new_token = $this->data_store->new_access_token($token, $consumer);
+
+ 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) {
+ $version = 1.0;
+ }
+ if ($version && $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->get_parameter("oauth_signature_method");
+ if (!$signature_method) {
+ $signature_method = "PLAINTEXT";
+ }
+ 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->get_parameter("oauth_consumer_key");
+ 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->get_parameter('oauth_token');
+ $token = $this->data_store->lookup_token(
+ $consumer, $token_type, $token_field
+ );
+ if (!$token) {
+ throw new OAuthException("Invalid $token_type token: $token_field");
+ }
+ 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->get_parameter('oauth_timestamp');
+ $nonce = @$request->get_parameter('oauth_nonce');
+
+ $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) {
+ // verify that timestamp is recentish
+ $now = time();
+ if ($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) {
+ // 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");
+ }
+ }
+
+}
+
+class OAuthDataStore {
+ function lookup_consumer($consumer_key) {
+ // implement me
+ }
+
+ function lookup_token($consumer, $token_type, $token) {
+ // implement me
+ }
+
+ function lookup_nonce($consumer, $token, $nonce, $timestamp) {
+ // implement me
+ }
+
+ function new_request_token($consumer) {
+ // return a new token attached to this consumer
+ }
+
+ function new_access_token($token, $consumer) {
+ // return a new access token attached to this consumer
+ // for the user associated with this token if the request token
+ // is authorized
+ // should also invalidate the request token
+ }
+
+}
+
+class OAuthUtil {
+ public static function urlencode_rfc3986($input) {
+ if (is_array($input)) {
+ return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
+ } else if (is_scalar($input)) {
+ return str_replace(
+ '+',
+ ' ',
+ str_replace('%7E', '~', rawurlencode($input))
+ );
+ } else {
+ return '';
+ }
+}
+
+
+ // This decode function isn't taking into consideration the above
+ // modifications to the encoding process. However, this method doesn't
+ // seem to be used anywhere so leaving it as is.
+ public static function urldecode_rfc3986($string) {
+ return urldecode($string);
+ }
+
+ // Utility function for turning the Authorization: header into
+ // parameters, has to do some unescaping
+ // Can filter out any non-oauth parameters if needed (default behaviour)
+ public static function split_header($header, $only_allow_oauth_parameters = true) {
+ $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/';
+ $offset = 0;
+ $params = array();
+ while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) {
+ $match = $matches[0];
+ $header_name = $matches[2][0];
+ $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0];
+ if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) {
+ $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content);
+ }
+ $offset = $match[1] + strlen($match[0]);
+ }
+
+ if (isset($params['realm'])) {
+ unset($params['realm']);
+ }
+
+ return $params;
+ }
+
+ // helper to try to sort out headers for people who aren't running apache
+ public static function get_headers() {
+ if (function_exists('apache_request_headers')) {
+ // we need this to get the actual Authorization: header
+ // because apache tends to tell us it doesn't exist
+ return apache_request_headers();
+ }
+ // otherwise we don't have apache and are just going to have to hope
+ // that $_SERVER actually contains what we need
+ $out = array();
+ foreach ($_SERVER as $key => $value) {
+ if (substr($key, 0, 5) == "HTTP_") {
+ // this is chaos, basically it is just there to capitalize the first
+ // letter of every word that is not an initial HTTP and strip HTTP
+ // code from przemek
+ $key = str_replace(
+ " ",
+ "-",
+ ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
+ );
+ $out[$key] = $value;
+ }
+ }
+ return $out;
+ }
+
+ // This function takes a input like a=b&a=c&d=e and returns the parsed
+ // parameters like this
+ // array('a' => array('b','c'), 'd' => 'e')
+ public static function parse_parameters( $input ) {
+ if (!isset($input) || !$input) return array();
+
+ $pairs = explode('&', $input);
+
+ $parsed_parameters = array();
+ foreach ($pairs as $pair) {
+ $split = explode('=', $pair, 2);
+ $parameter = OAuthUtil::urldecode_rfc3986($split[0]);
+ $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
+
+ if (isset($parsed_parameters[$parameter])) {
+ // We have already recieved parameter(s) with this name, so add to the list
+ // of parameters with this name
+
+ if (is_scalar($parsed_parameters[$parameter])) {
+ // This is the first duplicate, so transform scalar (string) into an array
+ // so we can add the duplicates
+ $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
+ }
+
+ $parsed_parameters[$parameter][] = $value;
+ } else {
+ $parsed_parameters[$parameter] = $value;
+ }
+ }
+ return $parsed_parameters;
+ }
+
+ public static function build_http_query($params) {
+ if (!$params) return '';
+
+ // Urlencode both keys and values
+ $keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
+ $values = OAuthUtil::urlencode_rfc3986(array_values($params));
+ $params = array_combine($keys, $values);
+
+ // Parameters are sorted by name, using lexicographical byte value ordering.
+ // Ref: Spec: 9.1.1 (1)
+ uksort($params, 'strcmp');
+
+ $pairs = array();
+ foreach ($params as $parameter => $value) {
+ if (is_array($value)) {
+ // If two or more parameters share the same name, they are sorted by their value
+ // Ref: Spec: 9.1.1 (1)
+ natsort($value);
+ foreach ($value as $duplicate_value) {
+ $pairs[] = $parameter . '=' . $duplicate_value;
+ }
+ } else {
+ $pairs[] = $parameter . '=' . $value;
+ }
+ }
+ // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
+ // Each name-value pair is separated by an '&' character (ASCII code 38)
+ return implode('&', $pairs);
+ }
+}
View
74 lib/OAuth/example/SimpleOAuthDataStore.php
@@ -0,0 +1,74 @@
+<?php
+
+/* A very naive dbm-based oauth storage
+ *
+ * NOTE: This is for reference ONLY,
+ * and contains, amongst others, a hole
+ * where you can get the token secret
+ * easily..
+ */
+class SimpleOAuthDataStore extends OAuthDataStore {/*{{{*/
+ private $dbh;
+
+ function __construct($path = "oauth.gdbm") {/*{{{*/
+ $this->dbh = dba_popen($path, 'c', 'gdbm');
+ }/*}}}*/
+
+ function __destruct() {/*{{{*/
+ dba_close($this->dbh);
+ }/*}}}*/
+
+ function lookup_consumer($consumer_key) {/*{{{*/
+ $rv = dba_fetch("consumer_$consumer_key", $this->dbh);
+ if ($rv === FALSE) {
+ return NULL;
+ }
+ $obj = unserialize($rv);
+ if (!($obj instanceof OAuthConsumer)) {
+ return NULL;
+ }
+ return $obj;
+ }/*}}}*/
+
+ function lookup_token($consumer, $token_type, $token) {/*{{{*/
+ $rv = dba_fetch("${token_type}_${token}", $this->dbh);
+ if ($rv === FALSE) {
+ return NULL;
+ }
+ $obj = unserialize($rv);
+ if (!($obj instanceof OAuthToken)) {
+ return NULL;
+ }
+ return $obj;
+ }/*}}}*/
+
+ function lookup_nonce($consumer, $token, $nonce, $timestamp) {/*{{{*/
+ if (dba_exists("nonce_$nonce", $this->dbh)) {
+ return TRUE;
+ } else {
+ dba_insert("nonce_$nonce", "1", $this->dbh);
+ return FALSE;
+ }
+ }/*}}}*/
+
+ function new_token($consumer, $type="request") {/*{{{*/
+ $key = md5(time());
+ $secret = time() + time();
+ $token = new OAuthToken($key, md5(md5($secret)));
+ if (!dba_insert("${type}_$key", serialize($token), $this->dbh)) {
+ throw new OAuthException("doooom!");
+ }
+ return $token;
+ }/*}}}*/
+
+ function new_request_token($consumer) {/*{{{*/
+ return $this->new_token($consumer, "request");
+ }/*}}}*/
+
+ function new_access_token($token, $consumer) {/*{{{*/
+
+ $token = $this->new_token($consumer, 'access');
+ dba_delete("request_" . $token->key, $this->dbh);
+ return $token;
+ }/*}}}*/
+}/*}}}*/
View
14 lib/OAuth/example/access_token.php
@@ -0,0 +1,14 @@
+<?php
+require_once("common.inc.php");
+
+try {
+ $req = OAuthRequest::from_request();
+ $token = $test_server->fetch_access_token($req);
+ print $token;
+} catch (OAuthException $e) {
+ print($e->getMessage() . "\n<hr />\n");
+ print_r($req);
+ die();
+}
+
+?>
View
133 lib/OAuth/example/client.php
@@ -0,0 +1,133 @@
+<?php
+require_once("common.inc.php");
+
+$key = @$_REQUEST['key'];
+$secret = @$_REQUEST['secret'];
+$token = @$_REQUEST['token'];
+$token_secret = @$_REQUEST['token_secret'];
+$endpoint = @$_REQUEST['endpoint'];
+$action = @$_REQUEST['action'];
+$dump_request = @$_REQUEST['dump_request'];
+$user_sig_method = @$_REQUEST['sig_method'];
+$sig_method = $hmac_method;
+if ($user_sig_method) {
+ $sig_method = $sig_methods[$user_sig_method];
+}
+
+$test_consumer = new OAuthConsumer($key, $secret, NULL);
+
+$test_token = NULL;
+if ($token) {
+ $test_token = new OAuthConsumer($token, $token_secret);
+}
+
+
+if ($action == "request_token") {
+ $parsed = parse_url($endpoint);
+ $params = array();
+ parse_str($parsed['query'], $params);
+
+ $req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $endpoint, $params);
+ $req_req->sign_request($sig_method, $test_consumer, NULL);
+ if ($dump_request) {
+ Header('Content-type: text/plain');
+ print "request url: " . $req_req->to_url(). "\n";
+ print_r($req_req);
+ exit;
+ }
+ Header("Location: $req_req");
+}
+else if ($action == "authorize") {
+ $callback_url = "$base_url/client.php?key=$key&secret=$secret&token=$token&token_secret=$token_secret&endpoint=" . urlencode($endpoint);
+ $auth_url = $endpoint . "?oauth_token=$token&oauth_callback=".urlencode($callback_url);
+ if ($dump_request) {
+ Header('Content-type: text/plain');
+ print("auth_url: " . $auth_url);
+ exit;
+ }
+ Header("Location: $auth_url");
+}
+else if ($action == "access_token") {
+ $parsed = parse_url($endpoint);
+ $params = array();
+ parse_str($parsed['query'], $params);
+
+ $acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $test_token, "GET", $endpoint, $params);
+ $acc_req->sign_request($sig_method, $test_consumer, $test_token);
+ if ($dump_request) {
+ Header('Content-type: text/plain');
+ print "request url: " . $acc_req->to_url() . "\n";
+ print_r($acc_req);
+ exit;
+ }
+ Header("Location: $acc_req");
+}
+
+?>
+<html>
+<head>
+<title>OAuth Test Client</title>
+</head>
+<body>
+<div><a href="index.php">server</a> | <a href="client.php">client</a></div>
+<h1>OAuth Test Client</h1>
+<h2>Instructions for Use</h2>
+<p>This is a test client that will let you test your OAuth server code. Enter the appropriate information below to test.</p>
+<p>Note: we don't store any of the information you type in.</p>
+
+<form method="POST" name="oauth_client">
+<h3>Choose a Signature Method</h3>
+<select name="sig_method">
+<?php
+foreach ($sig_methods as $name=> $method) {
+ $selected = "";
+ if ($name == $sig_method->get_name()) {
+ $selected = " selected='selected'";
+ }
+ print "<option value='$name'$selected>$name</option>\n";
+}
+?>
+</select>
+<h3>Enter The Endpoint to Test</h3>
+endpoint: <input type="text" name="endpoint" value="<?php echo $endpoint; ?>" size="100"/><br />
+<small style="color: green">Note: You can include query parameters in there to have them parsed in and signed too</small>
+<h3>Enter Your Consumer Key / Secret</h3>
+consumer key: <input type="text" name="key" value="<?php echo $key; ?>" /><br />
+consumer secret: <input type="text" name="secret" value="<?php echo $secret;?>" /><br />
+dump request, don't redirect: <input type="checkbox" name="dump_request" value="1" <?php if ($dump_request) echo 'checked="checked"'; ?>/><br />
+make a token request (don't forget to copy down the values you get)
+<input type="submit" name="action" value="request_token" />
+<h3>Enter Your Request Token / Secret</h3>
+token: <input type="text" name="token" value="<?php echo $token; ?>" /><br />
+token secret: <input type="text" name="token_secret" value="<?php echo $token_secret; ?>" /><br />
+<p><strong>Don't forget to update your endpoint to point at the auth or access token url</strong></p>
+try to authorize this token: <input type="submit" name="action" value="authorize" /><br />
+try to get an access token: <input type="submit" name="action" value="access_token" /><br />
+
+<h3>Currently Supported Signature Methods</h3>
+<p>Current signing method is: <?php echo $sig_method->get_name() ?></p>
+<ul>
+<?php
+foreach ($sig_methods as $key => $method) {
+
+ print "<li>$key";
+ if ($key != $sig_method->get_name()) {
+ print "(<a href='?sig_method=$key'>switch</a>)";
+ }
+ print "</li>\n";
+}
+?>
+</ul>
+
+<?php
+if ("RSA-SHA1" == $sig_method->get_name()) {
+ // passing test_server as a dummy referecne
+ print "<pre>" . $sig_method->fetch_private_cert($test_server). "</pre>\n";
+ print "<pre>" . $sig_method->fetch_public_cert($test_server) . "</pre>\n";
+}
+?>
+
+<h3>Further Resources</h3>
+<p>There is also a <a href="index.php">test server</a> implementation in here.</p>
+<p>The code running this example can be downloaded from the PHP section of the OAuth google code project: <a href="http://code.google.com/p/oauth/">http://code.google.com/p/oauth/</a>
+</body>
View
26 lib/OAuth/example/common.inc.php
@@ -0,0 +1,26 @@
+<?php
+require_once("../OAuth.php");
+require_once("../OAuth_TestServer.php");
+
+/*
+ * Config Section
+ */
+$domain = $_SERVER['HTTP_HOST'];
+$base = "/oauth/example";
+$base_url = "http://$domain$base";
+
+/**
+ * Some default objects
+ */
+
+$test_server = new TestOAuthServer(new MockOAuthDataStore());
+$hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
+$plaintext_method = new OAuthSignatureMethod_PLAINTEXT();
+$rsa_method = new TestOAuthSignatureMethod_RSA_SHA1();
+
+$test_server->add_signature_method($hmac_method);
+$test_server->add_signature_method($plaintext_method);
+$test_server->add_signature_method($rsa_method);
+
+$sig_methods = $test_server->get_signature_methods();
+?>
View
21 lib/OAuth/example/echo_api.php
@@ -0,0 +1,21 @@
+<?php
+require_once("common.inc.php");
+
+try {
+ $req = OAuthRequest::from_request();
+ list($consumer, $token) = $test_server->verify_request($req);
+
+ // lsit back the non-OAuth params
+ $total = array();
+ foreach($req->get_parameters() as $k => $v) {
+ if (substr($k, 0, 5) == "oauth") continue;
+ $total[] = urlencode($k) . "=" . urlencode($v);
+ }
+ print implode("&", $total);
+} catch (OAuthException $e) {
+ print($e->getMessage() . "\n<hr />\n");
+ print_r($req);
+ die();
+}
+
+?>
View
108 lib/OAuth/example/index.php
@@ -0,0 +1,108 @@
+<?php
+require_once("common.inc.php");
+
+
+$test_consumer = new OAuthConsumer("key", "secret", NULL);
+$req_token = new OAuthConsumer("requestkey", "requestsecret", 1);
+$acc_token = new OAuthConsumer("accesskey", "accesssecret", 1);
+
+$sig_method = $hmac_method;
+$user_sig_method = @$_GET['sig_method'];
+if ($user_sig_method) {
+ $sig_method = $sig_methods[$user_sig_method];
+}
+
+$req_req = OAuthRequest::from_consumer_and_token($test_consumer, NULL, "GET", $base_url . "/request_token.php");
+$req_req->sign_request($sig_method, $test_consumer, NULL);
+
+$acc_req = OAuthRequest::from_consumer_and_token($test_consumer, $req_token, "GET", $base_url . "/access_token.php");
+$acc_req->sign_request($sig_method, $test_consumer, $req_token);
+
+$echo_req = OAuthRequest::from_consumer_and_token($test_consumer, $acc_token, "GET", $base_url . "/echo_api.php", array("method"=> "foo%20bar", "bar" => "baz"));
+$echo_req->sign_request($sig_method, $test_consumer, $acc_token);
+
+?>
+<html>
+<head>
+<title>OAuth Test Server</title>
+</head>
+<body>
+<div><a href="index.php">server</a> | <a href="client.php">client</a></div>
+<h1>OAuth Test Server</h1>
+<h2>Instructions for Use</h2>
+<p>This is a test server with a predefined static set of keys and tokens, you can make your requests using them to test your code (and mine ;)).</p>
+<h3>Your Consumer Key / Secret</h3>
+<ul>
+<li>consumer key: <code><strong>key</strong></code></li>
+<li>consumer secret: <code><strong>secret</strong></code></li>
+</ul>
+<p>Use this key and secret for all your requests.</p>
+<h3>Getting a Request Token</h3>
+
+<ul>
+<li>request token endpoint: <code><strong><?php echo $base_url . "/request_token.php"; ?></strong></code></li>
+</ul>
+
+<p>A successful request will return the following:</p>
+<p><code>oauth_token=requestkey&amp;oauth_token_secret=requestsecret</code></p>
+
+<p>An unsuccessful request will attempt to describe what went wrong.</p>
+
+<h4>Example</h4>
+<a href="<?php echo $req_req; ?>"><?php echo $req_req; ?></a>
+
+<h3>Getting an Access Token</h3>
+<p>The Request Token provided above is already authorized, you may use it to request an Access Token right away.</p>
+
+<ul>
+<li>access token endpoint: <code><strong><?php echo $base_url . "/access_token.php"; ?></strong></code></li>
+</ul>
+
+<p>A successful request will return the following:</p>
+<p><code>oauth_token=accesskey&amp;oauth_token_secret=accesssecret</code></p>
+
+<p>An unsuccessful request will attempt to describe what went wrong.</p>
+
+<h4>Example</h4>
+<a href="<?php echo $acc_req; ?>"><?php echo $acc_req; ?></a>
+
+<h3>Making Authenticated Calls</h3>
+<p>Using your Access Token you can make authenticated calls.</p>
+
+<ul>
+<li>api endpoint: <code><strong><?php echo $base_url . "/echo_api.php"; ?></strong></code></li>
+</ul>
+<p>
+A successful request will echo the non-OAuth parameters sent to it, for example:</p>
+<p><code>method=foo&amp;bar=baz</code></p>
+<p>An unsuccessful request will attempt to describe what went wrong.</p>
+
+<h4>Example</h4>
+<a href="<?php echo $echo_req; ?>"><?php echo $echo_req; ?></a>
+
+<h3>Currently Supported Signature Methods</h3>
+<p>Current signing method is: <?php echo $user_sig_method ?></p>
+<ul>
+<?php
+$sig_methods = $test_server->get_signature_methods();
+foreach ($sig_methods as $key => $method) {
+ print "<li>$key";
+ if ($key != $sig_method->get_name()) {
+ print "(<a href='?sig_method=$key'>switch</a>)";
+ }
+ print "</li>\n";
+}
+?>
+</ul>
+
+<?php
+if ("RSA-SHA1" == $sig_method->get_name()) {
+ print "<pre>" . $sig_method->fetch_private_cert($req_req) . "</pre>\n";
+ print "<pre>" . $sig_method->fetch_public_cert($req_req) . "</pre>\n";
+}
+?>
+
+<h3>Further Resources</h3>
+<p>There is also a <a href="client.php">test client</a> implementation in here.</p>
+<p>The code running this example can be downloaded from the PHP section of the OAuth google code project: <a href="http://code.google.com/p/oauth/">http://code.google.com/p/oauth/</a>
+</body>
View
14 lib/OAuth/example/request_token.php
@@ -0,0 +1,14 @@
+<?php
+require_once("common.inc.php");
+
+try {
+ $req = OAuthRequest::from_request();
+ $token = $test_server->fetch_request_token($req);
+ print $token;
+} catch (OAuthException $e) {
+ print($e->getMessage() . "\n<hr />\n");
+ print_r($req);
+ die();
+}
+
+?>
View
170 lib/Yahoo/YahooCurl.class.php
@@ -0,0 +1,170 @@
+<?php
+
+/**
+ * Yahoo! PHP5 SDK
+ *
+ * * Yahoo! Query Language
+ * * Yahoo! Social API
+ *
+ * Find documentation and support on Yahoo! Developer Network: http://developer.yahoo.com
+ *
+ * Hosted on GitHub: http://github.com/yahoo/yos-social-php5/tree/master
+ *
+ * @package yos-social-php5
+ * @subpackage yahoo
+ *
+ * @author Dustin Whittle <dustin@yahoo-inc.com>
+ * @copyright Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
+ * @license BSD Open Source License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+class YahooCurl
+{
+
+ const VERSION = '1.0.0';
+
+ const GET = 'GET';
+ const PUT = 'PUT';
+ const POST = 'POST';
+ const DELETE = 'DELETE';
+ const HEAD = 'HEAD';
+
+
+ /**
+ * Fetches an HTTP resource
+ *
+ * @param string $url The request url
+ * @param string $params The request parameters
+ * @param string $header The request http headers
+ * @param string $method The request HTTP method (GET, POST, PUT, DELETE, HEAD)
+ * @param string $post The request body
+ *
+ * @return string Response body from the server
+ */
+ public static function fetch($url, $params, $headers = array(), $method = self::GET, $post = null, $options = array())
+ {
+ $options = array_merge(array(
+ 'timeout' => '10',
+ 'connect_timeout' => '10',
+ 'compression' => true,
+ 'debug' => true,
+ 'log' => sys_get_temp_dir().'/curl_debug.log',
+ ), $options);
+
+ if(!empty($params))
+ {
+ $url = $url.'?'.http_build_query($params);
+ }
+
+ $ch = curl_init($url);
+
+ // return headers
+ curl_setopt($ch, CURLOPT_HEADER, true);
+
+ // return body
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ // set headers
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+ // merge headers $request_headers["Content-Type"], "application/x-www-form-urlencoded"
+
+ // handle http methods
+ switch($method) {
+ case 'POST':
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
+ break;
+
+ case 'PUT':
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
+ break;
+
+ case 'HEAD':
+ case 'DELETE':
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
+ break;
+ }
+
+ // set user agent
+ curl_setopt($ch, CURLOPT_USERAGENT, sprintf('yos-social-php (%s) / PHP (%s)', self::VERSION, phpversion()));
+
+ // handle redirects
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+
+ // handle http compression
+ curl_setopt($ch, CURLOPT_ENCODING, '');
+
+ // timeouts
+ curl_setopt($ch, CURLOPT_TIMEOUT, $options['timeout']);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $options['timeout']);
+
+ // be nice to dev ssl certs
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_FAILONERROR, false);
+
+ // debug curl options
+ if($options['debug'])
+ {
+ curl_setopt($ch, CURLINFO_HEADER_OUT, true);
+ curl_setopt($ch, CURLOPT_VERBOSE, true);
+ }
+
+ $http = array();
+ $response = curl_exec($ch);
+
+ if($response === false)
+ {
+ // something bad happeneed (timeout, dns failure, ???)
+ error_log(curl_error($ch));
+ return false;
+ }
+
+ // process response
+ $http = array_merge($http, curl_getinfo($ch));
+
+ // process status code + headers
+ list($http['response_header'], $http['response_body']) = explode("\r\n\r\n", $response, 2);
+ $response_header_lines = explode("\r\n", $http['response_header']);
+ $http_response_line = array_shift($response_header_lines);
+ if (preg_match('@^HTTP/[0-9]\.[0-9] ([0-9]{3})@', $http_response_line, $matches)) {
+ $http['response_code'] = $matches[1];
+ }
+ $http['response_headers'] = array();
+ foreach ($response_header_lines as $header_line) {
+ list($header, $value) = explode(': ', $header_line, 2);
+ $http['response_headers'][$header] = $value;
+ }
+
+ if($options['debug'])
+ {
+ // debug info
+ error_log(sprintf('Fetching %s, method=%s, headers=%s, response=%s', $url, $method, var_export($headers, true), var_export($http, true)));
+ }
+
+ curl_close($ch);
+
+ return $http;
+ }
+
+}
View
101 lib/Yahoo/YahooOAuthAccessToken.class.php
@@ -0,0 +1,101 @@
+<?php
+
+/**
+ * Yahoo! PHP5 SDK
+ *
+ * * Yahoo! Query Language
+ * * Yahoo! Social API
+ *
+ * Find documentation and support on Yahoo! Developer Network: http://developer.yahoo.com
+ *
+ * Hosted on GitHub: http://github.com/yahoo/yos-social-php5/tree/master
+ *
+ * @package yos-social-php5
+ * @subpackage yahoo
+ *
+ * @author Dustin Whittle <dustin@yahoo-inc.com>
+ * @copyright Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
+ * @license BSD Open Source License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+class YahooOAuthAccessToken extends OAuthToken
+{
+
+ /*
+ AccessToken is a data type that represents an end user via an access token.
+
+ key -- the token
+ secret -- the token secret
+ expires_in -- authorization expiration from issue
+ session_handle -- scalable oauth session handle
+ authorization_expires_in -- authorization expiration timestamp
+ yahoo_guid -- yahoo guid
+ */
+ public $key = null,
+ $secret = null,
+ $expires_in = null,
+ $session_handle = null,
+ $authorization_expires_in = null,
+ $yahoo_guid = null,
+ $oauth_problem = null;
+
+ public function __construct($key, $secret, $expires_in=null, $session_handle=null, $authorization_expires_in=null, $yahoo_guid=null, $oauth_problem=null)
+ {
+ $this->key = $key;
+ $this->secret = $secret;
+ $this->expires_in = $expires_in;
+ $this->session_handle = $session_handle;
+ $this->authorization_expires_in = $authorization_expires_in;
+ $this->yahoo_guid = $yahoo_guid;
+ $this->oauth_problem = $oauth_problem;
+ }
+
+ public function to_string()
+ {
+ return http_build_query(array('oauth_token' => $this->key,
+ 'oauth_token_secret' => $this->secret,
+ 'oauth_expires_in' => $this->expires_in,
+ 'oauth_session_handle' => $this->session_handle,
+ 'oauth_authorization_expires_in' => $this->authorization_expires_in,
+ 'xoauth_yahoo_guid' => $this->yahoo_guid,
+ 'oauth_problem' => $this->oauth_problem
+ ));
+ }
+
+ public static function from_string($token)
+ {
+ /*
+ Returns a token from something like: oauth_token_secret=xxx&oauth_token=xxx
+ */
+ parse_str(trim($token), $params);
+
+ $key = isset($params['oauth_token']) ? $params['oauth_token'] : null;
+ $secret = isset($params['oauth_token_secret']) ? $params['oauth_token_secret'] : null;
+ $expires_in = isset($params['oauth_expires_in']) ? $params['oauth_expires_in'] : null;
+ $session_handle = isset($params['oauth_session_handle']) ? $params['oauth_session_handle'] : null;
+ $authorization_expires_in = isset($params['oauth_authorization_expires_in']) ? $params['oauth_authorization_expires_in'] : null;
+ $yahoo_guid = isset($params['xoauth_yahoo_guid']) ? $params['xoauth_yahoo_guid'] : null;
+ $oauth_problem = isset($params['oauth_problem']) ? $params['oauth_problem'] : null;
+
+ return new self($key, $secret, $expires_in, $session_handle, $authorization_expires_in, $yahoo_guid, $oauth_problem);
+ }
+
+}
View
441 lib/Yahoo/YahooOAuthApplication.class.php
@@ -0,0 +1,441 @@
+<?php
+
+/**
+ * Yahoo! PHP5 SDK
+ *
+ * * Yahoo! Query Language
+ * * Yahoo! Social API
+ *
+ * Find documentation and support on Yahoo! Developer Network: http://developer.yahoo.com
+ *
+ * Hosted on GitHub: http://github.com/yahoo/yos-social-php5/tree/master
+ *
+ * @package yos-social-php5
+ * @subpackage yahoo
+ *
+ * @author Dustin Whittle <dustin@yahoo-inc.com>
+ * @copyright Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
+ * @license BSD Open Source License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+require_once 'YahooCurl.class.php';
+require_once 'YahooYQLQuery.class.php';
+require_once 'YahooOAuthApplicationException.class.php';
+require_once 'YahooOAuthAccessToken.class.php';
+require_once 'YahooOAuthRequestToken.class.php';
+require_once 'YahooOAuthClient.class.php';
+
+
+class YahooOAuthApplication
+{
+ public function __construct($consumer_key, $consumer_secret, $application_id, $callback_url = null, $token = null, $options = array(), $client = null)
+ {
+ $this->client = is_null($client) ? new YahooOAuthClient() : $client;
+
+ $this->consumer_key = $consumer_key;
+ $this->consumer_secret = $consumer_secret;
+ $this->application_id = $application_id;
+ $this->callback_url = $callback_url;
+ $this->token = $token;
+ $this->options = $options;
+
+ $this->consumer = new OAuthConsumer($this->consumer_key, $this->consumer_secret);
+ $this->signature_method_plaintext = new OAuthSignatureMethod_PLAINTEXT();
+ $this->signature_method_hmac_sha1 = new OAuthSignatureMethod_HMAC_SHA1();
+ }
+
+ public function getOpenIDUrl($return_to = false, $lang = 'en', $openIdEndpoint = 'https://open.login.yahooapis.com/openid/op/auth')
+ {
+ $openid_request = array(
+ 'openid.ns' => 'http://specs.openid.net/auth/2.0',
+ 'openid.claimed_id' => 'http://specs.openid.net/auth/2.0/identifier_select',
+ 'openid.identity' => 'http://specs.openid.net/auth/2.0/identifier_select',
+ 'openid.realm' => $this->callback_url,
+ 'openid.ui.mode' => 'popup',
+ 'openid.return_to' => $return_to,
+ 'openid.mode' => 'checkid_setup',
+ 'openid.assoc_handle' => session_id(),
+ 'openid.ns.ui' => 'http://specs.openid.net/extensions/ui/1.0',
+ 'openid.ui.icon' => 'true',
+ 'openid.ui.language' => $lang,
+ 'openid.ns.ext1' => 'http://openid.net/srv/ax/1.0',
+ 'openid.ext1.mode' => 'fetch_request',
+ 'openid.ext1.type.email' => 'http://axschema.org/contact/email',
+ 'openid.ext1.type.first' => 'http://axschema.org/namePerson/first',
+ 'openid.ext1.type.last' => 'http://axschema.org/namePerson/last',
+ 'openid.ext1.type.country' => 'http://axschema.org/contact/country/home',
+ 'openid.ext1.type.lang' => 'http://axschema.org/pref/language',
+ 'openid.ext1.required' => 'email,first,last,country,lang',
+ 'openid.ns.oauth' => 'http://specs.openid.net/extensions/oauth/1.0',
+ 'openid.oauth.consumer' => $this->consumer_key,
+ 'openid.oauth.scope' => '',
+ 'xopenid_lang_pref' => $lang,
+ );
+
+ return $openIdEndpoint.'?'.http_build_query($openid_request);
+ }
+
+ public function getRequestToken($callback = "oob")
+ {
+ $parameters = array('xoauth_lang_pref' => 'en', 'oauth_callback' => $callback);
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, null, 'GET', YahooOAuthClient::REQUEST_TOKEN_API_URL, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, null);
+ return $this->client->fetch_request_token($oauth_request);
+ }
+
+ public function getAuthorizationUrl($oauth_request_token)
+ {
+ // $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $oauth_request_token, 'GET', YahooOAuthClient::AUTHORIZATION_API_URL);
+ // $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $oauth_request_token);
+ // return $oauth_request->to_url();
+
+ if(isset($oauth_request_token->request_auth_url) && !empty($oauth_request_token->request_auth_url))
+ {
+ $auth_url = $oauth_request_token->request_auth_url;
+ }
+ else
+ {
+ $auth_url = sprintf("%s?oauth_token=%s", YahooOAuthClient::AUTHORIZATION_API_URL, $oauth_request_token->key);
+ }
+
+ return $auth_url;
+ }
+
+ public function getAccessToken($oauth_request_token, $verifier = null)
+ {
+ if ($verifier == null)
+ {
+ $parameters = array();
+ }
+ else
+ {
+ $parameters = array('oauth_verifier' => $verifier);
+ }
+
+ if(isset($oauth_request_token->session_handle) && !empty($oauth_request_token->session_handle))
+ {
+ $parameters["oauth_session_handle"] = $oauth_request_token->session_handle;
+ }
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $oauth_request_token, 'GET', YahooOAuthClient::ACCESS_TOKEN_API_URL, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $oauth_request_token);
+ $this->token = $this->client->fetch_access_token($oauth_request);
+
+ return $this->token;
+ }
+
+ public function refreshAccessToken($oauth_access_token)
+ {
+ $parameters = array('oauth_session_handle' => $oauth_access_token->session_handle);
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $oauth_access_token, 'GET', YahooOAuthClient::REQUEST_TOKEN_API_URL, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $oauth_access_token);
+ $this->token = $this->client->fetch_access_token($oauth_request);
+
+ return $this->token;
+ }
+
+ public static function fromYAP($consumer_key, $consumer_secret, $application_id)
+ {
+ $is_canvas = (isset($_POST['yap_appid']) && isset($_POST['yap_view']) && isset($_POST['oauth_signature']));
+ if($is_canvas === false) {
+ throw new YahooOAuthException('YAP application environment not found in request.');
+ }
+
+ $yap_consumer_key = $_POST['yap_consumer_key'];
+ if($consumer_key != $yap_consumer_key) {
+ throw new YahooOAuthException(sprintf('Provided consumer key does not match yap_consumer_key: (%s)', $yap_consumer_key));
+ }
+
+ $consumer = new OAuthConsumer($consumer_key, $consumer_secret);
+ $token = new YahooOAuthAccessToken($_POST['yap_viewer_access_token'], $_POST['yap_viewer_access_token_secret'], null, null, null, $_POST['yap_viewer_guid']);
+ $application = new YahooOAuthApplication($consumer->key, $consumer->secret, $application_id, null, $token);
+
+ $signature_valid = $application->signature_method_hmac_sha1->check_signature(OAuthRequest::from_request(), $consumer, $token, $_POST['oauth_signature']);
+ if($signature_valid === false) {
+ // return false;
+ }
+
+ return $application;
+ }
+
+ public function getProfile($guid = null)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/profile', $guid);
+ $parameters = array('format' => 'json');
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $data = json_decode($this->client->access_resource($oauth_request));
+
+ return ($data) ? $data->profile : false;
+ }
+
+ public function getStatus($guid = null)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/profile/status', $guid);
+ $parameters = array('format' => 'json');
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ return json_decode($this->client->access_resource($oauth_request));
+ }
+
+ public function setStatus($guid = null, $status)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $body = '{"status":{"message":"'.$status.'"}}';
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/profile/status', $guid);
+ $parameters = array('format' => 'json');
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'PUT', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $http = YahooCurl::fetch($oauth_request->to_url(), array(), array('Content-Type: application/x-www-form-urlencoded', 'Accept: *'), $oauth_request->get_normalized_http_method(), $body);
+
+ return $http['response_body'];
+ }
+
+ public function getConnections($guid = null, $offset = 0, $limit = 10)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/connections', $guid);
+ $parameters = array('format' => 'json', 'view' => 'usercard', 'start' => $offset, 'count' => $limit);
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $data = json_decode($this->client->access_resource($oauth_request));
+
+ return ($data) ? $data->connections->connection : false;
+ }
+
+ public function getContacts($guid = null, $offset = 0, $limit = 10)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/contacts', $guid);
+ $parameters = array('format' => 'json', 'view' => 'tinyusercard', 'start' => $offset, 'count' => $limit);
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $data = json_decode($this->client->access_resource($oauth_request));
+
+ return ($data) ? $data->contacts->contact : false;
+ }
+
+ public function getContact($guid = NULL, $cid)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/contact/%s', $guid, $cid);
+ $parameters = array('format' => 'json');
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $data = json_decode($this->client->access_resource($oauth_request));
+
+ return ($data) ? $data->contact : false;
+ }
+
+ public function getContactSync($guid = null, $rev = 0)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/contacts', $guid);
+ $parameters = array('format' => 'json', 'view' => 'sync', 'rev' => $rev);
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $data = json_decode($this->client->access_resource($oauth_request));
+
+ return ($data) ? $data->contactsync : false;
+ }
+
+ public function syncContacts($guid = null, $contactsync)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/contacts', $guid);
+ $parameters = array('format' => 'json');
+
+ $data = array('contactsync' => $contactsync);
+ $body = json_encode($data);
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'PUT', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $http = YahooCurl::fetch($oauth_request->to_url(), array(), array('Content-Type: application/json', 'Accept: *'), $oauth_request->get_normalized_http_method(), $body);
+
+ return $http['response_body'];
+ }
+
+ public function addContact($guid = null, $contact)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/contacts', $guid);
+ $parameters = array('format' => 'json');
+
+ $data = array('contact' => $contact);
+ $body = json_encode($data);
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'POST', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $http = YahooCurl::fetch($oauth_request->to_url(), array(), array('Content-Type: application/json', 'Accept: *'), $oauth_request->get_normalized_http_method(), $body);
+
+ return $http['response_body'];
+ }
+
+ public function getUpdates($guid = null, $offset = 0, $limit = 10, $transform = null)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $url = sprintf(YahooOAuthClient::SOCIAL_API_URL.'/user/%s/updates', $guid);
+ $parameters = array('format' => 'json', 'start' => $offset, 'count' => $limit, 'transform' => ($transform) ? $transform : '( sort "pubDate" numeric descending (all) )');
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $data = json_decode($this->client->access_resource($oauth_request));
+
+ return ($data) ? $data->updates : false;
+ }
+
+ public function insertUpdate($guid = null, $description, $title, $link)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $source = 'APP.'.$this->application_id;
+ $suid = 'ugc'.rand(0, 1000);
+ $body = sprintf('
+ { "updates": [ {
+ "class": "app",
+ "collectionType": "guid",
+ "description": "%s",
+ "suid": "%s",
+ "link": "%s",
+ "source": "%s",
+ "pubDate": "%s",
+ "title": "%s",
+ "type": "appActivity",
+ "collectionID": "%s"
+ } ] }', $description, $suid, $link, $source, time(), $title, $guid);
+
+ $url = sprintf('%s/user/%s/updates/%s/%s', YahooOAuthClient::SOCIAL_API_URL, $guid, $source, $suid);
+ $parameters = array('format' => 'json');
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'PUT', $url, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ $http = YahooCurl::fetch($oauth_request->to_url(), array(), array('Content-Type: application/x-www-form-urlencoded', 'Accept: *'), $oauth_request->get_normalized_http_method(), $body);
+
+ return $http['response_body'];
+ }
+
+ public function getSocialGraph($guid = null, $offset = 0, $limit = 10)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $query = sprintf("select * from social.profile where guid in (select guid from social.connections (%s, %s) where owner_guid='%s')", $offset, $limit, $guid);
+ $data = $this->yql($query);
+
+ return isset($data->query->results) ? $data->query->results : false;
+ }
+
+ public function getProfileLocation($guid = null)
+ {
+ if($guid == null && !is_null($this->token))
+ {
+ $guid = $this->token->yahoo_guid;
+ }
+
+ $data = $this->yql(sprintf('select * from geo.places where text in (select location from social.profile where guid="%s")', $guid));
+
+ return isset($data->query->results) ? $data->query->results : false;
+ }
+
+ public function getGeoPlaces($location)
+ {
+ $data = $this->yql(sprintf('select * from geo.places where text="%s"', $location));
+
+ return isset($data->query->results) ? $data->query->results : false;
+ }
+
+ public function yql($query, $parameters = array())
+ {
+ if(is_array($query))
+ {
+ // handle multi queries
+ $query = sprintf('select * from query.multi where queries="%s"', implode(';', str_replace('"', "'", $query)));
+ }
+
+ $parameters = array_merge(array('q' => $query, 'format' => 'json', 'env' => YahooYQLQuery::DATATABLES_URL), $parameters);
+
+ $oauth_request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, 'GET', YahooYQLQuery::OAUTH_API_URL, $parameters);
+ $oauth_request->sign_request($this->signature_method_hmac_sha1, $this->consumer, $this->token);
+
+ return json_decode($this->client->access_resource($oauth_request));
+ }
+
+}
View
42 lib/Yahoo/YahooOAuthApplicationException.class.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Yahoo! PHP5 SDK
+ *
+ * * Yahoo! Query Language
+ * * Yahoo! Social API
+ *
+ * Find documentation and support on Yahoo! Developer Network: http://developer.yahoo.com
+ *
+ * Hosted on GitHub: http://github.com/yahoo/yos-social-php5/tree/master
+ *
+ * @package yos-social-php5
+ * @subpackage yahoo
+ *
+ * @author Dustin Whittle <dustin@yahoo-inc.com>
+ * @copyright Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
+ * @license BSD Open Source License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+class YahooOAuthApplicationException extends OAuthException
+{
+
+}
View
92 lib/Yahoo/YahooOAuthClient.class.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * Yahoo! PHP5 SDK
+ *
+ * * Yahoo! Query Language
+ * * Yahoo! Social API
+ *
+ * Find documentation and support on Yahoo! Developer Network: http://developer.yahoo.com
+ *
+ * Hosted on GitHub: http://github.com/yahoo/yos-social-php5/tree/master
+ *
+ * @package yos-social-php5
+ * @subpackage yahoo
+ *
+ * @author Dustin Whittle <dustin@yahoo-inc.com>
+ * @copyright Copyrights for code authored by Yahoo! Inc. is licensed under the following terms:
+ * @license BSD Open Source License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ **/
+
+class YahooOAuthClient
+{