ソースを参照

Add HTTPSignature util

Daniel Supernault 7 年 前
コミット
ee19583444
1 ファイル変更94 行追加0 行削除
  1. 94 0
      app/Util/ActivityPub/Concern/HTTPSignature.php

+ 94 - 0
app/Util/ActivityPub/Concern/HTTPSignature.php

@@ -0,0 +1,94 @@
+<?php
+
+namespace App\Util\ActivityPub\Concern;
+
+use Zttp\Zttp;
+
+class HTTPSignature {
+
+    protected $localhosts = [
+      '127.0.0.1', 'localhost', '::1'
+    ];
+    public $profile;
+    public $is_url;
+
+    public function validateUrl()
+    {
+        // If the profile exists, assume its valid
+        if($this->is_url === false) {
+          return true;
+        }
+
+        $url = $this->profile;
+        try {
+          $url = filter_var($url, FILTER_VALIDATE_URL);
+          $parsed = parse_url($url, PHP_URL_HOST);
+          if(!$parsed || in_array($parsed, $this->localhosts)) {
+            return false;
+          }
+        } catch (Exception $e) {
+          return false;
+        }
+        return true;
+    }
+
+    public function fetchPublicKey($profile, bool $is_url = true)
+    {
+        $this->profile = $profile;
+        $this->is_url = $is_url;
+        $valid = $this->validateUrl();
+        if(!$valid) {
+          throw new \Exception('Invalid URL provided');
+        }
+        if($is_url && isset($profile->public_key) && $profile->public_key) {
+          return $profile->public_key;
+        }
+
+        try {
+          $url = $this->profile;
+          $res = Zttp::timeout(60)->withoutVerifying()->withHeaders([
+              'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+              'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org'
+            ])->get($url);
+          $actor = json_decode($res->getBody(), true);
+        } catch (Exception $e) {
+          throw new Exception('Unable to fetch public key');
+        }
+
+        return $actor['publicKey']['publicKeyPem'];
+    }
+
+    public function sendSignedObject($senderProfile, $url, $body)
+    {
+        $profile = $senderProfile;
+        $context = new Context([
+            'keys' => [$profile->keyId() => $profile->private_key],
+            'algorithm' => 'rsa-sha256',
+            'headers' => ['(request-target)', 'Date'],
+        ]);
+
+        $handlerStack = GuzzleHttpSignatures::defaultHandlerFromContext($context);
+        $client = new Client(['handler' => $handlerStack]);
+
+        $headers = [
+            'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+            'Date' => date('D, d M Y h:i:s') . ' GMT',
+            'Content-Type' => 'application/activity+json',
+            'User-Agent' => 'PixelFedBot - https://pixelfed.org'
+        ];
+        
+        $response = $client->post($url, [
+            'options' => [
+                'allow_redirects' => false,
+                'verify' => true,
+                'timeout' => 30
+            ],
+            'headers' => $headers, 
+            'body' => $body
+        ]);
+
+        return $response->getBody();
+    }
+
+
+}