Remove ActivityPub Remote Subscribe since we should use OStatus for that after all

This commit is contained in:
Diogo Cordeiro 2018-07-27 19:18:31 +01:00
parent bff507bab8
commit e0d5b2ebd7
3 changed files with 26 additions and 463 deletions

View File

@ -148,17 +148,6 @@ class ActivityPubPlugin extends Plugin
'apActorProfile'
);
$m->connect(
':nickname/remote_follow',
['action' => 'apRemoteFollow'],
['nickname' => '[A-Za-z0-9_-]+']
);
$m->connect(
'activitypub/authorize_follow',
['action' => 'apAuthorizeRemoteFollow']
);
$m->connect(
'user/:id/liked.json',
['action' => 'apActorLiked'],
@ -208,6 +197,32 @@ class ActivityPubPlugin extends Plugin
return true;
}
/**
* Dummy string on AccountProfileBlock stating that ActivityPub is active
* this is more of a placeholder for eventual useful stuff ._.
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @return boolean hook return value
*/
public function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile)
{
if ($profile->isLocal()) {
return true;
}
try {
$aprofile = Activitypub_profile::getKV('profile_id', $profile->id);
} catch (NoResultException $e) {
// Not a remote ActivityPub_profile! Maybe some other network
// that has imported a non-local user (e.g.: OStatus)?
return true;
}
$out->elementStart('dl', 'entity_tags activitypub_profile');
$out->element('dt', null, _m('ActivityPub'));
$out->element('dd', null, _m('Active'));
$out->elementEnd('dl');
}
/**
* Make sure necessary tables are filled out.
*
@ -403,127 +418,6 @@ class ActivityPubPlugin extends Plugin
return false;
}
/********************************************************
* Remote Subscription Events *
********************************************************/
/**
* Add in an ActivityPub subscribe button
*
* @author GNU Social
* @param type $output
* @param type $profile
* @return boolean hook false
*/
public function onStartProfileRemoteSubscribe($output, $profile)
{
$this->onStartProfileListItemActionElements($output, $profile);
return false;
}
/**
* Add in an ActivityPub subscribe button
*
* @author GNU Social
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @param Action|Widget $item
* @return boolean hook return value
* @throws ServerException
*/
public function onStartProfileListItemActionElements($item)
{ // FIXME: This one can accept both an Action and a Widget. Confusing! Refactor to (HTMLOutputter $out, Profile $target)!
if (common_logged_in()) {
// only non-logged in users get to see the "remote subscribe" form
return true;
} elseif (!$item->getTarget()->isLocal()) {
// we can (for now) only provide remote subscribe forms for local users
return true;
}
if ($item instanceof ProfileAction) {
$output = $item;
} elseif ($item instanceof Widget) {
$output = $item->out;
} else {
// Bad $item class, don't know how to use this for outputting!
throw new ServerException('Bad item type for onStartProfileListItemActionElements');
}
// Add an ActivityPub subscribe
$output->elementStart('li', 'entity_subscribe');
$url = common_local_url(
'apRemoteFollow',
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');
return true;
}
/**
* Add in an ActivityPub subscribe button
*
* @author GNU Social
* @param type $action
* @param string $target
* @return boolean hook return value
*/
public function showEntityRemoteSubscribe($action, $target='apRemoteFollow')
{
if (!$action->getScoped() instanceof Profile) {
// early return if we're not logged in
return true;
}
if ($action->getScoped()->sameAs($action->getTarget())) {
$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),
'class' => 'entity_remote_subscribe'),
// TRANS: Link text for link to remote subscribe.
_m('Remote')
);
$action->elementEnd('p');
$action->elementEnd('div');
}
}
/**
* Dummy string on AccountProfileBlock stating that ActivityPub is active
* this is more of a placeholder for eventual useful stuff ._.
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @return boolean hook return value
*/
public function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile)
{
if ($profile->isLocal()) {
return true;
}
try {
$aprofile = Activitypub_profile::getKV('profile_id', $profile->id);
} catch (NoResultException $e) {
// Not a remote ActivityPub_profile! Maybe some other network
// that has imported a non-local user (e.g.: OStatus)?
return true;
}
$out->elementStart('dl', 'entity_tags activitypub_profile');
$out->element('dt', null, _m('ActivityPub'));
$out->element('dd', null, _m('Active'));
$out->elementEnd('dl');
}
/********************************************************
* Discovery Events *
********************************************************/

View File

@ -1,92 +0,0 @@
<?php
/**
* GNU social - a federating social network
*
* ActivityPubPlugin implementation for GNU Social
*
* LICENCE: 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 <http://www.gnu.org/licenses/>.
*
* @category Plugin
* @package GNUsocial
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @author Daniel Supernault <danielsupernault@gmail.com>
* @copyright 2018 Free Software Foundation http://fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link https://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* Authorize Remote Follow
*
* @category Plugin
* @package GNUsocial
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class apAuthorizeRemoteFollowAction extends Action
{
/**
* Prepare to handle the Authorize Remote Follow request.
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @param array $args
* @return boolean
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if (!common_logged_in()) {
// XXX: selfURL() didn't work. :<
common_set_returnto($_SERVER['REQUEST_URI']);
if (Event::handle('RedirectToLogin', array($this, null))) {
common_redirect(common_local_url('login'), 303);
}
return false;
} else {
if (!isset($_GET["acct"])) {
return false;
}
}
return true;
}
/**
* Handle the Authorize Remote Follow Request.
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
*/
protected function handle()
{
$other = Activitypub_profile::get_from_uri($_GET["acct"]);
$actor_profile = common_current_user()->getProfile();
$object_profile = $other->local_profile();
if (!Subscription::exists($actor_profile, $object_profile)) {
Subscription::start($actor_profile, $object_profile);
}
try {
$postman = new Activitypub_postman($actor_profile, [$other]);
$postman->follow();
} catch (Exception $e) {
// Meh, let the exception go on its merry way, it shouldn't be all
// that important really.
}
common_redirect(common_local_url('userbyid', array('id' => $other->profile_id)), 303);
}
}

