From 751ce50e2419f2343c49d15edc8f78ada876cb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=89=E6=AD=A3=E8=B6=85?= Date: Wed, 16 Aug 2023 16:56:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E7=A7=8D=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Signature.php | 29 ++++++++++++++++++++------- src/Support/XML.php | 2 +- tests/SignatureTest.php | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 tests/SignatureTest.php diff --git a/src/Signature.php b/src/Signature.php index 1b2f473..c5db057 100644 --- a/src/Signature.php +++ b/src/Signature.php @@ -21,7 +21,7 @@ public function __construct(public string $accessKey, public string $secretKey) { } - public function createAuthorizationHeader(RequestInterface $request, ?string $expires = null): string + public function createAuthorizationHeader(RequestInterface $request, int|string|\DateTimeInterface $expires = null): string { $signTime = self::getTimeSegments($expires); $queryToBeSigned = self::getQueryToBeSigned($request); @@ -68,10 +68,10 @@ protected static function getQueryToBeSigned(RequestInterface $request): array $query = []; foreach (explode('&', $request->getUri()->getQuery()) as $item) { if (! empty($item)) { - $tmpquery = explode('=', $item); - $key = strtolower($tmpquery[0]); - if (count($tmpquery) >= 2) { - $value = $tmpquery[1]; + $segments = explode('=', $item); + $key = strtolower($segments[0]); + if (count($segments) >= 2) { + $value = $segments[1]; } else { $value = ''; } @@ -83,13 +83,28 @@ protected static function getQueryToBeSigned(RequestInterface $request): array return $query; } - protected static function getTimeSegments(?string $expires): string + protected static function getTimeSegments(int|string|\DateTimeInterface $expires = '+60 minutes'): string { $timezone = \date_default_timezone_get(); date_default_timezone_set('PRC'); - $signTime = \sprintf('%s;%s', time() - 60, strtotime($expires ?? '+60 minutes')); + // '900'/900 + if (is_numeric($expires)) { + $expires = abs($expires); + } + + $expires = match (true) { + // 900/1700001234 + is_int($expires) => $expires >= time() ? $expires : time() + $expires, + // '+60 minutes'/'2023-01-01 00:00:00' + is_string($expires) => strtotime($expires), + // new \DateTime('2023-01-01 00:00:00') + $expires instanceof \DateTimeInterface => $expires->getTimestamp(), + default => time() + 60, + }; + + $signTime = \sprintf('%s;%s', time() - 60, $expires); date_default_timezone_set($timezone); diff --git a/src/Support/XML.php b/src/Support/XML.php index 56490ce..42a9275 100644 --- a/src/Support/XML.php +++ b/src/Support/XML.php @@ -16,7 +16,7 @@ public static function fromArray(array $data): bool|string if (empty($data)) { return ''; } - + return Transformer::toXml($data); } } diff --git a/tests/SignatureTest.php b/tests/SignatureTest.php new file mode 100644 index 0000000..6013ad3 --- /dev/null +++ b/tests/SignatureTest.php @@ -0,0 +1,44 @@ + time() + 900, + 60 => time() + 60, + time() + 3600 => time() + 3600, + '+ 1 hour' => strtotime('+ 1 hour'), + '+600 seconds' => strtotime('+600 seconds'), + '2021-01-01T00:00:00Z' => strtotime('2021-01-01T00:00:00Z'), + '2021-01-01' => strtotime('2021-01-01'), + '2021-01-01 00:00:00' => strtotime('2021-01-01 00:00:00'), + ]; + + foreach ($asserts as $input => $output) { + $expect = sprintf('q-sign-time=%d;%d&q-key-time=%d;%d', time() - 60, $output, time() - 60, $output); + $this->assertStringContainsString($expect, $signature->createAuthorizationHeader($request, $input)); + } + + // date + $date = \DateTimeImmutable::createFromFormat('Y-m-d 00:00:00', '2023-11-15 00:00:00'); + $expect = sprintf('q-sign-time=%d;%d&q-key-time=%d;%d', time() - 60, $date->getTimestamp(), time() - 60, $date->getTimestamp()); + + $this->assertStringContainsString($expect, $signature->createAuthorizationHeader($request, $date)); + + date_default_timezone_set($timezone); + } +}