Răsfoiți Sursa

Add Bearcap util

Daniel Supernault 3 ani în urmă
părinte
comite
e90637098a
3 a modificat fișierele cu 136 adăugiri și 1 ștergeri
  1. 2 1
      app/Story.php
  2. 57 0
      app/Util/Lexer/Bearcap.php
  3. 77 0
      tests/Unit/BearcapTest.php

+ 2 - 1
app/Story.php

@@ -6,6 +6,7 @@ use Auth;
 use Storage;
 use Illuminate\Database\Eloquent\Model;
 use Pixelfed\Snowflake\HasSnowflakePrimary;
+use App\Util\Lexer\Bearcap;
 
 class Story extends Model
 {
@@ -66,7 +67,7 @@ class Story extends Model
 
 	public function bearcapUrl()
 	{
-		return "bear:?t={$this->bearcap_token}&u={$this->url()}";
+		return Bearcap::encode($this->url(), $this->bearcap_token);
 	}
 
 	public function scopeToAudience($scope)

+ 57 - 0
app/Util/Lexer/Bearcap.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace App\Util\Lexer;
+
+use Illuminate\Support\Str;
+use App\Util\ActivityPub\Helpers;
+
+class Bearcap
+{
+	public static function encode($url, $token)
+	{
+		return "bear:?t={$token}&u={$url}";
+	}
+
+	public static function decode($str)
+	{
+		if(!Str::startsWith($str, 'bear:')) {
+			return false;
+		}
+
+		$query = parse_url($str, PHP_URL_QUERY);
+
+		if(!$query) {
+			return false;
+		}
+
+		$res = [];
+
+		$parts = Str::of($str)->substr(6)->explode('&')->toArray();
+
+		foreach($parts as $part) {
+			if(Str::startsWith($part, 't=')) {
+				$res['token'] = substr($part, 2);
+			}
+
+			if(Str::startsWith($part, 'u=')) {
+				$res['url'] = substr($part, 2);
+			}
+		}
+
+		if( !isset($res['token']) ||
+			!isset($res['url'])
+		) {
+			return false;
+		}
+
+		$url = $res['url'];
+		if(mb_substr($url, 0, 8) !== 'https://') {
+			return false;
+		}
+		$valid = filter_var($url, FILTER_VALIDATE_URL);
+		if(!$valid) {
+			return false;
+		}
+		return $res;
+	}
+}

+ 77 - 0
tests/Unit/BearcapTest.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace Tests\Unit;
+
+use PHPUnit\Framework\TestCase;
+use App\Util\Lexer\Bearcap;
+
+class BearcapTest extends TestCase
+{
+	/** @test */
+	public function validTest()
+	{
+		$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=https://pixelfed.test/stories/admin/337892163734081536';
+		$expected = [
+			"token" => "LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2",
+			"url" => "https://pixelfed.test/stories/admin/337892163734081536",
+		];
+		$actual = Bearcap::decode($str);
+		$this->assertEquals($expected, $actual);
+	}
+
+	/** @test */
+	public function invalidTokenParameterName()
+	{
+		$str = 'bear:?token=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=https://pixelfed.test/stories/admin/337892163734081536';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+
+	/** @test */
+	public function invalidUrlParameterName()
+	{
+		$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&url=https://pixelfed.test/stories/admin/337892163734081536';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+
+	/** @test */
+	public function invalidScheme()
+	{
+		$str = 'bearcap:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&url=https://pixelfed.test/stories/admin/337892163734081536';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+
+	/** @test */
+	public function missingToken()
+	{
+		$str = 'bear:?u=https://pixelfed.test/stories/admin/337892163734081536';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+
+	/** @test */
+	public function missingUrl()
+	{
+		$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+
+	/** @test */
+	public function invalidHttpUrl()
+	{
+		$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=http://pixelfed.test/stories/admin/337892163734081536';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+
+	/** @test */
+	public function invalidUrlSchema()
+	{
+		$str = 'bear:?t=LpVypnEUdHhwwgXE9tTqEwrtPvmLjqYaPexqyXnVo1flSfJy5AYMCdRPiFRmqld2&u=phar://pixelfed.test/stories/admin/337892163734081536';
+		$actual = Bearcap::decode($str);
+		$this->assertFalse($actual);
+	}
+}