aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorwinter2024-12-17 15:42:44 +0000
committerwinter2024-12-17 15:42:44 +0000
commitbc2cd99b108b8755a648c3915714e7c0e0771548 (patch)
tree3e762a283176c5e0c881bdd46eba3e38eab86a5a
parent8cbb7f7c632961f615f9b5f9bd51984b9a929340 (diff)
send auth header when fetching objects (untested again)
-rw-r--r--Digitigrade/Model.php4
-rw-r--r--Digitigrade/Model/FetchableModel.php5
-rw-r--r--misc/get_remote_object_authenticated.php40
3 files changed, 46 insertions, 3 deletions
diff --git a/Digitigrade/Model.php b/Digitigrade/Model.php
index b5c9e99..a065154 100644
--- a/Digitigrade/Model.php
+++ b/Digitigrade/Model.php
@@ -71,6 +71,10 @@ abstract class Model {
} elseif (is_array($value)) {
// arrays ought to be handled separately when saving (different db table)
$discarded = true;
+ } elseif ($value == null && $pName == 'id') {
+ // don't overwrite an existing primary key with null ..
+ // this is kinda janky but it hopefully will work
+ $discarded = true;
}
if (!$discarded)
$result[self::mangleName($pName)] = $value;
diff --git a/Digitigrade/Model/FetchableModel.php b/Digitigrade/Model/FetchableModel.php
index e091a87..bd25d39 100644
--- a/Digitigrade/Model/FetchableModel.php
+++ b/Digitigrade/Model/FetchableModel.php
@@ -15,9 +15,8 @@ abstract class FetchableModel extends Model implements RemoteFetchable {
protected static function fetchFromRemote(string $uri, bool $autoSave): ?static {
// fetch the object
- $data = @file_get_contents($uri, context: stream_context_create(['http' => [
- 'header' => 'Accept: application/json'
- ]]));
+ // janky hack: if this is an Instance then avoid recursively fetching itself
+ $data = @get_remote_object_authenticated($uri, static::class == Instance::class);
if ($data === false)
return null;
$data = json_decode($data);
diff --git a/misc/get_remote_object_authenticated.php b/misc/get_remote_object_authenticated.php
new file mode 100644
index 0000000..ba67473
--- /dev/null
+++ b/misc/get_remote_object_authenticated.php
@@ -0,0 +1,40 @@
+<?php
+
+use Digitigrade\Model\Instance;
+
+/**
+ * Makes an HTTPS GET 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
+ * @return false|string the response data, or false if it failed
+ */
+function get_remote_object_authenticated(string $uri, bool $dontLookUpInstance = false) {
+ if (!str_starts_with($uri, 'https://'))
+ return false;
+
+ $instance = null;
+ if (!$dontLookUpInstance) {
+ $instance = Instance::findByDomain(explode('/', $uri)[2]);
+ }
+
+ if ($instance?->auth?->outboundToken == null) {
+ // hopefully we can make the request anyway?
+ $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' => [
+ 'header' => 'Authorization: Bearer ' . $instance->auth->outboundToken
+ ]]);
+ return file_get_contents($uri, context: $context);
+} \ No newline at end of file