From 244c8edfca6cc7ab48c337bda37ab70bfe819413 Mon Sep 17 00:00:00 2001 From: Mario Date: Mon, 5 Oct 2020 11:47:22 +0000 Subject: =?UTF-8?q?=C3=83rework=20undo/delete=20to=20use=20inline=20object?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zotlabs/Lib/Activity.php | 46 +++++++++++++++++++++++++++++++++++++++------- Zotlabs/Lib/Libzot.php | 45 +++++++++++++++++---------------------------- 2 files changed, 56 insertions(+), 35 deletions(-) (limited to 'Zotlabs/Lib') diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 631606c46..9a31304d1 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -319,6 +319,26 @@ class Activity { $ret = Activity::encode_object($i['obj']); } + if (intval($i['item_deleted'])) { + $ret['type'] = 'Tombstone'; + $ret['formerType'] = $objtype; + $ret['id'] = $i['mid']; + if($i['id'] != $i['parent']) + $ret['inReplyTo'] = $i['thr_parent']; + + $ret['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + return $ret; + } + + if ($i['obj']) { + if (is_array($i['obj'])) { + $ret = $i['obj']; + } + else { + $ret = json_decode($i['obj'],true); + } + } + $ret['type'] = $objtype; if ($objtype === 'Question') { @@ -632,7 +652,7 @@ class Activity { - static function encode_activity($i) { + static function encode_activity($i, $dismiss_deleted = false) { $ret = []; $reply = false; @@ -646,10 +666,13 @@ class Activity { $ret['type'] = self::activity_mapper($i['verb']); $fragment = ''; - if (intval($i['item_deleted'])) { + if (intval($i['item_deleted']) && !$dismiss_deleted) { + $is_response = false; + if (in_array($ret['type'], [ 'Like', 'Dislike', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject' ])) { $ret['type'] = 'Undo'; $fragment = 'undo'; + $is_response = true; } else { $ret['type'] = 'Delete'; @@ -663,14 +686,23 @@ class Activity { else return []; - $ret['object'] = str_replace('/item/','/activity/',$i['mid']); +// $ret['object'] = str_replace('/item/','/activity/',$i['mid']); - if($i['id'] != $i['parent']) { - $ret['inReplyTo'] = $i['thr_parent']; + $obj = (($is_response) ? self::encode_activity($i,true) : self::encode_item($i,true)); + if ($obj) { + // do not leak private content in deletes + unset($obj['object']); + unset($obj['cc']); + $obj['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + $ret['object'] = $obj; } + else + return []; $ret['to'] = [ ACTIVITY_PUBLIC_INBOX ]; + return $ret; + } if($ret['type'] === 'emojiReaction') { @@ -2020,12 +2052,12 @@ class Activity { $s['expires'] = datetime_convert('UTC','UTC',$act->obj['expires']); } - if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'emojiReaction', 'Undo', 'Delete' ])) { + if(in_array($act->type, [ 'Like', 'Dislike', 'Flag', 'Block', 'Announce', 'Accept', 'Reject', 'TentativeAccept', 'emojiReaction' ])) { $response_activity = true; $s['mid'] = $act->id; - $s['parent_mid'] = $act->parent_id; //$act->obj['id']; + // $s['parent_mid'] = $act->obj['id']; $s['uuid'] = $act->data['diaspora:guid']; // over-ride the object timestamp with the activity diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index ab322ca86..f16f5258a 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -1202,10 +1202,6 @@ class Libzot { if(in_array($env['type'],['activity','response'])) { - $arr = Activity::decode_note($AS); - - //logger($AS->debug()); - $r = q("select hubloc_hash, hubloc_network from hubloc where hubloc_id_url = '%s' ", dbesc($AS->actor['id']) ); @@ -1727,7 +1723,7 @@ class Libzot { $arr['aid'] = $channel['channel_account_id']; $arr['uid'] = $channel['channel_id']; - $item_id = self::delete_imported_item($sender,$arr,$channel['channel_id'],$relay); + $item_id = self::delete_imported_item($sender,$act,$arr,$channel['channel_id'],$relay); $DR->update(($item_id) ? 'deleted' : 'delete_failed'); $result[] = $DR->get(); @@ -2110,7 +2106,7 @@ class Libzot { * @return boolean|int post_id */ - static function delete_imported_item($sender, $item, $uid, $relay) { + static function delete_imported_item($sender, $act, $item, $uid, $relay) { logger('invoked', LOGGER_DEBUG); @@ -2118,46 +2114,39 @@ class Libzot { $item_found = false; $post_id = 0; - $m = parse_url($item['mid']); - unset($m['fragment']); - $normalised = unparse_url($m); + if ($item['verb'] === 'Tombstone') { + // The id of the deleted thing is the item mid (activity id) + $mid = $item['mid']; + } + else { + // The id is the object id if the type is Undo or Delete + $mid = ((is_array($act->obj)) ? $act->obj['id'] : $act->obj); + } - // reactions such as like and dislike could have an mid with /activity/ in it. - // Check for both forms in order to prevent duplicates. + // we may have stored either the object id or the activity id if it was a response activity (like, dislike, etc.) $r = q("select * from item where ( author_xchan = '%s' or owner_xchan = '%s' or source_xchan = '%s' ) and mid IN ('%s', '%s') and uid = %d limit 1", dbesc($sender), dbesc($sender), dbesc($sender), - dbesc($normalised), - dbesc(str_replace('/activity/', '/item/', $normalised)), + dbesc($mid), + dbesc(str_replace('/activity/','/item/',$mid)), intval($uid) ); if($r) { $stored = $r[0]; - if($stored['author_xchan'] === $sender || $stored['owner_xchan'] === $sender || $stored['source_xchan'] === $sender) - $ownership_valid = true; + // we proved ownership in the sql query + $ownership_valid = true; $post_id = $stored['id']; $item_found = true; } else { - - // perhaps the item is still in transit and the delete notification got here before the actual item did. Store it with the deleted flag set. - // item_store() won't try to deliver any notifications or start delivery chains if this flag is set. - // This means we won't end up with potentially even more delivery threads trying to push this delete notification. - // But this will ensure that if the (undeleted) original post comes in at a later date, we'll reject it because it will have an older timestamp. - - logger('delete received for non-existent item - storing item data.'); - - if($item['author_xchan'] === $sender || $item['owner_xchan'] === $sender || $item['source_xchan'] === $sender) { - $ownership_valid = true; - $item_result = item_store($item); - $post_id = $item_result['item_id']; - } + // this will fail with an ownership issue, so explain the real reason + logger('delete received for non-existent item or not owned by sender - ignoring.'); } if($ownership_valid === false) { -- cgit v1.2.3