Version 2021.09 (unreleased)
Friendica Core
Simplified the proxy mechanism. The proxy cache directory (/proxy) can now be removed [annando]
+ DFRN is now always handled with the Diaspora transport layer. The legacy DFRN transport layer is removed [annando]
Version 2021.07 (2021-07-04)
Friendica Core
+++ /dev/null
-<?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/>.
- *
- * The dfrn notify endpoint
- *
- * @see PDF with dfrn specs: https://github.com/friendica/friendica/blob/stable/spec/dfrn2.pdf
- */
-
-use Friendica\App;
-use Friendica\Core\Logger;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Model\Contact;
-use Friendica\Model\Conversation;
-use Friendica\Network\HTTPException;
-use Friendica\Protocol\DFRN;
-use Friendica\Protocol\Diaspora;
-use Friendica\Util\Network;
-
-function dfrn_notify_post(App $a) {
- $postdata = Network::postdata();
-
- if (empty($_POST) || !empty($postdata)) {
- $data = json_decode($postdata);
- if (is_object($data)) {
- $nick = $a->argv[1] ?? '';
-
- $user = DBA::selectFirst('user', [], ['nickname' => $nick, 'account_expired' => false, 'account_removed' => false]);
- if (!DBA::isResult($user)) {
- throw new \Friendica\Network\HTTPException\InternalServerErrorException();
- }
- dfrn_dispatch_private($user, $postdata);
- } elseif (!dfrn_dispatch_public($postdata)) {
- require_once 'mod/salmon.php';
- salmon_post($a, $postdata);
- }
- }
- throw new HTTPException\BadRequestException();
-}
-
-function dfrn_dispatch_public($postdata)
-{
- $msg = Diaspora::decodeRaw($postdata, '', true);
- if (!$msg) {
- // We have to fail silently to be able to hand it over to the salmon parser
- return false;
- }
-
- // Fetch the corresponding public contact
- $contact_id = Contact::getIdForURL($msg['author']);
- if (empty($contact_id)) {
- Logger::log('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
- }
-
- $importer = DFRN::getImporter($contact_id);
-
- // This should never fail
- if (empty($importer)) {
- Logger::log('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
- }
-
- Logger::log('Importing post from ' . $msg['author'] . ' with the public envelope.', Logger::DEBUG);
-
- // Now we should be able to import it
- $ret = DFRN::import($msg['message'], $importer, Conversation::PARCEL_DIASPORA_DFRN, Conversation::RELAY);
- System::xmlExit($ret, 'Done');
-}
-
-function dfrn_dispatch_private($user, $postdata)
-{
- $msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? '');
- if (!$msg) {
- System::xmlExit(4, 'Unable to parse message');
- }
-
- // Check if the user has got this contact
- $cid = Contact::getIdForURL($msg['author'], $user['uid']);
- if (!$cid) {
- // Otherwise there should be a public contact
- $cid = Contact::getIdForURL($msg['author']);
- if (!$cid) {
- Logger::log('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
- }
- }
-
- $importer = DFRN::getImporter($cid, $user['uid']);
-
- // This should never fail
- if (empty($importer)) {
- Logger::log('Contact not found for address ' . $msg['author']);
- System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
- }
-
- Logger::log('Importing post from ' . $msg['author'] . ' to ' . $user['nickname'] . ' with the private envelope.', Logger::DEBUG);
-
- // Now we should be able to import it
- $ret = DFRN::import($msg['message'], $importer, Conversation::PARCEL_DIASPORA_DFRN, Conversation::PUSH);
- System::xmlExit($ret, 'Done');
-}
-
-function dfrn_notify_content(App $a) {
- throw new HTTPException\NotFoundException();
-}
+++ /dev/null
-<?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/>.
- *
- */
-
-use Friendica\App;
-use Friendica\Protocol\OStatus;
-use Friendica\Network\HTTPException;
-
-function dfrn_poll_init(App $a)
-{
- if ($a->argc > 1) {
- $nickname = $a->argv[1];
- header("Content-type: application/atom+xml");
- $last_update = $_GET['last_update'] ?? '';
- echo OStatus::feed($nickname, $last_update, 10);
- exit();
- }
- throw new HTTPException\BadRequestException();
-}
--- /dev/null
+<?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\DFRN;
+
+use Friendica\BaseModule;
+use Friendica\Core\Logger;
+use Friendica\Core\System;
+use Friendica\Model\Contact;
+use Friendica\Model\Conversation;
+use Friendica\Model\User;
+use Friendica\Protocol\DFRN;
+use Friendica\Protocol\Diaspora;
+use Friendica\Util\Network;
+use Friendica\Network\HTTPException;
+
+/**
+ * DFRN Notify
+ */
+class Notify extends BaseModule
+{
+ public static function post(array $parameters = [])
+ {
+ $postdata = Network::postdata();
+
+ if (empty($postdata)) {
+ throw new HTTPException\BadRequestException();
+ }
+
+ $data = json_decode($postdata);
+ if (is_object($data) && !empty($parameters['nickname'])) {
+ $user = User::getByNickname($parameters['nickname']);
+ if (empty($user)) {
+ throw new \Friendica\Network\HTTPException\InternalServerErrorException();
+ }
+ self::dispatchPrivate($user, $postdata);
+ } elseif (!self::dispatchPublic($postdata)) {
+ require_once 'mod/salmon.php';
+ salmon_post($a, $postdata);
+ }
+ }
+
+ private static function dispatchPublic($postdata)
+ {
+ $msg = Diaspora::decodeRaw($postdata, '', true);
+ if (!$msg) {
+ // We have to fail silently to be able to hand it over to the salmon parser
+ return false;
+ }
+
+ // Fetch the corresponding public contact
+ $contact_id = Contact::getIdForURL($msg['author']);
+ if (empty($contact_id)) {
+ Logger::notice('Contact not found', ['address' => $msg['author']]);
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
+ }
+
+ // Fetch the importer (Mixture of sender and receiver)
+ $importer = DFRN::getImporter($contact_id);
+ if (empty($importer)) {
+ Logger::notice('Importer contact not found', ['address' => $msg['author']]);
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
+ }
+
+ Logger::info('Importing post with the public envelope.', ['transmitter' => $msg['author']]);
+
+ // Now we should be able to import it
+ $ret = DFRN::import($msg['message'], $importer, Conversation::PARCEL_DIASPORA_DFRN, Conversation::RELAY);
+ System::xmlExit($ret, 'Done');
+ }
+
+ private static function dispatchPrivate($user, $postdata)
+ {
+ $msg = Diaspora::decodeRaw($postdata, $user['prvkey'] ?? '');
+ if (!$msg) {
+ System::xmlExit(4, 'Unable to parse message');
+ }
+
+ // Fetch the contact
+ $contact = Contact::getByURLForUser($msg['author'], $user['uid'], null, ['id', 'blocked', 'pending']);
+ if (empty($contact['id'])) {
+ Logger::notice('Contact not found', ['address' => $msg['author']]);
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
+ }
+
+ if ($contact['pending'] || $contact['blocked']) {
+ Logger::notice('Contact is blocked or pending', ['address' => $msg['author'], 'contact' => $contact]);
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
+ }
+
+ // Fetch the importer (Mixture of sender and receiver)
+ $importer = DFRN::getImporter($contact['id'], $user['uid']);
+ if (empty($importer)) {
+ Logger::notice('Importer contact not found for user', ['uid' => $user['uid'], 'cid' => $contact['id'], 'address' => $msg['author']]);
+ System::xmlExit(3, 'Contact ' . $msg['author'] . ' not found');
+ }
+
+ Logger::info('Importing post with the private envelope.', ['transmitter' => $msg['author'], 'receiver' => $user['nickname']]);
+
+ // Now we should be able to import it
+ $ret = DFRN::import($msg['message'], $importer, Conversation::PARCEL_DIASPORA_DFRN, Conversation::PUSH);
+ System::xmlExit($ret, 'Done');
+ }
+}
--- /dev/null
+<?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\DFRN;
+
+use Friendica\BaseModule;
+use Friendica\Protocol\OStatus;
+
+/**
+ * DFRN Poll
+ */
+class Poll extends BaseModule
+{
+ public static function rawContent(array $parameters = [])
+ {
+ header("Content-type: application/atom+xml");
+ $last_update = $_GET['last_update'] ?? '';
+ echo OStatus::feed($parameters['nickname'], $last_update, 10);
+ exit();
+ }
+}
'/hovercard' => [Module\Contact\Hovercard::class, [R::GET]],
],
- '/credits' => [Module\Credits::class, [R::GET]],
-
- '/delegation'=> [Module\Delegation::class, [R::GET, R::POST]],
- '/dirfind' => [Module\Search\Directory::class, [R::GET]],
- '/directory' => [Module\Directory::class, [R::GET]],
+ '/credits' => [Module\Credits::class, [R::GET]],
+ '/delegation' => [Module\Delegation::class, [R::GET, R::POST]],
+ '/dfrn_notify[/{nickname}]' => [Module\DFRN\Notify::class, [R::POST]],
+ '/dfrn_poll/{nickname}' => [Module\DFRN\Poll::class, [R::GET]],
+ '/dirfind' => [Module\Search\Directory::class, [R::GET]],
+ '/directory' => [Module\Directory::class, [R::GET]],
'/feed' => [
'/{nickname}' => [Module\Feed::class, [R::GET]],