friendica/src/Module/Debug/ActivityPubConversion.php

145 lines
4.4 KiB
PHP
Raw Normal View History

<?php
/**
* @copyright Copyright (C) 2020, Friendica
*
* @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\Debug;
use Friendica\BaseModule;
use Friendica\Content\Text;
use Friendica\Core\Logger;
use Friendica\Core\Renderer;
use Friendica\DI;
use Friendica\Model\Item;
use Friendica\Model\Tag;
use Friendica\Protocol\ActivityPub;
use Friendica\Util\JsonLD;
use Friendica\Util\XML;
class ActivityPubConversion extends BaseModule
{
public static function content(array $parameters = [])
{
function visible_whitespace($s)
{
return '<pre>' . htmlspecialchars($s) . '</pre>';
}
$results = [];
if (!empty($_REQUEST['source'])) {
try {
$source = json_decode($_REQUEST['source'], true);
$trust_source = true;
$uid = local_user();
$push = false;
if (!$source) {
throw new \Exception('Failed to decode source JSON');
}
$formatted = json_encode($source, JSON_PRETTY_PRINT);
$results[] = [
'title' => DI::l10n()->t('Formatted'),
'content' => visible_whitespace(trim(var_export($formatted, true), "'")),
];
$results[] = [
'title' => DI::l10n()->t('Source'),
'content' => visible_whitespace(var_export($source, true))
];
$activity = JsonLD::compact($source);
if (!$activity) {
throw new \Exception('Failed to compact JSON');
}
$results[] = [
'title' => DI::l10n()->t('Activity'),
'content' => visible_whitespace(var_export($activity, true))
];
$type = JsonLD::fetchElement($activity, '@type');
if (!$type) {
throw new \Exception('Empty type');
}
if (!JsonLD::fetchElement($activity, 'as:object', '@id')) {
throw new \Exception('Empty object');
}
if (!JsonLD::fetchElement($activity, 'as:actor', '@id')) {
throw new \Exception('Empty actor');
}
// Don't trust the source if "actor" differs from "attributedTo". The content could be forged.
if ($trust_source && ($type == 'as:Create') && is_array($activity['as:object'])) {
$actor = JsonLD::fetchElement($activity, 'as:actor', '@id');
$attributed_to = JsonLD::fetchElement($activity['as:object'], 'as:attributedTo', '@id');
$trust_source = ($actor == $attributed_to);
if (!$trust_source) {
throw new \Exception('Not trusting actor: ' . $actor . '. It differs from attributedTo: ' . $attributed_to);
}
}
// $trust_source is called by reference and is set to true if the content was retrieved successfully
$object_data = ActivityPub\Receiver::prepareObjectData($activity, $uid, $push, $trust_source);
if (empty($object_data)) {
throw new \Exception('No object data found');
}
if (!$trust_source) {
throw new \Exception('No trust for activity type "' . $type . '", so we quit now.');
}
if (!empty($body) && empty($object_data['raw'])) {
$object_data['raw'] = $body;
}
// Internal flag for thread completion. See Processor.php
if (!empty($activity['thread-completion'])) {
$object_data['thread-completion'] = $activity['thread-completion'];
}
$results[] = [
'title' => DI::l10n()->t('Object data'),
'content' => visible_whitespace(var_export($object_data, true))
];
$item = ActivityPub\Processor::createItem($object_data);
$results[] = [
'title' => DI::l10n()->t('Result Item'),
'content' => visible_whitespace(var_export($item, true))
];
} catch (\Throwable $e) {
$results[] = [
'title' => DI::l10n()->t('Error'),
'content' => $e->getMessage(),
];
}
}
$tpl = Renderer::getMarkupTemplate('debug/activitypubconversion.tpl');
$o = Renderer::replaceMacros($tpl, [
'$source' => ['source', DI::l10n()->t('Source activity'), $_REQUEST['source'] ?? '', ''],
'$results' => $results
]);
return $o;
}
}