diff options
Diffstat (limited to 'Zotlabs/Module')
-rw-r--r-- | Zotlabs/Module/Item.php | 452 |
1 files changed, 228 insertions, 224 deletions
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index bff092ec4..9964192fe 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -40,240 +40,24 @@ require_once('include/conversation.php'); */ class Item extends Controller { + private string $item_id; function init() { - if (Libzot::is_zot_request()) { - - $item_id = argv(1); - - if (!$item_id) - http_status_exit(404, 'Not found'); - - $portable_id = EMPTY_STR; - - $item_normal_extra = sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ", - dbesc(ACTIVITY_FOLLOW), - dbesc(ACTIVITY_UNFOLLOW) - ); - - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; - - $i = null; - - // do we have the item (at all)? - - $r = q("select parent_mid from item where uuid = '%s' $item_normal limit 1", - dbesc($item_id) - ); - - if (!$r) { - http_status_exit(404, 'Not found'); - } - - // process an authenticated fetch - - $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); - if ($sigdata['portable_id'] && $sigdata['header_valid']) { - $portable_id = $sigdata['portable_id']; - if (!check_channelallowed($portable_id)) { - http_status_exit(403, 'Permission denied'); - } - if (!check_siteallowed($sigdata['signer'])) { - http_status_exit(403, 'Permission denied'); - } - observer_auth($portable_id); - - $i = q("select id as item_id, uid from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1", - dbesc($r[0]['parent_mid']), - dbesc($portable_id) - ); - } - elseif (Config::get('system', 'require_authenticated_fetch', false)) { - http_status_exit(403, 'Permission denied'); - } - - // if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access - // with a bias towards those items owned by channels on this site (item_wall = 1) - - $sql_extra = item_permissions_sql(0); - - if (!$i) { - $i = q("select id as item_id, uid, item_private from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", - dbesc($r[0]['parent_mid']) - ); - } - - if (!$i) { - http_status_exit(403, 'Forbidden'); - } - - $chan = channelx_by_n($i[0]['uid']); - - if (!$chan) { - http_status_exit(404, 'Not found'); - } - - if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) { - http_status_exit(403, 'Forbidden'); - } - - $parents_str = ids_to_querystr($i, 'item_id'); + $this->item_id = argv(1); - // We won't need to check for privacy mismatches if the verified observer is also owner - $parent_item_private = ((isset($i[0]['item_private'])) ? " and item_private = " . intval($i[0]['item_private']) . " " : ''); - - $total = q("SELECT count(*) AS count FROM item WHERE parent = %d $parent_item_private $item_normal ", - intval($parents_str) - ); - - App::set_pager_total($total[0]['count']); - App::set_pager_itemspage(30); - - if (App::$pager['total'] > App::$pager['itemspage']) { - // let mod conversation handle this request - App::$query_string = str_replace('item', 'conversation', App::$query_string); - $i = Activity::paged_collection_init(App::$pager['total'], App::$query_string); - as_return_and_die($i ,$chan); - } - else { - $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent = %d $parent_item_private $item_normal ORDER BY item.id", - intval($parents_str) - ); - - xchan_query($items, true); - $items = fetch_post_tags($items, true); - - $i = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', App::$pager['total']); - } - - if ($portable_id && (!intval($items[0]['item_private']))) { - $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", - intval($items[0]['uid']), - dbesc($portable_id) - ); - if (!$c) { - ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); - } - } + if (!$this->item_id) { + http_status_exit(404, 'Not found'); + } - as_return_and_die($i ,$chan); + if (Libzot::is_zot_request()) { + $this->init_zot_request(); } if (ActivityStreams::is_as_request()) { - - $item_id = argv(1); - if (!$item_id) - http_status_exit(404, 'Not found'); - - $portable_id = EMPTY_STR; - - $item_normal_extra = sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ", - dbesc(ACTIVITY_FOLLOW), - dbesc(ACTIVITY_UNFOLLOW) - ); - - $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; - - $i = null; - - // do we have the item (at all)? - // add preferential bias to item owners (item_wall = 1) - - $r = q("select * from item where uuid = '%s' $item_normal order by item_wall desc limit 1", - dbesc($item_id) - ); - - if (!$r) { - http_status_exit(404, 'Not found'); - } - - // process an authenticated fetch - - $sigdata = HTTPSig::verify(EMPTY_STR); - if ($sigdata['portable_id'] && $sigdata['header_valid']) { - $portable_id = $sigdata['portable_id']; - if (!check_channelallowed($portable_id)) { - http_status_exit(403, 'Permission denied'); - } - if (!check_siteallowed($sigdata['signer'])) { - http_status_exit(403, 'Permission denied'); - } - observer_auth($portable_id); - - $i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ", - dbesc($r[0]['parent_mid']), - dbesc($portable_id) - ); - } - elseif (Config::get('system', 'require_authenticated_fetch', false)) { - http_status_exit(403, 'Permission denied'); - } - - // if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access - // with a bias towards those items owned by channels on this site (item_wall = 1) - - $sql_extra = item_permissions_sql(0); - - if (!$i) { - $i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", - dbesc($r[0]['parent_mid']) - ); - } - - $bear = Activity::token_from_request(); - if ($bear) { - logger('bear: ' . $bear, LOGGER_DEBUG); - if (!$i) { - $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", - dbesc($bear) - ); - if ($t) { - $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", - dbesc($item_id), - intval($t[0]['iid']) - ); - } - } - } - - if (!$i) { - http_status_exit(403, 'Forbidden'); - } - - // If we get to this point we have determined we can access the original in $r (fetched much further above), so use it. - - xchan_query($r, true); - $items = fetch_post_tags($r, false); - - $chan = channelx_by_n($items[0]['uid']); - - if (!$chan) - http_status_exit(404, 'Not found'); - - if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) - http_status_exit(403, 'Forbidden'); - - $i = Activity::encode_item($items[0]); - - if (!$i) - http_status_exit(404, 'Not found'); - - if ($portable_id && (!intval($items[0]['item_private']))) { - $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", - intval($items[0]['uid']), - dbesc($portable_id) - ); - if (!$c) { - ThreadListener::store(z_root() . '/item/' . $item_id, $portable_id); - } - } - - as_return_and_die($i ,$chan); - + $this->init_as_request(); } - if (argc() > 1 && argv(1) !== 'drop') { $x = q("select uid, item_wall, llink, mid, uuid from item where mid = '%s' or mid = '%s' or uuid = '%s'", dbesc(z_root() . '/item/' . argv(1)), @@ -1714,5 +1498,225 @@ class Item extends Controller { } } + private function init_zot_request() { + + $portable_id = EMPTY_STR; + + $item_normal_extra = sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ", + dbesc(ACTIVITY_FOLLOW), + dbesc(ACTIVITY_UNFOLLOW) + ); + + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + + $i = null; + + // do we have the item (at all)? + + $r = q("select parent_mid from item where uuid = '%s' $item_normal limit 1", + dbesc($this->item_id) + ); + + if (!$r) { + http_status_exit(404, 'Not found'); + } + + // process an authenticated fetch + + $sigdata = HTTPSig::verify(($_SERVER['REQUEST_METHOD'] === 'POST') ? file_get_contents('php://input') : EMPTY_STR); + if ($sigdata['portable_id'] && $sigdata['header_valid']) { + $portable_id = $sigdata['portable_id']; + if (!check_channelallowed($portable_id)) { + http_status_exit(403, 'Permission denied'); + } + if (!check_siteallowed($sigdata['signer'])) { + http_status_exit(403, 'Permission denied'); + } + observer_auth($portable_id); + + $i = q("select id as item_id, uid from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1", + dbesc($r[0]['parent_mid']), + dbesc($portable_id) + ); + } + elseif (Config::get('system', 'require_authenticated_fetch', false)) { + http_status_exit(403, 'Permission denied'); + } + + // if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access + // with a bias towards those items owned by channels on this site (item_wall = 1) + + $sql_extra = item_permissions_sql(0); + + if (!$i) { + $i = q("select id as item_id, uid, item_private from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", + dbesc($r[0]['parent_mid']) + ); + } + + if (!$i) { + http_status_exit(403, 'Forbidden'); + } + + $chan = channelx_by_n($i[0]['uid']); + + if (!$chan) { + http_status_exit(404, 'Not found'); + } + + if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) { + http_status_exit(403, 'Forbidden'); + } + + $parents_str = ids_to_querystr($i, 'item_id'); + + // We won't need to check for privacy mismatches if the verified observer is also owner + $parent_item_private = ((isset($i[0]['item_private'])) ? " and item_private = " . intval($i[0]['item_private']) . " " : ''); + + $total = q("SELECT count(*) AS count FROM item WHERE parent = %d $parent_item_private $item_normal ", + intval($parents_str) + ); + + App::set_pager_total($total[0]['count']); + App::set_pager_itemspage(30); + + if (App::$pager['total'] > App::$pager['itemspage']) { + // let mod conversation handle this request + App::$query_string = str_replace('item', 'conversation', App::$query_string); + $i = Activity::paged_collection_init(App::$pager['total'], App::$query_string); + as_return_and_die($i ,$chan); + } + else { + $items = q("SELECT item.*, item.id AS item_id FROM item WHERE item.parent = %d $parent_item_private $item_normal ORDER BY item.id", + intval($parents_str) + ); + + xchan_query($items, true); + $items = fetch_post_tags($items, true); + + $i = Activity::encode_item_collection($items, App::$query_string, 'OrderedCollection', App::$pager['total']); + } + + if ($portable_id && (!intval($items[0]['item_private']))) { + $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($items[0]['uid']), + dbesc($portable_id) + ); + if (!$c) { + ThreadListener::store(z_root() . '/item/' . $this->item_id, $portable_id); + } + } + + as_return_and_die($i ,$chan); + } + + private function init_as_request() { + + $portable_id = EMPTY_STR; + + $item_normal_extra = sprintf(" and not verb in ('Follow', 'Ignore', '%s', '%s') ", + dbesc(ACTIVITY_FOLLOW), + dbesc(ACTIVITY_UNFOLLOW) + ); + + $item_normal = " and item.item_hidden = 0 and item.item_type = 0 and item.item_unpublished = 0 and item.item_delayed = 0 and item.item_blocked = 0 $item_normal_extra "; + + $i = null; + + // do we have the item (at all)? + // add preferential bias to item owners (item_wall = 1) + + $r = q("select * from item where uuid = '%s' $item_normal order by item_wall desc limit 1", + dbesc($this->item_id) + ); + + if (!$r) { + http_status_exit(404, 'Not found'); + } + + // process an authenticated fetch + + $sigdata = HTTPSig::verify(EMPTY_STR); + if ($sigdata['portable_id'] && $sigdata['header_valid']) { + $portable_id = $sigdata['portable_id']; + if (!check_channelallowed($portable_id)) { + http_status_exit(403, 'Permission denied'); + } + if (!check_siteallowed($sigdata['signer'])) { + http_status_exit(403, 'Permission denied'); + } + observer_auth($portable_id); + + $i = q("select id as item_id from item where mid = '%s' $item_normal and owner_xchan = '%s' limit 1 ", + dbesc($r[0]['parent_mid']), + dbesc($portable_id) + ); + } + elseif (Config::get('system', 'require_authenticated_fetch', false)) { + http_status_exit(403, 'Permission denied'); + } + + // if we don't have a parent id belonging to the signer see if we can obtain one as a visitor that we have permission to access + // with a bias towards those items owned by channels on this site (item_wall = 1) + + $sql_extra = item_permissions_sql(0); + + if (!$i) { + $i = q("select id as item_id from item where mid = '%s' $item_normal $sql_extra order by item_wall desc limit 1", + dbesc($r[0]['parent_mid']) + ); + } + + $bear = Activity::token_from_request(); + if ($bear) { + logger('bear: ' . $bear, LOGGER_DEBUG); + if (!$i) { + $t = q("select * from iconfig where cat = 'ocap' and k = 'relay' and v = '%s'", + dbesc($bear) + ); + if ($t) { + $i = q("select id as item_id from item where uuid = '%s' and id = %d $item_normal limit 1", + dbesc($this->item_id), + intval($t[0]['iid']) + ); + } + } + } + + if (!$i) { + http_status_exit(403, 'Forbidden'); + } + + // If we get to this point we have determined we can access the original in $r (fetched much further above), so use it. + + xchan_query($r, true); + $items = fetch_post_tags($r, false); + + $chan = channelx_by_n($items[0]['uid']); + + if (!$chan) + http_status_exit(404, 'Not found'); + + if (!perm_is_allowed($chan['channel_id'], get_observer_hash(), 'view_stream')) + http_status_exit(403, 'Forbidden'); + + $i = Activity::encode_item($items[0]); + + if (!$i) + http_status_exit(404, 'Not found'); + + if ($portable_id && (!intval($items[0]['item_private']))) { + $c = q("select abook_id from abook where abook_channel = %d and abook_xchan = '%s'", + intval($items[0]['uid']), + dbesc($portable_id) + ); + if (!$c) { + ThreadListener::store(z_root() . '/item/' . $this->item_id, $portable_id); + } + } + + as_return_and_die($i ,$chan); + + } } |