diff --git a/actions/postnotice.php b/actions/postnotice.php index fb06703766..b2f6f1bb95 100644 --- a/actions/postnotice.php +++ b/actions/postnotice.php @@ -54,7 +54,10 @@ class PostnoticeAction extends Action */ function prepare($argarray) { + StatusNet::setApi(true); // Send smaller error pages + parent::prepare($argarray); + try { $this->checkNotice(); } catch (Exception $e) { @@ -71,6 +74,14 @@ class PostnoticeAction extends Action $srv = new OMB_Service_Provider(null, omb_oauth_datastore(), omb_oauth_server()); $srv->handlePostNotice(); + } catch (OMB_RemoteServiceException $rse) { + $msg = $rse->getMessage(); + if (preg_match('/Revoked accesstoken/', $msg) || + preg_match('/No subscriber/', $msg)) { + $this->clientError($msg, 403); + } else { + $this->clientError($msg); + } } catch (Exception $e) { $this->serverError($e->getMessage()); return; diff --git a/actions/updateprofile.php b/actions/updateprofile.php index e416a6fa93..bae6108cce 100644 --- a/actions/updateprofile.php +++ b/actions/updateprofile.php @@ -55,6 +55,8 @@ class UpdateprofileAction extends Action */ function prepare($argarray) { + StatusNet::setApi(true); // Send smaller error pages + parent::prepare($argarray); $license = $_POST['omb_listenee_license']; $site_license = common_config('license', 'url'); @@ -75,6 +77,14 @@ class UpdateprofileAction extends Action $srv = new OMB_Service_Provider(null, omb_oauth_datastore(), omb_oauth_server()); $srv->handleUpdateProfile(); + } catch (OMB_RemoteServiceException $rse) { + $msg = $rse->getMessage(); + if (preg_match('/Revoked accesstoken/', $msg) || + preg_match('/No subscriber/', $msg)) { + $this->clientError($msg, 403); + } else { + $this->clientError($msg); + } } catch (Exception $e) { $this->serverError($e->getMessage()); return; diff --git a/classes/Subscription.php b/classes/Subscription.php index d6fb3fcbdd..9cef2df1ad 100644 --- a/classes/Subscription.php +++ b/classes/Subscription.php @@ -172,6 +172,28 @@ class Subscription extends Memcached_DataObject assert(!empty($sub)); + // @todo: move this block to EndSubscribe handler for + // OMB plugin when it exists. + + if (!empty($sub->token)) { + + $token = new Token(); + + $token->tok = $sub->token; + + if ($token->find(true)) { + + $result = $token->delete(); + + if (!$result) { + common_log_db_error($token, 'DELETE', __FILE__); + throw new Exception(_('Couldn\'t delete subscription OMB token.')); + } + } else { + common_log(LOG_ERR, "Couldn't find credentials with token {$token->tok}"); + } + } + $result = $sub->delete(); if (!$result) { diff --git a/lib/oauthstore.php b/lib/oauthstore.php index eabe37f9fa..a6a6de7505 100644 --- a/lib/oauthstore.php +++ b/lib/oauthstore.php @@ -390,7 +390,7 @@ class StatusNetOAuthDataStore extends OAuthDataStore $sub->subscribed = $user->id; if (!$sub->find(true)) { - return 0; + return array(); } /* Since we do not use OMB_Service_Provider’s action methods, there diff --git a/lib/omb.php b/lib/omb.php index 17132a594f..8bbe5e8aac 100644 --- a/lib/omb.php +++ b/lib/omb.php @@ -77,7 +77,7 @@ function omb_broadcast_notice($notice) /* Get remote users subscribed to this profile. */ $rp = new Remote_profile(); - $rp->query('SELECT postnoticeurl, token, secret ' . + $rp->query('SELECT remote_profile.*, secret, token ' . 'FROM subscription JOIN remote_profile ' . 'ON subscription.subscriber = remote_profile.id ' . 'WHERE subscription.subscribed = ' . $notice->profile_id . ' '); @@ -93,7 +93,8 @@ function omb_broadcast_notice($notice) /* Post notice. */ $service = new StatusNet_OMB_Service_Consumer( - array(OMB_ENDPOINT_POSTNOTICE => $rp->postnoticeurl)); + array(OMB_ENDPOINT_POSTNOTICE => $rp->postnoticeurl), + $rp->uri); try { $service->setToken($rp->token, $rp->secret); $service->postNotice($omb_notice); @@ -125,7 +126,7 @@ function omb_broadcast_profile($profile) /* Get remote users subscribed to this profile. */ $rp = new Remote_profile(); - $rp->query('SELECT updateprofileurl, token, secret ' . + $rp->query('SELECT remote_profile.*, secret, token ' . 'FROM subscription JOIN remote_profile ' . 'ON subscription.subscriber = remote_profile.id ' . 'WHERE subscription.subscribed = ' . $profile->id . ' '); @@ -141,7 +142,11 @@ function omb_broadcast_profile($profile) /* Update profile. */ $service = new StatusNet_OMB_Service_Consumer( - array(OMB_ENDPOINT_UPDATEPROFILE => $rp->updateprofileurl)); + array(OMB_ENDPOINT_UPDATEPROFILE => $rp->updateprofileurl), + $rp->uri); + + common_debug('service = ' . print_r($service, true)); + try { $service->setToken($rp->token, $rp->secret); $service->updateProfile($omb_profile); @@ -159,13 +164,14 @@ function omb_broadcast_profile($profile) } class StatusNet_OMB_Service_Consumer extends OMB_Service_Consumer { - public function __construct($urls) + public function __construct($urls, $listener_uri=null) { $this->services = $urls; $this->datastore = omb_oauth_datastore(); $this->oauth_consumer = omb_oauth_consumer(); $this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); $this->fetcher->timeout = intval(common_config('omb', 'timeout')); + $this->listener_uri = $listener_uri; } } diff --git a/plugins/OStatus/classes/Magicsig.php b/plugins/OStatus/classes/Magicsig.php index 96900d8761..5a46aeeb6e 100644 --- a/plugins/OStatus/classes/Magicsig.php +++ b/plugins/OStatus/classes/Magicsig.php @@ -146,8 +146,10 @@ class Magicsig extends Memcached_DataObject $mod = base64_url_decode($matches[1]); $exp = base64_url_decode($matches[2]); - if ($matches[4]) { + if (!empty($matches[4])) { $private_exp = base64_url_decode($matches[4]); + } else { + $private_exp = false; } $params['public_key'] = new Crypt_RSA_KEY($mod, $exp, 'public'); diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 7b1aec76ba..93e8934c9e 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -1145,7 +1145,7 @@ class Ostatus_profile extends Memcached_DataObject if (!empty($poco)) { $url = $poco->getPrimaryURL(); - if ($url->type == 'homepage') { + if ($url && $url->type == 'homepage') { $homepage = $url->value; } } diff --git a/plugins/OStatus/lib/discovery.php b/plugins/OStatus/lib/discovery.php index 388df0a28f..f8449b309e 100644 --- a/plugins/OStatus/lib/discovery.php +++ b/plugins/OStatus/lib/discovery.php @@ -94,7 +94,7 @@ class Discovery $links = call_user_func(array($class, 'discover'), $uri); if ($link = Discovery::getService($links, Discovery::LRDD_REL)) { // Load the LRDD XRD - if ($link['template']) { + if (!empty($link['template'])) { $xrd_uri = Discovery::applyTemplate($link['template'], $uri); } else { $xrd_uri = $link['href']; diff --git a/plugins/OStatus/lib/xrd.php b/plugins/OStatus/lib/xrd.php index 16d27f8eb7..1de065db9f 100644 --- a/plugins/OStatus/lib/xrd.php +++ b/plugins/OStatus/lib/xrd.php @@ -53,17 +53,22 @@ class XRD $xrd = new XRD(); $dom = new DOMDocument(); - $dom->loadXML($xml); + if (!$dom->loadXML($xml)) { + throw new Exception("Invalid XML"); + } $xrd_element = $dom->getElementsByTagName('XRD')->item(0); // Check for host-meta host - $host = $xrd_element->getElementsByTagName('Host')->item(0)->nodeValue; + $host = $xrd_element->getElementsByTagName('Host')->item(0); if ($host) { - $xrd->host = $host; + $xrd->host = $host->nodeValue; } // Loop through other elements foreach ($xrd_element->childNodes as $node) { + if (!($node instanceof DOMElement)) { + continue; + } switch ($node->tagName) { case 'Expires': $xrd->expires = $node->nodeValue; diff --git a/plugins/OStatus/scripts/updateostatus.php b/plugins/OStatus/scripts/updateostatus.php new file mode 100644 index 0000000000..d553a7d625 --- /dev/null +++ b/plugins/OStatus/scripts/updateostatus.php @@ -0,0 +1,127 @@ +#!/usr/bin/env php +. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..')); + +$shortoptions = 'i:n:a'; +$longoptions = array('id=', 'nickname=', 'all'); + +$helptext = <<find()) { + while ($user->fetch()) { + updateOStatus($user); + } + } + } else { + show_help(); + exit(1); + } +} catch (Exception $e) { + print $e->getMessage()."\n"; + exit(1); +} + +function updateOStatus($user) +{ + if (!have_option('q', 'quiet')) { + echo "{$user->nickname}..."; + } + + $up = $user->getProfile(); + + $sp = $user->getSubscriptions(); + + $rps = array(); + + while ($sp->fetch()) { + $remote = Remote_profile::staticGet('id', $sp->id); + + if (!empty($remote)) { + $rps[] = clone($sp); + } + } + + if (!have_option('q', 'quiet')) { + echo count($rps) . "\n"; + } + + foreach ($rps as $rp) { + try { + if (!have_option('q', 'quiet')) { + echo "Checking {$rp->nickname}..."; + } + + $op = Ostatus_profile::ensureProfile($rp->profileurl); + + if (empty($op)) { + echo "can't convert.\n"; + continue; + } else { + if (!have_option('q', 'quiet')) { + echo "Converting..."; + } + Subscription::cancel($up, $rp); + Subscription::start($up, $op->localProfile()); + if (!have_option('q', 'quiet')) { + echo "done.\n"; + } + } + + } catch (Exception $e) { + if (!have_option('q', 'quiet')) { + echo "fail.\n"; + } + continue; + common_log(LOG_WARNING, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname . + ") to OStatus: " . $e->getMessage()); + continue; + } + } +}