aboutsummaryrefslogtreecommitdiffhomepage
path: root/misc/get_remote_object_authenticated.php
blob: 9f2db4350a13dfe076b6ee78526de11cc2b52da6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php

use Digitigrade\GlobalConfig;
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
 * @return false|string the response data, or false if it failed
 */
function get_remote_object_authenticated(string $uri, bool $dontLookUpInstance = false, string $method = 'GET'): false|string {
    if (!str_starts_with($uri, 'https://'))
        return false;

    $remoteHost = hostname_from_uri($uri);
    if ($remoteHost == GlobalConfig::getInstance()->getCanonicalHost()) {
        // refuse to fetch objects from ourself. that's silly
        return false;
    }

    $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();
            return false;
        }
        return $resp;
    }

    $context = stream_context_create(['http' => [
        'method' => $method,
        'header' => 'Authorization: Bearer ' . $instance->auth->outboundToken
    ]]);
    return file_get_contents($uri, context: $context);
}