145 lines
4.5 KiB
PHP
145 lines
4.5 KiB
PHP
<?php
|
|
/**
|
|
* @copyright Copyright (C) 2010-2022, 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\Debug;
|
|
|
|
use Friendica\BaseModule;
|
|
use Friendica\Core\Renderer;
|
|
use Friendica\DI;
|
|
use Friendica\Protocol\ActivityPub;
|
|
use Friendica\Util\JsonLD;
|
|
|
|
class ActivityPubConversion extends BaseModule
|
|
{
|
|
protected function content(array $request = []): string
|
|
{
|
|
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'];
|
|
}
|
|
|
|
if (!empty($activity['completion-mode'])) {
|
|
$object_data['completion-mode'] = $activity['completion-mode'];
|
|
}
|
|
|
|
$results[] = [
|
|
'title' => DI::l10n()->t('Object data'),
|
|
'content' => visible_whitespace(var_export($object_data, true))
|
|
];
|
|
|
|
$item = ActivityPub\Processor::createItem($object_data, true);
|
|
|
|
$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, [
|
|
'$title' => DI::l10n()->t('ActivityPub Conversion'),
|
|
'$source' => ['source', DI::l10n()->t('Source activity'), $_REQUEST['source'] ?? '', ''],
|
|
'$results' => $results,
|
|
'$submit' => DI::l10n()->t('Submit'),
|
|
]);
|
|
|
|
return $o;
|
|
}
|
|
}
|