diff --git a/docs/swagger/definitions/Error.json b/docs/swagger/definitions/Error.json
index 006fa47a..217f32c5 100644
--- a/docs/swagger/definitions/Error.json
+++ b/docs/swagger/definitions/Error.json
@@ -17,16 +17,6 @@
"status": {
"type": "number",
"description": "HTTP response status code"
- },
- "code": {
- "type": "string",
- "description": "**[Deprecated] Use type instead. Not returned for v2 of the REST API** A machine unique code",
- "deprecated": true
- },
- "message": {
- "type": "string",
- "description": "**[Deprecated] Use detail instead. Not returned for v2 of the REST API** A human-friendly error message",
- "deprecated": true
}
}
}
diff --git a/docs/swagger/definitions/ShortUrl.json b/docs/swagger/definitions/ShortUrl.json
index 9b259249..8111bd6e 100644
--- a/docs/swagger/definitions/ShortUrl.json
+++ b/docs/swagger/definitions/ShortUrl.json
@@ -31,11 +31,6 @@
},
"meta": {
"$ref": "./ShortUrlMeta.json"
- },
- "originalUrl": {
- "deprecated": true,
- "type": "string",
- "description": "The original long URL. [DEPRECATED. Use longUrl instead]"
}
}
}
diff --git a/docs/swagger/definitions/Visit.json b/docs/swagger/definitions/Visit.json
index 131bc84e..9e1eb5b5 100644
--- a/docs/swagger/definitions/Visit.json
+++ b/docs/swagger/definitions/Visit.json
@@ -16,11 +16,6 @@
},
"visitLocation": {
"$ref": "./VisitLocation.json"
- },
- "remoteAddr": {
- "type": "string",
- "description": "This value is deprecated and will always be null",
- "deprecated": true
}
}
}
diff --git a/docs/swagger/paths/v1_authenticate.json b/docs/swagger/paths/v1_authenticate.json
deleted file mode 100644
index cffa9e05..00000000
--- a/docs/swagger/paths/v1_authenticate.json
+++ /dev/null
@@ -1,84 +0,0 @@
-{
- "post": {
- "deprecated": true,
- "operationId": "authenticate",
- "tags": [
- "Authentication"
- ],
- "summary": "[Deprecated] Perform authentication",
- "description": "**This endpoint is deprecated, since the authentication can be performed via API key now**. Performs an authentication.",
- "requestBody": {
- "description": "Request body.",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "required": [
- "apiKey"
- ],
- "properties": {
- "apiKey": {
- "description": "The API key to authenticate with",
- "type": "string"
- }
- }
- }
- }
- }
- },
- "responses": {
- "200": {
- "description": "The authentication worked.",
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "token": {
- "type": "string",
- "description": "The authentication token that needs to be sent in the Authorization header"
- }
- }
- }
- }
- },
- "examples": {
- "application/json": {
- "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ"
- }
- }
- },
- "400": {
- "description": "An API key was not provided.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "../definitions/Error.json"
- }
- }
- }
- },
- "401": {
- "description": "The API key is incorrect, is disabled or has expired.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "../definitions/Error.json"
- }
- }
- }
- },
- "500": {
- "description": "Unexpected error.",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "../definitions/Error.json"
- }
- }
- }
- }
- }
- }
-}
diff --git a/docs/swagger/paths/v1_short-urls.json b/docs/swagger/paths/v1_short-urls.json
index 46708e22..0c6d0484 100644
--- a/docs/swagger/paths/v1_short-urls.json
+++ b/docs/swagger/paths/v1_short-urls.json
@@ -5,7 +5,7 @@
"Short URLs"
],
"summary": "List short URLs",
- "description": "Returns the list of short URLs.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Returns the list of short URLs.",
"parameters": [
{
"$ref": "../parameters/version.json"
@@ -77,9 +77,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
@@ -187,13 +184,10 @@
"Short URLs"
],
"summary": "Create short URL",
- "description": "Creates a new short URL.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.
**Param findIfExists:**: Starting with v1.16, this new param allows to force shlink to return existing short URLs when found based on provided params, instead of creating a new one. However, it might add complexity and have unexpected outputs.\n\nThese are the use cases:\n* Only the long URL is provided: It will return the newest match or create a new short URL if none is found.\n* Long url and custom slug are provided: It will return the short URL when both params match, return an error when the slug is in use for another long URL, or create a new short URL otherwise.\n* Any of the above but including other params (tags, validSince, validUntil, maxVisits): It will behave the same as the previous two cases, but it will try to exactly match existing results using all the params. If any of them does not match, it will try to create a new short URL.",
+ "description": "Creates a new short URL.
**Param findIfExists:**: Starting with v1.16, this new param allows to force shlink to return existing short URLs when found based on provided params, instead of creating a new one. However, it might add complexity and have unexpected outputs.\n\nThese are the use cases:\n* Only the long URL is provided: It will return the newest match or create a new short URL if none is found.\n* Long url and custom slug are provided: It will return the short URL when both params match, return an error when the slug is in use for another long URL, or create a new short URL otherwise.\n* Any of the above but including other params (tags, validSince, validUntil, maxVisits): It will behave the same as the previous two cases, but it will try to exactly match existing results using all the params. If any of them does not match, it will try to create a new short URL.",
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"parameters": [
diff --git a/docs/swagger/paths/v1_short-urls_shorten.json b/docs/swagger/paths/v1_short-urls_shorten.json
index 49233c49..c5ad9352 100644
--- a/docs/swagger/paths/v1_short-urls_shorten.json
+++ b/docs/swagger/paths/v1_short-urls_shorten.json
@@ -5,7 +5,7 @@
"Short URLs"
],
"summary": "Create a short URL",
- "description": "Creates a short URL in a single API call. Useful for third party integrations.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Creates a short URL in a single API call. Useful for third party integrations.",
"parameters": [
{
"$ref": "../parameters/version.json"
diff --git a/docs/swagger/paths/v1_short-urls_{shortCode}.json b/docs/swagger/paths/v1_short-urls_{shortCode}.json
index 95532868..d4537a83 100644
--- a/docs/swagger/paths/v1_short-urls_{shortCode}.json
+++ b/docs/swagger/paths/v1_short-urls_{shortCode}.json
@@ -5,7 +5,7 @@
"Short URLs"
],
"summary": "Parse short code",
- "description": "Get the long URL behind a short URL's short code.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Get the long URL behind a short URL's short code.",
"parameters": [
{
"$ref": "../parameters/version.json"
@@ -32,9 +32,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
@@ -94,7 +91,7 @@
"Short URLs"
],
"summary": "Edit short URL",
- "description": "Update certain meta arguments from an existing short URL.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Update certain meta arguments from an existing short URL.",
"parameters": [
{
"$ref": "../parameters/version.json"
@@ -137,9 +134,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
@@ -201,105 +195,13 @@
}
},
- "put": {
- "deprecated": true,
- "operationId": "editShortUrlPut",
- "tags": [
- "Short URLs"
- ],
- "summary": "[DEPRECATED] Edit short URL",
- "description": "**[DEPRECATED]** Use [editShortUrl](#/Short_URLs/getShortUrl) instead",
- "parameters": [
- {
- "$ref": "../parameters/version.json"
- },
- {
- "name": "shortCode",
- "in": "path",
- "description": "The short code to edit.",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "requestBody": {
- "description": "Request body.",
- "required": true,
- "content": {
- "application/json": {
- "schema": {
- "type": "object",
- "properties": {
- "validSince": {
- "description": "The date (in ISO-8601 format) from which this short code will be valid",
- "type": "string"
- },
- "validUntil": {
- "description": "The date (in ISO-8601 format) until which this short code will be valid",
- "type": "string"
- },
- "maxVisits": {
- "description": "The maximum number of allowed visits for this short code",
- "type": "number"
- }
- }
- }
- }
- }
- },
- "security": [
- {
- "ApiKey": []
- },
- {
- "Bearer": []
- }
- ],
- "responses": {
- "204": {
- "description": "The short code has been properly updated."
- },
- "400": {
- "description": "Provided meta arguments are invalid.",
- "content": {
- "application/problem+json": {
- "schema": {
- "$ref": "../definitions/Error.json"
- }
- }
- }
- },
- "404": {
- "description": "No short URL was found for provided short code.",
- "content": {
- "application/problem+json": {
- "schema": {
- "$ref": "../definitions/Error.json"
- }
- }
- }
- },
- "500": {
- "description": "Unexpected error.",
- "content": {
- "application/problem+json": {
- "schema": {
- "$ref": "../definitions/Error.json"
- }
- }
- }
- }
- }
- },
-
"delete": {
"operationId": "deleteShortUrl",
"tags": [
"Short URLs"
],
"summary": "Delete short URL",
- "description": "Deletes the short URL for provided short code.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Deletes the short URL for provided short code.",
"parameters": [
{
"$ref": "../parameters/version.json"
@@ -317,9 +219,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
diff --git a/docs/swagger/paths/v1_short-urls_{shortCode}_tags.json b/docs/swagger/paths/v1_short-urls_{shortCode}_tags.json
index 45142e62..4065f718 100644
--- a/docs/swagger/paths/v1_short-urls_{shortCode}_tags.json
+++ b/docs/swagger/paths/v1_short-urls_{shortCode}_tags.json
@@ -5,7 +5,7 @@
"Short URLs"
],
"summary": "Edit tags on short URL",
- "description": "Edit the tags on URL identified by provided short code.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Edit the tags on URL identified by provided short code.",
"parameters": [
{
"$ref": "../parameters/version.json"
@@ -46,9 +46,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
diff --git a/docs/swagger/paths/v1_short-urls_{shortCode}_visits.json b/docs/swagger/paths/v1_short-urls_{shortCode}_visits.json
index 508449de..4d1c1c6a 100644
--- a/docs/swagger/paths/v1_short-urls_{shortCode}_visits.json
+++ b/docs/swagger/paths/v1_short-urls_{shortCode}_visits.json
@@ -5,7 +5,7 @@
"Visits"
],
"summary": "List visits for short URL",
- "description": "Get the list of visits on the short URL behind provided short code.
**Important note**: Before shlink v1.13, this endpoint used to use the `/short-codes` path instead of `/short-urls`. Both of them will keep working, while the first one is considered deprecated.",
+ "description": "Get the list of visits on the short URL behind provided short code.",
"parameters": [
{
"$ref": "../parameters/version.json"
@@ -59,9 +59,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
diff --git a/docs/swagger/paths/v1_tags.json b/docs/swagger/paths/v1_tags.json
index a0fcc512..5e7fd71c 100644
--- a/docs/swagger/paths/v1_tags.json
+++ b/docs/swagger/paths/v1_tags.json
@@ -9,9 +9,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"parameters": [
@@ -78,9 +75,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"parameters": [
@@ -170,9 +164,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"parameters": [
@@ -279,9 +270,6 @@
"security": [
{
"ApiKey": []
- },
- {
- "Bearer": []
}
],
"responses": {
diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json
index e49a9ee1..ddf2b3ad 100644
--- a/docs/swagger/swagger.json
+++ b/docs/swagger/swagger.json
@@ -33,12 +33,6 @@
"type": "apiKey",
"in": "header",
"name": "X-Api-Key"
- },
- "Bearer": {
- "description": "**[DEPRECATED]** The JWT identifying a previously authenticated API key",
- "type": "http",
- "scheme": "bearer",
- "bearerFormat": "JWT"
}
}
},
@@ -63,10 +57,6 @@
{
"name": "URL Shortener",
"description": "Non-rest endpoints, used to be publicly exposed"
- },
- {
- "name": "Authentication",
- "description": "**[DEPRECATED]** Authentication-related endpoints"
}
],
@@ -104,10 +94,6 @@
},
"/{shortCode}/qr-code": {
"$ref": "paths/{shortCode}_qr-code.json"
- },
-
- "/rest/v1/authenticate": {
- "$ref": "paths/v1_authenticate.json"
}
}
}
diff --git a/module/Rest/config/auth.config.php b/module/Rest/config/auth.config.php
index 8cebff6e..f04337bf 100644
--- a/module/Rest/config/auth.config.php
+++ b/module/Rest/config/auth.config.php
@@ -17,13 +17,10 @@ return [
'plugins' => [
'factories' => [
Authentication\Plugin\ApiKeyHeaderPlugin::class => ConfigAbstractFactory::class,
- Authentication\Plugin\AuthorizationHeaderPlugin::class => ConfigAbstractFactory::class,
],
'aliases' => [
Authentication\Plugin\ApiKeyHeaderPlugin::HEADER_NAME =>
Authentication\Plugin\ApiKeyHeaderPlugin::class,
- Authentication\Plugin\AuthorizationHeaderPlugin::HEADER_NAME =>
- Authentication\Plugin\AuthorizationHeaderPlugin::class,
],
],
],
@@ -39,7 +36,6 @@ return [
],
ConfigAbstractFactory::class => [
- Authentication\Plugin\AuthorizationHeaderPlugin::class => [Authentication\JWTService::class],
Authentication\Plugin\ApiKeyHeaderPlugin::class => [Service\ApiKeyService::class],
Authentication\RequestToHttpAuthPlugin::class => [Authentication\AuthenticationPluginManager::class],
diff --git a/module/Rest/config/dependencies.config.php b/module/Rest/config/dependencies.config.php
index 70bb0556..11bfaed3 100644
--- a/module/Rest/config/dependencies.config.php
+++ b/module/Rest/config/dependencies.config.php
@@ -17,7 +17,6 @@ return [
'dependencies' => [
'factories' => [
- Authentication\JWTService::class => ConfigAbstractFactory::class,
ApiKeyService::class => ConfigAbstractFactory::class,
Action\HealthAction::class => ConfigAbstractFactory::class,
@@ -43,7 +42,6 @@ return [
],
ConfigAbstractFactory::class => [
- Authentication\JWTService::class => [AppOptions::class],
ApiKeyService::class => ['em'],
Action\HealthAction::class => [Connection::class, AppOptions::class, 'Logger_Shlink'],
diff --git a/module/Rest/src/Authentication/JWTService.php b/module/Rest/src/Authentication/JWTService.php
deleted file mode 100644
index cb985456..00000000
--- a/module/Rest/src/Authentication/JWTService.php
+++ /dev/null
@@ -1,111 +0,0 @@
-appOptions = $appOptions;
- }
-
- /**
- * Creates a new JSON web token por provided API key
- *
- * @param ApiKey $apiKey
- * @param int $lifetime
- * @return string
- */
- public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME): string
- {
- $currentTimestamp = time();
-
- return $this->encode([
- 'iss' => (string) $this->appOptions,
- 'iat' => $currentTimestamp,
- 'exp' => $currentTimestamp + $lifetime,
- 'sub' => 'auth',
- 'key' => $apiKey->getId(), // The ID is opaque. Returning the key would be insecure
- ]);
- }
-
- /**
- * Refreshes a token and returns it with the new expiration
- *
- * @param string $jwt
- * @param int $lifetime
- * @return string
- * @throws AuthenticationException If the token has expired
- */
- public function refresh(string $jwt, $lifetime = self::DEFAULT_LIFETIME): string
- {
- $payload = $this->getPayload($jwt);
- $payload['exp'] = time() + $lifetime;
- return $this->encode($payload);
- }
-
- /**
- * Verifies that certain JWT is valid
- *
- * @param string $jwt
- * @return bool
- */
- public function verify(string $jwt): bool
- {
- try {
- // If no exception is thrown while decoding the token, it is considered valid
- $this->decode($jwt);
- return true;
- } catch (UnexpectedValueException $e) {
- return false;
- }
- }
-
- /**
- * Decodes certain token and returns the payload
- *
- * @param string $jwt
- * @return array
- * @throws AuthenticationException If the token has expired
- */
- public function getPayload(string $jwt): array
- {
- try {
- return $this->decode($jwt);
- } catch (UnexpectedValueException $e) {
- throw AuthenticationException::expiredJWT($e);
- }
- }
-
- /**
- * @param array $data
- * @return string
- */
- private function encode(array $data): string
- {
- return JWT::encode($data, '', self::DEFAULT_ENCRYPTION_ALG);
- }
-
- /**
- * @param string $jwt
- * @return array
- */
- private function decode(string $jwt): array
- {
- return (array) JWT::decode($jwt, '', [self::DEFAULT_ENCRYPTION_ALG]);
- }
-}
diff --git a/module/Rest/src/Authentication/JWTServiceInterface.php b/module/Rest/src/Authentication/JWTServiceInterface.php
deleted file mode 100644
index 0ce840f1..00000000
--- a/module/Rest/src/Authentication/JWTServiceInterface.php
+++ /dev/null
@@ -1,50 +0,0 @@
-jwtService = $jwtService;
- }
-
- /**
- * @throws VerifyAuthenticationException
- */
- public function verify(ServerRequestInterface $request): void
- {
- // Get token making sure the an authorization type is provided
- $authToken = $request->getHeaderLine(self::HEADER_NAME);
- $authTokenParts = explode(' ', $authToken);
- if (count($authTokenParts) === 1) {
- throw VerifyAuthenticationException::forMissingAuthType();
- }
-
- // Make sure the authorization type is Bearer
- [$authType, $jwt] = $authTokenParts;
- if (strtolower($authType) !== 'bearer') {
- throw VerifyAuthenticationException::forInvalidAuthType($authType);
- }
-
- try {
- if (! $this->jwtService->verify($jwt)) {
- throw $this->createInvalidTokenError();
- }
- } catch (Throwable $e) {
- throw $this->createInvalidTokenError();
- }
- }
-
- private function createInvalidTokenError(): VerifyAuthenticationException
- {
- return VerifyAuthenticationException::forInvalidAuthToken();
- }
-
- public function update(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
- {
- $authToken = $request->getHeaderLine(self::HEADER_NAME);
- [, $jwt] = explode(' ', $authToken);
- $jwt = $this->jwtService->refresh($jwt);
-
- return $response->withHeader(self::HEADER_NAME, sprintf('Bearer %s', $jwt));
- }
-}
diff --git a/module/Rest/src/Authentication/RequestToHttpAuthPlugin.php b/module/Rest/src/Authentication/RequestToHttpAuthPlugin.php
index bb6454b2..91461704 100644
--- a/module/Rest/src/Authentication/RequestToHttpAuthPlugin.php
+++ b/module/Rest/src/Authentication/RequestToHttpAuthPlugin.php
@@ -17,7 +17,6 @@ class RequestToHttpAuthPlugin implements RequestToHttpAuthPluginInterface
// When more than one is matched, the first one to be found will take precedence.
public const SUPPORTED_AUTH_HEADERS = [
Plugin\ApiKeyHeaderPlugin::HEADER_NAME,
- Plugin\AuthorizationHeaderPlugin::HEADER_NAME,
];
private AuthenticationPluginManagerInterface $authPluginManager;
diff --git a/module/Rest/src/Exception/AuthenticationException.php b/module/Rest/src/Exception/AuthenticationException.php
deleted file mode 100644
index 3e60edb6..00000000
--- a/module/Rest/src/Exception/AuthenticationException.php
+++ /dev/null
@@ -1,16 +0,0 @@
-detail = $e->getMessage();
- $e->title = 'Invalid auth token';
- $e->type = 'INVALID_AUTH_TOKEN';
- $e->status = StatusCodeInterface::STATUS_UNAUTHORIZED;
-
- return $e;
- }
-
- /** @deprecated */
- public static function forMissingAuthType(): self
- {
- $e = new self('You need to provide the Bearer type in the Authorization header.');
-
- $e->detail = $e->getMessage();
- $e->title = 'Invalid authorization';
- $e->type = 'INVALID_AUTHORIZATION';
- $e->status = StatusCodeInterface::STATUS_UNAUTHORIZED;
-
- return $e;
- }
-
- /** @deprecated */
- public static function forInvalidAuthType(string $providedType): self
- {
- $e = new self(sprintf('Provided authorization type %s is not supported. Use Bearer instead.', $providedType));
-
- $e->detail = $e->getMessage();
- $e->title = 'Invalid authorization';
- $e->type = 'INVALID_AUTHORIZATION';
- $e->status = StatusCodeInterface::STATUS_UNAUTHORIZED;
-
- return $e;
- }
}
diff --git a/module/Rest/src/Middleware/CrossDomainMiddleware.php b/module/Rest/src/Middleware/CrossDomainMiddleware.php
index aacda9fc..ef98eb92 100644
--- a/module/Rest/src/Middleware/CrossDomainMiddleware.php
+++ b/module/Rest/src/Middleware/CrossDomainMiddleware.php
@@ -27,7 +27,6 @@ class CrossDomainMiddleware implements MiddlewareInterface, RequestMethodInterfa
$response = $response->withHeader('Access-Control-Allow-Origin', $request->getHeader('Origin'))
->withHeader('Access-Control-Expose-Headers', implode(', ', [
Authentication\Plugin\ApiKeyHeaderPlugin::HEADER_NAME,
- Authentication\Plugin\AuthorizationHeaderPlugin::HEADER_NAME,
]));
if ($request->getMethod() !== self::METHOD_OPTIONS) {
return $response;
diff --git a/module/Rest/test-api/Middleware/AuthenticationTest.php b/module/Rest/test-api/Middleware/AuthenticationTest.php
index 24cd8138..58ab396d 100644
--- a/module/Rest/test-api/Middleware/AuthenticationTest.php
+++ b/module/Rest/test-api/Middleware/AuthenticationTest.php
@@ -59,51 +59,4 @@ class AuthenticationTest extends ApiTestCase
yield 'key which is expired' => ['expired_api_key'];
yield 'key which is disabled' => ['disabled_api_key'];
}
-
- /**
- * @test
- * @dataProvider provideInvalidAuthorizations
- */
- public function authorizationErrorIsReturnedIfInvalidDataIsProvided(
- string $authValue,
- string $expectedDetail,
- string $expectedType,
- string $expectedTitle
- ): void {
- $resp = $this->callApi(self::METHOD_GET, '/short-urls', [
- 'headers' => [
- Plugin\AuthorizationHeaderPlugin::HEADER_NAME => $authValue,
- ],
- ]);
- $payload = $this->getJsonResponsePayload($resp);
-
- $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode());
- $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']);
- $this->assertEquals($expectedType, $payload['type']);
- $this->assertEquals($expectedDetail, $payload['detail']);
- $this->assertEquals($expectedTitle, $payload['title']);
- }
-
- public function provideInvalidAuthorizations(): iterable
- {
- yield 'no type' => [
- 'invalid',
- 'You need to provide the Bearer type in the Authorization header.',
- 'INVALID_AUTHORIZATION',
- 'Invalid authorization',
- ];
- yield 'invalid type' => [
- 'Basic invalid',
- 'Provided authorization type Basic is not supported. Use Bearer instead.',
- 'INVALID_AUTHORIZATION',
- 'Invalid authorization',
- ];
- yield 'invalid JWT' => [
- 'Bearer invalid',
- 'Missing or invalid auth token provided. Perform a new authentication request and send provided '
- . 'token on every new request on the Authorization header',
- 'INVALID_AUTH_TOKEN',
- 'Invalid auth token',
- ];
- }
}
diff --git a/module/Rest/test/Authentication/Plugin/AuthorizationHeaderPluginTest.php b/module/Rest/test/Authentication/Plugin/AuthorizationHeaderPluginTest.php
deleted file mode 100644
index 71d6eb20..00000000
--- a/module/Rest/test/Authentication/Plugin/AuthorizationHeaderPluginTest.php
+++ /dev/null
@@ -1,119 +0,0 @@
-jwtService = $this->prophesize(JWTServiceInterface::class);
- $this->plugin = new AuthorizationHeaderPlugin($this->jwtService->reveal());
- }
-
- /** @test */
- public function verifyAnAuthorizationWithoutBearerTypeThrowsException()
- {
- $authToken = 'ABC-abc';
- $request = (new ServerRequest())->withHeader(
- AuthorizationHeaderPlugin::HEADER_NAME,
- $authToken
- );
-
- $this->expectException(VerifyAuthenticationException::class);
- $this->expectExceptionMessage(sprintf(
- 'You need to provide the Bearer type in the %s header.',
- AuthorizationHeaderPlugin::HEADER_NAME
- ));
-
- $this->plugin->verify($request);
- }
-
- /** @test */
- public function verifyAnAuthorizationWithWrongTypeThrowsException()
- {
- $authToken = 'Basic ABC-abc';
- $request = (new ServerRequest())->withHeader(
- AuthorizationHeaderPlugin::HEADER_NAME,
- $authToken
- );
-
- $this->expectException(VerifyAuthenticationException::class);
- $this->expectExceptionMessage(
- 'Provided authorization type Basic is not supported. Use Bearer instead.'
- );
-
- $this->plugin->verify($request);
- }
-
- /** @test */
- public function verifyAnExpiredTokenThrowsException()
- {
- $authToken = 'Bearer ABC-abc';
- $request = (new ServerRequest())->withHeader(
- AuthorizationHeaderPlugin::HEADER_NAME,
- $authToken
- );
- $jwtVerify = $this->jwtService->verify('ABC-abc')->willReturn(false);
-
- $this->expectException(VerifyAuthenticationException::class);
- $this->expectExceptionMessage(sprintf(
- 'Missing or invalid auth token provided. Perform a new authentication request and send provided '
- . 'token on every new request on the %s header',
- AuthorizationHeaderPlugin::HEADER_NAME
- ));
-
- $this->plugin->verify($request);
-
- $jwtVerify->shouldHaveBeenCalledOnce();
- }
-
- /** @test */
- public function verifyValidTokenDoesNotThrowException()
- {
- $authToken = 'Bearer ABC-abc';
- $request = (new ServerRequest())->withHeader(
- AuthorizationHeaderPlugin::HEADER_NAME,
- $authToken
- );
- $jwtVerify = $this->jwtService->verify('ABC-abc')->willReturn(true);
-
- $this->plugin->verify($request);
-
- $jwtVerify->shouldHaveBeenCalledOnce();
- }
-
- /** @test */
- public function updateReturnsAnUpdatedResponseWithNewJwt()
- {
- $authToken = 'Bearer ABC-abc';
- $request = (new ServerRequest())->withHeader(
- AuthorizationHeaderPlugin::HEADER_NAME,
- $authToken
- );
- $jwtRefresh = $this->jwtService->refresh('ABC-abc')->willReturn('DEF-def');
-
- $response = $this->plugin->update($request, new Response());
-
- $this->assertTrue($response->hasHeader(AuthorizationHeaderPlugin::HEADER_NAME));
- $this->assertEquals('Bearer DEF-def', $response->getHeaderLine(AuthorizationHeaderPlugin::HEADER_NAME));
- $jwtRefresh->shouldHaveBeenCalledOnce();
- }
-}
diff --git a/module/Rest/test/Authentication/RequestToAuthPluginTest.php b/module/Rest/test/Authentication/RequestToAuthPluginTest.php
index d4de01a8..8b52f408 100644
--- a/module/Rest/test/Authentication/RequestToAuthPluginTest.php
+++ b/module/Rest/test/Authentication/RequestToAuthPluginTest.php
@@ -9,7 +9,6 @@ use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Rest\Authentication\AuthenticationPluginManagerInterface;
use Shlinkio\Shlink\Rest\Authentication\Plugin\ApiKeyHeaderPlugin;
use Shlinkio\Shlink\Rest\Authentication\Plugin\AuthenticationPluginInterface;
-use Shlinkio\Shlink\Rest\Authentication\Plugin\AuthorizationHeaderPlugin;
use Shlinkio\Shlink\Rest\Authentication\RequestToHttpAuthPlugin;
use Shlinkio\Shlink\Rest\Exception\MissingAuthenticationException;
use Zend\Diactoros\ServerRequest;
@@ -63,14 +62,7 @@ class RequestToAuthPluginTest extends TestCase
public function provideHeaders(): iterable
{
- yield 'API key header only' => [[
- ApiKeyHeaderPlugin::HEADER_NAME => 'foobar',
- ], ApiKeyHeaderPlugin::HEADER_NAME];
- yield 'Authorization header only' => [[
- AuthorizationHeaderPlugin::HEADER_NAME => 'foobar',
- ], AuthorizationHeaderPlugin::HEADER_NAME];
- yield 'Both headers' => [[
- AuthorizationHeaderPlugin::HEADER_NAME => 'foobar',
+ yield 'API key header' => [[
ApiKeyHeaderPlugin::HEADER_NAME => 'foobar',
], ApiKeyHeaderPlugin::HEADER_NAME];
}
diff --git a/module/Rest/test/Exception/AuthenticationExceptionTest.php b/module/Rest/test/Exception/AuthenticationExceptionTest.php
deleted file mode 100644
index da389acb..00000000
--- a/module/Rest/test/Exception/AuthenticationExceptionTest.php
+++ /dev/null
@@ -1,32 +0,0 @@
-assertEquals($prev, $e->getPrevious());
- $this->assertEquals(-1, $e->getCode());
- $this->assertEquals('The token has expired.', $e->getMessage());
- }
-
- public function providePrev(): iterable
- {
- yield 'with previous exception' => [new Exception('Prev')];
- yield 'without previous exception' => [null];
- }
-}
diff --git a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php
index 735338ca..28a85010 100644
--- a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php
+++ b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php
@@ -15,7 +15,6 @@ use Zend\Diactoros\ServerRequest;
use Zend\Expressive\Router\Route;
use Zend\Expressive\Router\RouteResult;
-use function implode;
use function Zend\Stratigility\middleware;
class CrossDomainMiddlewareTest extends TestCase
@@ -62,10 +61,10 @@ class CrossDomainMiddlewareTest extends TestCase
$headers = $response->getHeaders();
$this->assertEquals('local', $response->getHeaderLine('Access-Control-Allow-Origin'));
- $this->assertEquals(implode(', ', [
+ $this->assertEquals(
Authentication\Plugin\ApiKeyHeaderPlugin::HEADER_NAME,
- Authentication\Plugin\AuthorizationHeaderPlugin::HEADER_NAME,
- ]), $response->getHeaderLine('Access-Control-Expose-Headers'));
+ $response->getHeaderLine('Access-Control-Expose-Headers')
+ );
$this->assertArrayNotHasKey('Access-Control-Allow-Methods', $headers);
$this->assertArrayNotHasKey('Access-Control-Max-Age', $headers);
$this->assertArrayNotHasKey('Access-Control-Allow-Headers', $headers);
@@ -87,10 +86,10 @@ class CrossDomainMiddlewareTest extends TestCase
$headers = $response->getHeaders();
$this->assertEquals('local', $response->getHeaderLine('Access-Control-Allow-Origin'));
- $this->assertEquals(implode(', ', [
+ $this->assertEquals(
Authentication\Plugin\ApiKeyHeaderPlugin::HEADER_NAME,
- Authentication\Plugin\AuthorizationHeaderPlugin::HEADER_NAME,
- ]), $response->getHeaderLine('Access-Control-Expose-Headers'));
+ $response->getHeaderLine('Access-Control-Expose-Headers')
+ );
$this->assertArrayHasKey('Access-Control-Allow-Methods', $headers);
$this->assertEquals('1000', $response->getHeaderLine('Access-Control-Max-Age'));
$this->assertEquals('foo, bar, baz', $response->getHeaderLine('Access-Control-Allow-Headers'));