friendica/src/Module/Debug/ActivityPubConversion.php
Philipp Holzer 8bdd90066f
Make BaseModule a real entity
- Add all dependencies, necessary to run the content (baseUrl, Arguments)
- Encapsulate all POST/GET/DELETE/PATCH/PUT methods as protected methods inside the BaseModule
- Return Module content ONLY per `BaseModule::run()` (including the Hook logic there as well)
2021-11-27 12:40:36 +01:00

147 lines
4.5 KiB
PHP

<?php
/**
* @copyright Copyright (C) 2010-2021, 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\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
{
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'];
}
$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, [
'$title' => DI::l10n()->t('ActivityPub Conversion'),
'$source' => ['source', DI::l10n()->t('Source activity'), $_REQUEST['source'] ?? '', ''],
'$results' => $results,
'$submit' => DI::l10n()->t('Submit'),
]);
return $o;
}
}