aboutsummaryrefslogtreecommitdiffhomepage
path: root/misc/send_request_authenticated.php
diff options
context:
space:
mode:
Diffstat (limited to 'misc/send_request_authenticated.php')
-rw-r--r--misc/send_request_authenticated.php66
1 files changed, 66 insertions, 0 deletions
diff --git a/misc/send_request_authenticated.php b/misc/send_request_authenticated.php
new file mode 100644
index 0000000..9019da8
--- /dev/null
+++ b/misc/send_request_authenticated.php
@@ -0,0 +1,66 @@
+<?php
+
+use Digitigrade\GlobalConfig;
+use Digitigrade\Model\Actor;
+use Digitigrade\Model\Instance;
+
+/**
+ * Makes an HTTPS request to a remote instance, using the corresponding outbound auth token (if any)
+ * @param string $uri
+ * @param bool $dontLookUpInstance if true, will skip looking up the Instance, and consequently the auth token
+ * @param string $method HTTP verb
+ * @param ?Actor $actingAs if specified, the local actor to send the request on behalf of
+ * @return stdClass object with fields `body` and `headers`
+ */
+function send_request_authenticated(
+ string $uri,
+ bool $dontLookUpInstance = false,
+ string $method = 'GET',
+ ?Actor $actingAs = null
+) {
+ if (!str_starts_with($uri, 'https://')) {
+ throw new RuntimeException('refusing to fetch a non-https uri');
+ }
+
+ $remoteHost = hostname_from_uri($uri);
+ if ($remoteHost == GlobalConfig::getInstance()->getCanonicalHost()) {
+ throw new RuntimeException('refusing to fetch content from myself');
+ }
+
+ $instance = null;
+ if (!$dontLookUpInstance) {
+ $instance = Instance::findByHostname($remoteHost);
+ }
+
+ if (!isset($instance->auth->outboundToken) || $instance->auth->outboundToken == null) {
+ // hopefully we can make the request anyway?
+ $context = stream_context_create(['http' => ['method' => $method]]);
+ $resp = file_get_contents($uri);
+ // $http_response_header just poofs into existence .
+ // i don't like this api. i should probably use curl instead. hmm
+ // TODO: use curl instead of file_get_contents
+ if (str_contains($http_response_header[0], '401') || str_contains($http_response_header[0], '403')) {
+ // we can't authenticate right now because it's asynchronous
+ // so i'm choosing to begin the auth process now and return false in the hopes that
+ // this request will be retried later
+ $instance?->beginOutboundAuth();
+ }
+ $result = new stdClass();
+ $result->body = $resp;
+ $result->headers = $http_response_header;
+ return $result;
+ }
+
+ $header = 'Authorization: Bearer ' . $instance->auth->outboundToken;
+ if ($actingAs != null) {
+ $header .= "\nX-PawPub-Actor: $actingAs->uri";
+ }
+ $context = stream_context_create(['http' => [
+ 'method' => $method,
+ 'header' => $header
+ ]]);
+ $result = new stdClass();
+ $result->body = file_get_contents($uri, context: $context);
+ $result->headers = $http_response_header;
+ return $result;
+} \ No newline at end of file