[ActivityPub] Ensuring notice distribution

ActivityPubPlugin:
- Fix of accepted activity verbs to include SHARES
- Add attention profiles to delivery when announcing

Activitypub_notice:
- New local function to retrieve original URL
- Removal of unnecessary 'Atom*' attributes
- Small fix to the ensuring of actor profile

Activitypub_profile:
- New local function to fetch AP profiles from a collection

Activitypub_postman:
- Fix url passed in the announce activity
This commit is contained in:
brunoccast 2019-07-17 16:25:24 +01:00 committed by Diogo Peralta Cordeiro
parent 25390bf96f
commit 233bdf57ac
4 changed files with 66 additions and 32 deletions

View File

@ -805,37 +805,37 @@ class ActivityPubPlugin extends Plugin
return true; return true;
} }
// Ignore for activity/non-post-verb notices // Ignore for activity/non-(post/share)-verb notices
if (method_exists('ActivityUtils', 'compareVerbs')) { if (method_exists('ActivityUtils', 'compareVerbs')) {
$is_post_verb = ActivityUtils::compareVerbs( $is_valid_verb = ActivityUtils::compareVerbs($notice->verb,
$notice->verb, [ActivityVerb::POST,
[ActivityVerb::POST] ActivityVerb::SHARE]);
);
} else { } else {
$is_post_verb = ($notice->verb == ActivityVerb::POST ? true : false); $is_valid_verb = ($notice->verb == ActivityVerb::POST ||
$notice->verb == ActivityVerb::SHARE);
} }
if ($notice->source == 'activity' || !$is_post_verb) {
if ($notice->source == 'activity' || !$is_valid_verb) {
common_log(LOG_DEBUG, "Ignoring distribution of notice with id {$notice->id} due to invalid Verb");
return true; return true;
} }
$other = []; $other = Activitypub_profile::from_profile_collection(
foreach ($notice->getAttentionProfiles() as $mention) { $notice->getAttentionProfiles()
try { );
$other[] = Activitypub_profile::from_profile($mention);
} catch (Exception $e) {
// Local user can be ignored
}
}
// Is a reply? // Is a reply?
if ($notice->reply_to) { if ($notice->reply_to) {
try { try {
$other[] = Activitypub_profile::from_profile($notice->getParent()->getProfile()); $parent_notice = $notice->getParent();
} catch (Exception $e) {
// Local user can be ignored try {
} $other[] = Activitypub_profile::from_profile($parent_notice->getProfile());
try { } catch (Exception $e) {
foreach ($notice->getParent()->getAttentionProfiles() as $mention) { // Local user can be ignored
}
foreach ($parent_notice->getAttentionProfiles() as $mention) {
try { try {
$other[] = Activitypub_profile::from_profile($mention); $other[] = Activitypub_profile::from_profile($mention);
} catch (Exception $e) { } catch (Exception $e) {
@ -854,6 +854,11 @@ class ActivityPubPlugin extends Plugin
if ($notice->isRepeat()) { if ($notice->isRepeat()) {
$repeated_notice = Notice::getKV('id', $notice->repeat_of); $repeated_notice = Notice::getKV('id', $notice->repeat_of);
if ($repeated_notice instanceof Notice) { if ($repeated_notice instanceof Notice) {
$other = array_merge($other,
Activitypub_profile::from_profile_collection(
$repeated_notice->getAttentionProfiles()
));
try { try {
$other[] = Activitypub_profile::from_profile($repeated_notice->getProfile()); $other[] = Activitypub_profile::from_profile($repeated_notice->getProfile());
} catch (Exception $e) { } catch (Exception $e) {
@ -863,8 +868,10 @@ class ActivityPubPlugin extends Plugin
// That was it // That was it
$postman = new Activitypub_postman($profile, $other); $postman = new Activitypub_postman($profile, $other);
$postman->announce($repeated_notice); $postman->announce($repeated_notice);
return true;
} }
// either made the announce or found nothing to repeat
return true;
} }
// That was it // That was it

View File

@ -72,14 +72,13 @@ class Activitypub_notice extends Managed_DataObject
$item = [ $item = [
'@context' => 'https://www.w3.org/ns/activitystreams', '@context' => 'https://www.w3.org/ns/activitystreams',
'id' => common_local_url('apNotice', ['id' => $notice->getID()]), 'id' => self::getUrl($notice),
'type' => 'Note', 'type' => 'Note',
'published' => str_replace(' ', 'T', $notice->getCreated()).'Z', 'published' => str_replace(' ', 'T', $notice->getCreated()).'Z',
'url' => $notice->getUrl(), 'url' => self::getUrl($notice),
'attributedTo' => ActivityPubPlugin::actor_uri($profile), 'attributedTo' => ActivityPubPlugin::actor_uri($profile),
'to' => ['https://www.w3.org/ns/activitystreams#Public'], 'to' => ['https://www.w3.org/ns/activitystreams#Public'],
'cc' => $cc, 'cc' => $cc,
'atomUri' => $notice->getUrl(),
'conversation' => $notice->getConversationUrl(), 'conversation' => $notice->getConversationUrl(),
'content' => $notice->getRendered(), 'content' => $notice->getRendered(),
'isLocal' => $notice->isLocal(), 'isLocal' => $notice->isLocal(),
@ -89,8 +88,7 @@ class Activitypub_notice extends Managed_DataObject
// Is this a reply? // Is this a reply?
if (!empty($notice->reply_to)) { if (!empty($notice->reply_to)) {
$item['inReplyTo'] = common_local_url('apNotice', ['id' => $notice->getID()]); $item['inReplyTo'] = self::getUrl(Notice::getById($notice->reply_to));
$item['inReplyToAtomUri'] = Notice::getById($notice->reply_to)->getUrl();
} }
// Do we have a location for this notice? // Do we have a location for this notice?
@ -135,7 +133,7 @@ class Activitypub_notice extends Managed_DataObject
// Ensure Actor Profile // Ensure Actor Profile
if (is_null($actor_profile)) { if (is_null($actor_profile)) {
$actor_profile = ActivityPub_explorer::get_profile_from_url($object['actor']); $actor_profile = ActivityPub_explorer::get_profile_from_url($object['attributedTo']);
} }
$act = new Activity(); $act = new Activity();
@ -192,9 +190,9 @@ class Activitypub_notice extends Managed_DataObject
} }
/* Reject notice if it is too long (without the HTML) /* Reject notice if it is too long (without the HTML)
if (Notice::contentTooLong($content)) { if (Notice::contentTooLong($content)) {
throw new Exception('That\'s too long. Maximum notice size is %d character.'); throw new Exception('That\'s too long. Maximum notice size is %d character.');
}*/ }*/
$actobj = new ActivityObject(); $actobj = new ActivityObject();
$actobj->type = ActivityObject::NOTE; $actobj->type = ActivityObject::NOTE;
@ -249,4 +247,19 @@ class Activitypub_notice extends Managed_DataObject
} }
return true; return true;
} }
/**
* Get the original representation URL of a given notice.
*
* @param Notice $notice notice from which to retrieve the URL
* @return string URL
* @author Bruno Casteleiro <brunoccast@fc.up.pt>
*/
public static function getUrl(Notice $notice): string {
if ($notice->isLocal()) {
return common_local_url('apNotice', ['id' => $notice->getID()]);
} else {
return $notice->getUrl();
}
}
} }

View File

@ -229,6 +229,20 @@ class Activitypub_profile extends Managed_DataObject
return $aprofile; return $aprofile;
} }
public static function from_profile_collection(array $profiles): array {
$ap_profiles = [];
foreach ($profiles as $profile) {
try {
$ap_profiles[] = self::from_profile($profile);
} catch (Exception $e) {
// Don't mind local profiles
}
}
return $ap_profiles;
}
/** /**
* Given an existent local profile creates an ActivityPub profile. * Given an existent local profile creates an ActivityPub profile.
* One must be careful not to give a user profile to this function * One must be careful not to give a user profile to this function

View File

@ -283,7 +283,7 @@ class Activitypub_postman
{ {
$data = Activitypub_announce::announce_to_array( $data = Activitypub_announce::announce_to_array(
ActivityPubPlugin::actor_uri($this->actor), ActivityPubPlugin::actor_uri($this->actor),
$notice->getUri() Activitypub_notice::getUrl($notice)
); );
$data = json_encode($data, JSON_UNESCAPED_SLASHES); $data = json_encode($data, JSON_UNESCAPED_SLASHES);