X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=extlib%2Flibomb%2Fservice_provider.php;h=9a1a488a6b4db57a2073ee0ff4690599e194c70c;hb=382756a6ada508131ab1408a94daf7617a8fa0fc;hp=753152713bd13c0e86ca89aaa7f265dbc0f8fd82;hpb=cd650b090a339673f2cc7797c8cb9b0eb0196f82;p=quix0rs-gnu-social.git diff --git a/extlib/libomb/service_provider.php b/extlib/libomb/service_provider.php index 753152713b..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 - **/ - -class OMB_Service_Provider { - protected $user; /* An OMB_Profile representing the user */ - protected $datastore; /* AN OMB_Datastore */ - - protected $remote_user; /* An OMB_Profile representing the remote user during - the authorization process */ - - protected $oauth_server; /* An OAuthServer; should only be accessed via - getOAuthServer. */ - - /** - * 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; - } - - 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.'); + * @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 'constants.php'; +require_once 'helper.php'; +require_once 'notice.php'; +require_once 'remoteserviceexception.php'; + +/** + * 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 $remote_user; /* An OMB_Profile representing the remote user + during the authorization process */ + + protected $oauth_server; /* An OAuthServer; should only be accessed via + getOAuthServer. */ + + /** + * 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. */ + /** + * 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_version'] !== OMB_VERSION) { - throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, - 'Wrong OMB version ' . $_GET['omb_version']); + /** + * 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); } - if ($_GET['omb_listener'] !== $this->user->getIdentifierURI()) { - throw OMB_RemoteServiceException::forRequest(OAUTH_ENDPOINT_AUTHORIZE, - 'Wrong OMB listener ' . $_GET['omb_listener']); + /** + * 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()); } - 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, + /** + * 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'); - } + /* 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; } - $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) . '&'; + + /** + * 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); } - 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 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'); - 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); + } - 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; - } - - /** - * 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()); + $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 $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(); + + /** + * 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; } - 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->postNotice($notice); - } catch (Exception $e) { - $err[$subscriber['uri']] = $e; - continue; - } + /** + * 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; } - return $err; - } - - /** - * 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(); - - $this->datastore->saveProfile($this->user); - $subscribers = $this->datastore->getSubscriptions($uri); - - /* No one to post to. */ - if (is_null($subscribers)) { - return array(); + + /** + * 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(); + } + + 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->postNotice($notice); + } catch (Exception $e) { + $err[$subscriber['uri']] = $e; + continue; + } + } + return $err; } - 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; - } + /** + * 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(); + + $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; - } }