Remove ActivityPub Remote Subscribe since we should use OStatus for that after all
This commit is contained in:
parent
bff507bab8
commit
e0d5b2ebd7
@ -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 *
|
||||
********************************************************/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user