Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Http): Only allow valid HTTP status code values via template #49882

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions apps/settings/lib/Controller/LogSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ public function __construct(string $appName, IRequest $request, Log $logger) {
/**
* download logfile
*
* @psalm-suppress MoreSpecificReturnType The value of Content-Disposition is not relevant
* @psalm-suppress LessSpecificReturnStatement The value of Content-Disposition is not relevant
* @return StreamResponse<Http::STATUS_OK, array{Content-Type: 'application/octet-stream', 'Content-Disposition': string}>
* @return StreamResponse<Http::STATUS_OK, array{Content-Type: 'application/octet-stream', 'Content-Disposition': 'attachment; filename="nextcloud.log"'}>
*
* 200: Logfile returned
*/
Expand All @@ -38,11 +36,13 @@ public function download() {
if (!$this->log instanceof Log) {
throw new \UnexpectedValueException('Log file not available');
}
$resp = new StreamResponse($this->log->getLogPath());
$resp->setHeaders([
'Content-Type' => 'application/octet-stream',
'Content-Disposition' => 'attachment; filename="nextcloud.log"',
]);
return $resp;
return new StreamResponse(
$this->log->getLogPath(),
Http::STATUS_OK,
[
'Content-Type' => 'application/octet-stream',
'Content-Disposition' => 'attachment; filename="nextcloud.log"',
],
);
}
}
5 changes: 4 additions & 1 deletion apps/settings/openapi-administration.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
"type": "string",
"enum": [
"attachment; filename=\"nextcloud.log\""
]
Comment on lines +47 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should that be part of API definition 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ignored it before, but with these changes psalm is very unhappy somehow.
IMO the proper fix would be to ignore this header completely in openapi-extractor.

}
}
},
Expand Down
5 changes: 4 additions & 1 deletion apps/settings/openapi-full.json
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
"type": "string",
"enum": [
"attachment; filename=\"nextcloud.log\""
]
}
}
},
Expand Down
4 changes: 2 additions & 2 deletions lib/private/AppFramework/OCS/BaseResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

/**
* @psalm-import-type DataResponseType from DataResponse
* @template S of int
* @template S of Http::STATUS_*
* @template-covariant T of DataResponseType
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
abstract class BaseResponse extends Response {
/** @var array */
Expand Down
6 changes: 3 additions & 3 deletions lib/private/AppFramework/OCS/V1Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@

