Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@
- szaimen <szaimen@e.mail.de>
- tbartenstein <tbartenstein@users.noreply.github.com>
- tbelau666 <thomas.belau@gmx.de>
- TechnicalSuwako <suwako@076.moe>
- tgrant <tom.grant760@gmail.com>
- timm2k <timm2k@gmx.de>
- tux-rampage <tux-rampage@users.noreply.github.com>
Expand Down
21 changes: 19 additions & 2 deletions lib/private/Accounts/AccountManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ private function sanitizePropertyFediverse(IAccountProperty $property): void {

try {
// try the public account lookup API of mastodon
$response = $client->get("https://{$instance}/api/v1/accounts/lookup?acct={$username}@{$instance}");
$response = $client->get("https://{$instance}/.well-known/webfinger?resource=acct:{$username}@{$instance}");
// should be a json response with account information
$data = $response->getBody();
if (is_resource($data)) {
Expand All @@ -738,9 +738,26 @@ private function sanitizePropertyFediverse(IAccountProperty $property): void {
$decoded = json_decode($data, true);
// ensure the username is the same the user passed
// in this case we can assume this is a valid fediverse server and account
if (!is_array($decoded) || ($decoded['username'] ?? '') !== $username) {
if (!is_array($decoded) || ($decoded['subject'] ?? '') !== "acct:{$username}@{$instance}") {
throw new InvalidArgumentException();
}
// check for activitypub link
if (is_array($decoded['links']) && isset($decoded['links'])) {
$found = false;
foreach ($decoded['links'] as $link) {
// have application/activity+json or application/ld+json
if (isset($link['type']) && (
$link['type'] === 'application/activity+json' ||
$link['type'] === 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
)) {
$found = true;
break;
}
}
if (!$found) {
throw new InvalidArgumentException();
}
}
} catch (InvalidArgumentException) {
throw new InvalidArgumentException(self::PROPERTY_FEDIVERSE);
} catch (\Exception $error) {
Expand Down
35 changes: 29 additions & 6 deletions tests/lib/Accounts/AccountManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -786,20 +786,41 @@ public static function dataSanitizeFediverseServer(): array {
'@foo@example.com',
'foo@example.com',
true,
json_encode(['username' => 'foo']),
json_encode([
'subject' => 'acct:foo@example.com',
'links' => [
[
'rel' => 'self',
'type' => 'application/activity+json',
'href' => 'https://example.com/users/foo',
],
],
]),
],
'valid response - no at' => [
'foo@example.com',
'foo@example.com',
true,
json_encode(['username' => 'foo']),
json_encode([
'subject' => 'acct:foo@example.com',
'links' => [
[
'rel' => 'self',
'type' => 'application/activity+json',
'href' => 'https://example.com/users/foo',
],
],
]),
],
// failures
'invalid response' => [
'@foo@example.com',
null,
true,
json_encode(['not found']),
json_encode([
'subject' => 'acct:foo@example.com',
'links' => [],
]),
],
'no response' => [
'@foo@example.com',
Expand All @@ -811,7 +832,9 @@ public static function dataSanitizeFediverseServer(): array {
'@foo@example.com',
null,
true,
json_encode(['username' => 'foo@other.example.com']),
json_encode([
'links' => [],
]),
],
];
}
Expand All @@ -833,12 +856,12 @@ public function testSanitizingFediverseServer(string $input, ?string $output, bo
->willReturn($serverResponse);
$client->expects(self::once())
->method('get')
->with('https://example.com/api/v1/accounts/lookup?acct=foo@example.com')
->with('https://example.com/.well-known/webfinger?resource=acct:foo@example.com')
->willReturn($response);
} else {
$client->expects(self::once())
->method('get')
->with('https://example.com/api/v1/accounts/lookup?acct=foo@example.com')
->with('https://example.com/.well-known/webfinger?resource=acct:foo@example.com')
->willThrowException(new \Exception('404'));
}

Expand Down
Loading