From 3633ca04ebaf9043a8b704eaf8e3a520f40e08a5 Mon Sep 17 00:00:00 2001 From: tenma Date: Sun, 25 Aug 2019 03:14:50 +0100 Subject: [PATCH] [OStatus] Port remote-follow to the RemoteFollow plugin OStatusPlugin: - Stop adding the remote-follow button - Subscribe to required RemoteFollow plugin events - Drop main/ostatussub route and update urls to the main/RemoteFollowSub route - Bump plugin minor version number actions/ostatusgroup, actions/ostatuspeopletag: - Update urls to the main/RemoteFollowSub route lib/util: - Port required functions from OStatusSubAction and adapt to be used with the new events --- plugins/OStatus/OStatusPlugin.php | 102 ++++++++++--------- plugins/OStatus/README | 5 + plugins/OStatus/actions/ostatusgroup.php | 2 +- plugins/OStatus/actions/ostatuspeopletag.php | 2 +- plugins/OStatus/lib/util.php | 64 ++++++++++++ 5 files changed, 123 insertions(+), 52 deletions(-) create mode 100644 plugins/OStatus/lib/util.php diff --git a/plugins/OStatus/OStatusPlugin.php b/plugins/OStatus/OStatusPlugin.php index 5f09a9c89b..1f3f409f8b 100644 --- a/plugins/OStatus/OStatusPlugin.php +++ b/plugins/OStatus/OStatusPlugin.php @@ -28,9 +28,11 @@ if (!defined('GNUSOCIAL')) { exit(1); } +require_once __DIR__ . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'util.php'; + class OStatusPlugin extends Plugin { - const PLUGIN_VERSION = '2.0.3'; + const PLUGIN_VERSION = '2.1.0'; /** * Hook for RouterInitialized event. @@ -46,9 +48,6 @@ class OStatusPlugin extends Plugin $m->connect('main/ostatustag?nickname=:nickname', ['action' => 'ostatustag'], ['nickname' => '[A-Za-z0-9_-]+']); - $m->connect('main/ostatus/nickname/:nickname', - ['action' => 'ostatusinit'], - ['nickname' => '[A-Za-z0-9_-]+']); $m->connect('main/ostatus/group/:group', ['action' => 'ostatusinit'], ['group' => '[A-Za-z0-9_-]+']); @@ -60,8 +59,6 @@ class OStatusPlugin extends Plugin ['action' => 'ostatusinit']); // Remote subscription actions - $m->connect('main/ostatussub', - ['action' => 'ostatussub']); $m->connect('main/ostatusgroup', ['action' => 'ostatusgroup']); $m->connect('main/ostatuspeopletag', @@ -176,12 +173,16 @@ class OStatusPlugin extends Plugin } /** - * Add in an OStatus subscribe button + * Add in an OStatus list button + * + * @param HTMLOutputter $output + * @param Profile $profile + * @return bool hook return value */ - function onStartProfileRemoteSubscribe($output, $profile) + function onStartProfileRemoteSubscribe(HTMLOutputter $output, Profile $profile): bool { - $this->onStartProfileListItemActionElements($output, $profile); - return false; + $this->onStartProfileListItemActionElements($output); + return true; } function onStartGroupSubscribe($widget, $group) @@ -547,7 +548,7 @@ class OStatusPlugin extends Plugin function onEndProfileSettingsActions($out) { $siteName = common_config('site', 'name'); - $js = 'navigator.registerContentHandler("application/vnd.mozilla.maybe.feed", "'.addslashes(common_local_url('ostatussub', null, array('profile' => '%s'))).'", "'.addslashes($siteName).'")'; + $js = 'navigator.registerContentHandler("application/vnd.mozilla.maybe.feed", "'.addslashes(common_local_url('RemoteFollowSub', null, array('profile' => '%s'))).'", "'.addslashes($siteName).'")'; $out->elementStart('li'); $out->element('a', array('href' => 'javascript:'.$js), @@ -1169,21 +1170,7 @@ class OStatusPlugin extends Plugin } } - function onStartShowSubscriptionsContent($action) - { - $this->showEntityRemoteSubscribe($action); - - return true; - } - function onStartShowUserGroupsContent($action) - { - $this->showEntityRemoteSubscribe($action, 'ostatusgroup'); - - return true; - } - - function onEndShowSubscriptionsMiniList($action) { $this->showEntityRemoteSubscribe($action); @@ -1192,12 +1179,12 @@ class OStatusPlugin extends Plugin function onEndShowGroupsMiniList($action) { - $this->showEntityRemoteSubscribe($action, 'ostatusgroup'); + $this->showEntityRemoteSubscribe($action); return true; } - function showEntityRemoteSubscribe($action, $target='ostatussub') + function showEntityRemoteSubscribe($action) { if (!$action->getScoped() instanceof Profile) { // early return if we're not logged in @@ -1208,7 +1195,7 @@ class OStatusPlugin extends Plugin $action->elementStart('div', 'entity_actions'); $action->elementStart('p', array('id' => 'entity_remote_subscribe', 'class' => 'entity_subscribe')); - $action->element('a', array('href' => common_local_url($target), + $action->element('a', array('href' => common_local_url('ostatusgroup'), 'class' => 'entity_remote_subscribe'), // TRANS: Link text for link to remote subscribe. _m('Remote')); @@ -1306,7 +1293,11 @@ class OStatusPlugin extends Plugin if (common_logged_in()) { // only non-logged in users get to see the "remote subscribe" form return true; - } elseif (!$item->getTarget()->isLocal()) { + } + + $target = $item->getTarget(); + + if (!$target->isLocal()) { // we can (for now) only provide remote subscribe forms for local users return true; } @@ -1320,22 +1311,12 @@ class OStatusPlugin extends Plugin throw new ServerException('Bad item type for onStartProfileListItemActionElements'); } - // Add an OStatus subscribe - $output->elementStart('li', 'entity_subscribe'); - $url = common_local_url('ostatusinit', - array('nickname' => $item->getTarget()->getNickname())); - $output->element('a', array('href' => $url, - 'class' => 'entity_remote_subscribe'), - // TRANS: Link text for a user to subscribe to an OStatus user. - _m('Subscribe')); - $output->elementEnd('li'); - $output->elementStart('li', 'entity_tag'); - $url = common_local_url('ostatustag', - array('nickname' => $item->getTarget()->getNickname())); - $output->element('a', array('href' => $url, - 'class' => 'entity_remote_tag'), - // TRANS: Link text for a user to list an OStatus user. + $url = common_local_url('ostatustag', ['nickname' => $target->getNickname()]); + $output->element('a', + ['href' => $url, + 'class' => 'entity_remote_tag'], + // TRANS: Link text for a user to list an OStatus user. _m('List')); $output->elementEnd('li'); @@ -1480,12 +1461,6 @@ class OStatusPlugin extends Plugin $xrd->links[] = new XML_XRD_Element_Link(Salmon::NS_REPLIES, $salmon_url); $xrd->links[] = new XML_XRD_Element_Link(Salmon::NS_MENTIONS, $salmon_url); - // TODO - finalize where the redirect should go on the publisher - $xrd->links[] = new XML_XRD_Element_Link('http://ostatus.org/schema/1.0/subscribe', - common_local_url('ostatussub') . '?profile={uri}', - null, // type not set - true); // isTemplate - return true; } @@ -1611,4 +1586,31 @@ class OStatusPlugin extends Plugin $qm->enqueue($item, 'pushrenew'); } } + + /** + * Try to grab and store the remote profile by the given uri + * + * @param string $uri + * @param Profile &$profile + * @return bool + */ + public function onRemoteFollowPullProfile(string $uri, ?Profile &$profile): bool + { + $oprofile = pullRemoteProfile($uri); + if ($oprofile instanceof Ostatus_profile) { + + // validation + if ($oprofile->isGroup()) { + $target = common_local_url('ostatusgroup', [], ['profile' => $uri]); + common_redirect($target, 303); + } else if ($oprofile->isPeopletag()) { + $target = common_local_url('ostatuspeopletag', [], ['profile' => $uri]); + common_redirect($target, 303); + } + + $profile = $oprofile->localProfile(); + } + + return is_null($profile); + } } diff --git a/plugins/OStatus/README b/plugins/OStatus/README index 3b2fc7fd0d..2b18327d1b 100644 --- a/plugins/OStatus/README +++ b/plugins/OStatus/README @@ -8,6 +8,11 @@ currently non-WebSub feeds cannot be subscribed unless an external WebSub hub proxy is used. +Additional functionality: + +The RemoteFollow plugin is highly recommended as it is the only way to remote +follow a user in OStatus, it adds a remote follow button to user profiles. + Configuration options available: $config['ostatus']['hub'] diff --git a/plugins/OStatus/actions/ostatusgroup.php b/plugins/OStatus/actions/ostatusgroup.php index c6010c6aec..8ed11cebd7 100644 --- a/plugins/OStatus/actions/ostatusgroup.php +++ b/plugins/OStatus/actions/ostatusgroup.php @@ -47,7 +47,7 @@ class OStatusGroupAction extends OStatusSubAction { if (!$this->oprofile->isGroup()) { // Send us to the user subscription form for conf - $target = common_local_url('ostatussub', array(), array('profile' => $this->profile_uri)); + $target = common_local_url('RemoteFollowSub', array(), array('profile' => $this->profile_uri)); common_redirect($target, 303); } } diff --git a/plugins/OStatus/actions/ostatuspeopletag.php b/plugins/OStatus/actions/ostatuspeopletag.php index 96a55142f8..e7ccbc20a1 100644 --- a/plugins/OStatus/actions/ostatuspeopletag.php +++ b/plugins/OStatus/actions/ostatuspeopletag.php @@ -47,7 +47,7 @@ class OStatusPeopletagAction extends OStatusSubAction { if (!$this->oprofile->isPeopletag()) { // Send us to the user subscription form for conf - $target = common_local_url('ostatussub', array(), array('profile' => $this->profile_uri)); + $target = common_local_url('RemoteFollowSub', array(), array('profile' => $this->profile_uri)); common_redirect($target, 303); } } diff --git a/plugins/OStatus/lib/util.php b/plugins/OStatus/lib/util.php new file mode 100644 index 0000000000..eccd419a55 --- /dev/null +++ b/plugins/OStatus/lib/util.php @@ -0,0 +1,64 @@ +. + +defined('GNUSOCIAL') || die(); + +/** + * Pull (and store) remote profile from the its uri + * + * @param string $uri + * @return null|Ostatus_profile + */ +function pullRemoteProfile(string $uri): ?Ostatus_profile +{ + $validate = new Validate(); + + try { + $uri = Discovery::normalize($uri); + } catch (Exception $e) { + return null; + } + + try { + if (Discovery::isAcct($uri) && $validate->email(mb_substr($uri, 5))) { + $profile = Ostatus_profile::ensureWebfinger($uri); + } else if ($validate->uri($uri)) { + $profile = Ostatus_profile::ensureProfileURL($uri); + } else { + common_log(LOG_ERR, 'Invalid address format.'); + return null; + } + return $profile; + } catch (FeedSubBadURLException $e) { + common_log(LOG_ERR, 'Invalid URL or could not reach server.'); + } catch (FeedSubBadResponseException $e) { + common_log(LOG_ERR, 'Cannot read feed; server returned error.'); + } catch (FeedSubEmptyException $e) { + common_log(LOG_ERR, 'Cannot read feed; server returned an empty page.'); + } catch (FeedSubBadHTMLException $e) { + common_log(LOG_ERR, 'Bad HTML, could not find feed link.'); + } catch (FeedSubNoFeedException $e) { + common_log(LOG_ERR, 'Could not find a feed linked from this URL.'); + } catch (FeedSubUnrecognizedTypeException $e) { + common_log(LOG_ERR, 'Not a recognized feed type.'); + } catch (FeedSubNoHubException $e) { + common_log(LOG_ERR, 'No hub found.'); + } catch (Exception $e) { + common_log(LOG_ERR, sprintf('Bad feed URL: %s %s', get_class($e), $e->getMessage())); + } + + return null; +} \ No newline at end of file