From 72c6d3e7baafd259ac00bcd2ff2da31c17e062f6 Mon Sep 17 00:00:00 2001 From: Mario Date: Fri, 2 Oct 2020 12:09:23 +0000 Subject: item/activity fetching --- Zotlabs/Module/Activity.php | 96 +++++++++++++++++++++++++++++++++++++++++- Zotlabs/Module/Item.php | 100 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 2 deletions(-) (limited to 'Zotlabs/Module') diff --git a/Zotlabs/Module/Activity.php b/Zotlabs/Module/Activity.php index 9971ee60f..8f4593db3 100644 --- a/Zotlabs/Module/Activity.php +++ b/Zotlabs/Module/Activity.php @@ -19,9 +19,7 @@ class Activity extends Controller { function init() { if (Libzot::is_zot_request()) { - $item_id = argv(1); - if (! $item_id) http_status_exit(404, 'Not found'); @@ -170,6 +168,100 @@ class Activity extends Controller { } + if(ActivityStreams::is_as_request()) { + + $item_id = argv(1); + + if (! $item_id) { + return; + } + + $ob_authorise = false; + $item_uid = 0; + + $bear = ZlibActivity::token_from_request(); + if ($bear) { + logger('bear: ' . $bear, LOGGER_DEBUG); + $t = q("select item.uid, iconfig.v from iconfig left join item on iid = item.id where cat = 'ocap' and item.uuid = '%s'", + dbesc($item_id) + ); + if ($t) { + foreach ($t as $token) { + if ($token['v'] === $bear) { + $ob_authorize = true; + $item_uid = $token['uid']; + break; + } + } + } + } + + $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 "; + + $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); + } + + // if passed an owner_id of 0 to item_permissions_sql(), we force "guest access" or observer checking + // Give ocap tokens priority + + if ($ob_authorize) { + $sql_extra = " and item.uid = " . intval($token['uid']) . " "; + } + else { + $sql_extra = item_permissions_sql(0); + } + $r = q("select * from item where uuid = '%s' $item_normal $sql_extra limit 1", + dbesc($item_id) + ); + + if (! $r) { + $r = q("select * from item where uuid = '%s' $item_normal limit 1", + dbesc($item_id) + ); + if($r) { + http_status_exit(403, 'Forbidden'); + } + http_status_exit(404, 'Not found'); + } + + xchan_query($r,true); + $items = fetch_post_tags($r,false); + + $channel = channelx_by_n($items[0]['uid']); + + $x = array_merge( ['@context' => [ + ACTIVITYSTREAMS_JSONLD_REV, + 'https://w3id.org/security/v1', + z_root() . ZOT_APSCHEMA_REV + ]], ZlibActivity::encode_activity($items[0],true)); + + + $headers = []; + $headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ; + $x['signature'] = LDSignatures::sign($x,$channel); + $ret = json_encode($x, JSON_UNESCAPED_SLASHES); + $headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); + $headers['Digest'] = HTTPSig::generate_digest_header($ret); + $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + + $h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel)); + HTTPSig::set_headers($h); + echo $ret; + killme(); + + } + goaway(z_root() . '/item/' . argv(1)); } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index d8c837522..922a2ef06 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -157,6 +157,106 @@ class Item extends Controller { } + if(ActivityStreams::is_as_request()) { + + $item_id = argv(1); + if(! $item_id) + http_status_exit(404, 'Not found'); + + $portable_id = EMPTY_STR; + + $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 "; + + $i = null; + + // do we have the item (at all)? + // add preferential bias to item owners (item_wall = 1) + + $r = q("select * from item where mid = '%s' or uuid = '%s' $item_normal order by item_wall desc limit 1", + dbesc(z_root() . '/item/' . $item_id), + 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']) + ); + } + + 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],true); + + if(! $i) + http_status_exit(404, 'Not found'); + + $x = array_merge(['@context' => [ + ACTIVITYSTREAMS_JSONLD_REV, + 'https://w3id.org/security/v1', + z_root() . ZOT_APSCHEMA_REV + ]], $i); + + $headers = []; + $headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' ; + $x['signature'] = LDSignatures::sign($x,$chan); + $ret = json_encode($x, JSON_UNESCAPED_SLASHES); + $headers['Date'] = datetime_convert('UTC','UTC', 'now', 'D, d M Y H:i:s \\G\\M\\T'); + $headers['Digest'] = HTTPSig::generate_digest_header($ret); + $headers['(request-target)'] = strtolower($_SERVER['REQUEST_METHOD']) . ' ' . $_SERVER['REQUEST_URI']; + $h = HTTPSig::create_sig($headers,$chan['channel_prvkey'],channel_url($chan)); + HTTPSig::set_headers($h); + echo $ret; + killme(); + + } + + if(argc() > 1 && argv(1) !== 'drop') { $x = q("select uid, item_wall, llink, mid from item where mid = '%s' or mid = '%s' ", dbesc(z_root() . '/item/' . argv(1)), -- cgit v1.2.3