/**
* @psalm-import-type DataResponseType from DataResponse
* @template S of int
* @template S of Http::STATUS_*
* @template-covariant T of DataResponseType
* @template H of array<string, mixed>
* @template-extends BaseResponse<int, DataResponseType, array<string, mixed>>
* @template-extends BaseResponse<Http::STATUS_*, DataResponseType, array<string, mixed>>
*/
class V1Response extends BaseResponse {
/**
* The V1 endpoint has very limited http status codes basically everything
* is status 200 except 401
*
* @return int
* @return Http::STATUS_*
*/
public function getStatus() {
$status = parent::getStatus();
Expand Down
6 changes: 3 additions & 3 deletions lib/private/AppFramework/OCS/V2Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@

/**
* @psalm-import-type DataResponseType from DataResponse
* @template S of int
* @template S of Http::STATUS_*
* @template-covariant T of DataResponseType
* @template H of array<string, mixed>
* @template-extends BaseResponse<int, DataResponseType, array<string, mixed>>
* @template-extends BaseResponse<Http::STATUS_*, DataResponseType, array<string, mixed>>
*/
class V2Response extends BaseResponse {
/**
* The V2 endpoint just passes on status codes.
* Of course we have to map the OCS specific codes to proper HTTP status codes
*
* @return int
* @return Http::STATUS_*
*/
public function getStatus() {
$status = parent::getStatus();
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/DataDisplayResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
* Class DataDisplayResponse
*
* @since 8.1.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class DataDisplayResponse extends Response {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/DataDownloadResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
* Class DataDownloadResponse
*
* @since 8.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template C of string
* @template H of array<string, mixed>
* @template-extends DownloadResponse<int, string, array<string, mixed>>
* @template-extends DownloadResponse<Http::STATUS_*, string, array<string, mixed>>
*/
class DataDownloadResponse extends DownloadResponse {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/DataResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
* for responders to transform
* @since 8.0.0
* @psalm-type DataResponseType = array|int|float|string|bool|object|null|\stdClass|\JsonSerializable
* @template S of int
* @template S of Http::STATUS_*
* @template-covariant T of DataResponseType
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class DataResponse extends Response {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/DownloadResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
/**
* Prompts the user to download the a file
* @since 7.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template C of string
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class DownloadResponse extends Response {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/FileDisplayResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
* Class FileDisplayResponse
*
* @since 11.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class FileDisplayResponse extends Response implements ICallbackResponse {
/** @var File|ISimpleFile */
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/JSONResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
/**
* A renderer for JSON calls
* @since 6.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template-covariant T of array|object|\stdClass|\JsonSerializable
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class JSONResponse extends Response {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/NotFoundResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
/**
* A generic 404 response showing an 404 error page as well to the end-user
* @since 8.1.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends TemplateResponse<int, array<string, mixed>>
* @template-extends TemplateResponse<Http::STATUS_*, array<string, mixed>>
*/
class NotFoundResponse extends TemplateResponse {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/RedirectResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
/**
* Redirects to a different URL
* @since 7.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class RedirectResponse extends Response {
private $redirectURL;
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/RedirectToDefaultAppResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
*
* @since 16.0.0
* @deprecated 23.0.0 Use RedirectResponse() with IURLGenerator::linkToDefaultPageUrl() instead
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends RedirectResponse<int, array<string, mixed>>
* @template-extends RedirectResponse<Http::STATUS_*, array<string, mixed>>
*/
class RedirectToDefaultAppResponse extends RedirectResponse {
/**
Expand Down
2 changes: 1 addition & 1 deletion lib/public/AppFramework/Http/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
* It handles headers, HTTP status code, last modified and ETag.
* @since 6.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
*/
class Response {
Expand Down
6 changes: 4 additions & 2 deletions lib/public/AppFramework/Http/StandaloneTemplateResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@
*/
namespace OCP\AppFramework\Http;

use OCP\AppFramework\Http;

/**
* A template response that does not emit the loadAdditionalScripts events.
*
* This is useful for pages that are authenticated but do not yet show the
* full nextcloud UI. Like the 2FA page, or the grant page in the login flow.
*
* @since 16.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends TemplateResponse<int, array<string, mixed>>
* @template-extends TemplateResponse<Http::STATUS_*, array<string, mixed>>
*/
class StandaloneTemplateResponse extends TemplateResponse {
}
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/StreamResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
* Class StreamResponse
*
* @since 8.1.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class StreamResponse extends Response implements ICallbackResponse {
/** @var string */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*
* @since 14.0.0
* @template H of array<string, mixed>
* @template S of int
* @template-extends TemplateResponse<int, array<string, mixed>>
* @template S of Http::STATUS_*
* @template-extends TemplateResponse<Http::STATUS_*, array<string, mixed>>
*/
class PublicTemplateResponse extends TemplateResponse {
private $headerTitle = '';
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/TemplateResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
* Response for a normal template
* @since 6.0.0
*
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class TemplateResponse extends Response {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/TextPlainResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
/**
* A renderer for text responses
* @since 22.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class TextPlainResponse extends Response {
/** @var string */
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/TooManyRequestsResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
/**
* A generic 429 response showing an 404 error page as well to the end-user
* @since 19.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class TooManyRequestsResponse extends Response {
/**
Expand Down
4 changes: 2 additions & 2 deletions lib/public/AppFramework/Http/ZipResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
* Public library to send several files in one zip archive.
*
* @since 15.0.0
* @template S of int
* @template S of Http::STATUS_*
* @template H of array<string, mixed>
* @template-extends Response<int, array<string, mixed>>
* @template-extends Response<Http::STATUS_*, array<string, mixed>>
*/
class ZipResponse extends Response implements ICallbackResponse {
/** @var array{internalName: string, resource: resource, size: int, time: int}[] Files to be added to the zip response */
Expand Down
Loading