]> git.mxchange.org Git - friendica.git/commitdiff
Move mod/receive to src/Module/Diaspora/receive
authorPhilipp Holzer <admin+github@philipp.info>
Sun, 20 Oct 2019 11:00:08 +0000 (13:00 +0200)
committerPhilipp Holzer <admin+github@philipp.info>
Sun, 20 Oct 2019 11:07:16 +0000 (13:07 +0200)
- Added routes
- Make Diaspora::decode(Raw) more explicit
- Add new User::getByGuid() method

mod/dfrn_notify.php
mod/receive.php [deleted file]
src/Model/User.php
src/Module/Diaspora/Receive.php [new file with mode: 0644]
src/Protocol/Diaspora.php
static/routes.config.php

index dee6bad779538e3c540ba856befc2781a6df88e8..3d27593aaf51a6c93f93c01aa128b32364cc6166 100644 (file)
@@ -15,8 +15,8 @@ use Friendica\Model\Contact;
 use Friendica\Model\User;
 use Friendica\Protocol\DFRN;
 use Friendica\Protocol\Diaspora;
-use Friendica\Util\Strings;
 use Friendica\Util\Network;
+use Friendica\Util\Strings;
 
 function dfrn_notify_post(App $a) {
        Logger::log(__function__, Logger::TRACE);
@@ -184,7 +184,7 @@ function dfrn_notify_post(App $a) {
 
 function dfrn_dispatch_public($postdata)
 {
-       $msg = Diaspora::decodeRaw([], $postdata, true);
+       $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;
@@ -214,7 +214,7 @@ function dfrn_dispatch_public($postdata)
 
 function dfrn_dispatch_private($user, $postdata)
 {
-       $msg = Diaspora::decodeRaw($user, $postdata);
+       $msg = Diaspora::decodeRaw($postdata, $user);
        if (!$msg) {
                System::xmlExit(4, 'Unable to parse message');
        }
diff --git a/mod/receive.php b/mod/receive.php
deleted file mode 100644 (file)
index 182a1df..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-/**
- * @file mod/receive.php
- * @brief Diaspora endpoint
- */
-
-use Friendica\App;
-use Friendica\Core\Config;
-use Friendica\Core\Logger;
-use Friendica\Core\System;
-use Friendica\Database\DBA;
-use Friendica\Protocol\Diaspora;
-use Friendica\Util\Network;
-
-/**
- * @param App $a App
- * @return void
- * @throws ImagickException
- * @throws \Friendica\Network\HTTPException\InternalServerErrorException
- */
-function receive_post(App $a)
-{
-       $enabled = intval(Config::get('system', 'diaspora_enabled'));
-       if (!$enabled) {
-               Logger::log('mod-diaspora: disabled');
-               throw new \Friendica\Network\HTTPException\InternalServerErrorException();
-       }
-
-       if (($a->argc == 2) && ($a->argv[1] === 'public')) {
-               $public = true;
-               $importer = [];
-       } else {
-               $public = false;
-
-               if ($a->argc != 3 || $a->argv[1] !== 'users') {
-                       throw new \Friendica\Network\HTTPException\InternalServerErrorException();
-               }
-               $guid = $a->argv[2];
-
-               $importer = DBA::selectFirst('user', [], ['guid' => $guid, 'account_expired' => false, 'account_removed' => false]);
-               if (!DBA::isResult($importer)) {
-                       throw new \Friendica\Network\HTTPException\InternalServerErrorException();
-               }
-       }
-
-       // It is an application/x-www-form-urlencoded
-
-       Logger::log('mod-diaspora: receiving post', Logger::DEBUG);
-
-       if (empty($_POST['xml'])) {
-               $postdata = Network::postdata();
-               if ($postdata == '') {
-                       throw new \Friendica\Network\HTTPException\InternalServerErrorException();
-               }
-
-               Logger::log('mod-diaspora: message is in the new format', Logger::DEBUG);
-               $msg = Diaspora::decodeRaw($importer, $postdata);
-       } else {
-               $xml = urldecode($_POST['xml']);
-
-               Logger::log('mod-diaspora: decode message in the old format', Logger::DEBUG);
-               $msg = Diaspora::decode($importer, $xml);
-
-               if ($public && !$msg) {
-                       Logger::log('mod-diaspora: decode message in the new format', Logger::DEBUG);
-                       $msg = Diaspora::decodeRaw($importer, $xml);
-               }
-       }
-
-       Logger::log('mod-diaspora: decoded', Logger::DEBUG);
-
-       Logger::log('mod-diaspora: decoded msg: ' . print_r($msg, true), Logger::DATA);
-
-       if (!is_array($msg)) {
-               throw new \Friendica\Network\HTTPException\InternalServerErrorException();
-       }
-
-       Logger::log('mod-diaspora: dispatching', Logger::DEBUG);
-
-       $ret = true;
-       if ($public) {
-               Diaspora::dispatchPublic($msg);
-       } else {
-               $ret = Diaspora::dispatch($importer, $msg);
-       }
-
-       if ($ret) {
-               throw new \Friendica\Network\HTTPException\OKException();
-       } else {
-               throw new \Friendica\Network\HTTPException\InternalServerErrorException();
-       }
-}
index ef49f45edab1012f9873678c473f2137542d960f..499c55330bd5516c7be0dbe816b868a53e9fb4d0 100644 (file)
@@ -18,7 +18,6 @@ use Friendica\Core\Protocol;
 use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
-use Friendica\Model\Photo;
 use Friendica\Model\TwoFactor\AppSpecificPassword;
 use Friendica\Object\Image;
 use Friendica\Util\Crypto;
@@ -105,6 +104,27 @@ class User
                return DBA::selectFirst('user', $fields, ['uid' => $uid]);
        }
 
+       /**
+        * Returns a user record based on it's GUID
+        *
+        * @param string $guid   The guid of the user
+        * @param array  $fields The fields to retrieve
+        * @param bool   $active True, if only active records are searched
+        *
+        * @return array|boolean User record if it exists, false otherwise
+        * @throws Exception
+        */
+       public static function getByGuid(string $guid, array $fields = [], bool $active = true)
+       {
+               if ($active) {
+                       $cond = ['guid' => $guid, 'account_expired' => false, 'account_removed' => false];
+               } else {
+                       $cond = ['guid' => $guid];
+               }
+
+               return DBA::selectFirst('user', $fields, $cond);
+       }
+
        /**
         * @param  string        $nickname
         * @param array          $fields
diff --git a/src/Module/Diaspora/Receive.php b/src/Module/Diaspora/Receive.php
new file mode 100644 (file)
index 0000000..521b8ea
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+
+namespace Friendica\Module\Diaspora;
+
+use Friendica\App;
+use Friendica\BaseModule;
+use Friendica\Core\Config\Configuration;
+use Friendica\Model\User;
+use Friendica\Network\HTTPException;
+use Friendica\Protocol\Diaspora;
+use Friendica\Util\Network;
+use Psr\Log\LoggerInterface;
+
+/**
+ * This module is part of the Diaspora protocol.
+ * It is used for receiving single posts either for public or for a specific user.
+ */
+class Receive extends BaseModule
+{
+       /** @var LoggerInterface */
+       private static $logger;
+
+       public static function init()
+       {
+               /** @var LoggerInterface $logger */
+               self::$logger = self::getClass(LoggerInterface::class);
+       }
+
+       public static function post()
+       {
+               /** @var Configuration $config */
+               $config = self::getClass(Configuration::class);
+
+               $enabled = $config->get('system', 'diaspora_enabled', false);
+               if (!$enabled) {
+                       self::$logger->info('Diaspora disabled.');
+                       throw new HTTPException\InternalServerErrorException('Diaspora disabled.');
+               }
+
+               /** @var App\Arguments $args */
+               $args = self::getClass(App\Arguments::class);
+
+               $type = $args->get(1);
+
+               switch ($type) {
+                       case 'public':
+                               self::receivePublic();
+                               break;
+                       case 'users':
+                               self::receiveUser($args->get(2));
+                               break;
+                       default:
+                               self::$logger->info('Wrong call.');
+                               throw new HTTPException\InternalServerErrorException('wrong call.');
+                               break;
+               }
+       }
+
+       /**
+        * Receive a public Diaspora posting
+        *
+        * @throws HTTPException\InternalServerErrorException
+        * @throws \ImagickException
+        */
+       private static function receivePublic()
+       {
+               self::$logger->info('Diaspora: Receiving post.');
+
+               $msg = self::decodePost();
+
+               self::$logger->info('Diaspora: Dispatching.');
+
+               Diaspora::dispatchPublic($msg);
+       }
+
+       /**
+        * Receive a Diaspora posting for a user
+        *
+        * @param string $guid The GUID of the importer
+        *
+        * @throws HTTPException\InternalServerErrorException
+        * @throws \ImagickException
+        */
+       private static function receiveUser(string $guid)
+       {
+               self::$logger->info('Diaspora: Receiving post.');
+
+               $importer = User::getByGuid($guid);
+
+               $msg = self::decodePost(false, $importer['privKey'] ?? '');
+
+               self::$logger->info('Diaspora: Dispatching.');
+
+               if (Diaspora::dispatch($importer, $msg)) {
+                       throw new HTTPException\OKException();
+               } else {
+                       throw new HTTPException\InternalServerErrorException();
+               }
+       }
+
+       /**
+        * Decodes a Diaspora message based on the posted data
+        *
+        * @param string $privKey The private key of the importer
+        * @param bool   $public  True, if the post is public
+        *
+        * @return array
+        * @throws HTTPException\InternalServerErrorException
+        * @throws \ImagickException
+        */
+       private static function decodePost(bool $public = true, string $privKey = '')
+       {
+               if (empty($_POST['xml'])) {
+
+                       $postdata = Network::postdata();
+
+                       if (empty($postdata)) {
+                               throw new HTTPException\InternalServerErrorException('Missing postdata.');
+                       }
+
+                       self::$logger->info('Diaspora: Message is in the new format.');
+
+                       $msg = Diaspora::decodeRaw($postdata, $privKey);
+               } else {
+
+                       $xml = urldecode($_POST['xml']);
+
+                       self::$logger->info('Diaspora: Decode message in the old format.');
+                       $msg = Diaspora::decode($xml, $privKey);
+
+                       if ($public && !$msg) {
+                               self::$logger->info('Diaspora: Decode message in the new format.');
+                               $msg = Diaspora::decodeRaw($xml, $privKey);
+                       }
+               }
+
+               self::$logger->info('Diaspora: Post encoded.');
+               self::$logger->debug('Diaspora: Decoded message.', ['msg' => print_r($msg, true)]);
+
+               if (!is_array($msg)) {
+                       throw new HTTPException\InternalServerErrorException('Message is not an array.');
+               }
+
+               return $msg;
+       }
+}
index 587b34c3fe3b4839927e52a536fb09042f39ef40..aec3a283f8096f994d7d46044ba82bbfe6c3e488 100644 (file)
@@ -413,8 +413,8 @@ class Diaspora
        /**
         * @brief: Decodes incoming Diaspora message in the new format
         *
-        * @param array   $importer Array of the importer user
         * @param string  $raw      raw post message
+        * @param string  $privKey   The private key of the importer
         * @param boolean $no_exit  Don't do an http exit on error
         *
         * @return array
@@ -424,7 +424,7 @@ class Diaspora
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public static function decodeRaw(array $importer, $raw, $no_exit = false)
+       public static function decodeRaw(string $raw, string $privKey = '', bool $no_exit = false)
        {
                $data = json_decode($raw);
 
@@ -434,7 +434,7 @@ class Diaspora
                        $ciphertext = base64_decode($data->encrypted_magic_envelope);
 
                        $outer_key_bundle = '';
-                       @openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $importer['prvkey']);
+                       @openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $privKey);
                        $j_outer_key_bundle = json_decode($outer_key_bundle);
 
                        if (!is_object($j_outer_key_bundle)) {
@@ -519,8 +519,8 @@ class Diaspora
        /**
         * @brief: Decodes incoming Diaspora message in the deprecated format
         *
-        * @param array  $importer Array of the importer user
         * @param string $xml      urldecoded Diaspora salmon
+        * @param string $privKey  The private key of the importer
         *
         * @return array
         * 'message' -> decoded Diaspora XML message
@@ -529,7 +529,7 @@ class Diaspora
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public static function decode(array $importer, $xml)
+       public static function decode(string $xml, string $privKey = '')
        {
                $public = false;
                $basedom = XML::parseString($xml);
@@ -548,7 +548,7 @@ class Diaspora
                        $author_link = str_replace('acct:', '', $children->header->author_id);
                } else {
                        // This happens with posts from a relais
-                       if (!$importer) {
+                       if (empty($privKey)) {
                                Logger::log("This is no private post in the old format", Logger::DEBUG);
                                return false;
                        }
@@ -559,7 +559,7 @@ class Diaspora
                        $ciphertext = base64_decode($encrypted_header->ciphertext);
 
                        $outer_key_bundle = '';
-                       openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $importer['prvkey']);
+                       openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $privKey);
 
                        $j_outer_key_bundle = json_decode($outer_key_bundle);
 
index 0601d8e41d1dff48d9245d5dfe107530eef92d42..7cc9fdaa6d08d958e45dd0ea2c9d620a0c813158 100644 (file)
@@ -196,6 +196,11 @@ return [
                '/saved/remove'        => [Module\Search\Saved::class, [R::GET]],
        ],
 
+       '/receive' => [
+               '/public'       => [Module\Diaspora\Receive::class, [R::POST]],
+               '/users/{guid}' => [Module\Diaspora\Receive::class, [R::POST]],
+       ],
+
        '/settings' => [
                '/2fa' => [
                        '[/]'           => [Module\Settings\TwoFactor\Index::class,       [R::GET, R::POST]],