. * * @package StatusNet * @author James Walker * @copyright 2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ define('WEBFINGER_SERVICE_REL_VALUE', 'lrdd'); /** * Implement the webfinger protocol. */ class Webfinger { const PROFILEPAGE = 'http://webfinger.net/rel/profile-page'; const UPDATESFROM = 'http://schemas.google.com/g/2010#updates-from'; /** * Perform a webfinger lookup given an account. */ public function lookup($id) { $id = $this->normalize($id); list($name, $domain) = explode('@', $id); $links = $this->getServiceLinks($domain); if (!$links) { return false; } $services = array(); foreach ($links as $link) { if ($link['template']) { return $this->getServiceDescription($link['template'], $id); } if ($link['href']) { return $this->getServiceDescription($link['href'], $id); } } } /** * Normalize an account ID */ function normalize($id) { if (substr($id, 0, 7) == 'acct://') { return substr($id, 7); } else if (substr($id, 0, 5) == 'acct:') { return substr($id, 5); } return $id; } function getServiceLinks($domain) { $url = 'http://'. $domain .'/.well-known/host-meta'; $content = $this->fetchURL($url); if (empty($content)) { common_log(LOG_DEBUG, 'Error fetching host-meta'); return false; } $result = XRD::parse($content); // Ensure that the host == domain (spec may include signing later) if ($result->host != $domain) { return false; } $links = array(); foreach ($result->links as $link) { if ($link['rel'] == WEBFINGER_SERVICE_REL_VALUE) { $links[] = $link; } } return $links; } function getServiceDescription($template, $id) { $url = $this->applyTemplate($template, 'acct:' . $id); $content = $this->fetchURL($url); return XRD::parse($content); } function fetchURL($url) { try { $client = new HTTPClient(); $response = $client->get($url); } catch (HTTP_Request2_Exception $e) { return false; } if ($response->getStatus() != 200) { return false; } return $response->getBody(); } function applyTemplate($template, $id) { $template = str_replace('{uri}', urlencode($id), $template); return $template; } function getHostMeta($domain, $template) { $xrd = new XRD(); $xrd->host = $domain; $xrd->links[] = array('rel' => 'lrdd', 'template' => $template, 'title' => array('Resource Descriptor')); return $xrd->toXML(); } }