aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Zotlabs/Lib/Activity.php183
-rw-r--r--Zotlabs/Lib/Libzot.php115
2 files changed, 43 insertions, 255 deletions
diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php
index f10a2bace..90d7af8e8 100644
--- a/Zotlabs/Lib/Activity.php
+++ b/Zotlabs/Lib/Activity.php
@@ -8,7 +8,6 @@ use Zotlabs\Access\PermissionRoles;
use Zotlabs\Access\Permissions;
use Zotlabs\Daemon\Master;
use Zotlabs\Web\HTTPSig;
-use Zotlabs\Entity\Item;
require_once('include/event.php');
require_once('include/html2plain.php');
@@ -571,25 +570,6 @@ class Activity {
if ($i['mid'] !== $i['parent_mid']) {
$ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent']));
-
- $cnv = IConfig::Get($i['parent'], 'activitypub', 'context');
- if (!$cnv) {
- $cnv = $i['parent_mid'];
- }
- }
-
- if (empty($cnv)) {
- $cnv = IConfig::Get($i, 'activitypub', 'context');
- if (!$cnv) {
- $cnv = $i['parent_mid'];
- }
- }
-
- if (!empty($cnv)) {
- if (is_string($cnv) && str_starts_with($cnv, z_root())) {
- $cnv = str_replace(['/item/', '/activity/'], ['/conversation/', '/conversation/'], $cnv);
- }
- $ret['context'] = $cnv;
}
if ($i['mimetype'] === 'text/bbcode') {
@@ -609,12 +589,6 @@ class Activity {
$t = self::encode_taxonomy($i);
if ($t) {
- foreach($t as $tag) {
- if (strcasecmp($tag['name'], '#nsfw') === 0 || strcasecmp($tag['name'], '#sensitive') === 0) {
- $ret['sensitive'] = true;
- }
- }
-
$ret['tag'] = $t;
}
@@ -622,20 +596,7 @@ class Activity {
if ($a) {
$ret['attachment'] = $a;
}
-/*
- if ($i['target']) {
- if (is_string($i['target'])) {
- $tmp = json_decode($i['target'], true);
- if ($tmp !== null) {
- $i['target'] = $tmp;
- }
- }
- $tgt = self::encode_object($i['target']);
- if ($tgt) {
- $ret['target'] = $tgt;
- }
- }
-*/
+
if (intval($i['item_private']) === 0) {
$ret['to'] = [ACTIVITY_PUBLIC_INBOX];
}
@@ -846,32 +807,12 @@ class Activity {
$ret['type'] = self::activity_mapper($i['verb']);
if ((isset($i['item_deleted']) && intval($i['item_deleted'])) && !$recurse) {
+ $is_response = false;
- if ($i['verb'] === 'Add' && str_contains($i['tgt_type'], 'Collection')) {
- $ret['id'] = str_replace('/item/', '/activity/', $i['mid']) . '#Remove';
- $ret['type'] = 'Remove';
- if (is_string($i['obj'])) {
- $obj = json_decode($i['obj'], true);
- }
- elseif(is_array($i['obj'])) {
- $obj = $i['obj'];
- }
- if (isset($obj['id'])) {
- $ret['object'] = $obj['id'];
- }
- else {
- $ret['object'] = str_replace('/item/', '/activity/', $i['mid']);
- }
- $ret['target'] = is_array($i['target']) ? $i['target'] : json_decode($i['target'], true);
-
- return $ret;
- }
-
- $is_response = ActivityStreams::is_response_activity($ret['type']);
-
- if ($is_response) {
+ if (ActivityStreams::is_response_activity($ret['type'])) {
$ret['type'] = 'Undo';
$fragment = 'undo';
+ $is_response = true;
}
else {
$ret['type'] = 'Delete';
@@ -994,28 +935,9 @@ class Activity {
// inReplyTo needs to be set in the activity for followup actions (Like, Dislike, Announce, etc.),
// but *not* for comments and RSVPs, where it should only be present in the object
- if (!in_array($ret['type'], ['Create', 'Update', 'Add', 'Remove', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject'])) {
+ if (!in_array($ret['type'], ['Create', 'Update', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject'])) {
$ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent']));
}
-
- $cnv = IConfig::Get($i['parent'], 'activitypub', 'context');
- if (!$cnv) {
- $cnv = $item['parent_mid'];
- }
- }
-
- if (empty($cnv)) {
- $cnv = IConfig::Get($i, 'activitypub', 'context');
- if (!$cnv) {
- $cnv = $i['parent_mid'];
- }
- }
-
- if (!empty($cnv)) {
- if (is_string($cnv) && str_starts_with($cnv, z_root())) {
- $cnv = str_replace(['/item/', '/activity/'], ['/conversation/', '/conversation/'], $cnv);
- }
- $ret['context'] = $cnv;
}
$actor = self::encode_person($i['author'], false);
@@ -1088,7 +1010,6 @@ class Activity {
call_hooks('encode_activity', $hookinfo);
return $hookinfo['encoded'];
-
}
// Returns an array of URLS for any mention tags found in the item array $i.
@@ -2946,10 +2867,6 @@ class Activity {
// This isn't perfect but the best we can do for now.
$item['comment_policy'] = ((isset($act->data['commentPolicy'])) ? $act->data['commentPolicy'] : 'authenticated');
- if (!empty($act->obj['context'])) {
- IConfig::Set($item, 'activitypub', 'context', $act->obj['context'], 1);
- }
-
IConfig::Set($item, 'activitypub', 'recips', $act->raw_recips);
if (intval($act->sigok)) {
@@ -3137,13 +3054,6 @@ class Activity {
}
$a = new ActivityStreams($n);
- if ($a->type === 'Announce' && is_array($a->obj)
- && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) {
- // This is a relayed/forwarded Activity (as opposed to a shared/boosted object)
- // Reparse the encapsulated Activity and use that instead
- logger('relayed activity', LOGGER_DEBUG);
- $a = new ActivityStreams($a->obj);
- }
logger($a->debug(), LOGGER_DATA);
@@ -3152,6 +3062,24 @@ class Activity {
break;
}
+ if (in_array($a->type, ['Add', 'Remove'])
+ && is_array($a->obj)
+ && array_key_exists('object', $a->obj)
+ && array_key_exists('actor', $a->obj)
+ && !empty($a->tgt)) {
+
+ logger('unsupported collection operation', LOGGER_DEBUG);
+ return;
+ }
+
+ if ($a->type === 'Announce' && is_array($a->obj)
+ && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) {
+ // This is a relayed/forwarded Activity (as opposed to a shared/boosted object)
+ // Reparse the encapsulated Activity and use that instead
+ logger('relayed activity', LOGGER_DEBUG);
+ $a = new ActivityStreams($a->obj);
+ }
+
$item = Activity::decode_note($a);
if (!$item) {
@@ -3759,70 +3687,5 @@ class Activity {
}
}
- public static function addToCollection($channel, $object, $target, $sourceItem = null, $deliver = true) {
- if (!isset($channel['xchan_hash'])) {
- $channel = channelx_by_hash($channel['channel_hash']);
- }
-
- $item = ((new Item())
- ->setUid($channel['channel_id'])
- ->setVerb('Add')
- ->setAuthorXchan($channel['channel_hash'])
- ->setOwnerXchan($channel['channel_hash'])
- ->setObj($object)
- ->setObjType($object['type'])
- ->setParentMid(str_replace('/conversation/','/item/', $target))
- ->setThrParent(str_replace('/conversation/','/item/', $target))
- ->setApproved($object['object']['id'] ?? '')
- ->setReplyto(z_root() . '/channel/' . $channel['channel_address'])
- ->setTgtType('Collection')
- ->setTarget([
- 'id' => str_replace('/item/','/conversation/', $target),
- 'type' => 'Collection',
- 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'],
- ])
- );
- if ($sourceItem) {
- $item->setAllowCid($sourceItem['allow_cid'])
- ->setAllowGid($sourceItem['allow_gid'])
- ->setDenyCid($sourceItem['deny_cid'])
- ->setDenyGid($sourceItem['deny_gid'])
- ->setPrivate($sourceItem['item_private'])
- ->setNocomment($sourceItem['item_nocomment'])
- ->setCommentPolicy($sourceItem['comment_policy'])
- ->setPostopts($sourceItem['postopts']);
- }
- $result = post_activity_item($item->toArray(), deliver: $deliver, channel: $channel, observer: $channel, addAndSync: false);
- logger('addToCollection: ' . print_r($result, true));
- return $result;
- }
-
- public static function removeFromCollection($channel, $object, $target, $deliver = true) {
- if (!isset($channel['xchan_hash'])) {
- $channel = channelx_by_hash($channel['channel_hash']);
- }
-
- $item = ((new Item())
- ->setUid($channel['channel_id'])
- ->setVerb('Remove')
- ->setAuthorXchan($channel['channel_hash'])
- ->setOwnerXchan($channel['channel_hash'])
- ->setObj($object)
- ->setObjType($object['type'])
- ->setParentMid(str_replace('/conversation/','/item/', $target))
- ->setThrParent(str_replace('/conversation/','/item/', $target))
- ->setReplyto(z_root() . '/channel/' . $channel['channel_address'])
- ->setTgtType('Collection')
- ->setTarget([
- 'id' => str_replace('/item/','/conversation/', $target),
- 'type' => 'Collection',
- 'attributedTo' => z_root() . '/channel/' . $channel['channel_address']
- ])
- );
-
- $result = post_activity_item($item->toArray(), deliver: $deliver, channel: $channel, observer: $channel, addAndSync: false);
- logger('removeFromCollection: ' . print_r($result, true));
- return $result;
- }
}
diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php
index 41fec64d8..05134f433 100644
--- a/Zotlabs/Lib/Libzot.php
+++ b/Zotlabs/Lib/Libzot.php
@@ -1134,7 +1134,6 @@ class Libzot {
}
$message_request = false;
- $is_collection_operation = false;
$has_data = array_key_exists('data', $env) && $env['data'];
@@ -1142,44 +1141,26 @@ class Libzot {
$AS = null;
-
if ($env['encoding'] === 'activitystreams') {
$AS = new ActivityStreams($data);
-
- logger($AS->debug(), LOGGER_DATA);
-
if (!$AS->is_valid()) {
logger('Activity rejected: ' . print_r($data, true));
return;
}
- // process add/remove from collection separately, as it requires a target.
- // use the raw object, as it will not include actor expansion
if (in_array($AS->type, ['Add', 'Remove'])
&& is_array($AS->obj)
&& array_key_exists('object', $AS->obj)
&& array_key_exists('actor', $AS->obj)
&& !empty($AS->tgt)) {
- hz_syslog('relayed collection operation', LOGGER_DEBUG);
- $is_collection_operation = true;
-
- $original_id = $AS->id;
- $original_type = $AS->type;
-
- $raw_activity = $AS->data;
-
- $AS = new ActivityStreams($raw_activity['object'], portable_id: $env['sender']);
-
- // Store the original activity id and type for later usage
- $AS->meta['original_id'] = $original_id;
- $AS->meta['original_type'] = $original_type;
+ logger('unsupported collection operation', LOGGER_DEBUG);
+ return;
}
if (is_array($AS->obj)) {
$item = Activity::decode_note($AS);
-
if (!$item) {
logger('Could not decode activity: ' . print_r($AS, true));
return;
@@ -1189,7 +1170,7 @@ class Libzot {
$item = [];
}
-
+ logger($AS->debug(), LOGGER_DATA);
}
@@ -1332,12 +1313,7 @@ class Libzot {
$relay = (($env['type'] === 'response') ? true : false);
- if($is_collection_operation)
- hz_syslog('col');
- else
- hz_syslog('not col');
-
- $result = self::process_delivery($env['sender'], $AS, $item, $deliveries, $relay, false, $message_request, false, $is_collection_operation);
+ $result = self::process_delivery($env['sender'], $AS, $item, $deliveries, $relay, false, $message_request);
Activity::init_background_fetch($env['sender']);
}
@@ -1553,7 +1529,7 @@ class Libzot {
* @return array
*/
- static function process_delivery($sender, $act, $arr, $deliveries, $relay, $public = false, $request = false, $force = false, $is_collection_operation = false) {
+ static function process_delivery($sender, $act, $arr, $deliveries, $relay, $public = false, $request = false, $force = false) {
$result = [];
// We've validated the sender. Now make sure that the sender is the owner or author
@@ -1581,14 +1557,6 @@ class Libzot {
$DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>');
- $conversation_operation = $is_collection_operation && isset($arr['target']['attributedTo']);
-
- if (str_contains($arr['tgt_type'], 'Collection') && !$relay && !$conversation_operation) {
- $DR->update('not a collection activity');
- $result[] = $DR->get();
- continue;
- }
-
if (($act) && ($act->obj) && (!is_array($act->obj))) {
// The initial object fetch failed using the sys channel credentials.
// Try again using the delivery channel credentials.
@@ -1622,8 +1590,6 @@ class Libzot {
*
*/
-
-
if ($sender === $channel['channel_hash'] && $arr['author_xchan'] === $channel['channel_hash'] && !str_starts_with($arr['mid'], z_root())) {
$DR->update('self delivery ignored');
$result[] = $DR->get();
@@ -1864,12 +1830,6 @@ class Libzot {
}
}
- if($is_collection_operation)
- hz_syslog('col1');
- else
- hz_syslog('not col1');
-
-
// This is used to fetch allow/deny rules if either the sender
// or owner is a connection. post_is_importable() evaluates all of them
$abook = q("select * from abook where abook_channel = %d and ( abook_xchan = '%s' OR abook_xchan = '%s' )",
@@ -1878,15 +1838,11 @@ class Libzot {
dbesc($arr['author_xchan'])
);
- // Reactions such as like and dislike could have an mid with /activity/ in it.
+ // reactions such as like and dislike could have an mid with /activity/ in it.
// Check for both forms in order to prevent duplicates.
-
- // If we process an add/remove activity, look for the original activity id instead of the object id
- $sql_mid = (($is_collection_operation && $relay && $channel['channel_hash'] === $arr['owner_xchan']) ? $act->meta['original_id'] : $arr['mid']);
-
- $r = q("select * from item where mid in ('%s', '%s') and uid = %d limit 1",
- dbesc($sql_mid),
- dbesc(reverse_activity_mid($sql_mid)),
+ $r = q("select * from item where mid in ('%s','%s') and uid = %d limit 1",
+ dbesc($arr['mid']),
+ dbesc(str_replace(z_root() . '/activity/', z_root() . '/item/', $arr['mid'])),
intval($channel['channel_id'])
);
@@ -1915,29 +1871,21 @@ class Libzot {
$DR->update('update ignored');
$result[] = $DR->get();
}
-
- if ($relay && $channel['channel_hash'] === $item_result['item']['owner_xchan'] && $item_result['item']['verb'] !== 'Add' && !$is_collection_operation) {
- $approval = Activity::addToCollection($channel, $act->data, $item_result['item']['parent_mid'], $item_result['item'], deliver: false);
- }
-
}
else {
$DR->update('update ignored');
$result[] = $DR->get();
- // We need this line to ensure wall-to-wall comments and add/remove activities are relayed (by falling through to the relay bit),
+ // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit),
// and at the same time not relay any other relayable posts more than once, because to do so is very wasteful.
if (!intval($r[0]['item_origin']))
continue;
}
-
-
}
else {
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
-
// if it's a sourced post, call the post_local hooks as if it were
// posted locally so that crosspost connectors will be triggered.
$item_source = check_item_source($arr['uid'], $arr);
@@ -1966,15 +1914,10 @@ class Libzot {
}
if (post_is_importable($arr['uid'], $arr, $abook)) {
- $item_result = item_store($arr, addAndSync: false);
-
+ $item_result = item_store($arr);
if ($item_result['success']) {
$item_id = $item_result['item_id'];
- if ($relay && $channel['channel_hash'] === $item_result['item']['owner_xchan'] && $item_result['item']['verb'] !== 'Add' && !$is_collection_operation) {
- $approval = Activity::addToCollection($channel, $act->data, $item_result['item']['parent_mid'], $item_result['item'], deliver: false);
- }
-
if ($item_source && in_array($item_result['item']['obj_type'], ['Event', ACTIVITY_OBJ_EVENT])) {
event_addtocal($item_id, $channel['channel_id']);
}
@@ -2023,10 +1966,6 @@ class Libzot {
if ($relay && $item_id && $stored['item_blocked'] !== ITEM_MODERATED) {
logger('Invoking relay');
Master::Summon(['Notifier', 'relay', intval($item_id)]);
- if (!empty($approval) && $approval['item_id']) {
- Master::Summon(['Notifier', 'relay', intval($approval['item_id'])]);
- }
-
$DR->addto_update('relayed');
$result[] = $DR->get();
}
@@ -2080,7 +2019,12 @@ class Libzot {
$AS = new ActivityStreams($activity);
- if ($AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj)
+ if (!$AS->is_valid()) {
+ logger('Fetched activity rejected: ' . print_r($activity, true));
+ continue;
+ }
+
+ if ($AS->type === 'Announce' && is_array($AS->obj)
&& array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj)) {
// This is a relayed/forwarded Activity (as opposed to a shared/boosted object)
// Reparse the encapsulated Activity and use that instead
@@ -2088,33 +2032,14 @@ class Libzot {
$AS = new ActivityStreams($AS->obj);
}
- // process add/remove from collection separately, as it requires a target.
- // use the raw object, as it will not include actor expansion
if (in_array($AS->type, ['Add', 'Remove'])
&& is_array($AS->obj)
&& array_key_exists('object', $AS->obj)
&& array_key_exists('actor', $AS->obj)
&& !empty($AS->tgt)) {
- logger('relayed collection operation', LOGGER_DEBUG);
-
- $is_collection_operation = true;
-
- $original_id = $AS->id;
- $original_type = $AS->type;
-
- $raw_activity = $AS->data;
-
- $AS = new ActivityStreams($raw_activity['object'], portable_id: $env['sender']);
-
- // Store the original activity id and type for later usage
- $AS->meta['original_id'] = $original_id;
- $AS->meta['original_type'] = $original_type;
- }
-
- if (!$AS->is_valid()) {
- logger('Fetched activity rejected: ' . print_r($activity, true));
- continue;
+ logger('unsupported collection operation', LOGGER_DEBUG);
+ return;
}
// logger($AS->debug());
@@ -2305,7 +2230,7 @@ class Libzot {
}
- $x = item_store_update($item, addAndSync: false);
+ $x = item_store_update($item);
// If we're updating an event that we've saved locally, we store the item info first
// because event_addtocal will parse the body to get the 'new' event details