mirror of
https://github.com/friendica/friendica
synced 2025-04-19 14:30:10 +00:00
Add new admin debug module for ActivityPub
This commit is contained in:
parent
c26cc5b75e
commit
0a71495fa4
4 changed files with 170 additions and 0 deletions
144
src/Module/Debug/ActivityPubConversion.php
Normal file
144
src/Module/Debug/ActivityPubConversion.php
Normal file
|
@ -0,0 +1,144 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue