]> git.mxchange.org Git - friendica.git/blobdiff - src/Protocol/Diaspora.php
Merge pull request #13648 from annando/picture-upload
[friendica.git] / src / Protocol / Diaspora.php
index 5554af7d81c0b11c107c9170bf4a41114f781030..cc3016aae912c2e60079a09869292eee39e85d28 100644 (file)
@@ -267,7 +267,7 @@ class Diaspora
                                if ($no_exit) {
                                        return false;
                                } else {
-                                       throw new \Friendica\Network\HTTPException\BadRequestException();
+                                       throw new HTTPException\BadRequestException();
                                }
                        }
                } else {
@@ -281,7 +281,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               throw new \Friendica\Network\HTTPException\BadRequestException();
+                               throw new HTTPException\BadRequestException();
                        }
                }
 
@@ -307,7 +307,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               throw new \Friendica\Network\HTTPException\BadRequestException();
+                               throw new HTTPException\BadRequestException();
                        }
                }
 
@@ -322,7 +322,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               throw new \Friendica\Network\HTTPException\BadRequestException();
+                               throw new HTTPException\BadRequestException();
                        }
                }
 
@@ -332,7 +332,7 @@ class Diaspora
                        if ($no_exit) {
                                return false;
                        } else {
-                               throw new \Friendica\Network\HTTPException\BadRequestException();
+                               throw new HTTPException\BadRequestException();
                        }
                }
 
@@ -424,7 +424,7 @@ class Diaspora
 
                if (!$base) {
                        Logger::notice('unable to locate salmon data in xml');
-                       throw new \Friendica\Network\HTTPException\BadRequestException();
+                       throw new HTTPException\BadRequestException();
                }
 
 
@@ -444,14 +444,11 @@ class Diaspora
                $encoding = $base->encoding;
                $alg = $base->alg;
 
-
                $signed_data = $data . '.' . Strings::base64UrlEncode($type) . '.' . Strings::base64UrlEncode($encoding) . '.' . Strings::base64UrlEncode($alg);
 
-
                // decode the data
                $data = Strings::base64UrlDecode($data);
 
-
                if ($public) {
                        $inner_decrypted = $data;
                } else {
@@ -463,21 +460,21 @@ class Diaspora
                // Once we have the author URI, go to the web and try to find their public key
                // (first this will look it up locally if it is in the diaspora-contact cache)
                // This will also convert diaspora public key from pkcs#1 to pkcs#8
-               Logger::notice('Fetching key for ' . $author);
+               Logger::info('Fetching key for ' . $author);
                $key = self::key($author);
                if (!$key) {
                        Logger::notice('Could not retrieve author key.');
-                       throw new \Friendica\Network\HTTPException\BadRequestException();
+                       throw new HTTPException\BadRequestException();
                }
 
                $verify = Crypto::rsaVerify($signed_data, $signature, $key);
 
                if (!$verify) {
                        Logger::notice('Message did not verify. Discarding.');
-                       throw new \Friendica\Network\HTTPException\BadRequestException();
+                       throw new HTTPException\BadRequestException();
                }
 
-               Logger::notice('Message verified.');
+               Logger::info('Message verified.');
 
                return [
                        'message' => $inner_decrypted,
@@ -499,8 +496,7 @@ class Diaspora
         */
        public static function dispatchPublic(array $msg, int $direction)
        {
-               $enabled = intval(DI::config()->get('system', 'diaspora_enabled'));
-               if (!$enabled) {
+               if (!DI::config()->get('system', 'diaspora_enabled')) {
                        Logger::notice('Diaspora is disabled');
                        return false;
                }
@@ -800,7 +796,7 @@ class Diaspora
         */
        private static function key(WebFingerUri $uri): string
        {
-               Logger::info('Fetching diaspora key', ['handle' => $uri->getAddr(), 'callstack' => System::callstack(20)]);
+               Logger::info('Fetching diaspora key', ['handle' => $uri->getAddr()]);
                try {
                        return DI::dsprContact()->getByAddr($uri)->pubKey;
                } catch (HTTPException\NotFoundException | \InvalidArgumentException $e) {
@@ -940,7 +936,7 @@ class Diaspora
        {
                $item = Post::selectFirst(['id'], ['uid' => $uid, 'guid' => $guid]);
                if (DBA::isResult($item)) {
-                       Logger::notice('Message ' . $guid . ' already exists for user ' . $uid);
+                       Logger::notice('Message already exists.', ['uid' => $uid, 'guid' => $guid, 'id' => $item['id']]);
                        return $item['id'];
                }
 
@@ -951,6 +947,7 @@ class Diaspora
         * Checks for links to posts in a message
         *
         * @param array $item The item array
+        *
         * @return void
         */
        private static function fetchGuid(array $item)
@@ -1154,7 +1151,7 @@ class Diaspora
        {
                // Check for Diaspora (and Friendica) typical paths
                if (!preg_match('=(https?://.+)/(?:posts|display|objects)/([a-zA-Z0-9-_@.:%]+[a-zA-Z0-9])=i', $url, $matches)) {
-                       Logger::info('Invalid url', ['url' => $url]);
+                       Logger::notice('Invalid url', ['url' => $url]);
                        return false;
                }
 
@@ -1175,7 +1172,7 @@ class Diaspora
                        Logger::info('Found', ['id' => $item['id']]);
                        return $item['id'];
                } else {
-                       Logger::info('Not found', ['guid' => $guid, 'uid' => $uid]);
+                       Logger::notice('Not found', ['guid' => $guid, 'uid' => $uid]);
                        return false;
                }
        }
@@ -1195,6 +1192,7 @@ class Diaspora
        {
                $fields = [
                        'id', 'parent', 'body', 'wall', 'uri', 'guid', 'private', 'origin',
+                       'allow_cid', 'allow_gid', 'deny_cid', 'deny_gid',
                        'author-name', 'author-link', 'author-avatar', 'gravity',
                        'owner-name', 'owner-link', 'owner-avatar'
                ];
@@ -1225,7 +1223,7 @@ class Diaspora
                        Logger::notice('Parent item not found: parent: ' . $guid . ' - user: ' . $uid);
                        return false;
                } else {
-                       Logger::notice('Parent item found: parent: ' . $guid . ' - user: ' . $uid);
+                       Logger::info('Parent item found: parent: ' . $guid . ' - user: ' . $uid);
                        return $item;
                }
        }
@@ -1365,7 +1363,7 @@ class Diaspora
                        return false;
                }
 
-               Logger::notice('Got migration for ' . $old_author . ', to ' . $new_author . ' with user ' . $importer['uid']);
+               Logger::info('Got migration for ' . $old_author . ', to ' . $new_author . ' with user ' . $importer['uid']);
 
                // Check signature
                $signed_text = 'AccountMigration:' . $old_author . ':' . $new_author;
@@ -1399,7 +1397,7 @@ class Diaspora
 
                Contact::update($fields, ['addr' => $old_author->getAddr()]);
 
-               Logger::notice('Contacts are updated.');
+               Logger::info('Contacts are updated.');
 
                return true;
        }
@@ -1422,7 +1420,7 @@ class Diaspora
                }
                DBA::close($contacts);
 
-               Logger::notice('Removed contacts for ' . $author_handle);
+               Logger::info('Removed contacts for ' . $author_handle);
 
                return true;
        }
@@ -1570,6 +1568,12 @@ class Diaspora
                $datarray['verb'] = Activity::POST;
                $datarray['gravity'] = Item::GRAVITY_COMMENT;
 
+               $datarray['private']   = $toplevel_parent_item['private'];
+               $datarray['allow_cid'] = $toplevel_parent_item['allow_cid'];
+               $datarray['allow_gid'] = $toplevel_parent_item['allow_gid'];
+               $datarray['deny_cid']  = $toplevel_parent_item['deny_cid'];
+               $datarray['deny_gid']  = $toplevel_parent_item['deny_gid'];
+
                $datarray['thr-parent'] = $thr_parent ?: $toplevel_parent_item['uri'];
 
                $datarray['object-type'] = Activity\ObjectType::COMMENT;
@@ -1826,6 +1830,13 @@ class Diaspora
 
                $datarray['verb'] = $verb;
                $datarray['gravity'] = Item::GRAVITY_ACTIVITY;
+
+               $datarray['private']   = $toplevel_parent_item['private'];
+               $datarray['allow_cid'] = $toplevel_parent_item['allow_cid'];
+               $datarray['allow_gid'] = $toplevel_parent_item['allow_gid'];
+               $datarray['deny_cid']  = $toplevel_parent_item['deny_cid'];
+               $datarray['deny_gid']  = $toplevel_parent_item['deny_gid'];
+
                $datarray['thr-parent'] = $toplevel_parent_item['uri'];
 
                $datarray['object-type'] = Activity\ObjectType::NOTE;
@@ -2068,7 +2079,7 @@ class Diaspora
        }
 
        /**
-        * Processes poll participations - unssupported
+        * Processes poll participations - unsupported
         *
         * @param array  $importer Array of the importer user
         * @param object $data     The message object
@@ -2204,7 +2215,7 @@ class Diaspora
                $author = WebFingerUri::fromString($author_handle);
 
                // the current protocol version doesn't know these fields
-               // That means that we will assume their existance
+               // That means that we will assume their existence
                if (isset($data->following)) {
                        $following = (XML::unescape($data->following) == 'true');
                } else {
@@ -2255,7 +2266,7 @@ class Diaspora
                } elseif (!$following && $sharing) {
                        Logger::info("Author " . $author . " wants to share with us.");
                } elseif ($following && $sharing) {
-                       Logger::info("Author " . $author . " wants to have a bidirectional conection.");
+                       Logger::info("Author " . $author . " wants to have a bidirectional connection.");
                } elseif ($following && !$sharing) {
                        Logger::info("Author " . $author . " wants to listen to us.");
                }
@@ -2569,19 +2580,21 @@ class Diaspora
         *
         * @param int $uriid
         * @param object $photo
+        *
         * @return void
         */
        private static function storePhotoAsMedia(int $uriid, $photo)
        {
                // @TODO Need to find object type, roland@f.haeder.net
                Logger::debug('photo=' . get_class($photo));
-               $data = [];
-               $data['uri-id'] = $uriid;
-               $data['type'] = Post\Media::IMAGE;
-               $data['url'] = XML::unescape($photo->remote_photo_path) . XML::unescape($photo->remote_photo_name);
-               $data['height'] = (int)XML::unescape($photo->height ?? 0);
-               $data['width'] = (int)XML::unescape($photo->width ?? 0);
-               $data['description'] = XML::unescape($photo->text ?? '');
+               $data = [
+                       'uri-id'      => $uriid,
+                       'type'        => Post\Media::IMAGE,
+                       'url'         => XML::unescape($photo->remote_photo_path) . XML::unescape($photo->remote_photo_name),
+                       'height'      => (int)XML::unescape($photo->height ?? 0),
+                       'width'       => (int)XML::unescape($photo->width ?? 0),
+                       'description' => XML::unescape($photo->text ?? ''),
+               ];
 
                Post\Media::insert($data);
        }