View File

@ -1,239 +0,0 @@
<?php
/**
* GNU social - a federating social network
*
* ActivityPubPlugin implementation for GNU Social
*
* LICENCE: 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 <http://www.gnu.org/licenses/>.
*
* @category Plugin
* @package GNUsocial
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @author Daniel Supernault <danielsupernault@gmail.com>
* @copyright 2018 Free Software Foundation http://fsf.org
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link https://www.gnu.org/software/social/
*/
if (!defined('GNUSOCIAL')) {
exit(1);
}
/**
* Remote Follow
*
* @category Plugin
* @package GNUsocial
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://www.gnu.org/software/social/
*/
class apRemoteFollowAction extends Action
{
public $nickname;
public $local_profile;
public $remote_identifier;
public $err;
/**
* Prepare to handle the Remote Follow request.
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @param array $args
* @return boolean
*/
protected function prepare(array $args=array())
{
parent::prepare($args);
if (common_logged_in()) {
// TRANS: Client error.
$this->clientError(_m('You can use the local subscription!'));
}
// Local user the remote wants to subscribe to
$this->nickname = $this->trimmed('nickname');
$this->local_profile = User::getByNickname($this->nickname)->getProfile();
// Webfinger or profile URL of the remote user
$this->remote_identifier = $this->trimmed('remote_identifier');
return true;
}
/**
* Handle the Remote Follow Request.
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
*/
protected function handle()
{
parent::handle();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
/* Use a session token for CSRF protection. */
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
// TRANS: Client error displayed when the session token does not match or is not given.
$this->showForm(_m('There was a problem with your session token. '.
'Try again, please.'));
return;
}
$this->activitypub_connect();
} else {
$this->showForm();
}
}
/**
* Form.
*
* @author GNU Social
* @param string|null $err
*/
public function showForm($err = null)
{
$this->err = $err;
if ($this->boolean('ajax')) {
$this->startHTML('text/xml;charset=utf-8');
$this->elementStart('head');
// TRANS: Form title.
$this->element('title', null, _m('TITLE', 'Subscribe to user'));
$this->elementEnd('head');
$this->elementStart('body');
$this->showContent();
$this->elementEnd('body');
$this->endHTML();
} else {
$this->showPage();
}
}
/**
* Page content.
*
* @author GNU Social
*/
public function showContent()
{
// TRANS: Form legend. %s is a nickname.
$header = sprintf(_m('Subscribe to %s'), $this->nickname);
// TRANS: Button text to subscribe to a profile.
$submit = _m('BUTTON', 'Subscribe');
$this->elementStart(
'form',
['id' => 'form_activitypub_connect',
'method' => 'post',
'class' => 'form_settings',
'action' => common_local_url(
'apRemoteFollow',
['nickname' => $this->nickname]
)
]
);
$this->elementStart('fieldset');
$this->element('legend', null, $header);
$this->hidden('token', common_session_token());
$this->elementStart('ul', 'form_data');
$this->elementStart('li', array('id' => 'activitypub_nickname'));
// TRANS: Field label.
$this->input(
'nickname',
_m('User nickname'),
$this->nickname,
// TRANS: Field title.
_m('Nickname of the user you want to follow.')
);
$this->elementEnd('li');
$this->elementStart('li', array('id' => 'activitypub_profile'));
// TRANS: Field label.
$this->input(
'remote_identifier',
_m('Profile Account'),
$this->remote_identifier,
// TRANS: Tooltip for field label "Profile Account".
_m('Your account ID (e.g. user@example.net).')
);
$this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('submit', $submit);
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
/**
* Start connecting the two instances (will be finished with the authorization)
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @return void
*/
public function activitypub_connect()
{
$remote_profile = null;
try { // Try with ActivityPub system
$remote_profile = Activitypub_profile::get_from_uri($this->remote_identifier);
} catch (Exception $e) { // Fallback to compatibility WebFinger system
$validate = new Validate();
$opts = array('allowed_schemes' => array('http', 'https', 'acct'));
if ($validate->uri($this->remote_identifier, $opts)) {
$bits = parse_url($this->remote_identifier);
if ($bits['scheme'] == 'acct') {
$remote_profile = $this->connect_webfinger($bits['path']);
}
} elseif (strpos($this->remote_identifier, '@') !== false) {
$remote_profile = $this->connect_webfinger($this->remote_identifier);
}
}
if (!empty($remote_profile)) {
$url = ActivityPubPlugin::stripUrlPath($remote_profile->get_uri())."activitypub/authorize_follow?acct=".$this->local_profile->getUri();
common_log(LOG_INFO, "Sending remote subscriber $this->remote_identifier to $url");
common_redirect($url, 303);
return;
}
// TRANS: Client error.
$this->clientError(_m('Must provide a remote profile.'));
}
/**
* This function is used by activitypub_connect () and
* is a step of the process
*
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @param type $acct
* @return Profile Profile resulting of WebFinger connection
*/
private function connect_webfinger($acct)
{
$link = ActivityPubPlugin::pull_remote_profile($acct);
if (!is_null($link)) {
return $link;
}
// TRANS: Client error.
$this->clientError(_m('Could not confirm remote profile address.'));
}
/**
* Page title
*
* @return string Page title
*/
public function title()
{
// TRANS: Page title.
return _m('ActivityPub Connect');
}
}