summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortailor <cygnus@janrain.com>2007-01-11 20:34:25 +0000
committertailor <cygnus@janrain.com>2007-01-11 20:34:25 +0000
commitf1d90afb457e2391a0437fc65967a0018b2f2a45 (patch)
treed0e6515e67dbf8c74d10ccf97772cbaa817a6c7a
parentfac3f079bf00731b01d451a63c0c278373b5cf04 (diff)
downloadphp-openid-f1d90afb457e2391a0437fc65967a0018b2f2a45.zip
php-openid-f1d90afb457e2391a0437fc65967a0018b2f2a45.tar.gz
php-openid-f1d90afb457e2391a0437fc65967a0018b2f2a45.tar.bz2
[project @ [break] Refactor discovery]
-rw-r--r--Auth/OpenID/Discover.php116
-rw-r--r--Tests/Auth/OpenID/Consumer.php5
2 files changed, 93 insertions, 28 deletions
diff --git a/Auth/OpenID/Discover.php b/Auth/OpenID/Discover.php
index a959d44..4d5a5f7 100644
--- a/Auth/OpenID/Discover.php
+++ b/Auth/OpenID/Discover.php
@@ -20,6 +20,15 @@ define('Auth_OpenID_TYPE_1_0', 'http://openid.net/signon/1.0');
define('Auth_OpenID_TYPE_2_0_IDP', 'http://openid.net/server/2.0');
define('Auth_OpenID_TYPE_2_0', 'http://openid.net/signon/2.0');
+function Auth_OpenID_getOpenIDTypeURIs()
+{
+ return array(Auth_OpenID_TYPE_2_0_IDP,
+ Auth_OpenID_TYPE_2_0,
+ Auth_OpenID_TYPE_1_2,
+ Auth_OpenID_TYPE_1_1,
+ Auth_OpenID_TYPE_1_0);
+}
+
/**
* Object representing an OpenID service endpoint.
*/
@@ -200,12 +209,7 @@ function filter_MatchesAnyOpenIDType(&$service)
$uris = $service->getTypes();
foreach ($uris as $uri) {
- if (in_array($uri,
- array(Auth_OpenID_TYPE_1_0,
- Auth_OpenID_TYPE_1_1,
- Auth_OpenID_TYPE_1_2,
- Auth_OpenID_TYPE_2_0,
- Auth_OpenID_TYPE_2_0_IDP))) {
+ if (in_array($uri, Auth_OpenID_getOpenIDTypeURIs())) {
return true;
}
}
@@ -213,6 +217,71 @@ function filter_MatchesAnyOpenIDType(&$service)
return false;
}
+function Auth_OpenID_bestMatchingService($service)
+{
+ // Return the index of the first matching type, or something
+ // higher if no type matches.
+ //
+ // This provides an ordering in which service elements that
+ // contain a type that comes earlier in the preferred types list
+ // come before service elements that come later. If a service
+ // element has more than one type, the most preferred one wins.
+
+ foreach ($preferred_types as $index => $typ) {
+ if (in_array($typ, $service->type_uris)) {
+ return $index;
+ }
+ }
+
+ return count($preferred_types);
+}
+
+function Auth_OpenID_arrangeByType($service_list, $preferred_types)
+{
+ // Rearrange service_list in a new list so services are ordered by
+ // types listed in preferred_types. Return the new list.
+
+ // Build a list with the service elements in tuples whose
+ // comparison will prefer the one with the best matching service
+ $prio_services = array();
+ foreach ($service_list as $index => $service) {
+ $prio_services[] = array(Auth_OpenID_bestMatchingService($service),
+ $index, $service);
+ }
+
+ sort($prio_services);
+
+ // Now that the services are sorted by priority, remove the sort
+ // keys from the list.
+ foreach ($prio_services as $index => $s) {
+ $prio_services[$index] = $prio_services[$index][2];
+ }
+
+ return $prio_services;
+}
+
+// Extract OP Identifier services. If none found, return the rest,
+// sorted with most preferred first according to
+// OpenIDServiceEndpoint.openid_type_uris.
+//
+// openid_services is a list of OpenIDServiceEndpoint objects.
+//
+// Returns a list of OpenIDServiceEndpoint objects."""
+function Auth_OpenID_getOPOrUserServices($openid_services)
+{
+ $op_services = Auth_OpenID_arrangeByType($openid_services,
+ array(Auth_OpenID_TYPE_2_0_IDP));
+
+ $openid_services = arrangeByType($openid_services,
+ Auth_OpenID_getOpenIDTypeURIs());
+
+ if ($op_services) {
+ return $op_services;
+ } else {
+ return $openid_services;
+ }
+}
+
function Auth_OpenID_makeOpenIDEndpoints($uri, $endpoints)
{
$s = array();
@@ -267,22 +336,25 @@ function Auth_OpenID_discoverWithYadis($uri, &$fetcher)
}
if (!$openid_services) {
- return @Auth_OpenID_discoverWithoutYadis($uri,
- $fetcher);
- }
- if (!$openid_services) {
+ if (Services_Yadis_XRDS::parseXRDS($response->body) !== null) {
+ return @Auth_OpenID_discoverWithoutYadis($uri,
+ $fetcher);
+ }
+
$body = $response->body;
// Try to parse the response as HTML to get OpenID 1.0/1.1
// <link rel="...">
$openid_services = Auth_OpenID_ServiceEndpoint::fromHTML($identity_url,
- $body);
- } else {
- $openid_services = Auth_OpenID_makeOpenIDEndpoints($response->uri,
- $openid_services);
+ $body);
+ // } else {
+ // $openid_services = Auth_OpenID_makeOpenIDEndpoints($response->uri,
+ // $openid_services);
}
+ $openid_services = Auth_OpenID_getOPOrUserServices($openid_services);
+
return array($identity_url, $openid_services, $http_response);
}
@@ -322,20 +394,18 @@ function Auth_OpenID_discoverWithoutYadis($uri, &$fetcher)
function _Auth_OpenID_discoverXRI($iname, &$fetcher)
{
$services = new Services_Yadis_ProxyResolver($fetcher);
- list($canonicalID, $service_list) = $services->query($iname,
- array(Auth_OpenID_TYPE_1_0,
- Auth_OpenID_TYPE_1_1,
- Auth_OpenID_TYPE_1_2,
- Auth_OpenID_TYPE_2_0,
- Auth_OpenID_TYPE_2_0_IDP),
- array('filter_MatchesAnyOpenIDType'));
-
- $endpoints = Auth_OpenID_makeOpenIDEndpoints($iname, $service_list);
+ list($canonicalID, $service_list) =
+ $services->query($iname,
+ Auth_OpenID_getOpenIDTypeURIs(),
+ array('filter_MatchesAnyOpenIDType'));
for ($i = 0; $i < count($endpoints); $i++) {
$endpoints[$i]->canonicalID = $canonicalID;
+ $endpoints[$i]->claimed_id = $canonicalID;
}
+ $endpoints = Auth_OpenID_getOPOrUserServices($endpoints);
+
// FIXME: returned xri should probably be in some normal form
return array($iname, $endpoints, null);
}
diff --git a/Tests/Auth/OpenID/Consumer.php b/Tests/Auth/OpenID/Consumer.php
index b135f9a..7477007 100644
--- a/Tests/Auth/OpenID/Consumer.php
+++ b/Tests/Auth/OpenID/Consumer.php
@@ -226,10 +226,6 @@ class Tests_Auth_OpenID_Consumer extends PHPUnit_TestCase {
$result = $consumer->complete($message, $result->endpoint);
- if ($result->status != Auth_OpenID_SUCCESS) {
- print $result->message."\n";
- }
-
$this->assertEquals(Auth_OpenID_SUCCESS, $result->status);
$this->assertEquals($result->identity_url, $user_url);
}
@@ -387,7 +383,6 @@ class Tests_Auth_OpenID_Consumer_CheckNonceTest extends _TestIdRes {
array('openid.nonce'));
$ret = $this->consumer->_checkNonce($this->server_url, $this->response);
$this->assertEquals($ret->status, Auth_OpenID_SUCCESS);
- # print $ret->message."\n";
$this->assertEquals($ret->identity_url, $this->consumer_id);
}