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); }
/** * 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; }