@@ -2653,11 +2666,32 @@ class Diaspora
 
                $raw_body = $body = Markdown::toBBCode($text);
 
-               $datarray = [];
+               $datarray = [
+                       'guid'        => $guid,
+                       'plink'       => self::plink($author, $guid),
+                       'uid'         => $importer['uid'],
+                       'contact-id'  => $contact['id'],
+                       'network'     => Protocol::DIASPORA,
+                       'author-link' => $contact['url'],
+                       'author-id'   => Contact::getIdForURL($contact['url'], 0),
+                       'verb'        => Activity::POST,
+                       'gravity'     => Item::GRAVITY_PARENT,
+                       'protocol'    => Conversation::PARCEL_DIASPORA,
+                       'source'      => $xml,
+                       'body'        => self::replacePeopleGuid($body, $contact['url']),
+                       'raw-body'    => self::replacePeopleGuid($raw_body, $contact['url']),
+                       'private'     => (($public == 'false') ? Item::PRIVATE : Item::PUBLIC),
+                       // Default is note (aka. comment), later below is being checked the real type
+                       'object-type' => Activity\ObjectType::NOTE,
+                       'post-type'   => Item::PT_NOTE,
+               ];
 
-               $datarray['guid'] = $guid;
-               $datarray['uri'] = $datarray['thr-parent'] = self::getUriFromGuid($guid, $author);
-               $datarray['uri-id'] = ItemURI::insert(['uri' => $datarray['uri'], 'guid' => $datarray['guid']]);
+               $datarray['uri']        = $datarray['thr-parent'] = self::getUriFromGuid($guid, $author);
+               $datarray['uri-id']     = ItemURI::insert(['uri' => $datarray['uri'], 'guid' => $datarray['guid']]);
+               $datarray['owner-link'] = $datarray['author-link'];
+               $datarray['owner-id']   = $datarray['author-id'];
+
+               $datarray = self::setDirection($datarray, $direction);
 
                // Attach embedded pictures to the body
                if ($data->photo) {
@@ -2668,11 +2702,7 @@ class Diaspora
                        $datarray['object-type'] = Activity\ObjectType::IMAGE;
                        $datarray['post-type'] = Item::PT_IMAGE;
                } elseif ($data->poll) {
-                       $datarray['object-type'] = Activity\ObjectType::NOTE;
                        $datarray['post-type'] = Item::PT_POLL;
-               } else {
-                       $datarray['object-type'] = Activity\ObjectType::NOTE;
-                       $datarray['post-type'] = Item::PT_NOTE;
                }
 
                /// @todo enable support for polls
@@ -2684,27 +2714,6 @@ class Diaspora
 
                /// @todo enable support for events
 
-               $datarray['uid'] = $importer['uid'];
-               $datarray['contact-id'] = $contact['id'];
-               $datarray['network'] = Protocol::DIASPORA;
-
-               $datarray['author-link'] = $contact['url'];
-               $datarray['author-id'] = Contact::getIdForURL($contact['url'], 0);
-
-               $datarray['owner-link'] = $datarray['author-link'];
-               $datarray['owner-id'] = $datarray['author-id'];
-
-               $datarray['verb'] = Activity::POST;
-               $datarray['gravity'] = Item::GRAVITY_PARENT;
-
-               $datarray['protocol'] = Conversation::PARCEL_DIASPORA;
-               $datarray['source'] = $xml;
-
-               $datarray = self::setDirection($datarray, $direction);
-
-               $datarray['body'] = self::replacePeopleGuid($body, $contact['url']);
-               $datarray['raw-body'] = self::replacePeopleGuid($raw_body, $contact['url']);
-
                self::storeMentions($datarray['uri-id'], $text);
                Tag::storeRawTagsFromBody($datarray['uri-id'], $datarray['body']);
 
@@ -2717,8 +2726,6 @@ class Diaspora
                        $datarray['app'] = $provider_display_name;
                }
 
