public function __construct($providerUrl, osapiStorage $storage, osapiHttpProvider $httpProvider = null) {
    $this->providerUrl = $providerUrl;
    $this->providerName = $this->providerUrl;
    if ($httpProvider) {
      $this->httpProvider = $httpProvider;
    } else {
      $this->httpProvider = new osapiCurlProvider();
    }
    // See if we have any cached XRDS info so we can skip the http request. Cache time is currently hard-coded to 1 day
    if (($xrds = $storage->get($this->providerUrl.":xrds", 24 * 60 * 60)) !== false) {
      list($requestTokenUrl, $authorizeUrl, $accessTokenUrl, $restEndpoint, $rpcEndpoint, $this->providerName, $isOpenSocial) = $xrds;
    } else {
      // Start XRDS discovery

      $xrds = XrdsSimpleParser::doOAuthDiscovery($this->providerUrl, true, $this->httpProvider);

      // OAuth end-points
      $requestTokenUrl = $xrds['requestUrl'];
      $authorizeUrl = $xrds['authorizeUrl'];
      $accessTokenUrl = $xrds['accessUrl'];
      if (empty($requestTokenUrl) || empty($authorizeUrl) || empty($accessTokenUrl)) {
        throw new osapiException("Could not discover the required OAuth end-points");
      }
      
      $rddXml = $xrds['rdd'];

      // PortableContacts end-point, optional
      $pocoUrl = XrdsSimpleParser::getServiceByType($rddXml, 'http://portablecontacts.net/spec/1.0');
      if (empty($pocoUrl)) $pocoUrl = null;

      // These are not official end-point names, only partuza supports them currently, a proposal has been send to the spec list
      $restEndpoint = XrdsSimpleParser::getServiceByType($rddXml, 'http://ns.opensocial.org/rest/0.8');
      $rpcEndpoint = XrdsSimpleParser::getServiceByType($rddXml, 'http://ns.opensocial.org/rpc/0.8');
      if (empty($restEndpoint) && empty($rpcEndpoint)) {
        // no experimental simple end points found, try to find the rest base based on the people end-point
        $peopleEndpoint = XrdsSimpleParser::getServiceByType($rddXml, 'http://ns.opensocial.org/people/0.8');
        $restEndpoint = str_replace('/people', '', $peopleEndpoint);
      }
      $isOpenSocial = true;
      if (empty($restEndpoint) && empty($rpcEndpoint) && empty($pocoUrl)) {
        throw new osapiException("No supported social end-points found");
      } elseif (empty($restEndpoint) && empty($rpcEndpoint) && !empty($pocoUrl)) {
        $isOpenSocial = false;
        $restEndpoint = $pocoUrl;
        $rpcEndpoint = null;
      }

      // Store the results in cache so we can skip it next time
      $storage->set($this->providerUrl.":xrds", array((string)$requestTokenUrl, (string)$authorizeUrl, (string)$accessTokenUrl, (string)$restEndpoint, (string)$rpcEndpoint, (string)$this->providerName, (int)$isOpenSocial));
    }
    // Construct our selves based on the XRDS discovered end-points
    parent::__construct($requestTokenUrl, $authorizeUrl, $accessTokenUrl, $restEndpoint, $rpcEndpoint, $this->providerName, $isOpenSocial);
  }
Esempio n. 2
0
 /**
  * Performs OAuth Discovery on the given URL, and returns the OAuth endpoints.
  * 
  * @param $url       Protected endpoint URL to perform OAuth Discovery on (string)
  * @param $returnRdd Optional flag to also return the RDD found during discovery
  * @return           array containing named OAuth endpoints, and rdd if requested,
  *                   or false if OAuth Discovery fails
  * 
  * The returned endpoints information looks like this:
  *   array(
  *     'requestUrl'   => 'http://endpoint-for-getting-a-request-token',
  *     'authorizeUrl' => 'http://endpoint-for-authorizing-request-token',
  *     'accessUrl'    => 'http://endpoint-for-getting-an-access-token',
  *     'rddXml'       => [SimpleXmlElement for RDD, if requested]
  *   )
  */
 public static function doOAuthDiscovery($url, $returnRdd = false, $httpProvider = null)
 {
     if (!$httpProvider) {
         $httpProvider = new osapiCurlProvider();
     }
     $rddXml = XrdsSimpleParser::fetchRdd($url, $httpProvider);
     $oauthUrl = XrdsSimpleParser::getServiceByType($rddXml, 'http://oauth.net/discovery/1.0');
     if (!$oauthUrl) {
         return false;
     }
     // can't find rdd with oauth info
     $xrdId = null;
     if (strpos($oauthUrl, "#") !== false) {
         // extract fragment, which specifies the xml:id for the right XRD
         list($oauthUrl, $xrdId) = explode('#', $oauthUrl, 2);
     }
     // if we were pointed to a different RDD, fetch it now (but if we just got a fragment, keep the same RDD)
     if ($oauthUrl && $oauthUrl != $url) {
         $rddXml = XrdsSimpleParser::fetchRdd($oauthUrl, $httpProvider);
     }
     if (!$rddXml) {
         return false;
     }
     // can't find final RDD
     // look up the OAuth endpoints and return them, along with the final RDD
     $requestUrl = XrdsSimpleParser::getServiceByType($rddXml, 'http://oauth.net/core/1.0/endpoint/request', $xrdId);
     $authorizeUrl = XrdsSimpleParser::getServiceByType($rddXml, 'http://oauth.net/core/1.0/endpoint/authorize', $xrdId);
     $accessUrl = XrdsSimpleParser::getServiceByType($rddXml, 'http://oauth.net/core/1.0/endpoint/access', $xrdId);
     $endpoints = array('requestUrl' => $requestUrl, 'authorizeUrl' => $authorizeUrl, 'accessUrl' => $accessUrl);
     if ($returnRdd) {
         $endpoints['rdd'] = $rddXml;
     }
     // in case you want to perform additional discovery
     return $endpoints;
 }