aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorwinter2024-12-09 21:13:16 +0000
committerwinter2024-12-09 21:13:16 +0000
commit1ab1c4d9c6a28e9929052bd00f15866eb1a5a200 (patch)
tree1396a368e7e05eb3c701d69deb9311d7361dd2ba
parentbda28640d6e066ae338c6f31407df274ed09f026 (diff)
implement webfinger lookups
-rw-r--r--WpfTest/Model/Actor.php33
-rw-r--r--WpfTest/Model/FetchableModel.php2
-rwxr-xr-xbin/shell12
-rw-r--r--routes/webfinger.php12
4 files changed, 53 insertions, 6 deletions
diff --git a/WpfTest/Model/Actor.php b/WpfTest/Model/Actor.php
index 0b0e729..a745a96 100644
--- a/WpfTest/Model/Actor.php
+++ b/WpfTest/Model/Actor.php
@@ -4,6 +4,8 @@ namespace WpfTest\Model;
use WpfTest\RemoteFetchable;
class Actor extends FetchableModel implements \JsonSerializable {
+ public const REL_URI = "https://pawpub.entities.org.uk/rel/actor.html";
+
public ?int $id;
public string $uri;
public bool $isLocal = false;
@@ -32,6 +34,37 @@ class Actor extends FetchableModel implements \JsonSerializable {
return self::findWhere('is_local = true AND handle = ?', [$handle]);
}
+ public static function findByWebfinger(string $acct, bool $autoSave = true, bool $forceRefetch = false): ?self {
+ // normalise uri
+ if (!str_starts_with($acct, 'acct:')) {
+ if (str_starts_with($acct, '@')) {
+ $acct = substr($acct, 1);
+ }
+ $acct = "acct:$acct";
+ }
+ // fetch it
+ $domain = explode('@', $acct, 2)[1];
+ $data = @file_get_contents("https://$domain/.well-known/webfinger?resource=$acct",
+ context: stream_context_create([
+ 'http' => ['header' => 'Accept: application/jrd+json, application/json']
+ ])
+ );
+ if ($data === false)
+ return null;
+ $data = json_decode($data);
+ if ($data === null)
+ return null;
+ // find the right link
+ if (!isset($data->links))
+ return null;
+ $matching = array_filter($data->links, function (\stdClass $linkObj) {
+ return $linkObj->rel == self::REL_URI;
+ });
+ if (count($matching) == 0)
+ return null;
+ return self::findByUri($matching[0]->href, $autoSave, $forceRefetch);
+ }
+
public function jsonSerialize(): array {
return [
'type' => 'actor',
diff --git a/WpfTest/Model/FetchableModel.php b/WpfTest/Model/FetchableModel.php
index 44106d4..5dce010 100644
--- a/WpfTest/Model/FetchableModel.php
+++ b/WpfTest/Model/FetchableModel.php
@@ -21,7 +21,7 @@ abstract class FetchableModel extends Model implements RemoteFetchable {
if ($data === false)
return null;
$data = json_decode($data);
- if ($data === false)
+ if ($data === null)
return null;
// default everything nullable to null
$obj = new static();
diff --git a/bin/shell b/bin/shell
new file mode 100755
index 0000000..d699a14
--- /dev/null
+++ b/bin/shell
@@ -0,0 +1,12 @@
+#!/bin/sh
+# set up autoloads<?php echo "\n"; goto skipShell; ?>
+cd "$(dirname "$0")/../" || exit 1
+php -a -d auto_prepend_file=bin/shell
+exit
+
+<?php skipShell:
+require __DIR__ . '/../vendor/autoload.php';
+foreach (glob(__DIR__ . '/../misc/*.php') as $filename) {
+ require $filename;
+}
+
diff --git a/routes/webfinger.php b/routes/webfinger.php
index 4445cad..db29e73 100644
--- a/routes/webfinger.php
+++ b/routes/webfinger.php
@@ -3,6 +3,7 @@
use WpfTest\GlobalConfig;
use WpfTest\HttpResponseStatus\BadRequest;
use WpfTest\HttpResponseStatus\NotFound;
+use WpfTest\Model\Actor;
use WpfTest\Router;
Router::getInstance()->mount('/.well-known/webfinger', function (array $args) {
@@ -18,15 +19,16 @@ Router::getInstance()->mount('/.well-known/webfinger', function (array $args) {
if ($remotePart != GlobalConfig::getInstance()->getCanonicalHost()) {
throw new NotFound('i only know about local accounts');
}
- if ($localPart != 'winter') {
- throw new NotFound('i only know about winter!!!');
+ $actor = Actor::findLocalByHandle($localPart);
+ if ($actor == null) {
+ throw new NotFound('no local actor found with that name!');
}
json_response([
- 'subject' => "acct:$localPart@$remotePart",
+ 'subject' => "acct:$actor->handle@$remotePart",
'links' => [
[
- 'rel' => 'urn:example:wpf:actor',
- 'href' => path_to_uri('/user/winter'),
+ 'rel' => Actor::REL_URI,
+ 'href' => path_to_uri("/user/$actor->handle"),
'type' => 'application/json'
]
]