Skip to content

Commit

Permalink
Merge pull request #46807 from nextcloud/refactor/files/security-attr…
Browse files Browse the repository at this point in the history
…ibutes
  • Loading branch information
provokateurin authored Aug 1, 2024
2 parents 60b9bb4 + 3fde60d commit 13921ca
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 73 deletions.
51 changes: 20 additions & 31 deletions apps/files/lib/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
use OCA\Files\Service\ViewConfig;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\OpenAPI;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\Attribute\StrictCookiesRequired;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
Expand Down Expand Up @@ -69,10 +73,6 @@ public function __construct(string $appName,
*
* @since API version 1.0
*
* @NoAdminRequired
* @NoCSRFRequired
* @StrictCookieRequired
*
* @param int $x Width of the thumbnail
* @param int $y Height of the thumbnail
* @param string $file URL-encoded filename
Expand All @@ -82,6 +82,9 @@ public function __construct(string $appName,
* 400: Getting thumbnail is not possible
* 404: File not found
*/
#[NoAdminRequired]
#[NoCSRFRequired]
#[StrictCookiesRequired]
public function getThumbnail($x, $y, $file) {
if ($x < 1 || $y < 1) {
return new DataResponse(['message' => 'Requested size must be numeric and a positive value.'], Http::STATUS_BAD_REQUEST);
Expand Down Expand Up @@ -113,12 +116,11 @@ public function getThumbnail($x, $y, $file) {
* The passed tags are absolute, which means they will
* replace the actual tag selection.
*
* @NoAdminRequired
*
* @param string $path path
* @param array|string $tags array of tags
* @return DataResponse
*/
#[NoAdminRequired]
public function updateFileTags($path, $tags = null) {
$result = [];
// if tags specified or empty array, update tags
Expand Down Expand Up @@ -221,10 +223,9 @@ private function getShareTypesForNodes(array $nodes): array {
/**
* Returns a list of recently modified files.
*
* @NoAdminRequired
*
* @return DataResponse
*/
#[NoAdminRequired]
public function getRecentFiles() {
$nodes = $this->userFolder->getRecent(100);
$files = $this->formatNodes($nodes);
Expand All @@ -235,11 +236,10 @@ public function getRecentFiles() {
/**
* Returns the current logged-in user's storage stats.
*
* @NoAdminRequired
*
* @param ?string $dir the directory to get the storage stats from
* @return JSONResponse
*/
#[NoAdminRequired]
public function getStorageStats($dir = '/'): JSONResponse {
$storageInfo = \OC_Helper::getStorageInfo($dir ?: '/');
$response = new JSONResponse(['message' => 'ok', 'data' => $storageInfo]);
Expand All @@ -250,13 +250,12 @@ public function getStorageStats($dir = '/'): JSONResponse {
/**
* Set a user view config
*
* @NoAdminRequired
*
* @param string $view
* @param string $key
* @param string|bool $value
* @return JSONResponse
*/
#[NoAdminRequired]
public function setViewConfig(string $view, string $key, $value): JSONResponse {
try {
$this->viewConfig->setConfig($view, $key, (string)$value);
Expand All @@ -271,23 +270,21 @@ public function setViewConfig(string $view, string $key, $value): JSONResponse {
/**
* Get the user view config
*
* @NoAdminRequired
*
* @return JSONResponse
*/
#[NoAdminRequired]
public function getViewConfigs(): JSONResponse {
return new JSONResponse(['message' => 'ok', 'data' => $this->viewConfig->getConfigs()]);
}

/**
* Set a user config
*
* @NoAdminRequired
*
* @param string $key
* @param string|bool $value
* @return JSONResponse
*/
#[NoAdminRequired]
public function setConfig(string $key, $value): JSONResponse {
try {
$this->userConfig->setConfig($key, (string)$value);
Expand All @@ -302,23 +299,21 @@ public function setConfig(string $key, $value): JSONResponse {
/**
* Get the user config
*
* @NoAdminRequired
*
* @return JSONResponse
*/
#[NoAdminRequired]
public function getConfigs(): JSONResponse {
return new JSONResponse(['message' => 'ok', 'data' => $this->userConfig->getConfigs()]);
}

/**
* Toggle default for showing/hiding hidden files
*
* @NoAdminRequired
*
* @param bool $value
* @return Response
* @throws \OCP\PreConditionNotMetException
*/
#[NoAdminRequired]
public function showHiddenFiles(bool $value): Response {
$this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'show_hidden', $value ? '1' : '0');
return new Response();
Expand All @@ -327,12 +322,11 @@ public function showHiddenFiles(bool $value): Response {
/**
* Toggle default for cropping preview images
*
* @NoAdminRequired
*
* @param bool $value
* @return Response
* @throws \OCP\PreConditionNotMetException
*/
#[NoAdminRequired]
public function cropImagePreviews(bool $value): Response {
$this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'crop_image_previews', $value ? '1' : '0');
return new Response();
Expand All @@ -341,32 +335,27 @@ public function cropImagePreviews(bool $value): Response {
/**
* Toggle default for files grid view
*
* @NoAdminRequired
*
* @param bool $show
* @return Response
* @throws \OCP\PreConditionNotMetException
*/
#[NoAdminRequired]
public function showGridView(bool $show): Response {
$this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'show_grid', $show ? '1' : '0');
return new Response();
}

/**
* Get default settings for the grid view
*
* @NoAdminRequired
*/
#[NoAdminRequired]
public function getGridView() {
$status = $this->config->getUserValue($this->userSession->getUser()->getUID(), 'files', 'show_grid', '0') === '1';
return new JSONResponse(['gridview' => $status]);
}

/**
* @NoAdminRequired
* @NoCSRFRequired
* @PublicPage
*/
#[PublicPage]
#[NoCSRFRequired]
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
public function serviceWorker(): StreamResponse {
$response = new StreamResponse(__DIR__ . '/../../../../dist/preview-service-worker.js');
Expand Down
13 changes: 5 additions & 8 deletions apps/files/lib/Controller/DirectEditingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Exception;
use OCA\Files\Service\DirectEditingService;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\DirectEditing\IManager;
Expand All @@ -34,22 +35,19 @@ public function __construct(
}

/**
* @NoAdminRequired
*
* Get the direct editing capabilities
* @return DataResponse<Http::STATUS_OK, array{editors: array<string, array{id: string, name: string, mimetypes: string[], optionalMimetypes: string[], secure: bool}>, creators: array<string, array{id: string, editor: string, name: string, extension: string, templates: bool, mimetypes: string[]}>}, array{}>
*
* 200: Direct editing capabilities returned
*/
#[NoAdminRequired]
public function info(): DataResponse {
$response = new DataResponse($this->directEditingService->getDirectEditingCapabilitites());
$response->setETag($this->directEditingService->getDirectEditingETag());
return $response;
}

/**
* @NoAdminRequired
*
* Create a file for direct editing
*
* @param string $path Path of the file
Expand All @@ -62,6 +60,7 @@ public function info(): DataResponse {
* 200: URL for direct editing returned
* 403: Opening file is not allowed
*/
#[NoAdminRequired]
public function create(string $path, string $editorId, string $creatorId, ?string $templateId = null): DataResponse {
if (!$this->directEditingManager->isEnabled()) {
return new DataResponse(['message' => 'Direct editing is not enabled'], Http::STATUS_INTERNAL_SERVER_ERROR);
Expand All @@ -85,8 +84,6 @@ public function create(string $path, string $editorId, string $creatorId, ?strin
}

/**
* @NoAdminRequired
*
* Open a file for direct editing
*
* @param string $path Path of the file
Expand All @@ -98,6 +95,7 @@ public function create(string $path, string $editorId, string $creatorId, ?strin
* 200: URL for direct editing returned
* 403: Opening file is not allowed
*/
#[NoAdminRequired]
public function open(string $path, ?string $editorId = null, ?int $fileId = null): DataResponse {
if (!$this->directEditingManager->isEnabled()) {
return new DataResponse(['message' => 'Direct editing is not enabled'], Http::STATUS_INTERNAL_SERVER_ERROR);
Expand All @@ -123,8 +121,6 @@ public function open(string $path, ?string $editorId = null, ?int $fileId = null


/**
* @NoAdminRequired
*
* Get the templates for direct editing
*
* @param string $editorId ID of the editor
Expand All @@ -134,6 +130,7 @@ public function open(string $path, ?string $editorId = null, ?int $fileId = null
*
* 200: Templates returned
*/
#[NoAdminRequired]
public function templates(string $editorId, string $creatorId): DataResponse {
if (!$this->directEditingManager->isEnabled()) {
return new DataResponse(['message' => 'Direct editing is not enabled'], Http::STATUS_INTERNAL_SERVER_ERROR);
Expand Down
10 changes: 6 additions & 4 deletions apps/files/lib/Controller/DirectEditingViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

use Exception;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\OpenAPI;
use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\Attribute\UseSession;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\Http\Response;
use OCP\DirectEditing\IManager;
Expand All @@ -29,13 +32,12 @@ public function __construct(
}

/**
* @PublicPage
* @NoCSRFRequired
* @UseSession
*
* @param string $token
* @return Response
*/
#[PublicPage]
#[NoCSRFRequired]
#[UseSession]
public function edit(string $token): Response {
$this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager));
try {
Expand Down
13 changes: 7 additions & 6 deletions apps/files/lib/Controller/OpenLocalEditorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
use OCA\Files\Db\OpenLocalEditorMapper;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\UserRateLimit;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\AppFramework\Utility\ITimeFactory;
Expand Down Expand Up @@ -51,9 +54,6 @@ public function __construct(
}

/**
* @NoAdminRequired
* @UserRateThrottle(limit=10, period=120)
*
* Create a local editor
*
* @param string $path Path of the file
Expand All @@ -62,6 +62,8 @@ public function __construct(
*
* 200: Local editor returned
*/
#[NoAdminRequired]
#[UserRateLimit(limit: 10, period: 120)]
public function create(string $path): DataResponse {
$pathHash = sha1($path);

Expand Down Expand Up @@ -96,9 +98,6 @@ public function create(string $path): DataResponse {
}

/**
* @NoAdminRequired
* @BruteForceProtection(action=openLocalEditor)
*
* Validate a local editor
*
* @param string $path Path of the file
Expand All @@ -109,6 +108,8 @@ public function create(string $path): DataResponse {
* 200: Local editor validated successfully
* 404: Local editor not found
*/
#[NoAdminRequired]
#[BruteForceProtection(action: 'openLocalEditor')]
public function validate(string $path, string $token): DataResponse {
$pathHash = sha1($path);

Expand Down
10 changes: 4 additions & 6 deletions apps/files/lib/Controller/TemplateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use OCA\Files\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCSController;
Expand All @@ -32,21 +33,18 @@ public function __construct($appName, IRequest $request, ITemplateManager $templ
}

/**
* @NoAdminRequired
*
* List the available templates
*
* @return DataResponse<Http::STATUS_OK, array<FilesTemplateFileCreator>, array{}>
*
* 200: Available templates returned
*/
#[NoAdminRequired]
public function list(): DataResponse {
return new DataResponse($this->templateManager->listTemplates());
}

/**
* @NoAdminRequired
*
* Create a template
*
* @param string $filePath Path of the file
Expand All @@ -59,6 +57,7 @@ public function list(): DataResponse {
*
* 200: Template created successfully
*/
#[NoAdminRequired]
public function create(
string $filePath,
string $templatePath = '',
Expand All @@ -77,8 +76,6 @@ public function create(
}

/**
* @NoAdminRequired
*
* Initialize the template directory
*
* @param string $templatePath Path of the template directory
Expand All @@ -89,6 +86,7 @@ public function create(
*
* 200: Template directory initialized successfully
*/
#[NoAdminRequired]
public function path(string $templatePath = '', bool $copySystemTemplates = false) {
try {
/** @var string $templatePath */
Expand Down
Loading

0 comments on commit 13921ca

Please sign in to comment.