Send Pixelfed User-Agent on federated account deletion deliveries

pull/7140/head
Your Name 2 weeks ago
parent 9c5be0e271
commit 327348be02

@ -322,7 +322,13 @@ class UserAccountDelete extends Command
$responses = Http::pool(function (Pool $pool) use ($urlList, $privateKey, $keyId, $digest, $payload, $payloadLen) {
foreach ($urlList as $url) {
$headers = HttpSignature::signRawWithDigest($privateKey, $keyId, $url, $digest);
// Pass User-Agent/Accept per request so they are actually sent
// (and signed); Http::pool does not inherit the makeHttpClient
// instance headers, so without this Guzzle sends its default UA.
$headers = HttpSignature::signRawWithDigest($privateKey, $keyId, $url, $digest, [
'User-Agent' => 'Pixelfed ('.config('app.url').')',
'Accept' => 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
]);
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"';
$headers['Content-Length'] = (string) $payloadLen;
@ -392,7 +398,10 @@ class UserAccountDelete extends Command
protected function sendDebug(string $url, string $payload, string $digest, string $privateKey, string $keyId): int
{
$headers = HttpSignature::signRawWithDigest($privateKey, $keyId, $url, $digest);
$headers = HttpSignature::signRawWithDigest($privateKey, $keyId, $url, $digest, [
'User-Agent' => 'Pixelfed ('.config('app.url').')',
'Accept' => 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
]);
$headers['Content-Type'] = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"';

@ -0,0 +1,72 @@
<?php
use App\Console\Commands\User\UserAccountDelete;
use Illuminate\Foundation\Testing\LazilyRefreshDatabase;
use Illuminate\Support\Facades\Http;
uses(LazilyRefreshDatabase::class);
/*
|--------------------------------------------------------------------------
| UserAccountDelete outbound User-Agent
|--------------------------------------------------------------------------
|
| The federated account-deletion POSTs must carry the Pixelfed User-Agent
| (set per-request via the HTTP signature), not Guzzle's default. Http::pool
| does not inherit the makeHttpClient instance headers.
|
*/
function generatePrivateKeyPem(): string
{
$res = openssl_pkey_new([
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);
openssl_pkey_export($res, $pem);
return $pem;
}
it('sends the Pixelfed User-Agent on pooled delete deliveries', function () {
Http::fake([
'*' => Http::response('', 202),
]);
$privateKey = generatePrivateKeyPem();
$keyId = 'https://local.test/users/alice#main-key';
$payload = '{"type":"Delete"}';
$digest = base64_encode(hash('sha256', $payload, true));
$urls = collect(['https://remote.example/f/inbox']);
$command = app(UserAccountDelete::class);
$ref = new ReflectionMethod($command, 'sendBatch');
$ref->setAccessible(true);
// sendBatch(PendingRequest $client, string $privateKey, string $keyId,
// string $digest, Collection $urls, string $payload, int $payloadLen,
// int $concurrency, bool $verboseErrors)
$client = (new ReflectionMethod($command, 'makeHttpClient'));
$client->setAccessible(true);
$pendingClient = $client->invoke($command);
$ref->invoke(
$command,
$pendingClient,
$privateKey,
$keyId,
$digest,
$urls,
$payload,
strlen($payload),
5,
false
);
Http::assertSent(function ($request) {
return $request->url() === 'https://remote.example/f/inbox'
&& $request->hasHeader('User-Agent')
&& str_contains($request->header('User-Agent')[0], 'Pixelfed');
});
});
Loading…
Cancel
Save