use SimpleXMLElement;
/**
- * This class contain functions to create and send Diaspora XML files
+ * This class contains functions to communicate via the Diaspora protocol
+ * @see https://diaspora.github.io/diaspora_federation/
*/
class Diaspora
{
// Is it a private post? Then decrypt the outer Salmon
if (is_object($data)) {
- $encrypted_aes_key_bundle = base64_decode($data->aes_key);
- $ciphertext = base64_decode($data->encrypted_magic_envelope);
+ try {
+ if (!isset($data->aes_key) || !isset($data->encrypted_magic_envelope)) {
+ Logger::info('Missing keys "aes_key" and/or "encrypted_magic_envelope"', ['data' => $data]);
+ throw new \RuntimeException('Missing keys "aes_key" and/or "encrypted_magic_envelope"');
+ }
- $outer_key_bundle = '';
- @openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $privKey);
- $j_outer_key_bundle = json_decode($outer_key_bundle);
+ $encrypted_aes_key_bundle = base64_decode($data->aes_key);
+ $ciphertext = base64_decode($data->encrypted_magic_envelope);
+
+ $outer_key_bundle = '';
+ @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)) {
+ Logger::info('Unable to decode outer key bundle', ['outer_key_bundle' => $outer_key_bundle]);
+ throw new \RuntimeException('Unable to decode outer key bundle');
+ }
+
+ if (!isset($j_outer_key_bundle->iv) || !isset($j_outer_key_bundle->key)) {
+ Logger::info('Missing keys "iv" and/or "key" from outer Salmon', ['j_outer_key_bundle' => $j_outer_key_bundle]);
+ throw new \RuntimeException('Missing keys "iv" and/or "key" from outer Salmon');
+ }
- if (!is_object($j_outer_key_bundle)) {
+ $outer_iv = base64_decode($j_outer_key_bundle->iv);
+ $outer_key = base64_decode($j_outer_key_bundle->key);
+
+ $xml = self::aesDecrypt($outer_key, $outer_iv, $ciphertext);
+ } catch (\Throwable $e) {
Logger::notice('Outer Salmon did not verify. Discarding.');
if ($no_exit) {
return false;
throw new \Friendica\Network\HTTPException\BadRequestException();
}
}
-
- $outer_iv = base64_decode($j_outer_key_bundle->iv);
- $outer_key = base64_decode($j_outer_key_bundle->key);
-
- $xml = self::aesDecrypt($outer_key, $outer_iv, $ciphertext);
} else {
$xml = $raw;
}
$datarray = self::setDirection($datarray, $direction);
- $datarray['body'] = DI::contentItem()->createSharedPostByGuid($root_guid, $importer['uid'], $original_person['url']);
- $datarray['body'] = Diaspora::replacePeopleGuid($datarray['body'], $datarray['author-link']);
-
- /// @todo Copy tag data from original post
- Tag::storeFromBody($datarray['uri-id'], $datarray['body']);
+ $datarray['quote-uri-id'] = self::getQuoteUriId($root_guid, $importer['uid'], $original_person['url']);
+ if (empty($datarray['quote-uri-id'])) {
+ return false;
+ }
- $datarray['plink'] = self::plink($author, $guid);
+ $datarray['body'] = '';
+ $datarray['plink'] = self::plink($author, $guid);
$datarray['private'] = (($public == 'false') ? Item::PRIVATE : Item::PUBLIC);
$datarray['changed'] = $datarray['created'] = $datarray['edited'] = $created_at;
}
}
+ private static function getQuoteUriId(string $guid, int $uid, string $host): int
+ {
+ $shared_item = Post::selectFirst(['uri-id'], ['guid' => $guid, 'uid' => [$uid, 0], 'private' => [Item::PUBLIC, Item::UNLISTED]]);
+
+ if (!DBA::isResult($shared_item) && !empty($host) && Diaspora::storeByGuid($guid, $host, true)) {
+ Logger::debug('Fetched post', ['guid' => $guid, 'host' => $host, 'uid' => $uid]);
+ $shared_item = Post::selectFirst(['uri-id'], ['guid' => $guid, 'uid' => [$uid, 0], 'private' => [Item::PUBLIC, Item::UNLISTED]]);
+ } elseif (DBA::isResult($shared_item)) {
+ Logger::debug('Found existing post', ['guid' => $guid, 'host' => $host, 'uid' => $uid]);
+ }
+
+ if (!DBA::isResult($shared_item)) {
+ Logger::notice('Post does not exist.', ['guid' => $guid, 'host' => $host, 'uid' => $uid]);
+ return 0;
+ }
+
+ return $shared_item['uri-id'];
+ }
+
/**
* Processes retractions
*
*/
public static function getReshareDetails(array $item): array
{
- $reshared = DI::contentItem()->getSharedPost($item, ['network', 'author-addr']);
+ $reshared = DI::contentItem()->getSharedPost($item, ['guid', 'network', 'author-addr']);
if (empty($reshared)) {
return [];
}
return [
'root_handle' => strtolower($reshared['post']['author-addr']),
- 'root_guid' => $reshared['guid']
+ 'root_guid' => $reshared['post']['guid'],
];
}
$type = 'reshare';
} else {
$title = $item['title'];
- $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
+ $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item));
// Fetch the title from an attached link - if there is one
if (empty($item['title']) && DI::pConfig()->get($owner['uid'], 'system', 'attach_link_title')) {
}
}
- // @todo Check if this is obsolete and if we are still using different owners. (Possibly a fragment from the forum functionality)
- if ($item['author-link'] != $item['owner-link']) {
- $body = DI::contentItem()->createSharedBlockByArray($item);
- }
-
// convert to markdown
$body = html_entity_decode(BBCode::toMarkdown($body));
$thread_parent_item = Post::selectFirst(['guid', 'author-id', 'author-link', 'gravity'], ['uri' => $item['thr-parent'], 'uid' => $item['uid']]);
}
- $body = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']);
+ $body = Post\Media::addAttachmentsToBody($item['uri-id'], DI::contentItem()->addSharedPost($item));
// The replied to autor mention is prepended for clarity if:
// - Item replied isn't yours
Logger::info('Got relayable data ' . $type . ' for item ' . $item['guid'] . ' (' . $item['id'] . ')');
- $msg = json_decode($item['signed_text'], true);
+ $msg = json_decode($item['signed_text'] ?? '', true);
$message = [];
if (is_array($msg)) {
public static function performReshare(int $UriId, int $uid): int
{
- $post = DI::contentItem()->createSharedPostByUriId($UriId, $uid);
- if (empty($post)) {
- return 0;
- }
-
$owner = User::getOwnerDataById($uid);
$author = Contact::getPublicIdByUserId($uid);
$item = [
- 'uid' => $uid,
- 'verb' => Activity::POST,
- 'contact-id' => $owner['id'],
- 'author-id' => $author,
- 'owner-id' => $author,
- 'body' => $post,
- 'allow_cid' => $owner['allow_cid'] ?? '',
- 'allow_gid' => $owner['allow_gid']?? '',
- 'deny_cid' => $owner['deny_cid'] ?? '',
- 'deny_gid' => $owner['deny_gid'] ?? '',
+ 'uid' => $uid,
+ 'verb' => Activity::POST,
+ 'contact-id' => $owner['id'],
+ 'author-id' => $author,
+ 'owner-id' => $author,
+ 'body' => '',
+ 'quote-uri-id' => $UriId,
+ 'allow_cid' => $owner['allow_cid'] ?? '',
+ 'allow_gid' => $owner['allow_gid']?? '',
+ 'deny_cid' => $owner['deny_cid'] ?? '',
+ 'deny_gid' => $owner['deny_gid'] ?? '',
];
if (!empty($item['allow_cid'] . $item['allow_gid'] . $item['deny_cid'] . $item['deny_gid'])) {