-               $datarray['plink'] = self::plink($author, $guid);
-               $datarray['private'] = (($public == 'false') ? Item::PRIVATE : Item::PUBLIC);
                $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at;
 
                if (isset($address['address'])) {
@@ -2756,7 +2763,7 @@ class Diaspora
         * ************************************************************************************** */
 
        /**
-        * returnes the handle of a contact
+        * returns the handle of a contact
         *
         * @param array $contact contact array
         *
@@ -2770,7 +2777,7 @@ class Diaspora
                }
 
                // Normally we should have a filled "addr" field - but in the past this wasn't the case
-               // So - just in case - we build the the address here.
+               // So - just in case - we build the address here.
                if ($contact['nickname'] != '') {
                        $nick = $contact['nickname'];
                } else {
@@ -2839,7 +2846,7 @@ class Diaspora
        public static function buildMagicEnvelope(string $msg, array $user): string
        {
                $b64url_data = Strings::base64UrlEncode($msg);
-               $data = str_replace(["\n", "\r", " ", "\t"], ['', '', '', ''], $b64url_data);
+               $data = str_replace(["\n", "\r", ' ', "\t"], ['', '', '', ''], $b64url_data);
 
                $key_id = Strings::base64UrlEncode(self::myHandle($user));
                $type = 'application/xml';
@@ -2857,11 +2864,11 @@ class Diaspora
 
                $xmldata = [
                        'me:env' => [
-                               'me:data' => $data,
-                               '@attributes' => ['type' => $type],
-                               'me:encoding' => $encoding,
-                               'me:alg' => $alg,
-                               'me:sig' => $sig,
+                               'me:data'      => $data,
+                               '@attributes'  => ['type' => $type],
+                               'me:encoding'  => $encoding,
+                               'me:alg'       => $alg,
+                               'me:sig'       => $sig,
                                '@attributes2' => ['key_id' => $key_id]
                        ]
                ];
@@ -2955,7 +2962,7 @@ class Diaspora
                        return 0;
                }
 
-               Logger::notice('transmit: ' . $logid . '-' . $guid . ' ' . $dest_url);
+               Logger::info('transmit: ' . $logid . '-' . $guid . ' ' . $dest_url);
 
                if (!intval(DI::config()->get('system', 'diaspora_test'))) {
                        $content_type = (($public_batch) ? 'application/magic-envelope+xml' : 'application/json');
@@ -2973,7 +2980,7 @@ class Diaspora
                        GServer::setReachableById($contact['gsid'], Protocol::DIASPORA);
                }
 
-               Logger::notice('transmit: ' . $logid . '-' . $guid . ' to ' . $dest_url . ' returns: ' . $return_code);
+               Logger::info('transmit: ' . $logid . '-' . $guid . ' to ' . $dest_url . ' returns: ' . $return_code);
 
                return $return_code ? $return_code : -1;
        }
@@ -3029,7 +3036,7 @@ class Diaspora
                        // The "addr" field should always be filled.
                        // If this isn't the case, it will raise a notice some lines later.
                        // And in the log we will see where it came from, and we can handle it there.
-                       Logger::notice('Empty addr', ['contact' => $contact ?? [], 'callstack' => System::callstack(20)]);
+                       Logger::notice('Empty addr', ['contact' => $contact ?? []]);
                }
 
                $envelope = self::buildMessage($msg, $owner, $contact, $owner['uprvkey'], $pubkey ?? '', $public_batch);
@@ -3069,10 +3076,7 @@ class Diaspora
                // If the item belongs to a user, we take this user id.
                if ($item['uid'] == 0) {
                        // @todo Possibly use an administrator account?
-                       $condition = [
-                               'verified' => true, 'blocked' => false,
-                               'account_removed' => false, 'account_expired' => false, 'account-type' => User::ACCOUNT_TYPE_PERSON
-                       ];
+                       $condition = ['verified' => true, 'blocked' => false, 'account_removed' => false, 'account_expired' => false, 'account-type' => User::ACCOUNT_TYPE_PERSON];
                        $first_user = DBA::selectFirst('user', ['uid'], $condition, ['order' => ['uid']]);
                        $owner = User::getOwnerDataById($first_user['uid']);
                } else {
@@ -3880,7 +3884,7 @@ class Diaspora
         */
        private static function createProfileData(int $uid): array
        {
-               $profile = DBA::selectFirst('owner-view', ['uid', 'addr', 'name', 'location', 'net-publish', 'dob', 'about', 'pub_keywords'], ['uid' => $uid]);
+               $profile = DBA::selectFirst('owner-view', ['uid', 'addr', 'name', 'location', 'net-publish', 'dob', 'about', 'pub_keywords', 'updated'], ['uid' => $uid]);
 
                if (!DBA::isResult($profile)) {
                        return [];
@@ -3890,17 +3894,21 @@ class Diaspora
 
                $data = [
                        'author'           => $profile['addr'],
+                       'edited_at'        => DateTimeFormat::utc($profile['updated']),
+                       'full_name'        => $profile['name'],
                        'first_name'       => $split_name['first'],
                        'last_name'        => $split_name['last'],
                        'image_url'        => DI::baseUrl() . '/photo/custom/300/' . $profile['uid'] . '.jpg',
                        'image_url_medium' => DI::baseUrl() . '/photo/custom/100/' . $profile['uid'] . '.jpg',
                        'image_url_small'  => DI::baseUrl() . '/photo/custom/50/'  . $profile['uid'] . '.jpg',
-                       'searchable'       => ($profile['net-publish'] ? 'true' : 'false'),
+                       'bio'              => null,
                        'birthday'         => null,
-                       'about'            => null,
+                       'gender'           => null,
                        'location'         => null,
-                       'tag_string'       => null,
+                       'searchable'       => ($profile['net-publish'] ? 'true' : 'false'),
+                       'public'           => 'false',
                        'nsfw'             => 'false',
+                       'tag_string'       => null,
                ];
 
                if ($data['searchable'] === 'true') {
@@ -3914,7 +3922,7 @@ class Diaspora
                                $data['birthday'] = DateTimeFormat::utc($year . '-' . $month . '-' . $day, 'Y-m-d');
                        }
 
-                       $data['about'] = BBCode::toMarkdown($profile['about'] ?? '');
+                       $data['bio'] = BBCode::toMarkdown($profile['about'] ?? '');
 
                        $data['location'] = $profile['location'];
                        $data['tag_string'] = '';
@@ -3973,8 +3981,10 @@ class Diaspora
 
                // @todo Split this into single worker jobs
                foreach ($recipients as $recipient) {
-                       Logger::info('Send updated profile data for user ' . $uid . ' to contact ' . $recipient['id']);
-                       self::buildAndTransmit($owner, $recipient, 'profile', $message);
+                       if ((empty($recipient['gsid']) || GServer::isReachableById($recipient['gsid'])) && !Contact\User::isBlocked($recipient['id'], $uid)) {
+                               Logger::info('Send updated profile data for user ' . $uid . ' to contact ' . $recipient['id']);
+                               self::buildAndTransmit($owner, $recipient, 'profile', $message);
+                       }
                }
        }
 
@@ -4049,7 +4059,7 @@ class Diaspora
                        return false;
                }
 
-               if (!self::parentSupportDiaspora($item['thr-parent-id'])) {
+               if (!self::parentSupportDiaspora($item['thr-parent-id'], $uid)) {
                        Logger::info('One of the parents does not support Diaspora. A signature will not be created.', ['uri-id' => $item['uri-id'], 'guid' => $item['guid']]);
                        return false;
                }
@@ -4068,13 +4078,14 @@ class Diaspora
         * Check if the parent and their parents support Diaspora
         *
         * @param integer $parent_id
+        * @param integer $uid
         * @return boolean
         * @throws InternalServerErrorException
         * @throws \ImagickException
         */
-       private static function parentSupportDiaspora(int $parent_id): bool
+       private static function parentSupportDiaspora(int $parent_id, int $uid): bool
        {
-               $parent_post = Post::selectFirstPost(['gravity', 'signed_text', 'author-link', 'thr-parent-id'], ['uri-id' => $parent_id]);
+               $parent_post = Post::selectFirst(['gravity', 'signed_text', 'author-link', 'thr-parent-id', 'protocol'], ['uri-id' => $parent_id, 'uid' => [0, $uid]]);
                if (empty($parent_post['thr-parent-id'])) {
                        Logger::warning('Parent post does not exist.', ['parent-id' => $parent_id]);
                        return false;
@@ -4085,13 +4096,13 @@ class Diaspora
                        return false;
                }
 
-               if (($parent_post['gravity'] == Item::GRAVITY_COMMENT) && empty($parent_post['signed_text'])) {
+               if (($parent_post['protocol'] != Conversation::PARCEL_DIASPORA) && ($parent_post['gravity'] == Item::GRAVITY_COMMENT) && empty($parent_post['signed_text'])) {
                        Logger::info('Parent comment has got no Diaspora signature.', ['parent-id' => $parent_id]);
                        return false;
                }
 
                if ($parent_post['gravity'] == Item::GRAVITY_COMMENT) {
-                       return self::parentSupportDiaspora($parent_post['thr-parent-id']);
+                       return self::parentSupportDiaspora($parent_post['thr-parent-id'], $uid);
                }
 
                return true;