[ActivityPub] Properly handle Actor URIs by using events correctly

This should fix nulls on explorer lookups inputed by postman after generate_followers/getSubscribers, that I think were caused by calling common_profile_uri that, curiously, only handles local profiles
This commit is contained in:
Diogo Cordeiro 2019-12-10 22:27:32 +00:00 committed by Diogo Peralta Cordeiro
parent 165edc2609
commit 73af7be061
13 changed files with 37 additions and 66 deletions

View File

@ -2330,7 +2330,8 @@ function common_profile_uri($profile)
$user = User::getKV('id', $profile->id); $user = User::getKV('id', $profile->id);
if ($user instanceof User) { if ($user instanceof User) {
$uri = $user->getUri(); $uri = $user->getUri();
} } // FIXME: might be a remote profile, by this function name, I would guess it would be fine to call this
// On the other hand, there's Profile->getUri
Event::handle('EndCommonProfileURI', [$profile, &$uri]); Event::handle('EndCommonProfileURI', [$profile, &$uri]);
} }
} }

View File

@ -60,29 +60,22 @@ class ActivityPubPlugin extends Plugin
/** /**
* Returns a Actor's URI from its local $profile * Returns a Actor's URI from its local $profile
* Works both for local and remote users. * Works both for local and remote users.
* This is a discovery event but it seems more logical to have it separated.
* This ensures that Profile->getUri() will always return the intended for a remote AP profile.
* *
* @param Profile $profile Actor's local profile * @param Profile $profile Actor's local profile
* @return string Actor's URI * @param string &$uri I/O Actor's URI
* @throws Exception
* @author Diogo Cordeiro <diogo@fc.up.pt> * @author Diogo Cordeiro <diogo@fc.up.pt>
* @return bool event hook
*/ */
public static function actor_uri($profile) public function onStartGetProfileUri(Profile $profile, &$uri): bool
{ {
return common_profile_uri($profile); $aprofile = Activitypub_profile::getKV('profile_id', $profile->id);
} if ($aprofile instanceof Activitypub_profile) {
$uri = $aprofile->getUri();
/** return false;
* Returns a Actor's URL from its local $profile }
* Works both for local and remote users. return true;
*
* @param Profile $profile Actor's local profile
* @return string Actor's URL
* @throws Exception
* @author Diogo Cordeiro <diogo@fc.up.pt>
*/
public static function actor_url($profile)
{
return ActivityPubPlugin::actor_uri($profile)."/";
} }
/** /**
@ -621,7 +614,7 @@ class ActivityPubPlugin extends Plugin
if ($object->isPerson()) { if ($object->isPerson()) {
$link = new XML_XRD_Element_Link( $link = new XML_XRD_Element_Link(
'self', 'self',
ActivityPubPlugin::actor_uri($object->getProfile()), $object->getProfile()->getUri(),
'application/activity+json' 'application/activity+json'
); );
$xrd->links[] = clone($link); $xrd->links[] = clone($link);
@ -743,25 +736,6 @@ class ActivityPubPlugin extends Plugin
* Discovery Events * * Discovery Events *
********************************************************/ ********************************************************/
/**
* Profile URI for remote profiles.
*
* @author GNU social
* @author Diogo Cordeiro <diogo@fc.up.pt>
* @param Profile $profile
* @param string $uri in/out
* @return mixed hook return code
*/
public function onStartGetProfileUri(Profile $profile, &$uri)
{
$aprofile = Activitypub_profile::getKV('profile_id', $profile->id);
if ($aprofile instanceof Activitypub_profile) {
$uri = $aprofile->getUri();
return false;
}
return true;
}
/** /**
* Profile from URI. * Profile from URI.
* *

View File

@ -122,7 +122,7 @@ class apActorFollowersAction extends ManagedAction
/* Get followers' URLs */ /* Get followers' URLs */
foreach ($sub as $s) { foreach ($sub as $s) {
$subs[] = ActivityPubPlugin::actor_uri($s); $subs[] = $s->getUri();
} }
} catch (NoResultException $e) { } catch (NoResultException $e) {
// Just let the exception go on its merry way // Just let the exception go on its merry way

View File

@ -122,7 +122,7 @@ class apActorFollowingAction extends ManagedAction
/* Get followed' URLs */ /* Get followed' URLs */
foreach ($sub as $s) { foreach ($sub as $s) {
$subs[] = ActivityPubPlugin::actor_uri($s); $subs[] = $s->getUri();
} }
} catch (NoResultException $e) { } catch (NoResultException $e) {
// Just let the exception go on its merry way // Just let the exception go on its merry way

View File

@ -123,7 +123,7 @@ class apActorOutboxAction extends ManagedAction
// TODO: Handle other types // TODO: Handle other types
if ($note->object_type == 'http://activitystrea.ms/schema/1.0/note') { if ($note->object_type == 'http://activitystrea.ms/schema/1.0/note') {
$notices[] = Activitypub_create::create_to_array( $notices[] = Activitypub_create::create_to_array(
ActivityPubPlugin::actor_uri($note->getProfile()), $note->getProfile()->getUri(),
Activitypub_notice::notice_to_array($note) Activitypub_notice::notice_to_array($note)
); );
} }

View File

@ -86,7 +86,7 @@ class Activitypub_profile extends Managed_DataObject
*/ */
public static function profile_to_array($profile) public static function profile_to_array($profile)
{ {
$uri = ActivityPubPlugin::actor_uri($profile); $uri = $profile->getUri();
$id = $profile->getID(); $id = $profile->getID();
$rsa = new Activitypub_rsa(); $rsa = new Activitypub_rsa();
$public_key = $rsa->ensure_public_key($profile); $public_key = $rsa->ensure_public_key($profile);
@ -589,20 +589,16 @@ class Activitypub_profile extends Managed_DataObject
} }
$subs = Subscription::getSubscriberIDs($profile->id, $offset, $limit); $subs = Subscription::getSubscriberIDs($profile->id, $offset, $limit);
try { $profiles = [];
$profiles = [];
$users = User::multiGet('id', $subs); $users = User::multiGet('id', $subs);
foreach ($users->fetchAll() as $user) { foreach ($users->fetchAll() as $user) {
$profiles[$user->id] = $user->getProfile(); $profiles[$user->id] = $user->getProfile();
} }
$ap_profiles = Activitypub_profile::multiGet('profile_id', $subs); $ap_profiles = Activitypub_profile::multiGet('profile_id', $subs);
foreach ($ap_profiles->fetchAll() as $ap) { foreach ($ap_profiles->fetchAll() as $ap) {
$profiles[$ap->getID()] = $ap->local_profile(); $profiles[$ap->getID()] = $ap->local_profile();
}
} catch (NoResultException $e) {
return $e->obj;
} }
if ($cache) { if ($cache) {

View File

@ -115,7 +115,7 @@ class Activitypub_rsa extends Managed_DataObject
// ASSERT: This should never happen, but try to recover! // ASSERT: This should never happen, but try to recover!
common_log(LOG_ERR, "Activitypub_rsa: An impossible thing has happened... Please let the devs know that it entered in line 116 at Activitypub_rsa.php"); common_log(LOG_ERR, "Activitypub_rsa: An impossible thing has happened... Please let the devs know that it entered in line 116 at Activitypub_rsa.php");
if ($fetch) { if ($fetch) {
$res = Activitypub_explorer::get_remote_user_activity(ActivityPubPlugin::actor_uri($profile)); $res = Activitypub_explorer::get_remote_user_activity($profile->getUri());
Activitypub_rsa::update_public_key($profile, $res['publicKey']['publicKeyPem']); Activitypub_rsa::update_public_key($profile, $res['publicKey']['publicKeyPem']);
return self::ensure_public_key($profile, false); return self::ensure_public_key($profile, false);
} else { } else {

View File

@ -36,7 +36,7 @@ class HttpSignature
$key = openssl_pkey_get_private($actor_private_key); $key = openssl_pkey_get_private($actor_private_key);
openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256); openssl_sign($stringToSign, $signature, $key, OPENSSL_ALGO_SHA256);
$signature = base64_encode($signature); $signature = base64_encode($signature);
$signatureHeader = 'keyId="' . ActivityPubPlugin::actor_uri($user).'#public-key' . '",headers="' . $signedHeaders . '",algorithm="rsa-sha256",signature="' . $signature . '"'; $signatureHeader = 'keyId="' . $user->getUri() . '#public-key' . '",headers="' . $signedHeaders . '",algorithm="rsa-sha256",signature="' . $signature . '"';
unset($headers['(request-target)']); unset($headers['(request-target)']);
$headers['Signature'] = $signatureHeader; $headers['Signature'] = $signatureHeader;

View File

@ -46,7 +46,7 @@ class Activitypub_announce
*/ */
public static function announce_to_array(Profile $actor, Notice $notice): array public static function announce_to_array(Profile $actor, Notice $notice): array
{ {
$actor_uri = ActivityPubPlugin::actor_uri($actor); $actor_uri = $actor->getUri();
$notice_url = Activitypub_notice::getUrl($notice); $notice_url = Activitypub_notice::getUrl($notice);
$to = [common_local_url('apActorFollowers', ['id' => $actor->getID()])]; $to = [common_local_url('apActorFollowers', ['id' => $actor->getID()])];

View File

@ -85,13 +85,13 @@ class Activitypub_follow
if (!Subscription::exists($actor_profile, $object_profile)) { if (!Subscription::exists($actor_profile, $object_profile)) {
Subscription::start($actor_profile, $object_profile); Subscription::start($actor_profile, $object_profile);
Activitypub_profile::subscribeCacheUpdate($actor_profile, $object_profile); Activitypub_profile::subscribeCacheUpdate($actor_profile, $object_profile);
common_debug('ActivityPubPlugin: Accepted Follow request from '.ActivityPubPlugin::actor_uri($actor_profile).' to '.$object); common_debug('ActivityPubPlugin: Accepted Follow request from '.$actor_profile->getUri().' to '.$object);
} else { } else {
common_debug('ActivityPubPlugin: Received a repeated Follow request from '.ActivityPubPlugin::actor_uri($actor_profile).' to '.$object); common_debug('ActivityPubPlugin: Received a repeated Follow request from '.$actor_profile->getUri().' to '.$object);
} }
// Notify remote instance that we have accepted their request // Notify remote instance that we have accepted their request
common_debug('ActivityPubPlugin: Notifying remote instance that we have accepted their Follow request request from '.ActivityPubPlugin::actor_uri($actor_profile).' to '.$object); common_debug('ActivityPubPlugin: Notifying remote instance that we have accepted their Follow request request from '.$actor_profile->getUri().' to '.$object);
$postman = new Activitypub_postman($object_profile, [$actor_aprofile]); $postman = new Activitypub_postman($object_profile, [$actor_aprofile]);
$postman->accept_follow($id); $postman->accept_follow($id);
} }

View File

@ -63,7 +63,7 @@ class Activitypub_message
'id' => common_local_url('showmessage', ['message' => $message->getID()]), 'id' => common_local_url('showmessage', ['message' => $message->getID()]),
'type' => 'Note', 'type' => 'Note',
'published' => str_replace(' ', 'T', $message->created).'Z', 'published' => str_replace(' ', 'T', $message->created).'Z',
'attributedTo' => ActivityPubPlugin::actor_uri($from), 'attributedTo' => $from->getUri(),
'to' => $to, 'to' => $to,
'cc' => [], 'cc' => [],
'content' => $message->getRendered(), 'content' => $message->getRendered(),

View File

@ -85,7 +85,7 @@ class Activitypub_notice
'type' => 'Note', 'type' => 'Note',
'published' => str_replace(' ', 'T', $notice->getCreated()) . 'Z', 'published' => str_replace(' ', 'T', $notice->getCreated()) . 'Z',
'url' => self::getUrl($notice), 'url' => self::getUrl($notice),
'attributedTo' => ActivityPubPlugin::actor_uri($profile), 'attributedTo' => $profile->getUri(),
'to' => $to, 'to' => $to,
'cc' => $cc, 'cc' => $cc,
'conversation' => $notice->getConversationUrl(), 'conversation' => $notice->getConversationUrl(),
@ -205,7 +205,7 @@ class Activitypub_notice
foreach ($mentions_profiles as $mp) { foreach ($mentions_profiles as $mp) {
if (!$mp->hasBlocked($actor_profile)) { if (!$mp->hasBlocked($actor_profile)) {
$act->context->attention[ActivityPubPlugin::actor_uri($mp)] = 'http://activitystrea.ms/schema/1.0/person'; $act->context->attention[$mp->getUri()] = 'http://activitystrea.ms/schema/1.0/person';
} }
} }

View File

@ -58,7 +58,7 @@ class Activitypub_postman
$this->actor = $from; $this->actor = $from;
$this->to = $to; $this->to = $to;
$this->actor_uri = ActivityPubPlugin::actor_uri($this->actor); $this->actor_uri = $this->actor->getUri();
$this->client = new HTTPClient(); $this->client = new HTTPClient();
} }
@ -364,7 +364,7 @@ class Activitypub_postman
public function delete_note($notice) public function delete_note($notice)
{ {
$data = Activitypub_delete::delete_to_array( $data = Activitypub_delete::delete_to_array(
ActivityPubPlugin::actor_uri($notice->getProfile()), $notice->getProfile()->getUri(),
Activitypub_notice::getUrl($notice) Activitypub_notice::getUrl($notice)
); );
$errors = []; $errors = [];