4
* Handle the discovery of OAuth service provider endpoints and static consumer identity.
7
* @author Marc Worrell <marcw@pobox.com>
8
* @date Sep 4, 2008 5:05:19 PM
12
* Copyright (c) 2007-2008 Mediamatic Lab
14
* Permission is hereby granted, free of charge, to any person obtaining a copy
15
* of this software and associated documentation files (the "Software"), to deal
16
* in the Software without restriction, including without limitation the rights
17
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
* copies of the Software, and to permit persons to whom the Software is
19
* furnished to do so, subject to the following conditions:
21
* The above copyright notice and this permission notice shall be included in
22
* all copies or substantial portions of the Software.
24
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
require_once dirname(__FILE__).'/discovery/xrds_parse.php';
35
require_once dirname(__FILE__).'/OAuthException2.php';
36
require_once dirname(__FILE__).'/OAuthRequestLogger.php';
42
* Return a description how we can do a consumer allocation. Prefers static allocation if
43
* possible. If static allocation is possible
45
* See also: http://oauth.net/discovery/#consumer_identity_types
48
* @return array provider description
50
static function discover ( $uri )
52
// See what kind of consumer allocations are available
53
$xrds_file = self::discoverXRDS($uri);
54
if (!empty($xrds_file))
56
$xrds = xrds_parse($xrds_file);
59
throw new OAuthException2('Could not discover OAuth information for '.$uri);
64
throw new OAuthException2('Could not discover XRDS file at '.$uri);
67
// Fill an OAuthServer record for the uri found
68
$ps = parse_url($uri);
69
$host = isset($ps['host']) ? $ps['host'] : 'localhost';
70
$server_uri = $ps['scheme'].'://'.$host.'/';
75
'consumer_secret' => '',
76
'signature_methods' => '',
77
'server_uri' => $server_uri,
78
'request_token_uri' => '',
79
'authorize_uri' => '',
80
'access_token_uri' => ''
84
// Consumer identity (out of bounds or static)
85
if (isset($xrds['consumer_identity']))
87
// Try to find a static consumer allocation, we like those :)
88
foreach ($xrds['consumer_identity'] as $ci)
90
if ($ci['method'] == 'static' && !empty($ci['consumer_key']))
92
$p['consumer_key'] = $ci['consumer_key'];
93
$p['consumer_secret'] = '';
95
else if ($ci['method'] == 'oob' && !empty($ci['uri']))
97
// TODO: Keep this uri somewhere for the user?
98
$p['consumer_oob_uri'] = $ci['uri'];
104
if (isset($xrds['request'][0]['uri']))
106
$p['request_token_uri'] = $xrds['request'][0]['uri'];
107
if (!empty($xrds['request'][0]['signature_method']))
109
$p['signature_methods'] = $xrds['request'][0]['signature_method'];
112
if (isset($xrds['authorize'][0]['uri']))
114
$p['authorize_uri'] = $xrds['authorize'][0]['uri'];
115
if (!empty($xrds['authorize'][0]['signature_method']))
117
$p['signature_methods'] = $xrds['authorize'][0]['signature_method'];
120
if (isset($xrds['access'][0]['uri']))
122
$p['access_token_uri'] = $xrds['access'][0]['uri'];
123
if (!empty($xrds['access'][0]['signature_method']))
125
$p['signature_methods'] = $xrds['access'][0]['signature_method'];
133
* Discover the XRDS file at the uri. This is a bit primitive, you should overrule
134
* this function so that the XRDS file can be cached for later referral.
137
* @return string false when no XRDS file found
139
static protected function discoverXRDS ( $uri, $recur = 0 )
141
// Bail out when we are following redirects
147
$data = self::curl($uri);
149
// Check what we got back, could be:
150
// 1. The XRDS discovery file itself (check content-type)
151
// 2. The X-XRDS-Location header
153
if (is_string($data) && !empty($data))
155
list($head,$body) = explode("\r\n\r\n", $data);
159
// See if we got the XRDS file itself or we have to follow a location header
160
if ( preg_match('/^Content-Type:\s*application\/xrds+xml/im', $head)
161
|| preg_match('/^<\?xml[^>]*\?>\s*<xrds\s/i', $body)
162
|| preg_match('/^<xrds\s/i', $body)
167
else if ( preg_match('/^X-XRDS-Location:\s*([^\r\n]*)/im', $head, $m)
168
|| preg_match('/^Location:\s*([^\r\n]*)/im', $head, $m))
170
// Recurse to the given location
173
$xrds = self::discoverXRDS($m[1], $recur+1);
177
// Referring to the same uri, bail out
183
// Not an XRDS file an nowhere else to check
196
* Try to fetch an XRDS file at the given location. Sends an accept header preferring the xrds file.
199
* @return array (head,body), false on an error
201
static protected function curl ( $uri )
205
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/xrds+xml, */*;q=0.1'));
206
curl_setopt($ch, CURLOPT_USERAGENT, 'anyMeta/OAuth 1.0 - (OAuth Discovery $LastChangedRevision: 45 $)');
207
curl_setopt($ch, CURLOPT_URL, $uri);
208
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
209
curl_setopt($ch, CURLOPT_HEADER, true);
210
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
212
$txt = curl_exec($ch);
215
// Tell the logger what we requested and what we received back
217
OAuthRequestLogger::setSent($data, "");
218
OAuthRequestLogger::setReceived($txt);
225
/* vi:set ts=4 sts=4 sw=4 binary noeol: */
b'\\ No newline at end of file'