Browse Source

Merge pull request #720 from pixelfed/frontend-ui-refactor

Frontend ui refactor
daniel 6 years ago
parent
commit
ed4b217b3e

+ 2 - 0
.env.testing

@@ -53,3 +53,5 @@ MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
 MIX_APP_URL="${APP_URL}"
 MIX_API_BASE="${API_BASE}"
 MIX_API_SEARCH="${API_SEARCH}"
+
+TELESCOPE_ENABLED=false

+ 40 - 4
app/Http/Controllers/FederationController.php

@@ -180,6 +180,20 @@ XML;
         if($profile->status != null) {
             return ProfileController::accountCheck($profile);
         }
+        $body = $request->getContent();
+        $bodyDecoded = json_decode($body, true, 8);
+        if($this->verifySignature($request, $profile) == true) {
+            InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded);
+        } else if($this->blindKeyRotation($request, $profile) == true) {
+            InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded);
+        } else {
+            abort(400, 'Bad Signature');
+        }
+        return;
+    }
+
+    protected function verifySignature(Request $request, Profile $profile)
+    {
         $body = $request->getContent();
         $bodyDecoded = json_decode($body, true, 8);
         $signature = $request->header('signature');
@@ -209,11 +223,33 @@ XML;
         $pkey = openssl_pkey_get_public($actor->public_key);
         $inboxPath = "/users/{$profile->username}/inbox";
         list($verified, $headers) = HTTPSignature::verify($pkey, $signatureData, $request->headers->all(), $inboxPath, $body);
-        if($verified !== 1) { 
-            abort(400, 'Invalid signature.');
+        if($verified == 1) { 
+            return true;
+        } else {
+            return false;
         }
-        InboxWorker::dispatch($request->headers->all(), $profile, $bodyDecoded);
-        return;
+    }
+
+    protected function blindKeyRotation(Request $request, Profile $profile)
+    {
+        $signature = $request->header('signature');
+        if(!$signature) {
+            abort(400, 'Missing signature header');
+        }
+        $signatureData = HttpSignature::parseSignatureHeader($signature);
+        $keyId = Helpers::validateUrl($signatureData['keyId']);
+        $actor = Profile::whereKeyId($keyId)->first();
+        $res = Zttp::timeout(5)->withHeaders([
+          'Accept'     => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+          'User-Agent' => 'PixelFedBot v0.1 - https://pixelfed.org',
+        ])->get($actor->remote_url);
+        $res = json_decode($res->body(), true, 8);
+        if($res['publicKey']['id'] !== $actor->key_id) {
+            return false;
+        }
+        $actor->public_key = $res['publicKey']['publicKeyPem'];
+        $actor->save();
+        return $this->verifySignature($request, $profile);
     }
 
     public function userFollowing(Request $request, $username)

+ 32 - 0
app/Util/ActivityPub/Validator/Accept.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Util\ActivityPub\Validator;
+
+use Validator;
+use Illuminate\Validation\Rule;
+
+class Accept {
+
+	public static function validate($payload)
+	{
+		$valid = Validator::make($payload, [
+			'@context' => 'required',
+			'id' => 'required|string',
+			'type' => [
+				'required',
+				Rule::in(['Accept'])
+			],
+			'actor' => 'required|url|active_url',
+			'object' => 'required',
+			'object.id' => 'required|url|active_url',
+			'object.type' => [
+				'required',
+				Rule::in(['Follow'])
+			],
+			'object.actor' => 'required|url|active_url',
+			'object.object' => 'required|url|active_url|same:actor',
+		])->passes();
+
+		return $valid;
+	}
+}

+ 55 - 0
tests/Unit/ActivityPub/AcceptVerbTest.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace Tests\Unit;
+
+use Tests\TestCase;
+use Illuminate\Foundation\Testing\WithFaker;
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use App\Util\ActivityPub\Validator\Accept;
+
+class AcceptVerbTest extends TestCase
+{
+	protected $validAccept;
+	protected $invalidAccept;
+
+	public function setUp()
+	{
+		parent::setUp();
+		$this->validAccept = [
+			'@context' => 'https://www.w3.org/ns/activitystreams',
+			'id' => 'https://example.org/og/b3e4a40b-0b26-4c5a-9079-094bd633fab7',
+			'type' => 'Accept',
+			'actor' => 'https://example.org/u/alice',
+			'object' => [
+				'id' => 'https://example.net/u/bob#follows/bb27f601-ddb9-4567-8f16-023d90605ca9',
+				'type' => 'Follow',
+				'actor' => 'https://example.net/u/bob',
+				'object' => 'https://example.org/u/alice'
+			]
+		];
+		$this->invalidAccept = [
+			'@context' => 'https://www.w3.org/ns/activitystreams',
+			'id' => 'https://example.org/og/b3e4a40b-0b26-4c5a-9079-094bd633fab7',
+			'type' => 'Accept2',
+			'actor' => 'https://example.org/u/alice',
+			'object' => [
+				'id' => 'https://example.net/u/bob#follows/bb27f601-ddb9-4567-8f16-023d90605ca9',
+				'type' => 'Follow',
+				'actor' => 'https://example.net/u/bob',
+				'object' => 'https://example.org/u/alice'
+			]
+		];
+	}
+
+	/** @test */
+	public function basic_accept()
+	{
+		$this->assertTrue(Accept::validate($this->validAccept));
+	}
+
+	/** @test */
+	public function invalid_accept()
+	{
+		$this->assertFalse(Accept::validate($this->invalidAccept));
+	}
+}