From 15b1d130d2ddcf86bb46671f281a88de1f8921e9 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Tue, 29 Jun 2010 14:39:57 -0400 Subject: [PATCH] Update to last upstream version of libomb: coding style updates, static call fix, improved handling of invalid XRD URIs. --- extlib/libomb/base_url_xrds_mapper.php | 75 +- extlib/libomb/constants.php | 15 +- extlib/libomb/datastore.php | 330 ++++---- extlib/libomb/helper.php | 147 ++-- extlib/libomb/invalidparameterexception.php | 44 +- extlib/libomb/invalidyadisexception.php | 26 +- extlib/libomb/notice.php | 450 +++++----- extlib/libomb/omb_yadis_xrds.php | 339 ++++---- extlib/libomb/plain_xrds_writer.php | 128 +-- extlib/libomb/profile.php | 552 ++++++------ extlib/libomb/remoteserviceexception.php | 73 +- extlib/libomb/service_consumer.php | 799 +++++++++--------- extlib/libomb/service_provider.php | 786 ++++++++--------- extlib/libomb/unsupportedserviceexception.php | 25 +- extlib/libomb/xrds_mapper.php | 38 +- extlib/libomb/xrds_writer.php | 37 +- 16 files changed, 2072 insertions(+), 1792 deletions(-) diff --git a/extlib/libomb/base_url_xrds_mapper.php b/extlib/libomb/base_url_xrds_mapper.php index 6454595835..d45d6d69f9 100755 --- a/extlib/libomb/base_url_xrds_mapper.php +++ b/extlib/libomb/base_url_xrds_mapper.php @@ -1,14 +1,6 @@ writeXRDS. + * This file is part of libomb * * PHP version 5 * @@ -25,27 +17,56 @@ require_once 'constants.php'; * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Base_URL_XRDS_Mapper implements OMB_XRDS_Mapper { +require_once 'xrds_mapper.php'; +require_once 'constants.php'; - protected $urls; +/** + * Map XRDS actions to URLs using base URLs + * + * This class realizes a simple mapping of action URIs to handler URLs. The + * target URLs are constructed using a base URL. + */ +class OMB_Base_URL_XRDS_Mapper implements OMB_XRDS_Mapper +{ + protected $urls; - public function __construct($oauth_base, $omb_base) { - $this->urls = array( - OAUTH_ENDPOINT_REQUEST => $oauth_base . 'requesttoken', - OAUTH_ENDPOINT_AUTHORIZE => $oauth_base . 'userauthorization', - OAUTH_ENDPOINT_ACCESS => $oauth_base . 'accesstoken', - OMB_ENDPOINT_POSTNOTICE => $omb_base . 'postnotice', - OMB_ENDPOINT_UPDATEPROFILE => $omb_base . 'updateprofile'); - } + /** + * Constructor + * + * Initialize the XRDS mapper with base URLs for OAuth and OMB endpoints. + * + * @param string $oauth_base The base URL for OAuth endpoints + * @param string $omb_base The base URL for OMB endpoints + */ + public function __construct($oauth_base, $omb_base) + { + $this->urls = array( + OAUTH_ENDPOINT_REQUEST => $oauth_base . 'requesttoken', + OAUTH_ENDPOINT_AUTHORIZE => $oauth_base . 'userauthorization', + OAUTH_ENDPOINT_ACCESS => $oauth_base . 'accesstoken', + OMB_ENDPOINT_POSTNOTICE => $omb_base . 'postnotice', + OMB_ENDPOINT_UPDATEPROFILE => $omb_base . 'updateprofile'); + } - public function getURL($action) { - return $this->urls[$action]; - } + /** + * Fetch an URL for a specified action + * + * Returns the action URL for an action specified by the endpoint URI. + * + * @param string $action The endpoint URI + * + * @return string The action URL + */ + public function getURL($action) + { + return $this->urls[$action]; + } } ?> diff --git a/extlib/libomb/constants.php b/extlib/libomb/constants.php index a097443acc..2f8c0e514d 100644 --- a/extlib/libomb/constants.php +++ b/extlib/libomb/constants.php @@ -20,15 +20,16 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ /** * The OMB constants. - **/ + */ define('OMB_VERSION_01', 'http://openmicroblogging.org/protocol/0.1'); @@ -40,7 +41,7 @@ define('OMB_ENDPOINT_POSTNOTICE', OMB_VERSION . '/postNotice'); /** * The OAuth constants. - **/ + */ define('OAUTH_NAMESPACE', 'http://oauth.net/core/1.0/'); diff --git a/extlib/libomb/datastore.php b/extlib/libomb/datastore.php index ab52de547b..d67aafcc56 100755 --- a/extlib/libomb/datastore.php +++ b/extlib/libomb/datastore.php @@ -1,4 +1,28 @@ . + * + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ require_once 'OAuth.php'; @@ -27,174 +51,162 @@ require_once 'OAuth.php'; * Most of the parameters passed to these methods are unescaped and unverified * user input. Therefore they should be handled with extra care to avoid * security problems like SQL injections. - * - * PHP version 5 - * - * LICENSE: This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + */ +class OMB_Datastore extends OAuthDataStore +{ -class OMB_Datastore extends OAuthDataStore { + /********* + * OAUTH * + *********/ - /********* - * OAUTH * - *********/ + /** + * Revoke specified OAuth token + * + * Revokes the authorization token specified by $token_key. + * Throws exceptions in case of error. + * + * @param string $token_key The key of the token to be revoked + * + * @access public + */ + public function revoke_token($token_key) + { + throw new Exception(); + } - /** - * Revoke specified OAuth token - * - * Revokes the authorization token specified by $token_key. - * Throws exceptions in case of error. - * - * @param string $token_key The key of the token to be revoked - * - * @access public - **/ - public function revoke_token($token_key) { - throw new Exception(); - } + /** + * Authorize specified OAuth token + * + * Authorizes the authorization token specified by $token_key. + * Throws exceptions in case of error. + * + * @param string $token_key The key of the token to be authorized + * + * @access public + */ + public function authorize_token($token_key) + { + throw new Exception(); + } - /** - * Authorize specified OAuth token - * - * Authorizes the authorization token specified by $token_key. - * Throws exceptions in case of error. - * - * @param string $token_key The key of the token to be authorized - * - * @access public - **/ - public function authorize_token($token_key) { - throw new Exception(); - } + /********* + * OMB * + *********/ - /********* - * OMB * - *********/ + /** + * Get profile by identifying URI + * + * Returns an OMB_Profile object representing the OMB profile identified by + * $identifier_uri. + * Returns null if there is no such OMB profile. + * Throws exceptions in case of other error. + * + * @param string $identifier_uri The OMB identifier URI specifying the + * requested profile + * + * @access public + * + * @return OMB_Profile The corresponding profile + */ + public function getProfile($identifier_uri) + { + throw new Exception(); + } - /** - * Get profile by identifying URI - * - * Returns an OMB_Profile object representing the OMB profile identified by - * $identifier_uri. - * Returns null if there is no such OMB profile. - * Throws exceptions in case of other error. - * - * @param string $identifier_uri The OMB identifier URI specifying the - * requested profile - * - * @access public - * - * @return OMB_Profile The corresponding profile - **/ - public function getProfile($identifier_uri) { - throw new Exception(); - } + /** + * Save passed profile + * + * Stores the OMB profile $profile. Overwrites an existing entry. + * Throws exceptions in case of error. + * + * @param OMB_Profile $profile The OMB profile which should be saved + * + * @access public + */ + public function saveProfile($profile) + { + throw new Exception(); + } - /** - * Save passed profile - * - * Stores the OMB profile $profile. Overwrites an existing entry. - * Throws exceptions in case of error. - * - * @param OMB_Profile $profile The OMB profile which should be saved - * - * @access public - **/ - public function saveProfile($profile) { - throw new Exception(); - } + /** + * Save passed notice + * + * Stores the OMB notice $notice. The datastore may change the passed + * notice. This might by necessary for URIs depending on a database key. + * Note that it is the user’s duty to present a mechanism for his + * OMB_Datastore to appropriately change his OMB_Notice. + * Throws exceptions in case of error. + * + * @param OMB_Notice &$notice The OMB notice which should be saved + * + * @access public + */ + public function saveNotice(&$notice) + { + throw new Exception(); + } - /** - * Save passed notice - * - * Stores the OMB notice $notice. The datastore may change the passed notice. - * This might by neccessary for URIs depending on a database key. Note that - * it is the user’s duty to present a mechanism for his OMB_Datastore to - * appropriately change his OMB_Notice. TODO: Ugly. - * Throws exceptions in case of error. - * - * @param OMB_Notice $notice The OMB notice which should be saved - * - * @access public - **/ - public function saveNotice(&$notice) { - throw new Exception(); - } + /** + * Get subscriptions of a given profile + * + * Returns an array containing subscription informations for the specified + * profile. Every array entry should in turn be an array with keys + * 'uri´: The identifier URI of the subscriber + * 'token´: The subscribe token + * 'secret´: The secret token + * Throws exceptions in case of error. + * + * @param string $subscribed_user_uri The OMB identifier URI specifying the + * subscribed profile + * + * @access public + * + * @return mixed An array containing the subscriptions or 0 if no + * subscription has been found. + */ + public function getSubscriptions($subscribed_user_uri) + { + throw new Exception(); + } - /** - * Get subscriptions of a given profile - * - * Returns an array containing subscription informations for the specified - * profile. Every array entry should in turn be an array with keys - * 'uri´: The identifier URI of the subscriber - * 'token´: The subscribe token - * 'secret´: The secret token - * Throws exceptions in case of error. - * - * @param string $subscribed_user_uri The OMB identifier URI specifying the - * subscribed profile - * - * @access public - * - * @return mixed An array containing the subscriptions or 0 if no - * subscription has been found. - **/ - public function getSubscriptions($subscribed_user_uri) { - throw new Exception(); - } + /** + * Delete a subscription + * + * Deletes the subscription from $subscriber_uri to $subscribed_user_uri. + * Throws exceptions in case of error. + * + * @param string $subscriber_uri The OMB identifier URI specifying the + * subscribing profile + * + * @param string $subscribed_user_uri The OMB identifier URI specifying the + * subscribed profile + * + * @access public + */ + public function deleteSubscription($subscriber_uri, $subscribed_user_uri) + { + throw new Exception(); + } - /** - * Delete a subscription - * - * Deletes the subscription from $subscriber_uri to $subscribed_user_uri. - * Throws exceptions in case of error. - * - * @param string $subscriber_uri The OMB identifier URI specifying the - * subscribing profile - * - * @param string $subscribed_user_uri The OMB identifier URI specifying the - * subscribed profile - * - * @access public - **/ - public function deleteSubscription($subscriber_uri, $subscribed_user_uri) { - throw new Exception(); - } - - /** - * Save a subscription - * - * Saves the subscription from $subscriber_uri to $subscribed_user_uri. - * Throws exceptions in case of error. - * - * @param string $subscriber_uri The OMB identifier URI specifying - * the subscribing profile - * - * @param string $subscribed_user_uri The OMB identifier URI specifying - * the subscribed profile - * @param OAuthToken $token The access token - * - * @access public - **/ - public function saveSubscription($subscriber_uri, $subscribed_user_uri, - $token) { - throw new Exception(); - } + /** + * Save a subscription + * + * Saves the subscription from $subscriber_uri to $subscribed_user_uri. + * Throws exceptions in case of error. + * + * @param string $subscriber_uri The OMB identifier URI specifying + * the subscribing profile + * + * @param string $subscribed_user_uri The OMB identifier URI specifying + * the subscribed profile + * @param OAuthToken $token The access token + * + * @access public + */ + public function saveSubscription($subscriber_uri, $subscribed_user_uri, + $token) + { + throw new Exception(); + } } ?> diff --git a/extlib/libomb/helper.php b/extlib/libomb/helper.php index a1f21f2680..08e6e7ab44 100644 --- a/extlib/libomb/helper.php +++ b/extlib/libomb/helper.php @@ -1,11 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Helper { +require_once 'Validate.php'; - /** - * Non-scalar constants - * - * The set of OMB and OAuth Services an OMB Server has to implement. - */ +/** + * Helper functions for libomb + * + * This class contains helper functions for libomb. + */ +class OMB_Helper +{ - public static $OMB_SERVICES = - array(OMB_ENDPOINT_UPDATEPROFILE, OMB_ENDPOINT_POSTNOTICE); - public static $OAUTH_SERVICES = - array(OAUTH_ENDPOINT_REQUEST, OAUTH_ENDPOINT_AUTHORIZE, OAUTH_ENDPOINT_ACCESS); + /** + * Non-scalar constants + * + * The set of OMB and OAuth Services an OMB Server has to implement. + */ - /** - * Validate URL - * - * Basic URL validation. Currently http, https, ftp and gopher are supported - * schemes. - * - * @param string $url The URL which is to be validated. - * - * @return bool Whether URL is valid. - * - * @access public - */ - public static function validateURL($url) { - return Validate::uri($url, array('allowed_schemes' => array('http', 'https', - 'gopher', 'ftp'))); - } + public static $OMB_SERVICES = array(OMB_ENDPOINT_UPDATEPROFILE, + OMB_ENDPOINT_POSTNOTICE); + public static $OAUTH_SERVICES = array(OAUTH_ENDPOINT_REQUEST, + OAUTH_ENDPOINT_AUTHORIZE, + OAUTH_ENDPOINT_ACCESS); - /** - * Validate Media type - * - * Basic Media type validation. Checks for valid maintype and correct format. - * - * @param string $mediatype The Media type which is to be validated. - * - * @return bool Whether media type is valid. - * - * @access public - */ - public static function validateMediaType($mediatype) { - if (0 === preg_match('/^(\w+)\/([\w\d-+.]+)$/', $mediatype, $subtypes)) { - return false; + /** + * Validate URL + * + * Basic URL validation. Currently http, https, ftp and gopher are supported + * schemes. + * + * @param string $url The URL which is to be validated. + * + * @return bool Whether URL is valid. + * + * @access public + */ + public static function validateURL($url) + { + return Validate::uri($url, array('allowed_schemes' => array('http', + 'https', 'gopher', 'ftp'))); } - if (!in_array(strtolower($subtypes[1]), array('application', 'audio', 'image', - 'message', 'model', 'multipart', 'text', 'video'))) { - return false; - } - return true; - } - /** - * Remove escaping from request parameters - * - * Neutralise the evil effects of magic_quotes_gpc in the current request. - * This is used before handing a request off to OAuthRequest::from_request. - * Many thanks to Ciaran Gultnieks for this fix. - * - * @access public - */ - public static function removeMagicQuotesFromRequest() { - if(get_magic_quotes_gpc() == 1) { - $_POST = array_map('stripslashes', $_POST); - $_GET = array_map('stripslashes', $_GET); + /** + * Validate Media type + * + * Basic Media type validation. Checks for valid maintype and correct + * format. + * + * @param string $mediatype The Media type which is to be validated. + * + * @return bool Whether media type is valid. + * + * @access public + */ + public static function validateMediaType($mediatype) + { + return preg_match('/^(\w+)\/([\w\d-+.]+)$/', $mediatype, $subtypes) > 0 + && + in_array(strtolower($subtypes[1]), array('application', 'audio', + 'image', 'message', 'model', 'multipart', 'text', 'video')); + } + + /** + * Remove escaping from request parameters + * + * Neutralise the evil effects of magic_quotes_gpc in the current request. + * This is used before handing a request off to OAuthRequest::from_request. + * Many thanks to Ciaran Gultnieks for this fix. + * + * @access public + */ + public static function removeMagicQuotesFromRequest() + { + if (get_magic_quotes_gpc() === 1) { + $_POST = array_map('stripslashes', $_POST); + $_GET = array_map('stripslashes', $_GET); + } } - } } ?> diff --git a/extlib/libomb/invalidparameterexception.php b/extlib/libomb/invalidparameterexception.php index 163e1dd4cc..d95c7022cb 100755 --- a/extlib/libomb/invalidparameterexception.php +++ b/extlib/libomb/invalidparameterexception.php @@ -1,8 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ -class OMB_InvalidParameterException extends Exception { - public function __construct($value, $type, $parameter) { - parent::__construct("Invalid value $value for parameter $parameter in $type"); - } + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ + +/** + * Exception stating that a passed parameter is invalid + * + * This exception is raised when a parameter does not obey the OMB standard. + */ +class OMB_InvalidParameterException extends Exception +{ + /** + * Constructor + * + * Creates a new exception based on a parameter name, value, and object + * type. + * + * @param string $value The wrong value passed + * @param string $type The object type the parameter belongs to; + * Currently OMB uses profiles and notices + * @param string $parameter The name of the parameter the wrong value has + * been passed for + */ + public function __construct($value, $type, $parameter) + { + parent::__construct("Invalid value ‘${value}’ for parameter " . + "‘${parameter}’ in $type"); + } } ?> diff --git a/extlib/libomb/invalidyadisexception.php b/extlib/libomb/invalidyadisexception.php index 797b7b95bd..dc61a13ad4 100755 --- a/extlib/libomb/invalidyadisexception.php +++ b/extlib/libomb/invalidyadisexception.php @@ -1,9 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ -class OMB_InvalidYadisException extends Exception { + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ + +/** + * Exception stating that a requested url does not resolve to a valid yadis + * + * This exception is raised when OMB_Service is not able to discover a valid + * yadis location with XRDS. + */ +class OMB_InvalidYadisException extends Exception +{ } ?> diff --git a/extlib/libomb/notice.php b/extlib/libomb/notice.php index 9ac36640a2..4963597b2e 100755 --- a/extlib/libomb/notice.php +++ b/extlib/libomb/notice.php @@ -1,15 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Notice { - protected $author; - protected $uri; - protected $content; - protected $url; - protected $license_url; /* url is an own addition for clarification. */ - protected $seealso_url; /* url is an own addition for clarification. */ - protected $seealso_disposition; - protected $seealso_mediatype; - protected $seealso_license_url; /* url is an addition for clarification. */ +require_once 'invalidparameterexception.php'; +require_once 'Validate.php'; +require_once 'helper.php'; - /* The notice as OMB param array. Cached and rebuild on usage. - false while outdated. */ - protected $param_array; +/** + * OMB Notice representation + * + * This class represents an OMB notice. + * + * Do not call the setters with null values. Instead, if you want to delete a + * field, pass an empty string. The getters will return null for empty fields. + */ +class OMB_Notice +{ + protected $author; + protected $uri; + protected $content; + protected $url; + protected $license_url; /* url is an own addition for clarification. */ + protected $seealso_url; /* url is an own addition for clarification. */ + protected $seealso_disposition; + protected $seealso_mediatype; + protected $seealso_license_url; /* url is an addition for clarification. */ - /** - * Constructor for OMB_Notice - * - * Initializes the OMB_Notice object with author, uri and content. - * These parameters are mandatory for postNotice. - * - * @param object $author An OMB_Profile object representing the author of the - * notice. - * @param string $uri The notice URI as defined by the OMB. A unique and - * unchanging identifier for a notice. - * @param string $content The content of the notice. 140 chars recommended, - * but there is no limit. - * - * @access public - */ - public function __construct($author, $uri, $content) { - $this->content = $content; - if (is_null($author)) { - throw new OMB_InvalidParameterException('', 'notice', 'omb_listenee'); - } - $this->author = $author; + /* The notice as OMB param array. Cached and rebuild on usage. + false while outdated. */ + protected $param_array; - if (!Validate::uri($uri)) { - throw new OMB_InvalidParameterException($uri, 'notice', 'omb_notice'); - } - $this->uri = $uri; + /** + * Constructor for OMB_Notice + * + * Initializes the OMB_Notice object with author, uri and content. + * These parameters are mandatory for postNotice. + * + * @param object $author An OMB_Profile object representing the author of + * the notice. + * @param string $uri The notice URI as defined by the OMB. A unique and + * never changing identifier for a notice. + * @param string $content The content of the notice. 140 chars recommended, + * but there is no limit. + * + * @access public + */ + public function __construct($author, $uri, $content) + { + $this->content = $content; + if (is_null($author)) { + throw new OMB_InvalidParameterException('', 'notice', 'omb_listenee'); + } + $this->author = $author; - $this->param_array = false; - } + if (!Validate::uri($uri)) { + throw new OMB_InvalidParameterException($uri, 'notice', 'omb_notice'); + } + $this->uri = $uri; - /** - * Returns the notice as array - * - * The method returns an array which contains the whole notice as array. The - * array is cached and only rebuilt on changes of the notice. - * Empty optional values are not passed. - * - * @access public - * @returns array The notice as parameter array - */ - public function asParameters() { - if ($this->param_array !== false) { - return $this->param_array; + $this->param_array = false; } - $this->param_array = array( - 'omb_notice' => $this->uri, - 'omb_notice_content' => $this->content); + /** + * Return the notice as array + * + * Returns an array which contains the whole notice as array. The array is + * cached and only rebuilt on changes of the notice. + * Empty optional values are not passed. + * + * @access public + * @return array The notice as parameter array + */ + public function asParameters() + { + if ($this->param_array !== false) { + return $this->param_array; + } - if (!is_null($this->url)) - $this->param_array['omb_notice_url'] = $this->url; + $this->param_array = array( + 'omb_notice' => $this->uri, + 'omb_notice_content' => $this->content); - if (!is_null($this->license_url)) - $this->param_array['omb_notice_license'] = $this->license_url; + if (!is_null($this->url)) + $this->param_array['omb_notice_url'] = $this->url; - if (!is_null($this->seealso_url)) { - $this->param_array['omb_seealso'] = $this->seealso_url; + if (!is_null($this->license_url)) + $this->param_array['omb_notice_license'] = $this->license_url; - /* This is actually a free interpretation of the OMB standard. We assume - that additional seealso parameters are not of any use if seealso itself - is not set. */ - if (!is_null($this->seealso_disposition)) - $this->param_array['omb_seealso_disposition'] = + if (!is_null($this->seealso_url)) { + $this->param_array['omb_seealso'] = $this->seealso_url; + + /* This is actually a free interpretation of the OMB standard. We + assume that additional seealso parameters are not of any use if + seealso itself is not set. */ + if (!is_null($this->seealso_disposition)) + $this->param_array['omb_seealso_disposition'] = $this->seealso_disposition; - if (!is_null($this->seealso_mediatype)) - $this->param_array['omb_seealso_mediatype'] = $this->seealso_mediatype; + if (!is_null($this->seealso_mediatype)) + $this->param_array['omb_seealso_mediatype'] = + $this->seealso_mediatype; - if (!is_null($this->seealso_license_url)) - $this->param_array['omb_seealso_license'] = $this->seealso_license_url; - } - return $this->param_array; - } - - /** - * Builds an OMB_Notice object from array - * - * The method builds an OMB_Notice object from the passed parameters array. - * The array MUST provide a notice URI and content. The array fields HAVE TO - * be named according to the OMB standard, i. e. omb_notice_* and - * omb_seealso_*. Values are handled as not passed if the corresponding array - * fields are not set or the empty string. - * - * @param object $author An OMB_Profile object representing the author of - * the notice. - * @param string $parameters An array containing the notice parameters. - * - * @access public - * - * @returns OMB_Notice The built OMB_Notice. - */ - public static function fromParameters($author, $parameters) { - $notice = new OMB_Notice($author, $parameters['omb_notice'], - $parameters['omb_notice_content']); - - if (isset($parameters['omb_notice_url'])) { - $notice->setURL($parameters['omb_notice_url']); + if (!is_null($this->seealso_license_url)) + $this->param_array['omb_seealso_license'] = + $this->seealso_license_url; + } + return $this->param_array; } - if (isset($parameters['omb_notice_license'])) { - $notice->setLicenseURL($parameters['omb_notice_license']); + /** + * Build an OMB_Notice object from array + * + * Builds an OMB_Notice object from the passed parameters array. The array + * MUST provide a notice URI and content. The array fields HAVE TO be named + * according to the OMB standard, i. e. omb_notice_* and omb_seealso_*. + * Values are handled as not passed if the corresponding array fields are + * not set or the empty string. + * + * @param object $author An OMB_Profile object representing the author + * of the notice. + * @param string $parameters An array containing the notice parameters. + * + * @access public + * + * @returns OMB_Notice The built OMB_Notice. + */ + public static function fromParameters($author, $parameters) + { + $notice = new OMB_Notice($author, $parameters['omb_notice'], + $parameters['omb_notice_content']); + + if (isset($parameters['omb_notice_url'])) { + $notice->setURL($parameters['omb_notice_url']); + } + + if (isset($parameters['omb_notice_license'])) { + $notice->setLicenseURL($parameters['omb_notice_license']); + } + + if (isset($parameters['omb_seealso'])) { + $notice->setSeealsoURL($parameters['omb_seealso']); + } + + if (isset($parameters['omb_seealso_disposition'])) { + $notice->setSeealsoDisposition($parameters['omb_seealso_disposition']); + } + + if (isset($parameters['omb_seealso_mediatype'])) { + $notice->setSeealsoMediatype($parameters['omb_seealso_mediatype']); + } + + if (isset($parameters['omb_seealso_license'])) { + $notice->setSeealsoLicenseURL($parameters['omb_seealso_license']); + } + return $notice; } - if (isset($parameters['omb_seealso'])) { - $notice->setSeealsoURL($parameters['omb_seealso']); + public function getAuthor() + { + return $this->author; } - if (isset($parameters['omb_seealso_disposition'])) { - $notice->setSeealsoDisposition($parameters['omb_seealso_disposition']); + public function getIdentifierURI() + { + return $this->uri; } - if (isset($parameters['omb_seealso_mediatype'])) { - $notice->setSeealsoMediatype($parameters['omb_seealso_mediatype']); + public function getContent() + { + return $this->content; } - if (isset($parameters['omb_seealso_license'])) { - $notice->setSeealsoLicenseURL($parameters['omb_seealso_license']); + public function getURL() + { + return $this->url; } - return $notice; - } - public function getAuthor() { - return $this->author; - } - - public function getIdentifierURI() { - return $this->uri; - } - - public function getContent() { - return $this->content; - } - - public function getURL() { - return $this->url; - } - - public function getLicenseURL() { - return $this->license_url; - } - - public function getSeealsoURL() { - return $this->seealso_url; - } - - public function getSeealsoDisposition() { - return $this->seealso_disposition; - } - - public function getSeealsoMediatype() { - return $this->seealso_mediatype; - } - - public function getSeealsoLicenseURL() { - return $this->seealso_license_url; - } - - public function setURL($url) { - if ($url === '') { - $url = null; - } elseif (!OMB_Helper::validateURL($url)) { - throw new OMB_InvalidParameterException($url, 'notice', 'omb_notice_url'); + public function getLicenseURL() + { + return $this->license_url; } - $this->url = $url; - $this->param_array = false; - } - public function setLicenseURL($license_url) { - if ($license_url === '') { - $license_url = null; - } elseif (!OMB_Helper::validateURL($license_url)) { - throw new OMB_InvalidParameterException($license_url, 'notice', - 'omb_notice_license'); + public function getSeealsoURL() + { + return $this->seealso_url; } - $this->license_url = $license_url; - $this->param_array = false; - } - public function setSeealsoURL($seealso_url) { - if ($seealso_url === '') { - $seealso_url = null; - } elseif (!OMB_Helper::validateURL($seealso_url)) { - throw new OMB_InvalidParameterException($seealso_url, 'notice', - 'omb_seealso'); + public function getSeealsoDisposition() + { + return $this->seealso_disposition; } - $this->seealso_url = $seealso_url; - $this->param_array = false; - } - public function setSeealsoDisposition($seealso_disposition) { - if ($seealso_disposition === '') { - $seealso_disposition = null; - } elseif ($seealso_disposition !== 'link' && $seealso_disposition !== 'inline') { - throw new OMB_InvalidParameterException($seealso_disposition, 'notice', - 'omb_seealso_disposition'); + public function getSeealsoMediatype() + { + return $this->seealso_mediatype; } - $this->seealso_disposition = $seealso_disposition; - $this->param_array = false; - } - public function setSeealsoMediatype($seealso_mediatype) { - if ($seealso_mediatype === '') { - $seealso_mediatype = null; - } elseif (!OMB_Helper::validateMediaType($seealso_mediatype)) { - throw new OMB_InvalidParameterException($seealso_mediatype, 'notice', - 'omb_seealso_mediatype'); + public function getSeealsoLicenseURL() + { + return $this->seealso_license_url; } - $this->seealso_mediatype = $seealso_mediatype; - $this->param_array = false; - } - public function setSeealsoLicenseURL($seealso_license_url) { - if ($seealso_license_url === '') { - $seealso_license_url = null; - } elseif (!OMB_Helper::validateURL($seealso_license_url)) { - throw new OMB_InvalidParameterException($seealso_license_url, 'notice', - 'omb_seealso_license'); + public function setURL($url) + { + $this->setVal('notice_url', $url, 'OMB_Helper::validateURL', 'url'); + } + + public function setLicenseURL($license_url) + { + $this->setVal('license', $license_url, 'OMB_Helper::validateURL', + 'license_url'); + } + + public function setSeealsoURL($seealso_url) + { + $this->setVal('seealso', $seealso_url, 'OMB_Helper::validateURL', + 'seealso_url'); + } + + public function setSeealsoDisposition($seealso_disposition) + { + $this->setVal('seealso_disposition', $seealso_disposition, + 'OMB_Notice::validateDisposition'); + } + + protected static function validateDisposition($str) + { + return in_array($str, array('link', 'inline')); + } + + public function setSeealsoMediatype($seealso_mediatype) + { + $this->setVal('seealso_mediatype', $seealso_mediatype, + 'OMB_Helper::validateMediaType'); + } + + public function setSeealsoLicenseURL($seealso_license_url) + { + $this->setVal('seealso_license', $seealso_license_url, + 'OMB_Helper::validateURL', 'seealso_license_url'); + } + + /** + * Set a value + * + * Updates a value specified by a parameter name and the new value. + * + * @param string $param The parameter name according to OMB + * @param string $value The new value + * @param callback $validator A validator function for the parameter + * @param string $field The name of the field in OMB_Notice + * @param bool $force Whether null values should be checked as well + */ + protected function setVal($param, $value, $validator, $field = null, + $force = false) + { + if (is_null($field)) { + $field = $param; + } + if ($value === '' && !$force) { + $value = null; + } elseif (!call_user_func($validator, $value)) { + throw new OMB_InvalidParameterException($value, 'notice', $param); + } + if ($this->$field !== $value) { + $this->$field = $value; + $this->param_array = false; + } } - $this->seealso_license_url = $seealso_license_url; - $this->param_array = false; - } } ?> diff --git a/extlib/libomb/omb_yadis_xrds.php b/extlib/libomb/omb_yadis_xrds.php index 89921203b0..b84752c4c5 100755 --- a/extlib/libomb/omb_yadis_xrds.php +++ b/extlib/libomb/omb_yadis_xrds.php @@ -1,14 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Yadis_XRDS extends Auth_Yadis_XRDS { +require_once 'Auth/Yadis/Yadis.php'; +require_once 'unsupportedserviceexception.php'; +require_once 'invalidyadisexception.php'; - protected $fetcher; +/** + * OMB XRDS representation + * + * This class represents a Yadis XRDS file for OMB. It adds some useful methods to + * Auth_Yadis_XRDS. + */ +class OMB_Yadis_XRDS extends Auth_Yadis_XRDS +{ - /** - * Create an instance from URL - * - * Constructs an OMB_Yadis_XRDS object from a given URL. A full Yadis - * discovery is performed on the URL and the XRDS is parsed. - * Throws an OMB_InvalidYadisException when no Yadis is discovered or the - * detected XRDS file is broken. - * - * @param string $url The URL on which Yadis discovery - * should be performed on - * @param Auth_Yadis_HTTPFetcher $fetcher A fetcher used to get HTTP - * resources - * - * @access public - * - * @return OMB_Yadis_XRDS The initialized object representing the given - * resource - **/ - public static function fromYadisURL($url, $fetcher) { - /* Perform a Yadis discovery. */ - $yadis = Auth_Yadis_Yadis::discover($url, $fetcher); - if ($yadis->failed) { - throw new OMB_InvalidYadisException($url); + protected $fetcher; + + /** + * Create an instance from URL + * + * Constructs an OMB_Yadis_XRDS object from a given URL. A full Yadis + * discovery is performed on the URL and the XRDS is parsed. + * Throws an OMB_InvalidYadisException when no Yadis is discovered or the + * detected XRDS file is broken. + * + * @param string $url The URL on which Yadis discovery + * should be performed on + * @param Auth_Yadis_HTTPFetcher $fetcher A fetcher used to get HTTP + * resources + * + * @access public + * + * @return OMB_Yadis_XRDS The initialized object representing the given + * resource + */ + public static function fromYadisURL($url, $fetcher) + { + /* Perform a Yadis discovery. */ + $yadis = Auth_Yadis_Yadis::discover($url, $fetcher); + if ($yadis->failed) { + throw new OMB_InvalidYadisException($url); + } + + /* Parse the XRDS file. */ + $xrds = OMB_Yadis_XRDS::parseXRDS($yadis->response_text); + if ($xrds === null) { + throw new OMB_InvalidYadisException($url); + } + $xrds->fetcher = $fetcher; + return $xrds; } - /* Parse the XRDS file. */ - $xrds = OMB_Yadis_XRDS::parseXRDS($yadis->response_text); - if ($xrds === null) { - throw new OMB_InvalidYadisException($url); - } - $xrds->fetcher = $fetcher; - return $xrds; - } - - /** - * Get a specific service - * - * Returns the Auth_Yadis_Service object corresponding to the given service - * URI. - * Throws an OMB_UnsupportedServiceException if the service is not available. - * - * @param string $service URI specifier of the requested service - * - * @access public - * - * @return Auth_Yadis_Service The object representing the requested service - **/ - public function getService($service) { - $match = $this->services(array( create_function('$s', - "return in_array('$service', \$s->getTypes());"))); - if ($match === array()) { - throw new OMB_UnsupportedServiceException($service); - } - return $match[0]; - } - - /** - * Get a specific XRD - * - * Returns the OMB_Yadis_XRDS object corresponding to the given URI. - * Throws an OMB_UnsupportedServiceException if the XRD is not available. - * Note that getXRD tries to resolve external XRD parts as well. - * - * @param string $uri URI specifier of the requested XRD - * - * @access public - * - * @return OMB_Yadis_XRDS The object representing the requested XRD - **/ - public function getXRD($uri) { - $nexthash = strpos($uri, '#'); - if ($nexthash !== 0) { - if ($nexthash !== false) { - $cururi = substr($uri, 0, $nexthash); - $nexturi = substr($uri, $nexthash); - } - return - OMB_Yadis_XRDS::fromYadisURL($cururi, $this->fetcher)->getXRD($nexturi); + /** + * Get a specific service + * + * Returns the Auth_Yadis_Service object corresponding to the given service + * URI. + * Throws an OMB_UnsupportedServiceException if the service is not + * available. + * + * @param string $service URI specifier of the requested service + * + * @access public + * + * @return Auth_Yadis_Service The object representing the requested service + */ + public function getService($service) + { + $match = $this->services(array(create_function('$s', + "return in_array('$service', \$s->getTypes());"))); + if ($match === array()) { + throw new OMB_UnsupportedServiceException($service); + } + return $match[0]; } - $id = substr($uri, 1); - foreach ($this->allXrdNodes as $node) { - $attrs = $this->parser->attributes($node); - if (array_key_exists('xml:id', $attrs) && $attrs['xml:id'] == $id) { - /* Trick the constructor into thinking this is the only node. */ - $bogus_nodes = array($node); - return new OMB_Yadis_XRDS($this->parser, $bogus_nodes); - } - } - throw new OMB_UnsupportedServiceException($uri); - } + /** + * Get a specific XRD + * + * Returns the OMB_Yadis_XRDS object corresponding to the given URI. + * Throws an OMB_UnsupportedServiceException if the XRD is not available. + * Note that getXRD tries to resolve external XRD parts as well. + * + * @param string $uri URI specifier of the requested XRD + * + * @access public + * + * @return OMB_Yadis_XRDS The object representing the requested XRD + */ + public function getXRD($uri) + { + $nexthash = strpos($uri, '#'); + if ($nexthash === false) { + throw new OMB_InvalidYadisException("‘$uri’ does not specify a " . + 'valid XML node.'); + } - /** - * Parse an XML string containing a XRDS document - * - * Parse an XML string (XRDS document) and return either a - * Auth_Yadis_XRDS object or null, depending on whether the - * XRDS XML is valid. - * Copy and paste from parent to select correct constructor. - * - * @param string $xml_string An XRDS XML string. - * - * @access public - * - * @return mixed An instance of OMB_Yadis_XRDS or null, - * depending on the validity of $xml_string - **/ + if ($nexthash > 0) { + $cururi = substr($uri, 0, $nexthash); + $nexturi = substr($uri, $nexthash); + return OMB_Yadis_XRDS::fromYadisURL($cururi, $this->fetcher) + ->getXRD($nexturi); + } - public function &parseXRDS($xml_string, $extra_ns_map = null) { - $_null = null; - - if (!$xml_string) { - return $_null; + $id = substr($uri, 1); + foreach ($this->allXrdNodes as $node) { + $attrs = $this->parser->attributes($node); + if (array_key_exists('xml:id', $attrs) && $attrs['xml:id'] == $id) { + /* Trick the constructor into thinking this is the only node. */ + $bogus_nodes = array($node); + return new OMB_Yadis_XRDS($this->parser, $bogus_nodes); + } + } + throw new OMB_UnsupportedServiceException($uri); } - $parser = Auth_Yadis_getXMLParser(); + /** + * Parse an XML string containing a XRDS document + * + * Parses an XML string (XRDS document) and returns either an + * Auth_Yadis_XRDS object or null, depending on whether the XRDS XML is + * valid. + * This method is just copy and paste from the parent class to select the + * correct constructor. + * + * @param string $xml_string An XRDS XML string + * @param array $extra_ns_map Additional namespace declarations + * + * @access public + * + * @return mixed An instance of OMB_Yadis_XRDS or null, + * depending on the validity of $xml_string + */ + public function parseXRDS($xml_string, $extra_ns_map = null) + { + $_null = null; - $ns_map = Auth_Yadis_getNSMap(); + if (!$xml_string) { + return $_null; + } - if ($extra_ns_map && is_array($extra_ns_map)) { - $ns_map = array_merge($ns_map, $extra_ns_map); + $parser = Auth_Yadis_getXMLParser(); + + $ns_map = Auth_Yadis_getNSMap(); + + if ($extra_ns_map && is_array($extra_ns_map)) { + $ns_map = array_merge($ns_map, $extra_ns_map); + } + + if (!($parser && $parser->init($xml_string, $ns_map))) { + return $_null; + } + + // Try to get root element. + $root = $parser->evalXPath('/xrds:XRDS[1]'); + if (!$root) { + return $_null; + } + + if (is_array($root)) { + $root = $root[0]; + } + + $attrs = $parser->attributes($root); + + if (array_key_exists('xmlns:xrd', $attrs) && + $attrs['xmlns:xrd'] != Auth_Yadis_XMLNS_XRDS) { + return $_null; + } else if (array_key_exists('xmlns', $attrs) && + preg_match('/xri/', $attrs['xmlns']) && + $attrs['xmlns'] != Auth_Yadis_XMLNS_XRD_2_0) { + return $_null; + } + + // Get the last XRD node. + $xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD'); + + if (!$xrd_nodes) { + return $_null; + } + + $xrds = new OMB_Yadis_XRDS($parser, $xrd_nodes); + return $xrds; } - - if (!($parser && $parser->init($xml_string, $ns_map))) { - return $_null; - } - - // Try to get root element. - $root = $parser->evalXPath('/xrds:XRDS[1]'); - if (!$root) { - return $_null; - } - - if (is_array($root)) { - $root = $root[0]; - } - - $attrs = $parser->attributes($root); - - if (array_key_exists('xmlns:xrd', $attrs) && - $attrs['xmlns:xrd'] != Auth_Yadis_XMLNS_XRDS) { - return $_null; - } else if (array_key_exists('xmlns', $attrs) && - preg_match('/xri/', $attrs['xmlns']) && - $attrs['xmlns'] != Auth_Yadis_XMLNS_XRD_2_0) { - return $_null; - } - - // Get the last XRD node. - $xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD'); - - if (!$xrd_nodes) { - return $_null; - } - - $xrds = new OMB_Yadis_XRDS($parser, $xrd_nodes); - return $xrds; - } } diff --git a/extlib/libomb/plain_xrds_writer.php b/extlib/libomb/plain_xrds_writer.php index b4a6e990bc..ba1027b611 100755 --- a/extlib/libomb/plain_xrds_writer.php +++ b/extlib/libomb/plain_xrds_writer.php @@ -1,13 +1,6 @@ writeXRDS. + * This file is part of libomb * * PHP version 5 * @@ -24,25 +17,45 @@ require_once 'xrds_writer.php'; * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Plain_XRDS_Writer implements OMB_XRDS_Writer { - public function writeXRDS($user, $mapper) { - header('Content-Type: application/xrds+xml'); - $xw = new XMLWriter(); - $xw->openURI('php://output'); - $xw->setIndent(true); +require_once 'xrds_writer.php'; - $xw->startDocument('1.0', 'UTF-8'); - $this->writeFullElement($xw, 'XRDS', array('xmlns' => 'xri://$xrds'), array( - array('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', - 'xml:id' => 'oauth', - 'xmlns:simple' => 'http://xrds-simple.net/core/1.0', - 'version' => '2.0'), array( +/** + * Write OMB-specific XRDS using XMLWriter + * + * This class writes the XRDS file announcing the OMB server. It uses XMLWriter. + * An instance of OMB_Plain_XRDS_Writer should be passed to + * OMB_Service_Provider->writeXRDS. + */ +class OMB_Plain_XRDS_Writer implements OMB_XRDS_Writer +{ + /** + * Write XRDS using XMLWriter + * + * Outputs a XRDS document specifying an OMB service. + * + * @param OMB_profile $user The target user for the OMB service + * @param OMB_XRDS_Mapper $mapper An OMB_XRDS_Mapper providing endpoint URLs + */ + public function writeXRDS($user, $mapper) + { + header('Content-Type: application/xrds+xml'); + $xw = new XMLWriter(); + $xw->openURI('php://output'); + $xw->setIndent(true); + + $xw->startDocument('1.0', 'UTF-8'); + $this->_writeFullElement($xw, 'XRDS', array('xmlns' => 'xri://$xrds'), array( + array('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', + 'xml:id' => 'oauth', + 'xmlns:simple' => 'http://xrds-simple.net/core/1.0', + 'version' => '2.0'), array( array('Type', null, 'xri://$xrds*simple'), array('Service', null, array( array('Type', null, OAUTH_ENDPOINT_REQUEST), @@ -73,10 +86,10 @@ class OMB_Plain_XRDS_Writer implements OMB_XRDS_Writer { array('Type', null, OAUTH_HMAC_SHA1) )) )), - array('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', - 'xml:id' => 'omb', - 'xmlns:simple' => 'http://xrds-simple.net/core/1.0', - 'version' => '2.0'), array( + array('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', + 'xml:id' => 'omb', + 'xmlns:simple' => 'http://xrds-simple.net/core/1.0', + 'version' => '2.0'), array( array('Type', null, 'xri://$xrds*simple'), array('Service', null, array( array('Type', null, OMB_ENDPOINT_POSTNOTICE), @@ -87,8 +100,8 @@ class OMB_Plain_XRDS_Writer implements OMB_XRDS_Writer { array('URI', null, $mapper->getURL(OMB_ENDPOINT_UPDATEPROFILE)) )) )), - array('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', - 'version' => '2.0'), array( + array('XRD', array('xmlns' => 'xri://$xrd*($v*2.0)', + 'version' => '2.0'), array( array('Type', null, 'xri://$xrds*simple'), array('Service', null, array( array('Type', null, OAUTH_DISCOVERY), @@ -98,27 +111,40 @@ class OMB_Plain_XRDS_Writer implements OMB_XRDS_Writer { array('Type', null, OMB_VERSION), array('URI', null, '#omb') )) - )) - )); - $xw->endDocument(); - $xw->flush(); - } + )))); + $xw->endDocument(); + $xw->flush(); + } - public static function writeFullElement($xw, $tag, $attributes, $content) { - $xw->startElement($tag); - if (!is_null($attributes)) { - foreach ($attributes as $name => $value) { - $xw->writeAttribute($name, $value); - } + /** + * Write a complex XML element + * + * Outputs a XML element with attributes and content. + * + * @param XMLWriter $xw The XMLWriter used to output the element + * @param string $tag The tag name + * @param array|null $attributes A map of XML attributes + * @param array|string $content The content of the element; either an + * array of child nodes each specified by a + * three entry-array ($tag, $attributes, + * $content) or a string + */ + private function _writeFullElement($xw, $tag, $attributes, $content) + { + $xw->startElement($tag); + if (!is_null($attributes)) { + foreach ($attributes as $name => $value) { + $xw->writeAttribute($name, $value); + } + } + if (is_array($content)) { + foreach ($content as $val) { + $this->_writeFullElement($xw, $val[0], $val[1], $val[2]); + } + } else { + $xw->text($content); + } + $xw->fullEndElement(); } - if (is_array($content)) { - foreach ($content as $values) { - OMB_Plain_XRDS_Writer::writeFullElement($xw, $values[0], $values[1], $values[2]); - } - } else { - $xw->text($content); - } - $xw->fullEndElement(); - } } ?> diff --git a/extlib/libomb/profile.php b/extlib/libomb/profile.php index 13314d3e80..d732e10d7d 100755 --- a/extlib/libomb/profile.php +++ b/extlib/libomb/profile.php @@ -1,15 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Profile { - protected $identifier_uri; - protected $profile_url; - protected $nickname; - protected $license_url; - protected $fullname; - protected $homepage; - protected $bio; - protected $location; - protected $avatar_url; +require_once 'invalidparameterexception.php'; +require_once 'Validate.php'; +require_once 'helper.php'; - /* The profile as OMB param array. Cached and rebuild on usage. - false while outdated. */ - protected $param_array; +/** + * OMB profile representation + * + * This class represents an OMB profile. + * + * Do not call the setters with null values. Instead, if you want to delete a + * field, pass an empty string. The getters will return null for empty fields. + */ +class OMB_Profile +{ + protected $identifier_uri; + protected $profile_url; + protected $nickname; + protected $license_url; + protected $fullname; + protected $homepage; + protected $bio; + protected $location; + protected $avatar_url; - /** - * Constructor for OMB_Profile - * - * Initializes the OMB_Profile object with an identifier uri. - * - * @param string $identifier_uri The profile URI as defined by the OMB. A unique - * and unchanging identifier for a profile. - * - * @access public - */ - public function __construct($identifier_uri) { - if (!Validate::uri($identifier_uri)) { - throw new OMB_InvalidParameterException($identifier_uri, 'profile', + /* The profile as OMB param array. Cached and rebuild on usage. + false while outdated. */ + protected $param_array; + + /** + * Constructor for OMB_Profile + * + * Initializes the OMB_Profile object with an identifier uri. + * + * @param string $identifier_uri The profile URI as defined by the OMB; + * A unique and never changing identifier for + * a profile + * + * @access public + */ + public function __construct($identifier_uri) + { + if (!Validate::uri($identifier_uri)) { + throw new OMB_InvalidParameterException($identifier_uri, 'profile', 'omb_listenee or omb_listener'); - } - $this->identifier_uri = $identifier_uri; - $this->param_array = false; - } - - /** - * Returns the profile as array - * - * The method returns an array which contains the whole profile as array. The - * array is cached and only rebuilt on changes of the profile. - * - * @param bool $force_all Specifies whether empty fields should be added to - * the array as well. This is neccessary to clear - * fields via updateProfile. - * - * @param string $prefix The common prefix to the key for all parameters. - * - * @access public - * - * @return array The profile as parameter array - */ - public function asParameters($prefix, $force_all = false) { - if ($this->param_array === false) { - $this->param_array = array('' => $this->identifier_uri); - - if ($force_all || !is_null($this->profile_url)) { - $this->param_array['_profile'] = $this->profile_url; - } - - if ($force_all || !is_null($this->homepage)) { - $this->param_array['_homepage'] = $this->homepage; - } - - if ($force_all || !is_null($this->nickname)) { - $this->param_array['_nickname'] = $this->nickname; - } - - if ($force_all || !is_null($this->license_url)) { - $this->param_array['_license'] = $this->license_url; - } - - if ($force_all || !is_null($this->fullname)) { - $this->param_array['_fullname'] = $this->fullname; - } - - if ($force_all || !is_null($this->bio)) { - $this->param_array['_bio'] = $this->bio; - } - - if ($force_all || !is_null($this->location)) { - $this->param_array['_location'] = $this->location; - } - - if ($force_all || !is_null($this->avatar_url)) { - $this->param_array['_avatar'] = $this->avatar_url; - } - - } - $ret = array(); - foreach ($this->param_array as $k => $v) { - $ret[$prefix . $k] = $v; - } - return $ret; - } - - /** - * Builds an OMB_Profile object from array - * - * The method builds an OMB_Profile object from the passed parameters array. The - * array MUST provide a profile URI. The array fields HAVE TO be named according - * to the OMB standard. The prefix (omb_listener or omb_listenee) is passed as a - * parameter. - * - * @param string $parameters An array containing the profile parameters. - * @param string $prefix The common prefix of the profile parameter keys. - * - * @access public - * - * @returns OMB_Profile The built OMB_Profile. - */ - public static function fromParameters($parameters, $prefix) { - if (!isset($parameters[$prefix])) { - throw new OMB_InvalidParameterException('', 'profile', $prefix); + } + $this->identifier_uri = $identifier_uri; + $this->param_array = false; } - $profile = new OMB_Profile($parameters[$prefix]); - $profile->updateFromParameters($parameters, $prefix); - return $profile; - } + /** + * Return the profile as array + * + * Returns an array which contains the whole profile as array. + * The array is cached and only rebuilt on changes of the profile. + * + * @param string $prefix The common prefix to the key for all parameters + * @param bool $force_all Specifies whether empty fields should be added + * to the array as well; This is necessary to + * clear fields via updateProfile + * + * @access public + * + * @return array The profile as parameter array + */ + public function asParameters($prefix, $force_all = false) + { + if ($this->param_array === false) { + $this->param_array = array('' => $this->identifier_uri); - /** - * Update from array - * - * Updates from the passed parameters array. The array does not have to - * provide a profile URI. The array fields HAVE TO be named according to the - * OMB standard. The prefix (omb_listener or omb_listenee) is passed as a - * parameter. - * - * @param string $parameters An array containing the profile parameters. - * @param string $prefix The common prefix of the profile parameter keys. - * - * @access public - */ - public function updateFromParameters($parameters, $prefix) { - if (isset($parameters[$prefix.'_profile'])) { - $this->setProfileURL($parameters[$prefix.'_profile']); + if ($force_all || !is_null($this->profile_url)) { + $this->param_array['_profile'] = $this->profile_url; + } + + if ($force_all || !is_null($this->homepage)) { + $this->param_array['_homepage'] = $this->homepage; + } + + if ($force_all || !is_null($this->nickname)) { + $this->param_array['_nickname'] = $this->nickname; + } + + if ($force_all || !is_null($this->license_url)) { + $this->param_array['_license'] = $this->license_url; + } + + if ($force_all || !is_null($this->fullname)) { + $this->param_array['_fullname'] = $this->fullname; + } + + if ($force_all || !is_null($this->bio)) { + $this->param_array['_bio'] = $this->bio; + } + + if ($force_all || !is_null($this->location)) { + $this->param_array['_location'] = $this->location; + } + + if ($force_all || !is_null($this->avatar_url)) { + $this->param_array['_avatar'] = $this->avatar_url; + } + + } + $ret = array(); + foreach ($this->param_array as $k => $v) { + $ret[$prefix . $k] = $v; + } + return $ret; } - if (isset($parameters[$prefix.'_license'])) { - $this->setLicenseURL($parameters[$prefix.'_license']); + /** + * Build an OMB_Profile object from array + * + * Builds an OMB_Profile object from the passed parameters array. The + * array MUST provide a profile URI. The array fields HAVE TO be named + * according to the OMB standard. The prefix (omb_listener or omb_listenee) + * is passed as a parameter. + * + * @param string $parameters An array containing the profile parameters + * @param string $prefix The common prefix of the profile parameter keys + * + * @access public + * + * @returns OMB_Profile The built OMB_Profile + */ + public static function fromParameters($parameters, $prefix) + { + if (!isset($parameters[$prefix])) { + throw new OMB_InvalidParameterException('', 'profile', $prefix); + } + + $profile = new OMB_Profile($parameters[$prefix]); + $profile->updateFromParameters($parameters, $prefix); + return $profile; } - if (isset($parameters[$prefix.'_nickname'])) { - $this->setNickname($parameters[$prefix.'_nickname']); + /** + * Update from array + * + * Updates from the passed parameters array. The array does not have to + * provide a profile URI. The array fields HAVE TO be named according to the + * OMB standard. The prefix (omb_listener or omb_listenee) is passed as a + * parameter. + * + * @param string $parameters An array containing the profile parameters + * @param string $prefix The common prefix of the profile parameter keys + * + * @access public + */ + public function updateFromParameters($parameters, $prefix) + { + if (isset($parameters[$prefix.'_profile'])) { + $this->setProfileURL($parameters[$prefix.'_profile']); + } + + if (isset($parameters[$prefix.'_license'])) { + $this->setLicenseURL($parameters[$prefix.'_license']); + } + + if (isset($parameters[$prefix.'_nickname'])) { + $this->setNickname($parameters[$prefix.'_nickname']); + } + + if (isset($parameters[$prefix.'_fullname'])) { + $this->setFullname($parameters[$prefix.'_fullname']); + } + + if (isset($parameters[$prefix.'_homepage'])) { + $this->setHomepage($parameters[$prefix.'_homepage']); + } + + if (isset($parameters[$prefix.'_bio'])) { + $this->setBio($parameters[$prefix.'_bio']); + } + + if (isset($parameters[$prefix.'_location'])) { + $this->setLocation($parameters[$prefix.'_location']); + } + + if (isset($parameters[$prefix.'_avatar'])) { + $this->setAvatarURL($parameters[$prefix.'_avatar']); + } } - if (isset($parameters[$prefix.'_fullname'])) { - $this->setFullname($parameters[$prefix.'_fullname']); + public function getIdentifierURI() + { + return $this->identifier_uri; } - if (isset($parameters[$prefix.'_homepage'])) { - $this->setHomepage($parameters[$prefix.'_homepage']); + public function getProfileURL() + { + return $this->profile_url; } - if (isset($parameters[$prefix.'_bio'])) { - $this->setBio($parameters[$prefix.'_bio']); + public function getHomepage() + { + return $this->homepage; } - if (isset($parameters[$prefix.'_location'])) { - $this->setLocation($parameters[$prefix.'_location']); + public function getNickname() + { + return $this->nickname; } - if (isset($parameters[$prefix.'_avatar'])) { - $this->setAvatarURL($parameters[$prefix.'_avatar']); - } - } - - public function getIdentifierURI() { - return $this->identifier_uri; - } - - public function getProfileURL() { - return $this->profile_url; - } - - public function getHomepage() { - return $this->homepage; - } - - public function getNickname() { - return $this->nickname; - } - - public function getLicenseURL() { - return $this->license_url; - } - - public function getFullname() { - return $this->fullname; - } - - public function getBio() { - return $this->bio; - } - - public function getLocation() { - return $this->location; - } - - public function getAvatarURL() { - return $this->avatar_url; - } - - public function setProfileURL($profile_url) { - if (!OMB_Helper::validateURL($profile_url)) { - throw new OMB_InvalidParameterException($profile_url, 'profile', - 'omb_listenee_profile or omb_listener_profile'); - } - $this->profile_url = $profile_url; - $this->param_array = false; - } - - public function setNickname($nickname) { - if (!Validate::string($nickname, - array('min_length' => 1, - 'max_length' => 64, - 'format' => VALIDATE_NUM . VALIDATE_ALPHA))) { - throw new OMB_InvalidParameterException($nickname, 'profile', 'nickname'); + public function getLicenseURL() + { + return $this->license_url; } - $this->nickname = $nickname; - $this->param_array = false; - } - - public function setLicenseURL($license_url) { - if (!OMB_Helper::validateURL($license_url)) { - throw new OMB_InvalidParameterException($license_url, 'profile', - 'omb_listenee_license or omb_listener_license'); + public function getFullname() + { + return $this->fullname; } - $this->license_url = $license_url; - $this->param_array = false; - } - public function setFullname($fullname) { - if ($fullname === '') { - $fullname = null; - } elseif (!Validate::string($fullname, array('max_length' => 255))) { - throw new OMB_InvalidParameterException($fullname, 'profile', 'fullname'); + public function getBio() + { + return $this->bio; } - $this->fullname = $fullname; - $this->param_array = false; - } - public function setHomepage($homepage) { - if ($homepage === '') { - $homepage = null; + public function getLocation() + { + return $this->location; } - $this->homepage = $homepage; - $this->param_array = false; - } - public function setBio($bio) { - if ($bio === '') { - $bio = null; - } elseif (!Validate::string($bio, array('max_length' => 140))) { - throw new OMB_InvalidParameterException($bio, 'profile', 'fullname'); + public function getAvatarURL() + { + return $this->avatar_url; } - $this->bio = $bio; - $this->param_array = false; - } - public function setLocation($location) { - if ($location === '') { - $location = null; - } elseif (!Validate::string($location, array('max_length' => 255))) { - throw new OMB_InvalidParameterException($location, 'profile', 'fullname'); + public function setProfileURL($profile_url) + { + $this->setVal('profile', $profile_url, 'OMB_Helper::validateURL', + 'profile_url'); } - $this->location = $location; - $this->param_array = false; - } - public function setAvatarURL($avatar_url) { - if ($avatar_url === '') { - $avatar_url = null; - } elseif (!OMB_Helper::validateURL($avatar_url)) { - throw new OMB_InvalidParameterException($avatar_url, 'profile', - 'omb_listenee_avatar or omb_listener_avatar'); + public function setNickname($nickname) + { + $this->setVal('nickname', $nickname, 'OMB_Profile::validateNickname', + 'nickname', true); } - $this->avatar_url = $avatar_url; - $this->param_array = false; - } + public function setLicenseURL($license_url) + { + $this->setVal('license', $license_url, 'OMB_Helper::validateURL', + 'license_url'); + } + + public function setFullname($fullname) + { + $this->setVal('fullname', $fullname, 'OMB_Profile::validate255'); + } + + public function setHomepage($homepage) + { + $this->setVal('homepage', $homepage, 'OMB_Helper::validateURL'); + } + + public function setBio($bio) + { + $this->setVal('bio', $bio, 'OMB_Profile::validate140'); + } + + public function setLocation($location) + { + $this->setVal('location', $location, 'OMB_Profile::validate255'); + } + + public function setAvatarURL($avatar_url) + { + $this->setVal('avatar', $avatar_url, 'OMB_Helper::validateURL', + 'avatar_url'); + } + + protected static function validate255($str) + { + return Validate::string($str, array('max_length' => 255)); + } + + protected static function validate140($str) + { + return Validate::string($str, array('max_length' => 140)); + } + + protected static function validateNickname($str) + { + return Validate::string($str, + array('min_length' => 1, + 'max_length' => 64, + 'format' => VALIDATE_NUM . VALIDATE_ALPHA)); + } + + /** + * Set a value + * + * Updates a value specified by a parameter name and the new value. + * + * @param string $param The parameter name according to OMB + * @param string $value The new value + * @param callback $validator A validator function for the parameter + * @param string $field The name of the field in OMB_Profile + * @param bool $force Whether null values should be checked as well + */ + protected function setVal($param, $value, $validator, $field = null, + $force = false) + { + if (is_null($field)) { + $field = $param; + } + if ($value === '' && !$force) { + $value = null; + } elseif (!call_user_func($validator, $value)) { + throw new OMB_InvalidParameterException($value, 'profile', $param); + } + if ($this->$field !== $value) { + $this->$field = $value; + $this->param_array = false; + } + } } ?> diff --git a/extlib/libomb/remoteserviceexception.php b/extlib/libomb/remoteserviceexception.php index 374d15973b..f8341e82b6 100755 --- a/extlib/libomb/remoteserviceexception.php +++ b/extlib/libomb/remoteserviceexception.php @@ -1,9 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ -class OMB_RemoteServiceException extends Exception { - public static function fromYadis($request_uri, $result) { - if ($result->status == 200) { - $err = 'Got wrong response ' . $result->body; - } else { - $err = 'Got error code ' . $result->status . ' with response ' . $result->body; - } - return new OMB_RemoteServiceException($request_uri . ': ' . $err); - } + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ - public static function forRequest($action_uri, $failure) { - return new OMB_RemoteServiceException("Handler for $action_uri: " . $failure); - } +/** + * Exception stating that the remote service had a failure + * + * This exception is raised when a remote service failed to return a valid + * response to a request or send a valid request. + */ +class OMB_RemoteServiceException extends Exception +{ + /** + * Create exception from Yadis response + * + * Creates an exception from a passed yadis result. + * + * @param string $request_uri The target URI for the failed + * request + * @param Auth_Yadis_HTTPResponse $result The result of the failed + * request + * + * @return OMB_RemoteServiceException A new exception + */ + public static function fromYadis($request_uri, $result) + { + if ($result->status == 200) { + $err = 'Got wrong response ' . $result->body; + } else { + $err = 'Got error code ' . $result->status . ' with response ' . + $result->body; + } + return OMB_RemoteServiceException::forRequest($request_uri, $err); + } + + /** + * Create exception for a call to a resource + * + * Creates an exception for a given error message and target URI. + * + * @param string $action_uri The target URI for the failed request + * @param string $failure An error message + * + * @return OMB_RemoteServiceException A new exception + */ + public static function forRequest($action_uri, $failure) + { + return new OMB_RemoteServiceException("Handler for $action_uri: $failure"); + } } ?> diff --git a/extlib/libomb/service_consumer.php b/extlib/libomb/service_consumer.php index 273fd052ec..33ebccc654 100755 --- a/extlib/libomb/service_consumer.php +++ b/extlib/libomb/service_consumer.php @@ -1,19 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Service_Consumer { - protected $url; /* The service URL */ - protected $services; /* An array of strings mapping service URI to - service URL */ +require_once 'Validate.php'; +require_once 'Auth/Yadis/Yadis.php'; +require_once 'OAuth.php'; +require_once 'constants.php'; +require_once 'helper.php'; +require_once 'omb_yadis_xrds.php'; +require_once 'profile.php'; +require_once 'remoteserviceexception.php'; +require_once 'unsupportedserviceexception.php'; - protected $token; /* An OAuthToken */ +/** + * OMB service representation + * + * This class represents a complete remote OMB service. It provides discovery + * and execution of the service’s methods. + */ +class OMB_Service_Consumer +{ + protected $url; /* The service URL */ + protected $services; /* An array of strings mapping service URI to + service URL */ - protected $listener_uri; /* The URI identifying the listener, i. e. the - remote user. */ + protected $token; /* An OAuthToken */ - protected $listenee_uri; /* The URI identifying the listenee, i. e. the - local user during an auth request. */ + protected $listener_uri; /* The URI identifying the listener, i. e. the + remote user. */ - /** - * According to OAuth Core 1.0, an user authorization request is no full-blown - * OAuth request. nonce, timestamp, consumer_key and signature are not needed - * in this step. See http://laconi.ca/trac/ticket/827 for more informations. - * - * Since Laconica up to version 0.7.2 performs a full OAuth request check, a - * correct request would fail. - **/ - public $performLegacyAuthRequest = true; + protected $listenee_uri; /* The URI identifying the listenee, i. e. the + local user during an auth request. */ - /* Helper stuff we are going to need. */ - protected $fetcher; - protected $oauth_consumer; - protected $datastore; + /** + * According to OAuth Core 1.0, an user authorization request is no + * full-blown OAuth request. nonce, timestamp, consumer_key and signature + * are not needed in this step. See http://laconi.ca/trac/ticket/827 for + * more informations. + * + * Since Laconica up to version 0.7.2 performs a full OAuth request check, a + * correct request would fail. + */ + public $performLegacyAuthRequest = true; - /** - * Constructor for OMB_Service_Consumer - * - * Initializes an OMB_Service_Consumer object representing the OMB service - * specified by $service_url. Performs a complete service discovery using - * Yadis. - * Throws OMB_UnsupportedServiceException if XRDS file does not specify a - * complete OMB service. - * - * @param string $service_url The URL of the service - * @param string $consumer_url An URL representing the consumer - * @param OMB_Datastore $datastore An instance of a class implementing - * OMB_Datastore - * - * @access public - **/ - public function __construct ($service_url, $consumer_url, $datastore) { - $this->url = $service_url; - $this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); - $this->datastore = $datastore; - $this->oauth_consumer = new OAuthConsumer($consumer_url, ''); + /* Helper stuff we are going to need. */ + protected $fetcher; + protected $oauth_consumer; + protected $datastore; - $xrds = OMB_Yadis_XRDS::fromYadisURL($service_url, $this->fetcher); + /** + * Constructor for OMB_Service_Consumer + * + * Initializes an OMB_Service_Consumer object representing the OMB service + * specified by $service_url. Performs a complete service discovery using + * Yadis. + * Throws OMB_UnsupportedServiceException if XRDS file does not specify a + * complete OMB service. + * + * @param string $service_url The URL of the service + * @param string $consumer_url An URL representing the consumer + * @param OMB_Datastore $datastore An instance of a class implementing + * OMB_Datastore + * + * @access public + */ + public function __construct ($service_url, $consumer_url, $datastore) + { + $this->url = $service_url; + $this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); + $this->datastore = $datastore; + $this->oauth_consumer = new OAuthConsumer($consumer_url, ''); - /* Detect our services. This performs a validation as well, since - getService und getXRD throw exceptions on failure. */ - $this->services = array(); + $xrds = OMB_Yadis_XRDS::fromYadisURL($service_url, $this->fetcher); - foreach (array(OAUTH_DISCOVERY => OMB_Helper::$OAUTH_SERVICES, - OMB_VERSION => OMB_Helper::$OMB_SERVICES) - as $service_root => $targetservices) { - $uris = $xrds->getService($service_root)->getURIs(); - $xrd = $xrds->getXRD($uris[0]); - foreach ($targetservices as $targetservice) { - $yadis_service = $xrd->getService($targetservice); - if ($targetservice == OAUTH_ENDPOINT_REQUEST) { - $localid = $yadis_service->getElements('xrd:LocalID'); - $this->listener_uri = $yadis_service->parser->content($localid[0]); + /* Detect our services. This performs a validation as well, since + getService und getXRD throw exceptions on failure. */ + $this->services = array(); + + foreach (array(OAUTH_DISCOVERY => OMB_Helper::$OAUTH_SERVICES, + OMB_VERSION => OMB_Helper::$OMB_SERVICES) + as $service_root => $targetservices) { + $uris = $xrds->getService($service_root)->getURIs(); + $xrd = $xrds->getXRD($uris[0]); + foreach ($targetservices as $targetservice) { + $yadis_service = $xrd->getService($targetservice); + if ($targetservice == OAUTH_ENDPOINT_REQUEST) { + $localid = + $yadis_service->getElements('xrd:LocalID'); + $this->listener_uri = + $yadis_service->parser->content($localid[0]); + } + $uris = $yadis_service->getURIs(); + $this->services[$targetservice] = $uris[0]; + } } - $uris = $yadis_service->getURIs(); - $this->services[$targetservice] = $uris[0]; - } - } - } - - /** - * Get the handler URI for a service - * - * Returns the URI the remote web service has specified for the given - * service. - * - * @param string $service The URI identifying the service - * - * @access public - * - * @return string The service handler URI - **/ - public function getServiceURI($service) { - return $this->services[$service]; - } - - /** - * Get the remote user’s URI - * - * Returns the URI of the remote user, i. e. the listener. - * - * @access public - * - * @return string The remote user’s URI - **/ - public function getRemoteUserURI() { - return $this->listener_uri; - } - - /** - * Get the listenee’s URI - * - * Returns the URI of the user being subscribed to, i. e. the local user. - * - * @access public - * - * @return string The local user’s URI - **/ - public function getListeneeURI() { - return $this->listenee_uri; - } - - /** - * Request a request token - * - * Performs a token request on the service. Returns an OAuthToken on success. - * Throws an exception if the request fails. - * - * @access public - * - * @return OAuthToken An unauthorized request token - **/ - public function requestToken() { - /* Set the token to null just in case the user called setToken. */ - $this->token = null; - - $result = $this->performAction(OAUTH_ENDPOINT_REQUEST, - array('omb_listener' => $this->listener_uri)); - if ($result->status != 200) { - throw OMB_RemoteServiceException::fromYadis(OAUTH_ENDPOINT_REQUEST, - $result); - } - parse_str($result->body, $return); - if (!isset($return['oauth_token']) || !isset($return['oauth_token_secret'])) { - throw OMB_RemoteServiceException::fromYadis(OAUTH_ENDPOINT_REQUEST, - $result); - } - $this->setToken($return['oauth_token'], $return['oauth_token_secret']); - return $this->token; - } - - /** - * - * Request authorization - * - * Returns an URL which equals to an authorization request. The end user - * should be redirected to this location to perform authorization. - * The $finish_url should be a local resource which invokes - * OMB_Consumer::finishAuthorization on request. - * - * @param OMB_Profile $profile An OMB_Profile object representing the - * soon-to-be subscribed (i. e. local) user - * @param string $finish_url Target location after successful - * authorization - * - * @access public - * - * @return string An URL representing an authorization request - **/ - public function requestAuthorization($profile, $finish_url) { - if ($this->performLegacyAuthRequest) { - $params = $profile->asParameters('omb_listenee', false); - $params['omb_listener'] = $this->listener_uri; - $params['oauth_callback'] = $finish_url; - - $url = $this->prepareAction(OAUTH_ENDPOINT_AUTHORIZE, $params, 'GET')->to_url(); - } else { - - $params = array( - 'oauth_callback' => $finish_url, - 'oauth_token' => $this->token->key, - 'omb_version' => OMB_VERSION, - 'omb_listener' => $this->listener_uri); - - $params = array_merge($profile->asParameters('omb_listenee', false). $params); - - /* Build result URL. */ - $url = $this->services[OAUTH_ENDPOINT_AUTHORIZE]; - $url .= (strrpos($url, '?') === false ? '?' : '&'); - foreach ($params as $k => $v) { - $url .= OAuthUtil::urlencode_rfc3986($k) . '=' . OAuthUtil::urlencode_rfc3986($v) . '&'; - } } - $this->listenee_uri = $profile->getIdentifierURI(); - - return $url; - } - - /** - * Finish authorization - * - * Finish the subscription process by converting the received and authorized - * request token into an access token. After that, the subscriber’s profile - * and the subscription are stored in the database. - * Expects an OAuthRequest in query parameters. - * Throws exceptions on failure. - * - * @access public - **/ - public function finishAuthorization() { - OMB_Helper::removeMagicQuotesFromRequest(); - $req = OAuthRequest::from_request(); - if ($req->get_parameter('oauth_token') != - $this->token->key) { - /* That’s not the token I wanted to get authorized. */ - throw new OAuthException('The authorized token does not equal the ' . - 'submitted token.'); + /** + * Get the handler URI for a service + * + * Returns the URI the remote web service has specified for the given + * service. + * + * @param string $service The URI identifying the service + * + * @access public + * + * @return string The service handler URI + */ + public function getServiceURI($service) + { + return $this->services[$service]; } - if ($req->get_parameter('omb_version') != OMB_VERSION) { - throw new OMB_RemoteServiceException('The remote service uses an ' . - 'unsupported OMB version'); + /** + * Get the remote user’s URI + * + * Returns the URI of the remote user, i. e. the listener. + * + * @access public + * + * @return string The remote user’s URI + */ + public function getRemoteUserURI() + { + return $this->listener_uri; } - /* Construct the profile to validate it. */ - - /* Fix OMB bug. Listener URI is not passed. */ - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - $params = $_POST; - } else { - $params = $_GET; - } - $params['omb_listener'] = $this->listener_uri; - - require_once 'profile.php'; - $listener = OMB_Profile::fromParameters($params, 'omb_listener'); - - /* Ask the remote service to convert the authorized request token into an - access token. */ - - $result = $this->performAction(OAUTH_ENDPOINT_ACCESS, array()); - if ($result->status != 200) { - throw new OAuthException('Could not get access token'); + /** + * Get the listenee’s URI + * + * Returns the URI of the user being subscribed to, i. e. the local user. + * + * @access public + * + * @return string The local user’s URI + */ + public function getListeneeURI() + { + return $this->listenee_uri; } - parse_str($result->body, $return); - if (!isset($return['oauth_token']) || !isset($return['oauth_token_secret'])) { - throw new OAuthException('Could not get access token'); + /** + * Request a request token + * + * Performs a token request on the service. Returns an OAuthToken on success. + * Throws an exception if the request fails. + * + * @access public + * + * @return OAuthToken An unauthorized request token + */ + public function requestToken() + { + /* Set the token to null just in case the user called setToken. */ + $this->token = null; + + $result = $this->performAction(OAUTH_ENDPOINT_REQUEST, + array('omb_listener' => $this->listener_uri)); + if ($result->status != 200) { + throw OMB_RemoteServiceException::fromYadis(OAUTH_ENDPOINT_REQUEST, + $result); + } + parse_str($result->body, $return); + if (!isset($return['oauth_token']) || + !isset($return['oauth_token_secret'])) { + throw OMB_RemoteServiceException::fromYadis(OAUTH_ENDPOINT_REQUEST, + $result); + } + $this->setToken($return['oauth_token'], $return['oauth_token_secret']); + return $this->token; } - $this->setToken($return['oauth_token'], $return['oauth_token_secret']); - /* Subscription is finished and valid. Now store the new subscriber and the - subscription in the database. */ + /** + * Request authorization + * + * Returns an URL which equals to an authorization request. The end user + * should be redirected to this location to perform authorization. + * The $finish_url should be a local resource which invokes + * OMB_Consumer::finishAuthorization on request. + * + * @param OMB_Profile $profile An OMB_Profile object representing the + * soon-to-be subscribed (i. e. local) user + * @param string $finish_url Target location after successful + * authorization + * + * @access public + * + * @return string An URL representing an authorization request + */ + public function requestAuthorization($profile, $finish_url) + { + if ($this->performLegacyAuthRequest) { + $params = $profile->asParameters('omb_listenee', + false); + $params['omb_listener'] = $this->listener_uri; + $params['oauth_callback'] = $finish_url; - $this->datastore->saveProfile($listener); - $this->datastore->saveSubscription($this->listener_uri, - $this->listenee_uri, - $this->token); - } + $url = $this->prepareAction(OAUTH_ENDPOINT_AUTHORIZE, $params, + 'GET')->to_url(); + } else { + $params = array('oauth_callback' => $finish_url, + 'oauth_token' => $this->token->key, + 'omb_version' => OMB_VERSION, + 'omb_listener' => $this->listener_uri); - /** - * Return the URI identifying the listener - * - * Returns the URI for the OMB user who tries to subscribe or already has - * subscribed our user. This method is a workaround for a serious OMB flaw: - * The Listener URI is not passed in the finishauthorization call. - * - * @access public - * - * @return string the listener’s URI - **/ - public function getListenerURI() { - return $this->listener_uri; - } + $params = array_merge($profile->asParameters('omb_listenee', false), + $params); - /** - * Inform the service about a profile update - * - * Sends an updated profile to the service. - * - * @param OMB_Profile $profile The profile that has changed - * - * @access public - **/ - public function updateProfile($profile) { - $params = $profile->asParameters('omb_listenee', true); - $this->performOMBAction(OMB_ENDPOINT_UPDATEPROFILE, $params, $profile->getIdentifierURI()); - } + /* Build result URL. */ + $url = $this->services[OAUTH_ENDPOINT_AUTHORIZE] . + (strrpos($url, '?') === false ? '?' : '&'); + foreach ($params as $k => $v) { + $url .= OAuthUtil::urlencode_rfc3986($k) . '=' . + OAuthUtil::urlencode_rfc3986($v) . '&'; + } + } - /** - * Inform the service about a new notice - * - * Sends a notice to the service. - * - * @param OMB_Notice $notice The notice - * - * @access public - **/ - public function postNotice($notice) { - $params = $notice->asParameters(); - $params['omb_listenee'] = $notice->getAuthor()->getIdentifierURI(); - $this->performOMBAction(OMB_ENDPOINT_POSTNOTICE, $params, $params['omb_listenee']); - } + $this->listenee_uri = $profile->getIdentifierURI(); - /** - * Set the token member variable - * - * Initializes the token based on given token and secret token. - * - * @param string $token The token - * @param string $secret The secret token - * - * @access public - **/ - public function setToken($token, $secret) { - $this->token = new OAuthToken($token, $secret); - } - - /** - * Prepare an OAuthRequest object - * - * Creates an OAuthRequest object mapping the request specified by the - * parameters. - * - * @param string $action_uri The URI specifying the target service - * @param array $params Additional parameters for the service call - * @param string $method The HTTP method used to call the service - * ('POST' or 'GET', usually) - * - * @access protected - * - * @return OAuthRequest the prepared request - **/ - protected function prepareAction($action_uri, $params, $method) { - $url = $this->services[$action_uri]; - - $url_params = array(); - parse_str(parse_url($url, PHP_URL_QUERY), $url_params); - - /* Add OMB version. */ - $url_params['omb_version'] = OMB_VERSION; - - /* Add user-defined parameters. */ - $url_params = array_merge($url_params, $params); - - $req = OAuthRequest::from_consumer_and_token($this->oauth_consumer, - $this->token, $method, $url, $url_params); - - /* Sign the request. */ - $req->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), - $this->oauth_consumer, $this->token); - - return $req; - } - - /** - * Perform a service call - * - * Creates an OAuthRequest object and execute the mapped call as POST request. - * - * @param string $action_uri The URI specifying the target service - * @param array $params Additional parameters for the service call - * - * @access protected - * - * @return Auth_Yadis_HTTPResponse The POST request response - **/ - protected function performAction($action_uri, $params) { - $req = $this->prepareAction($action_uri, $params, 'POST'); - - /* Return result page. */ - return $this->fetcher->post($req->get_normalized_http_url(), $req->to_postdata(), array()); - } - - /** - * Perform an OMB action - * - * Executes an OMB action – to date, it’s one of updateProfile or postNotice. - * - * @param string $action_uri The URI specifying the target service - * @param array $params Additional parameters for the service call - * @param string $listenee_uri The URI identifying the local user for whom - * the action is performed - * - * @access protected - **/ - protected function performOMBAction($action_uri, $params, $listenee_uri) { - $result = $this->performAction($action_uri, $params); - if ($result->status == 403) { - /* The remote user unsubscribed us. */ - $this->datastore->deleteSubscription($this->listener_uri, $listenee_uri); - } else if ($result->status != 200 || - strpos($result->body, 'omb_version=' . OMB_VERSION) === false) { - /* The server signaled an error or sent an incorrect response. */ - throw OMB_RemoteServiceException::fromYadis($action_uri, $result); + return $url; + } + + /** + * Finish authorization + * + * Finish the subscription process by converting the received and authorized + * request token into an access token. After that, the subscriber’s profile + * and the subscription are stored in the database. + * Expects an OAuthRequest in query parameters. + * Throws exceptions on failure. + * + * @access public + */ + public function finishAuthorization() + { + OMB_Helper::removeMagicQuotesFromRequest(); + $req = OAuthRequest::from_request(); + if ($req->get_parameter('oauth_token') != $this->token->key) { + /* That’s not the token I wanted to get authorized. */ + throw new OAuthException('The authorized token does not equal ' . + 'the submitted token.'); + } + + if ($req->get_parameter('omb_version') != OMB_VERSION) { + throw new OMB_RemoteServiceException('The remote service uses an ' . + 'unsupported OMB version'); + } + + /* Construct the profile to validate it. */ + + /* Fix OMB bug. Listener URI is not passed. */ + if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $params = $_POST; + } else { + $params = $_GET; + } + $params['omb_listener'] = $this->listener_uri; + + $listener = OMB_Profile::fromParameters($params, 'omb_listener'); + + /* Ask the remote service to convert the authorized request token into + an access token. */ + + $result = $this->performAction(OAUTH_ENDPOINT_ACCESS, array()); + if ($result->status != 200) { + throw new OAuthException('Could not get access token'); + } + + parse_str($result->body, $return); + if (!isset($return['oauth_token']) || + !isset($return['oauth_token_secret'])) { + throw new OAuthException('Could not get access token'); + } + $this->setToken($return['oauth_token'], $return['oauth_token_secret']); + + /* Subscription is finished and valid. Now store the new subscriber and + the subscription in the database. */ + + $this->datastore->saveProfile($listener); + $this->datastore->saveSubscription($this->listener_uri, + $this->listenee_uri, + $this->token); + } + + /** + * Return the URI identifying the listener + * + * Returns the URI for the OMB user who tries to subscribe or already has + * subscribed our user. This method is a workaround for a serious OMB flaw: + * The Listener URI is not passed in the finishauthorization call. + * + * @access public + * + * @return string the listener’s URI + */ + public function getListenerURI() + { + return $this->listener_uri; + } + + /** + * Inform the service about a profile update + * + * Sends an updated profile to the service. + * + * @param OMB_Profile $profile The profile that has changed + * + * @access public + */ + public function updateProfile($profile) + { + $params = $profile->asParameters('omb_listenee', true); + $this->performOMBAction(OMB_ENDPOINT_UPDATEPROFILE, $params, + $profile->getIdentifierURI()); + } + + /** + * Inform the service about a new notice + * + * Sends a notice to the service. + * + * @param OMB_Notice $notice The notice + * + * @access public + */ + public function postNotice($notice) + { + $params = $notice->asParameters(); + $params['omb_listenee'] = $notice->getAuthor()->getIdentifierURI(); + $this->performOMBAction(OMB_ENDPOINT_POSTNOTICE, $params, + $params['omb_listenee']); + } + + /** + * Set the token member variable + * + * Initializes the token based on given token and secret token. + * + * @param string $token The token + * @param string $secret The secret token + * + * @access public + */ + public function setToken($token, $secret) + { + $this->token = new OAuthToken($token, $secret); + } + + /** + * Prepare an OAuthRequest object + * + * Creates an OAuthRequest object mapping the request specified by the + * parameters. + * + * @param string $action_uri The URI specifying the target service + * @param array $params Additional parameters for the service call + * @param string $method The HTTP method used to call the service + * ('POST' or 'GET', usually) + * + * @access protected + * + * @return OAuthRequest the prepared request + */ + protected function prepareAction($action_uri, $params, $method) + { + $url = $this->services[$action_uri]; + + $url_params = array(); + parse_str(parse_url($url, PHP_URL_QUERY), $url_params); + + /* Add OMB version. */ + $url_params['omb_version'] = OMB_VERSION; + + /* Add user-defined parameters. */ + $url_params = array_merge($url_params, $params); + + $req = OAuthRequest::from_consumer_and_token($this->oauth_consumer, + $this->token, $method, + $url, $url_params); + + /* Sign the request. */ + $req->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), + $this->oauth_consumer, $this->token); + + return $req; + } + + /** + * Perform a service call + * + * Creates an OAuthRequest object and execute the mapped call as POST + * request. + * + * @param string $action_uri The URI specifying the target service + * @param array $params Additional parameters for the service call + * + * @access protected + * + * @return Auth_Yadis_HTTPResponse The POST request response + */ + protected function performAction($action_uri, $params) + { + $req = $this->prepareAction($action_uri, $params, 'POST'); + + /* Return result page. */ + return $this->fetcher->post($req->get_normalized_http_url(), + $req->to_postdata(), array()); + } + + /** + * Perform an OMB action + * + * Executes an OMB action – as of OMB 0.1, it’s one of updateProfile and + * postNotice. + * + * @param string $action_uri The URI specifying the target service + * @param array $params Additional parameters for the service call + * @param string $listenee_uri The URI identifying the local user for whom + * the action is performed + * + * @access protected + */ + protected function performOMBAction($action_uri, $params, $listenee_uri) + { + $result = $this->performAction($action_uri, $params); + if ($result->status == 403) { + /* The remote user unsubscribed us. */ + $this->datastore->deleteSubscription($this->listener_uri, + $listenee_uri); + } else if ($result->status != 200 || + strpos($result->body, 'omb_version=' . OMB_VERSION) === false) { + /* The server signaled an error or sent an incorrect response. */ + throw OMB_RemoteServiceException::fromYadis($action_uri, $result); + } } - } } +?> diff --git a/extlib/libomb/service_provider.php b/extlib/libomb/service_provider.php index a1c69e86ff..9a1a488a6b 100755 --- a/extlib/libomb/service_provider.php +++ b/extlib/libomb/service_provider.php @@ -1,13 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -class OMB_Service_Provider { - protected $user; /* An OMB_Profile representing the user */ - protected $datastore; /* AN OMB_Datastore */ +require_once 'constants.php'; +require_once 'helper.php'; +require_once 'notice.php'; +require_once 'remoteserviceexception.php'; - protected $remote_user; /* An OMB_Profile representing the remote user during - the authorization process */ +/** + * OMB service realization + * + * This class realizes a complete, simple OMB service. + */ +class OMB_Service_Provider +{ + protected $user; /* An OMB_Profile representing the user */ + protected $datastore; /* AN OMB_Datastore */ - protected $oauth_server; /* An OAuthServer; should only be accessed via - getOAuthServer. */ + protected $remote_user; /* An OMB_Profile representing the remote user + during the authorization process */ - /** - * Initialize an OMB_Service_Provider object - * - * Constructs an OMB_Service_Provider instance that provides OMB services - * referring to a particular user. - * - * @param OMB_Profile $user An OMB_Profile; mandatory for XRDS - * output, user auth handling and OMB - * action performing - * @param OMB_Datastore $datastore An OMB_Datastore; mandatory for - * everything but XRDS output - * @param OAuthServer $oauth_server An OAuthServer; used for token writing - * and OMB action handling; will use - * default value if not set - * - * @access public - **/ - public function __construct ($user = null, $datastore = null, $oauth_server = null) { - $this->user = $user; - $this->datastore = $datastore; - $this->oauth_server = $oauth_server; - } + protected $oauth_server; /* An OAuthServer; should only be accessed via + getOAuthServer. */ - public function getRemoteUser() { - return $this->remote_user; - } - - /** - * Write a XRDS document - * - * Writes a XRDS document specifying the OMB service. Optionally uses a - * given object of a class implementing OMB_XRDS_Writer for output. Else - * OMB_Plain_XRDS_Writer is used. - * - * @param OMB_XRDS_Mapper $xrds_mapper An object mapping actions to URLs - * @param OMB_XRDS_Writer $xrds_writer Optional; The OMB_XRDS_Writer used to - * write the XRDS document - * - * @access public - * - * @return mixed Depends on the used OMB_XRDS_Writer; OMB_Plain_XRDS_Writer - * returns nothing. - **/ - public function writeXRDS($xrds_mapper, $xrds_writer = null) { - if ($xrds_writer == null) { - require_once 'plain_xrds_writer.php'; - $xrds_writer = new OMB_Plain_XRDS_Writer(); - } - return $xrds_writer->writeXRDS($this->user, $xrds_mapper); - } - - /** - * Echo a request token - * - * Outputs an unauthorized request token for the query found in $_GET or - * $_POST. - * - * @access public - **/ - public function writeRequestToken() { - OMB_Helper::removeMagicQuotesFromRequest(); - echo $this->getOAuthServer()->fetch_request_token(OAuthRequest::from_request()); - } - - /** - * Handle an user authorization request. - * - * Parses an authorization request. This includes OAuth and OMB verification. - * Throws exceptions on failures. Returns an OMB_Profile object representing - * the remote user. - * - * The OMB_Profile passed to the constructor of OMB_Service_Provider should - * not represent the user specified in the authorization request, but the one - * currently logged in to the service. This condition being satisfied, - * handleUserAuth will check whether the listener specified in the request is - * identical to the logged in user. - * - * @access public - * - * @return OMB_Profile The profile of the soon-to-be subscribed, i. e. remote - * user - **/ - public function handleUserAuth() { - OMB_Helper::removeMagicQuotesFromRequest(); - - /* Verify the request token. */ - - $this->token = $this->datastore->lookup_token(null, "request", $_GET['oauth_token']); - if (is_null($this->token)) { - throw new OAuthException('The given request token has not been issued ' . - 'by this service.'); + /** + * Initialize an OMB_Service_Provider object + * + * Constructs an OMB_Service_Provider instance that provides OMB services + * referring to a particular user. + * + * @param OMB_Profile $user An OMB_Profile; mandatory for XRDS + * output, user auth handling and OMB + * action performing + * @param OMB_Datastore $datastore An OMB_Datastore; mandatory for + * everything but XRDS output + * @param OAuthServer $oauth_server An OAuthServer; used for token writing + * and OMB action handling; will use + * default value if not set + * + * @access public + */ + public function __construct ($user = null, $datastore = null, + $oauth_server = null) + { + $this->user = $user; + $this->datastore = $datastore; + $this->oauth_server = $oauth_server; } - /* Verify the OMB part. */ - - if ($_GET['omb_version'] !== OMB_VERSION) { - throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, - 'Wrong OMB version ' . $_GET['omb_version']); + /** + * Return the remote user during user authorization + * + * Returns an OMB_Profile representing the remote user during the user + * authorization request. + * + * @return OMB_Profile The remote user + */ + public function getRemoteUser() + { + return $this->remote_user; } - if ($_GET['omb_listener'] !== $this->user->getIdentifierURI()) { - throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, - 'Wrong OMB listener ' . $_GET['omb_listener']); - } - - foreach (array('omb_listenee', 'omb_listenee_profile', - 'omb_listenee_nickname', 'omb_listenee_license') as $param) { - if (!isset($_GET[$param]) || is_null($_GET[$param])) { - throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, - "Required parameter '$param' not found"); - } - } - - /* Store given callback for later use. */ - if (isset($_GET['oauth_callback']) && $_GET['oauth_callback'] !== '') { - $this->callback = $_GET['oauth_callback']; - if (!OMB_Helper::validateURL($this->callback)) { - throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, - 'Invalid callback URL specified'); - } - } - $this->remote_user = OMB_Profile::fromParameters($_GET, 'omb_listenee'); - - return $this->remote_user; - } - - /** - * Continue the OAuth dance after user authorization - * - * Performs the appropriate actions after user answered the authorization - * request. - * - * @param bool $accepted Whether the user granted authorization - * - * @access public - * - * @return array A two-component array with the values: - * - callback The callback URL or null if none given - * - token The authorized request token or null if not - * authorized. - **/ - public function continueUserAuth($accepted) { - $callback = $this->callback; - if (!$accepted) { - $this->datastore->revoke_token($this->token->key); - $this->token = null; - /* TODO: The handling is probably wrong in terms of OAuth 1.0 but the way - laconica works. Moreover I don’t know the right way either. */ - - } else { - $this->datastore->authorize_token($this->token->key); - $this->datastore->saveProfile($this->remote_user); - $this->datastore->saveSubscription($this->user->getIdentifierURI(), - $this->remote_user->getIdentifierURI(), $this->token); - - if (!is_null($this->callback)) { - /* Callback wants to get some informations as well. */ - $params = $this->user->asParameters('omb_listener', false); - - $params['oauth_token'] = $this->token->key; - $params['omb_version'] = OMB_VERSION; - - $callback .= (parse_url($this->callback, PHP_URL_QUERY) ? '&' : '?'); - foreach ($params as $k => $v) { - $callback .= OAuthUtil::urlencode_rfc3986($k) . '=' . - OAuthUtil::urlencode_rfc3986($v) . '&'; + /** + * Write a XRDS document + * + * Writes a XRDS document specifying the OMB service. Optionally uses a + * given object of a class implementing OMB_XRDS_Writer for output. Else + * OMB_Plain_XRDS_Writer is used. + * + * @param OMB_XRDS_Mapper $xrds_mapper An object mapping actions to URLs + * @param OMB_XRDS_Writer $xrds_writer Optional; The OMB_XRDS_Writer used to + * write the XRDS document + * + * @access public + * + * @return mixed Depends on the used OMB_XRDS_Writer; OMB_Plain_XRDS_Writer + * returns nothing. + */ + public function writeXRDS($xrds_mapper, $xrds_writer = null) + { + if ($xrds_writer == null) { + require_once 'plain_xrds_writer.php'; + $xrds_writer = new OMB_Plain_XRDS_Writer(); } - } + return $xrds_writer->writeXRDS($this->user, $xrds_mapper); } - return array($callback, $this->token); - } - /** - * Echo an access token - * - * Outputs an access token for the query found in $_POST. OMB 0.1 specifies - * that the access token request has to be a POST even if OAuth allows GET as - * well. - * - * @access public - **/ - public function writeAccessToken() { - OMB_Helper::removeMagicQuotesFromRequest(); - echo $this->getOAuthServer()->fetch_access_token( + /** + * Echo a request token + * + * Outputs an unauthorized request token for the query found in $_GET or + * $_POST. + * + * @access public + */ + public function writeRequestToken() + { + OMB_Helper::removeMagicQuotesFromRequest(); + echo $this->getOAuthServer()->fetch_request_token( + OAuthRequest::from_request()); + } + + /** + * Handle an user authorization request. + * + * Parses an authorization request. This includes OAuth and OMB + * verification. + * Throws exceptions on failures. Returns an OMB_Profile object representing + * the remote user. + * + * The OMB_Profile passed to the constructor of OMB_Service_Provider should + * not represent the user specified in the authorization request, but the + * one currently logged in to the service. This condition being satisfied, + * handleUserAuth will check whether the listener specified in the request + * is identical to the logged in user. + * + * @access public + * + * @return OMB_Profile The profile of the soon-to-be subscribed, i. e. + * remote user + */ + public function handleUserAuth() + { + OMB_Helper::removeMagicQuotesFromRequest(); + + /* Verify the request token. */ + + $this->token = $this->datastore->lookup_token(null, "request", + $_GET['oauth_token']); + if (is_null($this->token)) { + throw new OAuthException('The given request token has not been ' . + 'issued by this service.'); + } + + /* Verify the OMB part. */ + + if ($_GET['omb_version'] !== OMB_VERSION) { + throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, + 'Wrong OMB version ' . + $_GET['omb_version']); + } + + if ($_GET['omb_listener'] !== $this->user->getIdentifierURI()) { + throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, + 'Wrong OMB listener ' . + $_GET['omb_listener']); + } + + foreach (array('omb_listenee', 'omb_listenee_profile', + 'omb_listenee_nickname', 'omb_listenee_license') as $param) { + if (!isset($_GET[$param]) || is_null($_GET[$param])) { + throw OMB_RemoteServiceException::forRequest( + OAUTH_ENDPOINT_AUTHORIZE, + "Required parameter '$param' not found"); + } + } + + /* Store given callback for later use. */ + if (isset($_GET['oauth_callback']) && $_GET['oauth_callback'] !== '') { + $this->callback = $_GET['oauth_callback']; + if (!OMB_Helper::validateURL($this->callback)) { + throw OMB_RemoteServiceException::forRequest( + OAUTH_ENDPOINT_AUTHORIZE, + 'Invalid callback URL specified'); + } + } + $this->remote_user = OMB_Profile::fromParameters($_GET, 'omb_listenee'); + + return $this->remote_user; + } + + /** + * Continue the OAuth dance after user authorization + * + * Performs the appropriate actions after user answered the authorization + * request. + * + * @param bool $accepted Whether the user granted authorization + * + * @access public + * + * @return array A two-component array with the values: + * - callback The callback URL or null if none given + * - token The authorized request token or null if not + * authorized. + */ + public function continueUserAuth($accepted) + { + $callback = $this->callback; + if (!$accepted) { + $this->datastore->revoke_token($this->token->key); + $this->token = null; + + } else { + $this->datastore->authorize_token($this->token->key); + $this->datastore->saveProfile($this->remote_user); + $this->datastore->saveSubscription($this->user->getIdentifierURI(), + $this->remote_user->getIdentifierURI(), + $this->token); + + if (!is_null($this->callback)) { + /* Callback wants to get some informations as well. */ + $params = $this->user->asParameters('omb_listener', false); + + $params['oauth_token'] = $this->token->key; + $params['omb_version'] = OMB_VERSION; + + $callback .= (parse_url($this->callback, PHP_URL_QUERY) ? '&' : '?'); + foreach ($params as $k => $v) { + $callback .= OAuthUtil::urlencode_rfc3986($k) . '=' . + OAuthUtil::urlencode_rfc3986($v) . '&'; + } + } + } + return array($callback, $this->token); + } + + /** + * Echo an access token + * + * Outputs an access token for the query found in $_POST. OMB 0.1 specifies + * that the access token request has to be a POST even if OAuth allows GET + * as well. + * + * @access public + */ + public function writeAccessToken() + { + OMB_Helper::removeMagicQuotesFromRequest(); + echo $this->getOAuthServer()->fetch_access_token( OAuthRequest::from_request('POST')); - } - - /** - * Handle an updateprofile request - * - * Handles an updateprofile request posted to this service. Updates the - * profile through the OMB_Datastore. - * - * @access public - * - * @return OMB_Profile The updated profile - **/ - public function handleUpdateProfile() { - list($req, $profile) = $this->handleOMBRequest(OMB_ENDPOINT_UPDATEPROFILE); - $profile->updateFromParameters($req->get_parameters(), 'omb_listenee'); - $this->datastore->saveProfile($profile); - $this->finishOMBRequest(); - return $profile; - } - - /** - * Handle a postnotice request - * - * Handles a postnotice request posted to this service. Saves the notice - * through the OMB_Datastore. - * - * @access public - * - * @return OMB_Notice The received notice - **/ - public function handlePostNotice() { - list($req, $profile) = $this->handleOMBRequest(OMB_ENDPOINT_POSTNOTICE); - require_once 'notice.php'; - $notice = OMB_Notice::fromParameters($profile, $req->get_parameters()); - $this->datastore->saveNotice($notice); - $this->finishOMBRequest(); - return $notice; - } - - /** - * Handle an OMB request - * - * Performs common OMB request handling. - * - * @param string $uri The URI defining the OMB endpoint being served - * - * @access protected - * - * @return array(OAuthRequest, OMB_Profile) - **/ - protected function handleOMBRequest($uri) { - - OMB_Helper::removeMagicQuotesFromRequest(); - $req = OAuthRequest::from_request('POST'); - $listenee = $req->get_parameter('omb_listenee'); - - try { - list($consumer, $token) = $this->getOAuthServer()->verify_request($req); - } catch (OAuthException $e) { - header('HTTP/1.1 403 Forbidden'); - // @debug hack - throw OMB_RemoteServiceException::forRequest($uri, - 'Revoked accesstoken for ' . $listenee . ': ' . $e->getMessage()); - // @end debug - throw OMB_RemoteServiceException::forRequest($uri, - 'Revoked accesstoken for ' . $listenee); } - $version = $req->get_parameter('omb_version'); - if ($version !== OMB_VERSION) { - header('HTTP/1.1 400 Bad Request'); - throw OMB_RemoteServiceException::forRequest($uri, - 'Wrong OMB version ' . $version); + /** + * Handle an updateprofile request + * + * Handles an updateprofile request posted to this service. Updates the + * profile through the OMB_Datastore. + * + * @access public + * + * @return OMB_Profile The updated profile + */ + public function handleUpdateProfile() + { + list($req, $profile) = $this->handleOMBRequest(OMB_ENDPOINT_UPDATEPROFILE); + $profile->updateFromParameters($req->get_parameters(), 'omb_listenee'); + $this->datastore->saveProfile($profile); + $this->finishOMBRequest(); + return $profile; } - $profile = $this->datastore->getProfile($listenee); - if (is_null($profile)) { - header('HTTP/1.1 400 Bad Request'); - throw OMB_RemoteServiceException::forRequest($uri, - 'Unknown remote profile ' . $listenee); + /** + * Handle a postnotice request + * + * Handles a postnotice request posted to this service. Saves the notice + * through the OMB_Datastore. + * + * @access public + * + * @return OMB_Notice The received notice + */ + public function handlePostNotice() + { + list($req, $profile) = $this->handleOMBRequest(OMB_ENDPOINT_POSTNOTICE); + + $notice = OMB_Notice::fromParameters($profile, $req->get_parameters()); + $this->datastore->saveNotice($notice); + $this->finishOMBRequest(); + + return $notice; } - $subscribers = $this->datastore->getSubscriptions($listenee); - if (count($subscribers) === 0) { - header('HTTP/1.1 403 Forbidden'); - throw OMB_RemoteServiceException::forRequest($uri, - 'No subscriber for ' . $listenee); + /** + * Handle an OMB request + * + * Performs common OMB request handling. + * + * @param string $uri The URI defining the OMB endpoint being served + * + * @access protected + * + * @return array(OAuthRequest, OMB_Profile) + */ + protected function handleOMBRequest($uri) + { + OMB_Helper::removeMagicQuotesFromRequest(); + $req = OAuthRequest::from_request('POST'); + $listenee = $req->get_parameter('omb_listenee'); + + try { + list($consumer, $token) = $this->getOAuthServer()->verify_request($req); + } catch (OAuthException $e) { + header('HTTP/1.1 403 Forbidden'); + throw OMB_RemoteServiceException::forRequest($uri, + 'Revoked accesstoken for ' . $listenee); + } + + $version = $req->get_parameter('omb_version'); + if ($version !== OMB_VERSION) { + header('HTTP/1.1 400 Bad Request'); + throw OMB_RemoteServiceException::forRequest($uri, + 'Wrong OMB version ' . $version); + } + + $profile = $this->datastore->getProfile($listenee); + if (is_null($profile)) { + header('HTTP/1.1 400 Bad Request'); + throw OMB_RemoteServiceException::forRequest($uri, + 'Unknown remote profile ' . $listenee); + } + + $subscribers = $this->datastore->getSubscriptions($listenee); + if (count($subscribers) === 0) { + header('HTTP/1.1 403 Forbidden'); + throw OMB_RemoteServiceException::forRequest($uri, + 'No subscriber for ' . $listenee); + } + + return array($req, $profile); } - return array($req, $profile); - } + /** + * Finishes an OMB request handling + * + * Performs common OMB request handling finishing. + * + * @access protected + */ + protected function finishOMBRequest() + { + header('HTTP/1.1 200 OK'); + header('Content-type: text/plain'); + /* There should be no clutter but the version. */ + echo "omb_version=" . OMB_VERSION; + } - /** - * Finishes an OMB request handling - * - * Performs common OMB request handling finishing. - * - * @access protected - **/ - protected function finishOMBRequest() { - header('HTTP/1.1 200 OK'); - header('Content-type: text/plain'); - /* There should be no clutter but the version. */ - echo "omb_version=" . OMB_VERSION; - } - - /** - * Return an OAuthServer - * - * Checks whether the OAuthServer is null. If so, initializes it with a - * default value. Returns the OAuth server. - * - * @access protected - **/ - protected function getOAuthServer() { - if (is_null($this->oauth_server)) { - $this->oauth_server = new OAuthServer($this->datastore); - $this->oauth_server->add_signature_method( + /** + * Return an OAuthServer + * + * Checks whether the OAuthServer is null. If so, initializes it with a + * default value. Returns the OAuth server. + * + * @access protected + */ + protected function getOAuthServer() + { + if (is_null($this->oauth_server)) { + $this->oauth_server = new OAuthServer($this->datastore); + $this->oauth_server->add_signature_method( new OAuthSignatureMethod_HMAC_SHA1()); - } - return $this->oauth_server; - } - - /** - * Publish a notice - * - * Posts an OMB notice. This includes storing the notice and posting it to - * subscribed users. - * - * @param OMB_Notice $notice The new notice - * - * @access public - * - * @return array An array mapping subscriber URIs to the exception posting to - * them has raised; Empty array if no exception occured - **/ - public function postNotice($notice) { - $uri = $this->user->getIdentifierURI(); - - /* $notice is passed by reference and may change. */ - $this->datastore->saveNotice($notice); - $subscribers = $this->datastore->getSubscriptions($uri); - - /* No one to post to. */ - if (is_null($subscribers)) { - return array(); + } + return $this->oauth_server; } - require_once 'service_consumer.php'; + /** + * Publish a notice + * + * Posts an OMB notice. This includes storing the notice and posting it to + * subscribed users. + * + * @param OMB_Notice $notice The new notice + * + * @access public + * + * @return array An array mapping subscriber URIs to the exception posting + * to them has raised; Empty array if no exception occured + */ + public function postNotice($notice) + { + $uri = $this->user->getIdentifierURI(); - $err = array(); - foreach($subscribers as $subscriber) { - try { - $service = new OMB_Service_Consumer($subscriber['uri'], $uri, $this->datastore); - $service->setToken($subscriber['token'], $subscriber['secret']); - $service->postNotice($notice); - } catch (Exception $e) { - $err[$subscriber['uri']] = $e; - continue; - } - } - return $err; - } + /* $notice is passed by reference and may change. */ + $this->datastore->saveNotice($notice); + $subscribers = $this->datastore->getSubscriptions($uri); - /** - * Publish a profile update - * - * Posts the current profile as an OMB profile update. This includes updating - * the stored profile and posting it to subscribed users. - * - * @access public - * - * @return array An array mapping subscriber URIs to the exception posting to - * them has raised; Empty array if no exception occured - **/ - public function updateProfile() { - $uri = $this->user->getIdentifierURI(); + /* No one to post to. */ + if (is_null($subscribers)) { + return array(); + } - $this->datastore->saveProfile($this->user); - $subscribers = $this->datastore->getSubscriptions($uri); + require_once 'service_consumer.php'; - /* No one to post to. */ - if (is_null($subscribers)) { - return array(); + $err = array(); + foreach ($subscribers as $subscriber) { + try { + $service = new OMB_Service_Consumer($subscriber['uri'], $uri, + $this->datastore); + $service->setToken($subscriber['token'], $subscriber['secret']); + $service->postNotice($notice); + } catch (Exception $e) { + $err[$subscriber['uri']] = $e; + continue; + } + } + return $err; } - require_once 'service_consumer.php'; + /** + * Publish a profile update + * + * Posts the current profile as an OMB profile update. This includes + * updating the stored profile and posting it to subscribed users. + * + * @access public + * + * @return array An array mapping subscriber URIs to the exception posting + * to them has raised; Empty array if no exception occured + */ + public function updateProfile() + { + $uri = $this->user->getIdentifierURI(); - $err = array(); - foreach($subscribers as $subscriber) { - try { - $service = new OMB_Service_Consumer($subscriber['uri'], $uri, $this->datastore); - $service->setToken($subscriber['token'], $subscriber['secret']); - $service->updateProfile($this->user); - } catch (Exception $e) { - $err[$subscriber['uri']] = $e; - continue; - } + $this->datastore->saveProfile($this->user); + $subscribers = $this->datastore->getSubscriptions($uri); + + /* No one to post to. */ + if (is_null($subscribers)) { + return array(); + } + + require_once 'service_consumer.php'; + + $err = array(); + foreach ($subscribers as $subscriber) { + try { + $service = new OMB_Service_Consumer($subscriber['uri'], $uri, + $this->datastore); + $service->setToken($subscriber['token'], $subscriber['secret']); + $service->updateProfile($this->user); + } catch (Exception $e) { + $err[$subscriber['uri']] = $e; + continue; + } + } + return $err; } - return $err; - } } diff --git a/extlib/libomb/unsupportedserviceexception.php b/extlib/libomb/unsupportedserviceexception.php index 4dab63ebee..be30a1f69b 100755 --- a/extlib/libomb/unsupportedserviceexception.php +++ b/extlib/libomb/unsupportedserviceexception.php @@ -1,9 +1,6 @@ . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ -class OMB_UnsupportedServiceException extends Exception { + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ +/** + * Exception stating that a requested service is not available + * + * This exception is raised when OMB_Service is asked to call a service the + * remote server does not provide. + */ +class OMB_UnsupportedServiceException extends Exception +{ } ?> diff --git a/extlib/libomb/xrds_mapper.php b/extlib/libomb/xrds_mapper.php index 7552154e55..8fbe65249c 100755 --- a/extlib/libomb/xrds_mapper.php +++ b/extlib/libomb/xrds_mapper.php @@ -1,10 +1,6 @@ writeXRDS. + * This file is part of libomb * * PHP version 5 * @@ -21,13 +17,31 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -interface OMB_XRDS_Mapper { - public function getURL($action); +/** + * Map XRDS actions to URLs + * + * This interface specifies classes which write the XRDS file announcing + * the OMB server. An instance of an implementing class should be passed to + * OMB_Service_Provider->writeXRDS. + */ +interface OMB_XRDS_Mapper +{ + /** + * Fetch an URL for a specified action + * + * Returns the action URL for an action specified by the endpoint URI. + * + * @param string $action The endpoint URI + * + * @return string The action URL + */ + public function getURL($action); } ?> diff --git a/extlib/libomb/xrds_writer.php b/extlib/libomb/xrds_writer.php index 31b451b9ce..c7939d60ad 100755 --- a/extlib/libomb/xrds_writer.php +++ b/extlib/libomb/xrds_writer.php @@ -1,10 +1,6 @@ writeXRDS. + * This file is part of libomb * * PHP version 5 * @@ -21,13 +17,30 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - * @package OMB - * @author Adrian Lang - * @copyright 2009 Adrian Lang - * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 - **/ + * @package OMB + * @author Adrian Lang + * @license http://www.gnu.org/licenses/agpl.html GNU AGPL 3.0 + * @version 0.1a-20090828 + * @link http://adrianlang.de/libomb + */ -interface OMB_XRDS_Writer { - public function writeXRDS($user, $mapper); +/** + * Write OMB-specific XRDS + * + * This interface specifies classes which write the XRDS file announcing + * the OMB server. An instance of an implementing class should be passed to + * OMB_Service_Provider->writeXRDS. + */ +interface OMB_XRDS_Writer +{ + /** + * Write XRDS + * + * Outputs a XRDS document specifying an OMB service. + * + * @param OMB_profile $user The target user for the OMB service + * @param OMB_XRDS_Mapper $mapper An OMB_XRDS_Mapper providing endpoint URLs + */ + public function writeXRDS($user, $mapper); } ?>