]> git.mxchange.org Git - friendica.git/commitdiff
Move ActivityPub endpoints to an AP class
authorMichael <heluecht@pirati.ca>
Sat, 17 Jul 2021 20:28:46 +0000 (20:28 +0000)
committerMichael <heluecht@pirati.ca>
Sat, 17 Jul 2021 20:28:46 +0000 (20:28 +0000)
12 files changed:
src/Module/ActivityPub/Followers.php [new file with mode: 0644]
src/Module/ActivityPub/Following.php [new file with mode: 0644]
src/Module/ActivityPub/Inbox.php [new file with mode: 0644]
src/Module/ActivityPub/Objects.php [new file with mode: 0644]
src/Module/ActivityPub/Outbox.php [new file with mode: 0644]
src/Module/Followers.php [deleted file]
src/Module/Following.php [deleted file]
src/Module/Inbox.php [deleted file]
src/Module/Objects.php [deleted file]
src/Module/Outbox.php [deleted file]
src/Protocol/ActivityPub/Transmitter.php
static/routes.config.php

diff --git a/src/Module/ActivityPub/Followers.php b/src/Module/ActivityPub/Followers.php
new file mode 100644 (file)
index 0000000..e1f1ccc
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\ActivityPub;
+
+use Friendica\BaseModule;
+use Friendica\Model\Contact;
+use Friendica\Model\User;
+use Friendica\Protocol\ActivityPub;
+
+/**
+ * ActivityPub Followers
+ */
+class Followers extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               if (empty($parameters['nickname'])) {
+                       throw new \Friendica\Network\HTTPException\NotFoundException();
+               }
+
+               // @TODO: Replace with parameter from router
+               $owner = User::getOwnerDataByNick($parameters['nickname']);
+               if (empty($owner)) {
+                       throw new \Friendica\Network\HTTPException\NotFoundException();
+               }
+
+               $page = $_REQUEST['page'] ?? null;
+
+               $followers = ActivityPub\Transmitter::getContacts($owner, [Contact::FOLLOWER, Contact::FRIEND], 'followers', $page);
+
+               header('Content-Type: application/activity+json');
+               echo json_encode($followers);
+               exit();
+       }
+}
diff --git a/src/Module/ActivityPub/Following.php b/src/Module/ActivityPub/Following.php
new file mode 100644 (file)
index 0000000..e9cb10b
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\ActivityPub;
+
+use Friendica\BaseModule;
+use Friendica\Model\Contact;
+use Friendica\Model\User;
+use Friendica\Protocol\ActivityPub;
+
+/**
+ * ActivityPub Following
+ */
+class Following extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               if (empty($parameters['nickname'])) {
+                       throw new \Friendica\Network\HTTPException\NotFoundException();
+               }
+
+               $owner = User::getOwnerDataByNick($parameters['nickname']);
+               if (empty($owner)) {
+                       throw new \Friendica\Network\HTTPException\NotFoundException();
+               }
+
+               $page = $_REQUEST['page'] ?? null;
+
+               $following = ActivityPub\Transmitter::getContacts($owner, [Contact::SHARING, Contact::FRIEND], 'following', $page);
+
+               header('Content-Type: application/activity+json');
+               echo json_encode($following);
+               exit();
+       }
+}
diff --git a/src/Module/ActivityPub/Inbox.php b/src/Module/ActivityPub/Inbox.php
new file mode 100644 (file)
index 0000000..36940cb
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\ActivityPub;
+
+use Friendica\BaseModule;
+use Friendica\Core\Logger;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Protocol\ActivityPub;
+use Friendica\Util\HTTPSignature;
+use Friendica\Util\Network;
+
+/**
+ * ActivityPub Inbox
+ */
+class Inbox extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               $postdata = Network::postdata();
+
+               if (empty($postdata)) {
+                       throw new \Friendica\Network\HTTPException\BadRequestException();
+               }
+
+               if (DI::config()->get('debug', 'ap_inbox_log')) {
+                       if (HTTPSignature::getSigner($postdata, $_SERVER)) {
+                               $filename = 'signed-activitypub';
+                       } else {
+                               $filename = 'failed-activitypub';
+                       }
+                       $tempfile = tempnam(get_temppath(), $filename);
+                       file_put_contents($tempfile, json_encode(['parameters' => $parameters, 'header' => $_SERVER, 'body' => $postdata], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
+                       Logger::notice('Incoming message stored', ['file' => $tempfile]);
+               }
+
+               if (!empty($parameters['nickname'])) {
+                       $user = DBA::selectFirst('user', ['uid'], ['nickname' => $parameters['nickname']]);
+                       if (!DBA::isResult($user)) {
+                               throw new \Friendica\Network\HTTPException\NotFoundException();
+                       }
+                       $uid = $user['uid'];
+               } else {
+                       $uid = 0;
+               }
+
+               ActivityPub\Receiver::processInbox($postdata, $_SERVER, $uid);
+
+               throw new \Friendica\Network\HTTPException\AcceptedException();
+       }
+}
diff --git a/src/Module/ActivityPub/Objects.php b/src/Module/ActivityPub/Objects.php
new file mode 100644 (file)
index 0000000..f597b09
--- /dev/null
@@ -0,0 +1,147 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\ActivityPub;
+
+use Friendica\BaseModule;
+use Friendica\Core\Logger;
+use Friendica\Core\System;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Contact;
+use Friendica\Model\Item;
+use Friendica\Model\Post;
+use Friendica\Network\HTTPException;
+use Friendica\Protocol\ActivityPub;
+use Friendica\Util\HTTPSignature;
+use Friendica\Util\Network;
+use Friendica\Util\Strings;
+
+/**
+ * ActivityPub Objects
+ */
+class Objects extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               if (empty($parameters['guid'])) {
+                       throw new HTTPException\BadRequestException();
+               }
+
+               if (!ActivityPub::isRequest()) {
+                       DI::baseUrl()->redirect(str_replace('objects/', 'display/', DI::args()->getQueryString()));
+               }
+
+               $itemuri = DBA::selectFirst('item-uri', ['id'], ['guid' => $parameters['guid']]);
+
+               if (DBA::isResult($itemuri)) {
+                       Logger::info('Provided GUID found.', ['guid' => $parameters['guid'], 'uri-id' => $itemuri['id']]);
+               } else {
+                       // The item URI does not always contain the GUID. This means that we have to search the URL instead
+                       $url = DI::baseUrl()->get() . '/' . DI::args()->getQueryString();
+                       $nurl = Strings::normaliseLink($url);
+                       $ssl_url = str_replace('http://', 'https://', $nurl);
+
+                       $itemuri = DBA::selectFirst('item-uri', ['guid', 'id'], ['uri' => [$url, $nurl, $ssl_url]]);
+                       if (DBA::isResult($itemuri)) {
+                               Logger::info('URL found.', ['url' => $url, 'guid' => $itemuri['guid'], 'uri-id' => $itemuri['id']]);
+                       } else {
+                               Logger::info('URL not found.', ['url' => $url]);
+                               throw new HTTPException\NotFoundException();
+                       }
+               }
+
+               $item = Post::selectFirst(['id', 'uid', 'origin', 'author-link', 'changed', 'private', 'psid', 'gravity', 'deleted', 'parent-uri-id'],
+                       ['uri-id' => $itemuri['id']], ['order' => ['origin' => true]]);
+
+               if (!DBA::isResult($item)) {
+                       throw new HTTPException\NotFoundException();
+               }
+
+               $validated = in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]);
+
+               if (!$validated) {
+                       $requester = HTTPSignature::getSigner('', $_SERVER);
+                       if (!empty($requester) && $item['origin']) {
+                               $requester_id = Contact::getIdForURL($requester, $item['uid']);
+                               if (!empty($requester_id)) {
+                                       $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $item['uid']);
+                                       if (!empty($permissionSets)) {
+                                               $psid = array_merge($permissionSets->column('id'),
+                                                       [DI::permissionSet()->getIdFromACL($item['uid'], '', '', '', '')]);
+                                               $validated = in_array($item['psid'], $psid);
+                                       }
+                               }
+                       }
+               }
+
+               if ($validated) {
+                       // Valid items are original post or posted from this node (including in the case of a forum)
+                       $validated = ($item['origin'] || (parse_url($item['author-link'], PHP_URL_HOST) == parse_url(DI::baseUrl()->get(), PHP_URL_HOST)));
+
+                       if (!$validated && $item['deleted']) {
+                               $validated = Post::exists(['origin' => true, 'uri-id' => $item['parent-uri-id']]);
+                       }
+               }
+
+               if (!$validated) {
+                       throw new HTTPException\NotFoundException();
+               }
+
+               $etag          = md5($parameters['guid'] . '-' . $item['changed']);
+               $last_modified = $item['changed'];
+               Network::checkEtagModified($etag, $last_modified);
+
+               if (empty($parameters['activity']) && ($item['gravity'] != GRAVITY_ACTIVITY)) {
+                       $activity = ActivityPub\Transmitter::createActivityFromItem($item['id'], true);
+                       if (empty($activity['type'])) {
+                               throw new HTTPException\NotFoundException();
+                       }
+
+                       $activity['type'] = $activity['type'] == 'Update' ? 'Create' : $activity['type'];
+
+                       // Only display "Create" activity objects here, no reshares or anything else
+                       if (empty($activity['object']) || ($activity['type'] != 'Create')) {
+                               throw new HTTPException\NotFoundException();
+                       }
+
+                       $data = ['@context' => ActivityPub::CONTEXT];
+                       $data = array_merge($data, $activity['object']);
+               } elseif (empty($parameters['activity']) || in_array($parameters['activity'],
+                       ['Create', 'Announce', 'Update', 'Like', 'Dislike', 'Accept', 'Reject',
+                       'TentativeAccept', 'Follow', 'Add'])) {
+                       $data = ActivityPub\Transmitter::createActivityFromItem($item['id']);
+                       if (empty($data)) {
+                               throw new HTTPException\NotFoundException();
+                       }
+                       if (!empty($parameters['activity']) && ($parameters['activity'] != 'Create')) {
+                               $data['type'] = $parameters['activity'];
+                               $data['id'] = str_replace('/Create', '/' . $parameters['activity'], $data['id']);
+                       }
+               } else {
+                       throw new HTTPException\NotFoundException();
+               }
+
+               // Relaxed CORS header for public items
+               header('Access-Control-Allow-Origin: *');
+               System::jsonExit($data, 'application/activity+json');
+       }
+}
diff --git a/src/Module/ActivityPub/Outbox.php b/src/Module/ActivityPub/Outbox.php
new file mode 100644 (file)
index 0000000..fe83896
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Module\ActivityPub;
+
+use Friendica\BaseModule;
+use Friendica\Model\User;
+use Friendica\Protocol\ActivityPub;
+use Friendica\Util\HTTPSignature;
+
+/**
+ * ActivityPub Outbox
+ */
+class Outbox extends BaseModule
+{
+       public static function rawContent(array $parameters = [])
+       {
+               if (empty($parameters['nickname'])) {
+                       throw new \Friendica\Network\HTTPException\NotFoundException();
+               }
+
+               $owner = User::getOwnerDataByNick($parameters['nickname']);
+               if (empty($owner)) {
+                       throw new \Friendica\Network\HTTPException\NotFoundException();
+               }
+
+               $page = $_REQUEST['page'] ?? null;
+
+               $requester = HTTPSignature::getSigner('', $_SERVER);
+               $outbox = ActivityPub\Transmitter::getOutbox($owner, $page, $requester);
+               header('Content-Type: application/activity+json');
+               echo json_encode($outbox);
+               exit();
+       }
+}
diff --git a/src/Module/Followers.php b/src/Module/Followers.php
deleted file mode 100644 (file)
index 932ebb4..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\User;
-use Friendica\Protocol\ActivityPub;
-
-/**
- * ActivityPub Followers
- */
-class Followers extends BaseModule
-{
-       public static function rawContent(array $parameters = [])
-       {
-               $a = DI::app();
-
-               // @TODO: Replace with parameter from router
-               if (empty($a->argv[1])) {
-                       throw new \Friendica\Network\HTTPException\NotFoundException();
-               }
-
-               // @TODO: Replace with parameter from router
-               $owner = User::getOwnerDataByNick($a->argv[1]);
-               if (empty($owner)) {
-                       throw new \Friendica\Network\HTTPException\NotFoundException();
-               }
-
-               $page = $_REQUEST['page'] ?? null;
-
-               $followers = ActivityPub\Transmitter::getContacts($owner, [Contact::FOLLOWER, Contact::FRIEND], 'followers', $page);
-
-               header('Content-Type: application/activity+json');
-               echo json_encode($followers);
-               exit();
-       }
-}
diff --git a/src/Module/Following.php b/src/Module/Following.php
deleted file mode 100644 (file)
index 3070c5b..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\User;
-use Friendica\Protocol\ActivityPub;
-
-/**
- * ActivityPub Following
- */
-class Following extends BaseModule
-{
-       public static function rawContent(array $parameters = [])
-       {
-               $a = DI::app();
-
-               // @TODO: Replace with parameter from router
-               if (empty($a->argv[1])) {
-                       throw new \Friendica\Network\HTTPException\NotFoundException();
-               }
-
-               // @TODO: Replace with parameter from router
-               $owner = User::getOwnerDataByNick($a->argv[1]);
-               if (empty($owner)) {
-                       throw new \Friendica\Network\HTTPException\NotFoundException();
-               }
-
-               $page = $_REQUEST['page'] ?? null;
-
-               $following = ActivityPub\Transmitter::getContacts($owner, [Contact::SHARING, Contact::FRIEND], 'following', $page);
-
-               header('Content-Type: application/activity+json');
-               echo json_encode($following);
-               exit();
-       }
-}
diff --git a/src/Module/Inbox.php b/src/Module/Inbox.php
deleted file mode 100644 (file)
index 048edb5..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\Core\Logger;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Protocol\ActivityPub;
-use Friendica\Util\HTTPSignature;
-use Friendica\Util\Network;
-
-/**
- * ActivityPub Inbox
- */
-class Inbox extends BaseModule
-{
-       public static function rawContent(array $parameters = [])
-       {
-               $a = DI::app();
-
-               $postdata = Network::postdata();
-
-               if (empty($postdata)) {
-                       throw new \Friendica\Network\HTTPException\BadRequestException();
-               }
-
-               if (DI::config()->get('debug', 'ap_inbox_log')) {
-                       if (HTTPSignature::getSigner($postdata, $_SERVER)) {
-                               $filename = 'signed-activitypub';
-                       } else {
-                               $filename = 'failed-activitypub';
-                       }
-                       $tempfile = tempnam(get_temppath(), $filename);
-                       file_put_contents($tempfile, json_encode(['argv' => $a->argv, 'header' => $_SERVER, 'body' => $postdata], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
-                       Logger::log('Incoming message stored under ' . $tempfile);
-               }
-
-               // @TODO: Replace with parameter from router
-               if (!empty($a->argv[1])) {
-                       $user = DBA::selectFirst('user', ['uid'], ['nickname' => $a->argv[1]]);
-                       if (!DBA::isResult($user)) {
-                               throw new \Friendica\Network\HTTPException\NotFoundException();
-                       }
-                       $uid = $user['uid'];
-               } else {
-                       $uid = 0;
-               }
-
-               ActivityPub\Receiver::processInbox($postdata, $_SERVER, $uid);
-
-               throw new \Friendica\Network\HTTPException\AcceptedException();
-       }
-}
diff --git a/src/Module/Objects.php b/src/Module/Objects.php
deleted file mode 100644 (file)
index 8f1bbf2..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\Core\Logger;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\Contact;
-use Friendica\Model\Item;
-use Friendica\Model\Post;
-use Friendica\Network\HTTPException;
-use Friendica\Protocol\ActivityPub;
-use Friendica\Util\HTTPSignature;
-use Friendica\Util\Network;
-use Friendica\Util\Strings;
-
-/**
- * ActivityPub Objects
- */
-class Objects extends BaseModule
-{
-       public static function rawContent(array $parameters = [])
-       {
-               if (empty($parameters['guid'])) {
-                       throw new HTTPException\BadRequestException();
-               }
-
-               if (!ActivityPub::isRequest()) {
-                       DI::baseUrl()->redirect(str_replace('objects/', 'display/', DI::args()->getQueryString()));
-               }
-
-               $itemuri = DBA::selectFirst('item-uri', ['id'], ['guid' => $parameters['guid']]);
-
-               if (DBA::isResult($itemuri)) {
-                       Logger::info('Provided GUID found.', ['guid' => $parameters['guid'], 'uri-id' => $itemuri['id']]);
-               } else {
-                       // The item URI does not always contain the GUID. This means that we have to search the URL instead
-                       $url = DI::baseUrl()->get() . '/' . DI::args()->getQueryString();
-                       $nurl = Strings::normaliseLink($url);
-                       $ssl_url = str_replace('http://', 'https://', $nurl);
-
-                       $itemuri = DBA::selectFirst('item-uri', ['guid', 'id'], ['uri' => [$url, $nurl, $ssl_url]]);
-                       if (DBA::isResult($itemuri)) {
-                               Logger::info('URL found.', ['url' => $url, 'guid' => $itemuri['guid'], 'uri-id' => $itemuri['id']]);
-                       } else {
-                               Logger::info('URL not found.', ['url' => $url]);
-                               throw new HTTPException\NotFoundException();
-                       }
-               }
-
-               $item = Post::selectFirst(['id', 'uid', 'origin', 'author-link', 'changed', 'private', 'psid', 'gravity', 'deleted', 'parent-uri-id'],
-                       ['uri-id' => $itemuri['id']], ['order' => ['origin' => true]]);
-
-               if (!DBA::isResult($item)) {
-                       throw new HTTPException\NotFoundException();
-               }
-
-               $validated = in_array($item['private'], [Item::PUBLIC, Item::UNLISTED]);
-
-               if (!$validated) {
-                       $requester = HTTPSignature::getSigner('', $_SERVER);
-                       if (!empty($requester) && $item['origin']) {
-                               $requester_id = Contact::getIdForURL($requester, $item['uid']);
-                               if (!empty($requester_id)) {
-                                       $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $item['uid']);
-                                       if (!empty($permissionSets)) {
-                                               $psid = array_merge($permissionSets->column('id'),
-                                                       [DI::permissionSet()->getIdFromACL($item['uid'], '', '', '', '')]);
-                                               $validated = in_array($item['psid'], $psid);
-                                       }
-                               }
-                       }
-               }
-
-               if ($validated) {
-                       // Valid items are original post or posted from this node (including in the case of a forum)
-                       $validated = ($item['origin'] || (parse_url($item['author-link'], PHP_URL_HOST) == parse_url(DI::baseUrl()->get(), PHP_URL_HOST)));
-
-                       if (!$validated && $item['deleted']) {
-                               $validated = Post::exists(['origin' => true, 'uri-id' => $item['parent-uri-id']]);
-                       }
-               }
-
-               if (!$validated) {
-                       throw new HTTPException\NotFoundException();
-               }
-
-               $etag          = md5($parameters['guid'] . '-' . $item['changed']);
-               $last_modified = $item['changed'];
-               Network::checkEtagModified($etag, $last_modified);
-
-               if (empty($parameters['activity']) && ($item['gravity'] != GRAVITY_ACTIVITY)) {
-                       $activity = ActivityPub\Transmitter::createActivityFromItem($item['id'], true);
-                       if (empty($activity['type'])) {
-                               throw new HTTPException\NotFoundException();
-                       }
-
-                       $activity['type'] = $activity['type'] == 'Update' ? 'Create' : $activity['type'];
-
-                       // Only display "Create" activity objects here, no reshares or anything else
-                       if (empty($activity['object']) || ($activity['type'] != 'Create')) {
-                               throw new HTTPException\NotFoundException();
-                       }
-
-                       $data = ['@context' => ActivityPub::CONTEXT];
-                       $data = array_merge($data, $activity['object']);
-               } elseif (empty($parameters['activity']) || in_array($parameters['activity'],
-                       ['Create', 'Announce', 'Update', 'Like', 'Dislike', 'Accept', 'Reject',
-                       'TentativeAccept', 'Follow', 'Add'])) {
-                       $data = ActivityPub\Transmitter::createActivityFromItem($item['id']);
-                       if (empty($data)) {
-                               throw new HTTPException\NotFoundException();
-                       }
-                       if (!empty($parameters['activity']) && ($parameters['activity'] != 'Create')) {
-                               $data['type'] = $parameters['activity'];
-                               $data['id'] = str_replace('/Create', '/' . $parameters['activity'], $data['id']);
-                       }
-               } else {
-                       throw new HTTPException\NotFoundException();
-               }
-
-               // Relaxed CORS header for public items
-               header('Access-Control-Allow-Origin: *');
-               System::jsonExit($data, 'application/activity+json');
-       }
-}
diff --git a/src/Module/Outbox.php b/src/Module/Outbox.php
deleted file mode 100644 (file)
index 6e095b7..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Module;
-
-use Friendica\BaseModule;
-use Friendica\DI;
-use Friendica\Model\User;
-use Friendica\Protocol\ActivityPub;
-use Friendica\Util\HTTPSignature;
-
-/**
- * ActivityPub Outbox
- */
-class Outbox extends BaseModule
-{
-       public static function rawContent(array $parameters = [])
-       {
-               $a = DI::app();
-
-               // @TODO: Replace with parameter from router
-               if (empty($a->argv[1])) {
-                       throw new \Friendica\Network\HTTPException\NotFoundException();
-               }
-
-               $owner = User::getOwnerDataByNick($a->argv[1]);
-               if (empty($owner)) {
-                       throw new \Friendica\Network\HTTPException\NotFoundException();
-               }
-
-               $page = $_REQUEST['page'] ?? null;
-
-               $requester = HTTPSignature::getSigner('', $_SERVER);
-               $outbox = ActivityPub\Transmitter::getOutbox($owner, $page, $requester);
-               header('Content-Type: application/activity+json');
-               echo json_encode($outbox);
-               exit();
-       }
-}
index a65f85542296cc79a047f33db4b92fcdfde58946..a65ebc8cda8ab1ff202860c9b6414b3630336972 100644 (file)
@@ -235,26 +235,28 @@ class Transmitter
         */
        public static function getOutbox($owner, $page = null, $requester = '')
        {
-               $public_contact = Contact::getIdForURL($owner['url']);
-               $condition = ['uid' => 0, 'contact-id' => $public_contact,
-                       'private' => [Item::PUBLIC, Item::UNLISTED]];
+               $condition = ['private' => [Item::PUBLIC, Item::UNLISTED]];
 
                if (!empty($requester)) {
                        $requester_id = Contact::getIdForURL($requester, $owner['uid']);
                        if (!empty($requester_id)) {
                                $permissionSets = DI::permissionSet()->selectByContactId($requester_id, $owner['uid']);
                                if (!empty($permissionSets)) {
-                                       $condition = ['uid' => $owner['uid'], 'origin' => true,
-                                               'psid' => array_merge($permissionSets->column('id'),
+                                       $condition = ['psid' => array_merge($permissionSets->column('id'),
                                                        [DI::permissionSet()->getIdFromACL($owner['uid'], '', '', '', '')])];
                                }
                        }
                }
 
                $condition = array_merge($condition,
-                       ['author-id' => $public_contact,
-                       'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT],
-                       'deleted' => false, 'visible' => true]);
+                       ['uid'           => $owner['uid'],
+                       'author-id'      => Contact::getIdForURL($owner['url'], 0, false),
+                       'gravity'        => [GRAVITY_PARENT, GRAVITY_COMMENT],
+                       'network'        => Protocol::FEDERATED,
+                       'parent-network' => Protocol::FEDERATED,
+                       'origin'         => true,
+                       'deleted'        => false,
+                       'visible'        => true]);
 
                $count = Post::count($condition);
 
@@ -269,8 +271,6 @@ class Transmitter
                        $data['type'] = 'OrderedCollectionPage';
                        $list = [];
 
-                       $condition['parent-network'] = Protocol::NATIVE_SUPPORT;
-
                        $items = Post::select(['id'], $condition, ['limit' => [($page - 1) * 20, 20], 'order' => ['created' => true]]);
                        while ($item = Post::fetch($items)) {
                                $activity = self::createActivityFromItem($item['id'], true);
index dfa7dad187d7c9a80e42f285a6af48da691268ab..64a4346656d5b50593ac1e5bca8b549bfd9e97d1 100644 (file)
@@ -266,14 +266,14 @@ return [
                '/status_message/{guid}' => [Module\Diaspora\Fetch::class, [R::GET]],
                '/reshare/{guid}'        => [Module\Diaspora\Fetch::class, [R::GET]],
        ],
-       '/filed'             => [Module\Search\Filed::class,    [R::GET]],
-       '/filer[/{id:\d+}]'  => [Module\Filer\SaveTag::class,   [R::GET]],
-       '/filerm/{id:\d+}'   => [Module\Filer\RemoveTag::class, [R::GET]],
-       '/follow_confirm'    => [Module\FollowConfirm::class,   [R::GET, R::POST]],
-       '/followers/{owner}' => [Module\Followers::class,       [R::GET]],
-       '/following/{owner}' => [Module\Following::class,       [R::GET]],
-       '/friendica[/json]'  => [Module\Friendica::class,       [R::GET]],
-       '/friendica/inbox'   => [Module\Inbox::class,           [R::GET, R::POST]],
+       '/filed'                => [Module\Search\Filed::class,          [R::GET]],
+       '/filer[/{id:\d+}]'     => [Module\Filer\SaveTag::class,         [R::GET]],
+       '/filerm/{id:\d+}'      => [Module\Filer\RemoveTag::class,       [R::GET]],
+       '/follow_confirm'       => [Module\FollowConfirm::class,         [R::GET, R::POST]],
+       '/followers/{nickname}' => [Module\ActivityPub\Followers::class, [R::GET]],
+       '/following/{nickname}' => [Module\ActivityPub\Following::class, [R::GET]],
+       '/friendica[/json]'     => [Module\Friendica::class,             [R::GET]],
+       '/friendica/inbox'      => [Module\ActivityPub\Inbox::class,     [R::GET, R::POST]],
 
        '/fsuggest/{contact:\d+}' => [Module\FriendSuggest::class,  [R::GET, R::POST]],
 
@@ -288,12 +288,12 @@ return [
                '/{group:\d+}/add/{contact:\d+}'    => [Module\Group::class, [R::GET, R::POST]],
                '/{group:\d+}/remove/{contact:\d+}' => [Module\Group::class, [R::GET, R::POST]],
        ],
-       '/hashtag'                    => [Module\Hashtag::class,   [R::GET]],
-       '/help[/{doc:.+}]'            => [Module\Help::class,      [R::GET]],
-       '/home'                       => [Module\Home::class,      [R::GET]],
-       '/hcard/{profile}[/{action}]' => [Module\HoverCard::class, [R::GET]],
-       '/inbox[/{nickname}]'         => [Module\Inbox::class,     [R::GET, R::POST]],
-       '/invite'                     => [Module\Invite::class,    [R::GET, R::POST]],
+       '/hashtag'                    => [Module\Hashtag::class,           [R::GET]],
+       '/help[/{doc:.+}]'            => [Module\Help::class,              [R::GET]],
+       '/home'                       => [Module\Home::class,              [R::GET]],
+       '/hcard/{profile}[/{action}]' => [Module\HoverCard::class,         [R::GET]],
+       '/inbox[/{nickname}]'         => [Module\ActivityPub\Inbox::class, [R::GET, R::POST]],
+       '/invite'                     => [Module\Invite::class,            [R::GET, R::POST]],
 
        '/install'         => [
                '[/]'                    => [Module\Install::class, [R::GET, R::POST]],
@@ -355,10 +355,10 @@ return [
                '/h2b'    => [Module\Oembed::class, [R::GET]],
                '/{hash}' => [Module\Oembed::class, [R::GET]],
        ],
-       '/outbox/{owner}' => [Module\Outbox::class,          [R::GET]],
-       '/owa'            => [Module\Owa::class,             [R::GET]],
-       '/openid'         => [Module\Security\OpenID::class, [R::GET]],
-       '/opensearch'     => [Module\OpenSearch::class,      [R::GET]],
+       '/outbox/{nickname}' => [Module\ActivityPub\Outbox::class, [R::GET]],
+       '/owa'               => [Module\Owa::class,                [R::GET]],
+       '/openid'            => [Module\Security\OpenID::class,    [R::GET]],
+       '/opensearch'        => [Module\OpenSearch::class,         [R::GET]],
 
        '/parseurl'                           => [Module\ParseUrl::class,          [R::GET]],
        '/permission/tooltip/{type}/{id:\d+}' => [Module\PermissionTooltip::class, [R::GET]],