From: jld3103 Date: Wed, 15 Mar 2023 16:29:32 +0000 (+0100) Subject: core: Add OpenAPI spec X-Git-Tag: v28.0.0beta1~711^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1be836273ddba6e0ddb3509a1d898535df9fd169;p=nextcloud-server.git core: Add OpenAPI spec Signed-off-by: jld3103 --- diff --git a/core/Controller/AppPasswordController.php b/core/Controller/AppPasswordController.php index 90020330ea1..096261d2311 100644 --- a/core/Controller/AppPasswordController.php +++ b/core/Controller/AppPasswordController.php @@ -8,6 +8,7 @@ declare(strict_types=1); * @author Christoph Wurst * @author Daniel Kesselberg * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -31,6 +32,7 @@ use OC\Authentication\Events\AppPasswordCreatedEvent; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSForbiddenException; use OCP\Authentication\Exceptions\CredentialsUnavailableException; @@ -57,7 +59,12 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired * - * @throws OCSForbiddenException + * Create app password + * + * @return DataResponse + * @throws OCSForbiddenException Creating app password is not allowed + * + * 200: App password returned */ public function getAppPassword(): DataResponse { // We do not allow the creation of new tokens if this is an app password @@ -102,6 +109,13 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired + * + * Delete app password + * + * @return DataResponse, array{}> + * @throws OCSForbiddenException Deleting app password is not allowed + * + * 200: App password deleted successfully */ public function deleteAppPassword(): DataResponse { if (!$this->session->exists('app_password')) { @@ -122,6 +136,13 @@ class AppPasswordController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired + * + * Rotate app password + * + * @return DataResponse + * @throws OCSForbiddenException Rotating app password is not allowed + * + * 200: App password returned */ public function rotateAppPassword(): DataResponse { if (!$this->session->exists('app_password')) { diff --git a/core/Controller/AutoCompleteController.php b/core/Controller/AutoCompleteController.php index 29a0788ad57..15b78e53dc0 100644 --- a/core/Controller/AutoCompleteController.php +++ b/core/Controller/AutoCompleteController.php @@ -30,6 +30,8 @@ declare(strict_types=1); */ namespace OC\Core\Controller; +use OCA\Core\ResponseDefinitions; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; use OCP\Collaboration\AutoComplete\AutoCompleteEvent; @@ -39,6 +41,9 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\IRequest; use OCP\Share\IShare; +/** + * @psalm-import-type CoreAutocompleteResult from ResponseDefinitions + */ class AutoCompleteController extends OCSController { public function __construct( string $appName, @@ -52,7 +57,17 @@ class AutoCompleteController extends OCSController { /** * @NoAdminRequired + * + * Autocomplete a query + * + * @param string $search Text to search for + * @param string|null $itemType Type of the items to search for + * @param string|null $itemId ID of the items to search for * @param string|null $sorter can be piped, top prio first, e.g.: "commenters|share-recipients" + * @param int[] $shareTypes Types of shares to search for + * @param int $limit Maximum number of results to return + * + * @return DataResponse */ public function get(string $search, ?string $itemType, ?string $itemId, ?string $sorter = null, array $shareTypes = [IShare::TYPE_USER], int $limit = 10): DataResponse { // if enumeration/user listings are disabled, we'll receive an empty @@ -89,18 +104,37 @@ class AutoCompleteController extends OCSController { return new DataResponse($results); } + /** + * @return CoreAutocompleteResult[] + */ protected function prepareResultArray(array $results): array { $output = []; + /** @var string $type */ foreach ($results as $type => $subResult) { foreach ($subResult as $result) { + /** @var ?string $icon */ + $icon = array_key_exists('icon', $result) ? $result['icon'] : null; + + /** @var string $label */ + $label = $result['label']; + + /** @var ?string $subline */ + $subline = array_key_exists('subline', $result) ? $result['subline'] : null; + + /** @var ?string $status */ + $status = array_key_exists('status', $result) && is_string($result['status']) ? $result['status'] : null; + + /** @var ?string $shareWithDisplayNameUnique */ + $shareWithDisplayNameUnique = array_key_exists('shareWithDisplayNameUnique', $result) ? $result['shareWithDisplayNameUnique'] : null; + $output[] = [ 'id' => (string) $result['value']['shareWith'], - 'label' => $result['label'], - 'icon' => $result['icon'] ?? '', + 'label' => $label, + 'icon' => $icon ?? '', 'source' => $type, - 'status' => $result['status'] ?? '', - 'subline' => $result['subline'] ?? '', - 'shareWithDisplayNameUnique' => $result['shareWithDisplayNameUnique'] ?? '', + 'status' => $status ?? '', + 'subline' => $subline ?? '', + 'shareWithDisplayNameUnique' => $shareWithDisplayNameUnique ?? '', ]; } } diff --git a/core/Controller/AvatarController.php b/core/Controller/AvatarController.php index ba1792af708..32858b52612 100644 --- a/core/Controller/AvatarController.php +++ b/core/Controller/AvatarController.php @@ -12,6 +12,7 @@ * @author Roeland Jago Douma * @author Thomas Müller * @author Vincent Petry + * @author Kate Döen * * @license AGPL-3.0 * @@ -72,7 +73,14 @@ class AvatarController extends Controller { * @NoSameSiteCookieRequired * @PublicPage * - * @return JSONResponse|FileDisplayResponse + * Get the dark avatar + * + * @param string $userId ID of the user + * @param int $size Size of the avatar + * @return FileDisplayResponse|JSONResponse, array{}> + * + * 200: Avatar returned + * 404: Avatar not found */ public function getAvatarDark(string $userId, int $size) { if ($size <= 64) { @@ -111,7 +119,14 @@ class AvatarController extends Controller { * @NoSameSiteCookieRequired * @PublicPage * - * @return JSONResponse|FileDisplayResponse + * Get the avatar + * + * @param string $userId ID of the user + * @param int $size Size of the avatar + * @return FileDisplayResponse|JSONResponse, array{}> + * + * 200: Avatar returned + * 404: Avatar not found */ public function getAvatar(string $userId, int $size) { if ($size <= 64) { diff --git a/core/Controller/CSRFTokenController.php b/core/Controller/CSRFTokenController.php index 95e67371b5d..fb51744fb74 100644 --- a/core/Controller/CSRFTokenController.php +++ b/core/Controller/CSRFTokenController.php @@ -7,6 +7,7 @@ declare(strict_types=1); * * @author Christoph Wurst * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -29,9 +30,11 @@ namespace OC\Core\Controller; use OC\Security\CSRF\CsrfTokenManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; +#[IgnoreOpenAPI] class CSRFTokenController extends Controller { public function __construct( string $appName, diff --git a/core/Controller/ClientFlowLoginController.php b/core/Controller/ClientFlowLoginController.php index 082d5b3f92e..3f92ad8cf30 100644 --- a/core/Controller/ClientFlowLoginController.php +++ b/core/Controller/ClientFlowLoginController.php @@ -12,6 +12,7 @@ * @author Roeland Jago Douma * @author RussellAult * @author Sergej Nikolaev + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -41,6 +42,7 @@ use OCA\OAuth2\Db\AccessTokenMapper; use OCA\OAuth2\Db\ClientMapper; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\StandaloneTemplateResponse; @@ -56,6 +58,7 @@ use OCP\Security\ICrypto; use OCP\Security\ISecureRandom; use OCP\Session\Exceptions\SessionNotAvailableException; +#[IgnoreOpenAPI] class ClientFlowLoginController extends Controller { public const STATE_NAME = 'client.flow.state.token'; diff --git a/core/Controller/ClientFlowLoginV2Controller.php b/core/Controller/ClientFlowLoginV2Controller.php index 8a21148f589..b03f961742e 100644 --- a/core/Controller/ClientFlowLoginV2Controller.php +++ b/core/Controller/ClientFlowLoginV2Controller.php @@ -31,8 +31,10 @@ use OC\Authentication\Exceptions\InvalidTokenException; use OC\Core\Db\LoginFlowV2; use OC\Core\Exception\LoginFlowV2NotFoundException; use OC\Core\Service\LoginFlowV2Service; +use OCA\Core\ResponseDefinitions; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\RedirectResponse; @@ -47,6 +49,10 @@ use OCP\IUser; use OCP\IUserSession; use OCP\Security\ISecureRandom; +/** + * @psalm-import-type CoreLoginFlowV2Credentials from ResponseDefinitions + * @psalm-import-type CoreLoginFlowV2 from ResponseDefinitions + */ class ClientFlowLoginV2Controller extends Controller { public const TOKEN_NAME = 'client.flow.v2.login.token'; public const STATE_NAME = 'client.flow.v2.state.token'; @@ -69,6 +75,14 @@ class ClientFlowLoginV2Controller extends Controller { /** * @NoCSRFRequired * @PublicPage + * + * Poll the login flow credentials + * + * @param string $token Token of the flow + * @return JSONResponse|JSONResponse, array{}> + * + * 200: Login flow credentials returned + * 404: Login flow not found or completed */ public function poll(string $token): JSONResponse { try { @@ -77,13 +91,14 @@ class ClientFlowLoginV2Controller extends Controller { return new JSONResponse([], Http::STATUS_NOT_FOUND); } - return new JSONResponse($creds); + return new JSONResponse($creds->jsonSerialize()); } /** * @NoCSRFRequired * @PublicPage */ + #[IgnoreOpenAPI] #[UseSession] public function landing(string $token, $user = ''): Response { if (!$this->loginFlowV2Service->startLoginFlow($token)) { @@ -101,6 +116,7 @@ class ClientFlowLoginV2Controller extends Controller { * @NoCSRFRequired * @PublicPage */ + #[IgnoreOpenAPI] #[UseSession] public function showAuthPickerPage($user = ''): StandaloneTemplateResponse { try { @@ -134,6 +150,7 @@ class ClientFlowLoginV2Controller extends Controller { * @NoCSRFRequired * @NoSameSiteCookieRequired */ + #[IgnoreOpenAPI] #[UseSession] public function grantPage(?string $stateToken): StandaloneTemplateResponse { if ($stateToken === null) { @@ -267,6 +284,10 @@ class ClientFlowLoginV2Controller extends Controller { /** * @NoCSRFRequired * @PublicPage + * + * Init a login flow + * + * @return JSONResponse */ public function init(): JSONResponse { // Get client user agent diff --git a/core/Controller/CollaborationResourcesController.php b/core/Controller/CollaborationResourcesController.php index da90f27c9ef..832b4207e6f 100644 --- a/core/Controller/CollaborationResourcesController.php +++ b/core/Controller/CollaborationResourcesController.php @@ -8,6 +8,7 @@ declare(strict_types=1); * @author Joas Schilling * @author Julius Härtl * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -29,6 +30,7 @@ declare(strict_types=1); namespace OC\Core\Controller; use Exception; +use OCA\Core\ResponseDefinitions; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; @@ -41,6 +43,10 @@ use OCP\IRequest; use OCP\IUserSession; use Psr\Log\LoggerInterface; +/** + * @psalm-import-type CoreOpenGraphObject from ResponseDefinitions + * @psalm-import-type CoreCollection from ResponseDefinitions + */ class CollaborationResourcesController extends OCSController { public function __construct( string $appName, @@ -70,8 +76,13 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param int $collectionId - * @return DataResponse + * Get a collection + * + * @param int $collectionId ID of the collection + * @return DataResponse|DataResponse, array{}> + * + * 200: Collection returned + * 404: Collection not found */ public function listCollection(int $collectionId): DataResponse { try { @@ -86,8 +97,13 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param string $filter - * @return DataResponse + * Search for collections + * + * @param string $filter Filter collections + * @return DataResponse|DataResponse, array{}> + * + * 200: Collections returned + * 404: Collection not found */ public function searchCollections(string $filter): DataResponse { try { @@ -102,10 +118,15 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param int $collectionId - * @param string $resourceType - * @param string $resourceId - * @return DataResponse + * Add a resource to a collection + * + * @param int $collectionId ID of the collection + * @param string $resourceType Name of the resource + * @param string $resourceId ID of the resource + * @return DataResponse|DataResponse, array{}> + * + * 200: Collection returned + * 404: Collection not found or resource inaccessible */ public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse { try { @@ -131,10 +152,15 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param int $collectionId - * @param string $resourceType - * @param string $resourceId - * @return DataResponse + * Remove a resource from a collection + * + * @param int $collectionId ID of the collection + * @param string $resourceType Name of the resource + * @param string $resourceId ID of the resource + * @return DataResponse|DataResponse, array{}> + * + * 200: Collection returned + * 404: Collection or resource not found */ public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse { try { @@ -157,9 +183,14 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param string $resourceType - * @param string $resourceId - * @return DataResponse + * Get collections by resource + * + * @param string $resourceType Type of the resource + * @param string $resourceId ID of the resource + * @return DataResponse|DataResponse, array{}> + * + * 200: Collections returned + * 404: Resource not accessible */ public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse { try { @@ -178,10 +209,16 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param string $baseResourceType - * @param string $baseResourceId - * @param string $name - * @return DataResponse + * Create a collection for a resource + * + * @param string $baseResourceType Type of the base resource + * @param string $baseResourceId ID of the base resource + * @param string $name Name of the collection + * @return DataResponse|DataResponse, array{}> + * + * 200: Collection returned + * 400: Creating collection is not possible + * 404: Resource inaccessible */ public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse { if (!isset($name[0]) || isset($name[64])) { @@ -207,9 +244,14 @@ class CollaborationResourcesController extends OCSController { /** * @NoAdminRequired * - * @param int $collectionId - * @param string $collectionName - * @return DataResponse + * Rename a collection + * + * @param int $collectionId ID of the collection + * @param string $collectionName New name + * @return DataResponse|DataResponse, array{}> + * + * 200: Collection returned + * 404: Collection not found */ public function renameCollection(int $collectionId, string $collectionName): DataResponse { try { @@ -223,6 +265,9 @@ class CollaborationResourcesController extends OCSController { return $this->respondCollection($collection); } + /** + * @return DataResponse|DataResponse, array{}> + */ protected function respondCollection(ICollection $collection): DataResponse { try { return new DataResponse($this->prepareCollection($collection)); @@ -234,6 +279,9 @@ class CollaborationResourcesController extends OCSController { } } + /** + * @return CoreCollection[] + */ protected function prepareCollections(array $collections): array { $result = []; @@ -249,6 +297,9 @@ class CollaborationResourcesController extends OCSController { return $result; } + /** + * @return CoreCollection + */ protected function prepareCollection(ICollection $collection): array { if (!$collection->canAccess($this->userSession->getUser())) { throw new CollectionException('Can not access collection'); @@ -261,7 +312,10 @@ class CollaborationResourcesController extends OCSController { ]; } - protected function prepareResources(array $resources): ?array { + /** + * @return CoreOpenGraphObject[] + */ + protected function prepareResources(array $resources): array { $result = []; foreach ($resources as $resource) { @@ -276,6 +330,9 @@ class CollaborationResourcesController extends OCSController { return $result; } + /** + * @return CoreOpenGraphObject + */ protected function prepareResource(IResource $resource): array { if (!$resource->canAccess($this->userSession->getUser())) { throw new ResourceException('Can not access resource'); diff --git a/core/Controller/CssController.php b/core/Controller/CssController.php index 7aec5850aea..30e0b0ce73b 100644 --- a/core/Controller/CssController.php +++ b/core/Controller/CssController.php @@ -11,6 +11,7 @@ declare(strict_types=1); * @author Morris Jobke * @author Roeland Jago Douma * @author Thomas Citharel + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -33,6 +34,7 @@ namespace OC\Core\Controller; use OC\Files\AppData\Factory; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\FileDisplayResponse; use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\Response; @@ -43,6 +45,7 @@ use OCP\Files\SimpleFS\ISimpleFile; use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IRequest; +#[IgnoreOpenAPI] class CssController extends Controller { protected IAppData $appData; diff --git a/core/Controller/ErrorController.php b/core/Controller/ErrorController.php index 550b320a989..9882b481951 100644 --- a/core/Controller/ErrorController.php +++ b/core/Controller/ErrorController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2022 Julius Härtl * * @author Julius Härtl + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -27,8 +28,10 @@ declare(strict_types=1); namespace OC\Core\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\TemplateResponse; +#[IgnoreOpenAPI] class ErrorController extends \OCP\AppFramework\Controller { /** * @PublicPage diff --git a/core/Controller/GuestAvatarController.php b/core/Controller/GuestAvatarController.php index 6f06451b796..3270a1f7f5a 100644 --- a/core/Controller/GuestAvatarController.php +++ b/core/Controller/GuestAvatarController.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2019, Michael Weimann * * @author Michael Weimann + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -25,6 +26,7 @@ namespace OC\Core\Controller; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\FileDisplayResponse; +use OCP\AppFramework\Http\Response; use OCP\IAvatarManager; use OCP\IRequest; use Psr\Log\LoggerInterface; @@ -46,14 +48,18 @@ class GuestAvatarController extends Controller { } /** - * Returns a guest avatar image response. + * Returns a guest avatar image response * * @PublicPage * @NoCSRFRequired * * @param string $guestName The guest name, e.g. "Albert" * @param string $size The desired avatar size, e.g. 64 for 64x64px - * @return FileDisplayResponse|Http\Response + * @param bool|null $darkTheme Return dark avatar + * @return FileDisplayResponse|Response + * + * 200: Custom avatar returned + * 201: Avatar returned */ public function getAvatar(string $guestName, string $size, ?bool $darkTheme = false) { $size = (int) $size; @@ -95,8 +101,17 @@ class GuestAvatarController extends Controller { } /** + * Returns a dark guest avatar image response + * * @PublicPage * @NoCSRFRequired + * + * @param string $guestName The guest name, e.g. "Albert" + * @param string $size The desired avatar size, e.g. 64 for 64x64px + * @return FileDisplayResponse|Response + * + * 200: Custom avatar returned + * 201: Avatar returned */ public function getAvatarDark(string $guestName, string $size) { return $this->getAvatar($guestName, $size, true); diff --git a/core/Controller/HoverCardController.php b/core/Controller/HoverCardController.php index cfe95be0431..9a76ee4a09a 100644 --- a/core/Controller/HoverCardController.php +++ b/core/Controller/HoverCardController.php @@ -5,6 +5,7 @@ declare(strict_types=1); * @copyright 2021 Joas Schilling * * @author Joas Schilling + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -25,13 +26,16 @@ declare(strict_types=1); namespace OC\Core\Controller; use OC\Contacts\ContactsMenu\Manager; +use OCA\Core\ResponseDefinitions; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; -use OCP\Contacts\ContactsMenu\IEntry; use OCP\IRequest; use OCP\IUserSession; use OCP\Share\IShare; +/** + * @psalm-import-type CoreContactsAction from ResponseDefinitions + */ class HoverCardController extends \OCP\AppFramework\OCSController { public function __construct( IRequest $request, @@ -43,6 +47,14 @@ class HoverCardController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired + * + * Get the user details for a hovercard + * + * @param string $userId ID of the user + * @return DataResponse|DataResponse, array{}> + * + * 200: User details returned + * 404: User not found */ public function getUser(string $userId): DataResponse { $contact = $this->manager->findOne($this->userSession->getUser(), IShare::TYPE_USER, $userId); @@ -51,21 +63,18 @@ class HoverCardController extends \OCP\AppFramework\OCSController { return new DataResponse([], Http::STATUS_NOT_FOUND); } - $data = $this->entryToArray($contact); + $data = $contact->jsonSerialize(); $actions = $data['actions']; if ($data['topAction']) { array_unshift($actions, $data['topAction']); } + /** @var CoreContactsAction[] $actions */ return new DataResponse([ 'userId' => $userId, 'displayName' => $contact->getFullName(), 'actions' => $actions, ]); } - - protected function entryToArray(IEntry $entry): array { - return json_decode(json_encode($entry), true); - } } diff --git a/core/Controller/JsController.php b/core/Controller/JsController.php index 0ad78d5f87f..02e0c16b5a1 100644 --- a/core/Controller/JsController.php +++ b/core/Controller/JsController.php @@ -11,6 +11,7 @@ declare(strict_types=1); * @author Morris Jobke * @author Roeland Jago Douma * @author Thomas Citharel + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -33,6 +34,7 @@ namespace OC\Core\Controller; use OC\Files\AppData\Factory; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\FileDisplayResponse; use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\Response; @@ -43,6 +45,7 @@ use OCP\Files\SimpleFS\ISimpleFile; use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IRequest; +#[IgnoreOpenAPI] class JsController extends Controller { protected IAppData $appData; diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php index 1bee366b00f..5f94c8f8a32 100644 --- a/core/Controller/LoginController.php +++ b/core/Controller/LoginController.php @@ -16,6 +16,7 @@ declare(strict_types=1); * @author Michael Weimann * @author Rayn0r * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -42,6 +43,7 @@ use OC\User\Session; use OC_App; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\RedirectResponse; @@ -58,6 +60,7 @@ use OCP\IUserManager; use OCP\Notification\IManager; use OCP\Util; +#[IgnoreOpenAPI] class LoginController extends Controller { public const LOGIN_MSG_INVALIDPASSWORD = 'invalidpassword'; public const LOGIN_MSG_USERDISABLED = 'userdisabled'; diff --git a/core/Controller/LostController.php b/core/Controller/LostController.php index 7de93b7107a..9a1424c4c48 100644 --- a/core/Controller/LostController.php +++ b/core/Controller/LostController.php @@ -17,6 +17,7 @@ * @author Roeland Jago Douma * @author Thomas Müller * @author Victor Dubiniuk + * @author Kate Döen * * @license AGPL-3.0 * @@ -37,6 +38,7 @@ namespace OC\Core\Controller; use Exception; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; @@ -72,6 +74,7 @@ use function reset; * * @package OC\Core\Controller */ +#[IgnoreOpenAPI] class LostController extends Controller { protected string $from; diff --git a/core/Controller/NavigationController.php b/core/Controller/NavigationController.php index 62c4dd98756..db1d67cc778 100644 --- a/core/Controller/NavigationController.php +++ b/core/Controller/NavigationController.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2018 Julius Härtl * * @author Julius Härtl + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -22,6 +23,7 @@ */ namespace OC\Core\Controller; +use OCA\Core\ResponseDefinitions; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; @@ -29,6 +31,9 @@ use OCP\INavigationManager; use OCP\IRequest; use OCP\IURLGenerator; +/** + * @psalm-import-type CoreNavigationEntry from ResponseDefinitions + */ class NavigationController extends OCSController { public function __construct( string $appName, @@ -42,6 +47,14 @@ class NavigationController extends OCSController { /** * @NoAdminRequired * @NoCSRFRequired + * + * Get the apps navigation + * + * @param bool $absolute Rewrite URLs to absolute ones + * @return DataResponse|DataResponse, array{}> + * + * 200: Apps navigation returned + * 304: No apps navigation changed */ public function getAppsNavigation(bool $absolute = false): DataResponse { $navigation = $this->navigationManager->getAll(); @@ -61,6 +74,14 @@ class NavigationController extends OCSController { /** * @NoAdminRequired * @NoCSRFRequired + * + * Get the settings navigation + * + * @param bool $absolute Rewrite URLs to absolute ones + * @return DataResponse|DataResponse, array{}> + * + * 200: Apps navigation returned + * 304: No apps navigation changed */ public function getSettingsNavigation(bool $absolute = false): DataResponse { $navigation = $this->navigationManager->getAll('settings'); diff --git a/core/Controller/OCJSController.php b/core/Controller/OCJSController.php index 48bd842e6e2..096242b5e9c 100644 --- a/core/Controller/OCJSController.php +++ b/core/Controller/OCJSController.php @@ -8,6 +8,7 @@ * @author Lukas Reschke * @author Morris Jobke * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -33,6 +34,7 @@ use OC\Template\JSConfigHelper; use OCP\App\IAppManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\DataDisplayResponse; use OCP\Defaults; use OCP\IConfig; @@ -44,6 +46,7 @@ use OCP\IURLGenerator; use OCP\IUserSession; use OCP\L10N\IFactory; +#[IgnoreOpenAPI] class OCJSController extends Controller { private JSConfigHelper $helper; diff --git a/core/Controller/OCSController.php b/core/Controller/OCSController.php index 036cdfc2d60..64234a65634 100644 --- a/core/Controller/OCSController.php +++ b/core/Controller/OCSController.php @@ -8,6 +8,7 @@ * @author Julius Härtl * @author Lukas Reschke * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -29,6 +30,8 @@ namespace OC\Core\Controller; use OC\CapabilitiesManager; use OC\Security\IdentityProof\Manager; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\DataResponse; use OCP\IRequest; use OCP\IUserManager; @@ -49,6 +52,7 @@ class OCSController extends \OCP\AppFramework\OCSController { /** * @PublicPage */ + #[IgnoreOpenAPI] public function getConfig(): DataResponse { $data = [ 'version' => '1.7', @@ -63,14 +67,18 @@ class OCSController extends \OCP\AppFramework\OCSController { /** * @PublicPage + * + * Get the capabilities + * + * @return DataResponse}, array{}> */ public function getCapabilities(): DataResponse { $result = []; [$major, $minor, $micro] = \OCP\Util::getVersion(); $result['version'] = [ - 'major' => $major, - 'minor' => $minor, - 'micro' => $micro, + 'major' => (int)$major, + 'minor' => (int)$minor, + 'micro' => (int)$micro, 'string' => \OC_Util::getVersionString(), 'edition' => '', 'extendedSupport' => \OCP\Util::hasExtendedSupport() @@ -91,6 +99,7 @@ class OCSController extends \OCP\AppFramework\OCSController { * @PublicPage * @BruteForceProtection(action=login) */ + #[IgnoreOpenAPI] public function personCheck(string $login = '', string $password = ''): DataResponse { if ($login !== '' && $password !== '') { if ($this->userManager->checkPassword($login, $password)) { @@ -111,6 +120,7 @@ class OCSController extends \OCP\AppFramework\OCSController { /** * @PublicPage */ + #[IgnoreOpenAPI] public function getIdentityProof(string $cloudId): DataResponse { $userObject = $this->userManager->get($cloudId); diff --git a/core/Controller/PreviewController.php b/core/Controller/PreviewController.php index 38373e2d147..c9183466f90 100644 --- a/core/Controller/PreviewController.php +++ b/core/Controller/PreviewController.php @@ -54,7 +54,20 @@ class PreviewController extends Controller { * @NoAdminRequired * @NoCSRFRequired * - * @return DataResponse|FileDisplayResponse + * Get a preview by file path + * + * @param string $file Path of the file + * @param int $x Width of the preview + * @param int $y Height of the preview + * @param bool $a Whether to not crop the preview + * @param bool $forceIcon Force returning an icon + * @param string $mode How to crop the image + * @return FileDisplayResponse|DataResponse, array{}> + * + * 200: Preview returned + * 400: Getting preview is not possible + * 403: Getting preview is not allowed + * 404: Preview not found */ public function getPreview( string $file = '', @@ -81,7 +94,20 @@ class PreviewController extends Controller { * @NoAdminRequired * @NoCSRFRequired * - * @return DataResponse|FileDisplayResponse + * Get a preview by file ID + * + * @param int $fileId ID of the file + * @param int $x Width of the preview + * @param int $y Height of the preview + * @param bool $a Whether to not crop the preview + * @param bool $forceIcon Force returning an icon + * @param string $mode How to crop the image + * @return FileDisplayResponse|DataResponse, array{}> + * + * 200: Preview returned + * 400: Getting preview is not possible + * 403: Getting preview is not allowed + * 404: Preview not found */ public function getPreviewByFileId( int $fileId = -1, @@ -107,7 +133,7 @@ class PreviewController extends Controller { } /** - * @return DataResponse|FileDisplayResponse + * @return FileDisplayResponse|DataResponse, array{}> */ private function fetchPreview( Node $node, diff --git a/core/Controller/ProfileApiController.php b/core/Controller/ProfileApiController.php index e66d4f21c2b..ccbbc6c78bd 100644 --- a/core/Controller/ProfileApiController.php +++ b/core/Controller/ProfileApiController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright 2021 Christopher Ng * * @author Christopher Ng + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -27,6 +28,7 @@ declare(strict_types=1); namespace OC\Core\Controller; use OC\Core\Db\ProfileConfigMapper; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCS\OCSForbiddenException; @@ -53,6 +55,18 @@ class ProfileApiController extends OCSController { * @NoSubAdminRequired * @PasswordConfirmationRequired * @UserRateThrottle(limit=40, period=600) + * + * Update the visiblity of a parameter + * + * @param string $targetUserId ID of the user + * @param string $paramId ID of the parameter + * @param string $visibility New visibility + * @return DataResponse, array{}> + * @throws OCSBadRequestException Updating visibility is not possible + * @throws OCSForbiddenException Not allowed to edit other users visibility + * @throws OCSNotFoundException User not found + * + * 200: Visibility updated successfully */ public function setVisibility(string $targetUserId, string $paramId, string $visibility): DataResponse { $requestingUser = $this->userSession->getUser(); diff --git a/core/Controller/ProfilePageController.php b/core/Controller/ProfilePageController.php index 23dbf104b6b..5034a665684 100644 --- a/core/Controller/ProfilePageController.php +++ b/core/Controller/ProfilePageController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright 2021 Christopher Ng * * @author Christopher Ng + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -27,6 +28,7 @@ declare(strict_types=1); namespace OC\Core\Controller; use OC\Profile\ProfileManager; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\Profile\BeforeTemplateRenderedEvent; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\TemplateResponse; @@ -39,6 +41,7 @@ use OCP\Share\IManager as IShareManager; use OCP\UserStatus\IManager as IUserStatusManager; use OCP\EventDispatcher\IEventDispatcher; +#[IgnoreOpenAPI] class ProfilePageController extends Controller { public function __construct( string $appName, diff --git a/core/Controller/RecommendedAppsController.php b/core/Controller/RecommendedAppsController.php index 5765b946613..5d2c2ba67ce 100644 --- a/core/Controller/RecommendedAppsController.php +++ b/core/Controller/RecommendedAppsController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright 2019 Christoph Wurst * * @author Christoph Wurst + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -26,12 +27,14 @@ declare(strict_types=1); namespace OC\Core\Controller; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\StandaloneTemplateResponse; use OCP\IInitialStateService; use OCP\IRequest; use OCP\IURLGenerator; +#[IgnoreOpenAPI] class RecommendedAppsController extends Controller { public function __construct( IRequest $request, diff --git a/core/Controller/ReferenceApiController.php b/core/Controller/ReferenceApiController.php index 3df2e41c2a9..c16ca348d88 100644 --- a/core/Controller/ReferenceApiController.php +++ b/core/Controller/ReferenceApiController.php @@ -5,6 +5,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2022 Julius Härtl * * @author Julius Härtl + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -24,11 +25,18 @@ declare(strict_types=1); namespace OC\Core\Controller; +use OCA\Core\ResponseDefinitions; +use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\Collaboration\Reference\IDiscoverableReferenceProvider; use OCP\Collaboration\Reference\IReferenceManager; +use OCP\Collaboration\Reference\Reference; use OCP\IRequest; +/** + * @psalm-import-type CoreReference from ResponseDefinitions + * @psalm-import-type CoreReferenceProvider from ResponseDefinitions + */ class ReferenceApiController extends \OCP\AppFramework\OCSController { public function __construct( string $appName, @@ -41,6 +49,13 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired + * + * Extract references from a text + * + * @param string $text Text to extract from + * @param bool $resolve Resolve the references + * @param int $limit Maximum amount of references to extract + * @return DataResponse}, array{}> */ public function extract(string $text, bool $resolve = false, int $limit = 1): DataResponse { $references = $this->referenceManager->extractReferences($text); @@ -52,7 +67,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController { break; } - $result[$reference] = $resolve ? $this->referenceManager->resolveReference($reference) : null; + $result[$reference] = $resolve ? $this->referenceManager->resolveReference($reference)->jsonSerialize() : null; } return new DataResponse([ @@ -62,11 +77,17 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired + * + * Resolve a reference + * + * @param string $reference Reference to resolve + * @return DataResponse}, array{}> */ public function resolveOne(string $reference): DataResponse { - $resolvedReference = $this->referenceManager->resolveReference(trim($reference)); + /** @var ?CoreReference $resolvedReference */ + $resolvedReference = $this->referenceManager->resolveReference(trim($reference))?->jsonSerialize(); - $response = new DataResponse(['references' => [ $reference => $resolvedReference ]]); + $response = new DataResponse(['references' => [$reference => $resolvedReference]]); $response->cacheFor(3600, false, true); return $response; } @@ -74,7 +95,11 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired * - * @param string[] $references + * Resolve multiple references + * + * @param string[] $references References to resolve + * @param int $limit Maximum amount of references to resolve + * @return DataResponse}, array{}> */ public function resolve(array $references, int $limit = 1): DataResponse { $result = []; @@ -84,16 +109,20 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController { break; } - $result[$reference] = $this->referenceManager->resolveReference($reference); + $result[$reference] = $this->referenceManager->resolveReference($reference)?->jsonSerialize(); } return new DataResponse([ - 'references' => array_filter($result) + 'references' => $result ]); } /** * @NoAdminRequired + * + * Get the providers + * + * @return DataResponse */ public function getProvidersInfo(): DataResponse { $providers = $this->referenceManager->getDiscoverableProviders(); @@ -105,6 +134,12 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController { /** * @NoAdminRequired + * + * Touch a provider + * + * @param string $providerId ID of the provider + * @param int|null $timestamp Timestamp of the last usage + * @return DataResponse */ public function touchProvider(string $providerId, ?int $timestamp = null): DataResponse { if ($this->userId !== null) { diff --git a/core/Controller/ReferenceController.php b/core/Controller/ReferenceController.php index a8a489aeeab..cec2dc90cf5 100644 --- a/core/Controller/ReferenceController.php +++ b/core/Controller/ReferenceController.php @@ -5,6 +5,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2022 Julius Härtl * * @author Julius Härtl + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -24,7 +25,6 @@ declare(strict_types=1); namespace OC\Core\Controller; -use OCP\AppFramework\Http\Response; use OCP\Collaboration\Reference\IReferenceManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; @@ -48,10 +48,16 @@ class ReferenceController extends Controller { /** * @PublicPage * @NoCSRFRequired + * + * Get a preview for a reference + * * @param string $referenceId the reference cache key - * @return Response + * @return DataDownloadResponse|DataResponse + * + * 200: Preview returned + * 404: Reference not found */ - public function preview(string $referenceId): Response { + public function preview(string $referenceId): DataDownloadResponse|DataResponse { $reference = $this->referenceManager->getReferenceByCacheKey($referenceId); try { diff --git a/core/Controller/TranslationApiController.php b/core/Controller/TranslationApiController.php index c1628c24555..3f70a5bcb05 100644 --- a/core/Controller/TranslationApiController.php +++ b/core/Controller/TranslationApiController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2022 Julius Härtl * * @author Julius Härtl + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -47,10 +48,14 @@ class TranslationApiController extends \OCP\AppFramework\OCSController { /** * @PublicPage + * + * Get the list of supported languages + * + * @return DataResponse */ public function languages(): DataResponse { return new DataResponse([ - 'languages' => $this->translationManager->getLanguages(), + 'languages' => array_map(fn ($lang) => $lang->jsonSerialize(), $this->translationManager->getLanguages()), 'languageDetection' => $this->translationManager->canDetectLanguage(), ]); } @@ -59,6 +64,17 @@ class TranslationApiController extends \OCP\AppFramework\OCSController { * @PublicPage * @UserRateThrottle(limit=25, period=120) * @AnonRateThrottle(limit=10, period=120) + * + * Translate a text + * + * @param string $text Text to be translated + * @param string|null $fromLanguage Language to translate from + * @param string $toLanguage Language to translate to + * @return DataResponse|DataResponse + * + * 200: Translated text returned + * 400: Language not detected or unable to translate + * 412: Translating is not possible */ public function translate(string $text, ?string $fromLanguage, string $toLanguage): DataResponse { try { diff --git a/core/Controller/TwoFactorChallengeController.php b/core/Controller/TwoFactorChallengeController.php index 40b100c41bd..172d0240f20 100644 --- a/core/Controller/TwoFactorChallengeController.php +++ b/core/Controller/TwoFactorChallengeController.php @@ -7,6 +7,7 @@ * @author Joas Schilling * @author Lukas Reschke * @author Roeland Jago Douma + * @author Kate Döen * * @license AGPL-3.0 * @@ -28,6 +29,7 @@ namespace OC\Core\Controller; use OC\Authentication\TwoFactorAuth\Manager; use OC_User; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\StandaloneTemplateResponse; @@ -41,6 +43,7 @@ use OCP\IURLGenerator; use OCP\IUserSession; use Psr\Log\LoggerInterface; +#[IgnoreOpenAPI] class TwoFactorChallengeController extends Controller { public function __construct( string $appName, diff --git a/core/Controller/UnifiedSearchController.php b/core/Controller/UnifiedSearchController.php index 7e73ac8100f..346717599e0 100644 --- a/core/Controller/UnifiedSearchController.php +++ b/core/Controller/UnifiedSearchController.php @@ -8,6 +8,7 @@ declare(strict_types=1); * @author Christoph Wurst * @author Joas Schilling * @author John Molakvoæ + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -29,6 +30,7 @@ namespace OC\Core\Controller; use OC\Search\SearchComposer; use OC\Search\SearchQuery; +use OCA\Core\ResponseDefinitions; use OCP\AppFramework\OCSController; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; @@ -39,6 +41,10 @@ use OCP\Route\IRouter; use OCP\Search\ISearchQuery; use Symfony\Component\Routing\Exception\ResourceNotFoundException; +/** + * @psalm-import-type CoreUnifiedSearchProvider from ResponseDefinitions + * @psalm-import-type CoreUnifiedSearchResult from ResponseDefinitions + */ class UnifiedSearchController extends OCSController { public function __construct( IRequest $request, @@ -54,7 +60,10 @@ class UnifiedSearchController extends OCSController { * @NoAdminRequired * @NoCSRFRequired * + * Get the providers for unified search + * * @param string $from the url the user is currently at + * @return DataResponse */ public function getProviders(string $from = ''): DataResponse { [$route, $parameters] = $this->getRouteInformation($from); @@ -69,14 +78,19 @@ class UnifiedSearchController extends OCSController { * @NoAdminRequired * @NoCSRFRequired * - * @param string $providerId - * @param string $term - * @param int|null $sortOrder - * @param int|null $limit - * @param int|string|null $cursor - * @param string $from + * Search + * + * @param string $providerId ID of the provider + * @param string $term Term to search + * @param int|null $sortOrder Order of entries + * @param int|null $limit Maximum amount of entries + * @param int|string|null $cursor Offset for searching + * @param string $from The current user URL + * + * @return DataResponse|DataResponse * - * @return DataResponse + * 200: Search entries returned + * 400: Searching is not possible */ public function search(string $providerId, string $term = '', @@ -101,7 +115,7 @@ class UnifiedSearchController extends OCSController { $route, $routeParameters ) - ) + )->jsonSerialize() ); } diff --git a/core/Controller/UnsupportedBrowserController.php b/core/Controller/UnsupportedBrowserController.php index 8cdc190deea..d736401c218 100644 --- a/core/Controller/UnsupportedBrowserController.php +++ b/core/Controller/UnsupportedBrowserController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright 2021 John Molakvoæ * * @author John Molakvoæ + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -27,11 +28,13 @@ declare(strict_types=1); namespace OC\Core\Controller; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\TemplateResponse; use OCP\IRequest; use OCP\Util; +#[IgnoreOpenAPI] class UnsupportedBrowserController extends Controller { public function __construct(IRequest $request) { parent::__construct('core', $request); diff --git a/core/Controller/WalledGardenController.php b/core/Controller/WalledGardenController.php index 0079cc5a69a..b1668bb6d97 100644 --- a/core/Controller/WalledGardenController.php +++ b/core/Controller/WalledGardenController.php @@ -4,6 +4,7 @@ * * @author Christoph Wurst * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -25,8 +26,10 @@ namespace OC\Core\Controller; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\Response; +#[IgnoreOpenAPI] class WalledGardenController extends Controller { /** * @PublicPage diff --git a/core/Controller/WellKnownController.php b/core/Controller/WellKnownController.php index 2e317ae01b5..a4fd1689cdf 100644 --- a/core/Controller/WellKnownController.php +++ b/core/Controller/WellKnownController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright 2020 Christoph Wurst * * @author Christoph Wurst + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -28,10 +29,12 @@ namespace OC\Core\Controller; use OC\Http\WellKnown\RequestManager; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\IgnoreOpenAPI; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; use OCP\IRequest; +#[IgnoreOpenAPI] class WellKnownController extends Controller { public function __construct( IRequest $request, diff --git a/core/Controller/WhatsNewController.php b/core/Controller/WhatsNewController.php index 0791ce616f5..2d48f3cc485 100644 --- a/core/Controller/WhatsNewController.php +++ b/core/Controller/WhatsNewController.php @@ -4,6 +4,7 @@ * * @author Arthur Schiwon * @author Christoph Wurst + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -54,6 +55,13 @@ class WhatsNewController extends OCSController { /** * @NoAdminRequired + * + * Get the changes + * + * @return DataResponse|DataResponse, array{}> + * + * 200: Changes returned + * 204: No changes */ public function get():DataResponse { $user = $this->userSession->getUser(); @@ -92,8 +100,15 @@ class WhatsNewController extends OCSController { /** * @NoAdminRequired * + * Dismiss the changes + * + * @param string $version Version to dismiss the changes for + * + * @return DataResponse, array{}> * @throws \OCP\PreConditionNotMetException * @throws DoesNotExistException + * + * 200: Changes dismissed */ public function dismiss(string $version):DataResponse { $user = $this->userSession->getUser(); diff --git a/core/Controller/WipeController.php b/core/Controller/WipeController.php index 6ffb950ca86..537fd7126f6 100644 --- a/core/Controller/WipeController.php +++ b/core/Controller/WipeController.php @@ -6,6 +6,7 @@ declare(strict_types=1); * @copyright Copyright (c) 2019, Roeland Jago Douma * * @author Roeland Jago Douma + * @author Kate Döen * * @license GNU AGPL version 3 or any later version * @@ -48,9 +49,14 @@ class WipeController extends Controller { * * @AnonRateThrottle(limit=10, period=300) * - * @param string $token + * Check if the device should be wiped * - * @return JSONResponse + * @param string $token App password + * + * @return JSONResponse|JSONResponse, array{}> + * + * 200: Device should be wiped + * 404: Device should not be wiped */ public function checkWipe(string $token): JSONResponse { try { @@ -74,9 +80,14 @@ class WipeController extends Controller { * * @AnonRateThrottle(limit=10, period=300) * - * @param string $token + * Finish the wipe + * + * @param string $token App password + * + * @return JSONResponse, array{}> * - * @return JSONResponse + * 200: Wipe finished successfully + * 404: Device should not be wiped */ public function wipeDone(string $token): JSONResponse { try { diff --git a/core/ResponseDefinitions.php b/core/ResponseDefinitions.php new file mode 100644 index 00000000000..9ca194ef8fb --- /dev/null +++ b/core/ResponseDefinitions.php @@ -0,0 +1,131 @@ + + * + * @author Kate Döen + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCA\Core; + +/** + * @psalm-type CoreLoginFlowV2Credentials = array{ + * server: string, + * loginName: string, + * appPassword: string, + * } + * + * @psalm-type CoreLoginFlowV2 = array{ + * poll: array{ + * token: string, + * endpoint: string, + * }, + * login: string, + * } + * + * @psalm-type CoreNavigationEntry = array{ + * id: string, + * order: int|string, + * href: string, + * icon: string, + * type: string, + * name: string, + * active: bool, + * classes: string, + * unread: int, + * } + * + * @psalm-type CoreContactsAction = array{ + * title: string, + * icon: string, + * hyperlink: string, + * appId: string, + * } + * + * @psalm-type CoreOpenGraphObject = array{ + * richObjectType: string, + * richObject: array, + * openGraphObject: array{ + * id: string, + * name: string, + * description: ?string, + * thumb: ?string, + * link: string, + * }, + * accessible: bool, + * } + * + * @psalm-type CoreCollection = array{ + * id: int, + * name: string, + * resources: CoreOpenGraphObject[], + * } + * + * @psalm-type CoreReference = array{ + * richObjectType: string, + * richObject: array, + * openGraphObject: CoreOpenGraphObject, + * accessible: bool, + * } + * + * @psalm-type CoreReferenceProvider = array{ + * id: string, + * title: string, + * icon_url: string, + * order: int, + * search_providers_ids: ?string[] + * } + * + * @psalm-type CoreUnifiedSearchProvider = array{ + * id: string, + * name: string, + * order: int, + * } + * + * @psalm-type CoreUnifiedSearchResultEntry = array{ + * thumbnailUrl: string, + * title: string, + * subline: string, + * resourceUrl: string, + * icon: string, + * rounded: bool, + * attributes: string[], + * } + * + * @psalm-type CoreUnifiedSearchResult = array{ + * name: string, + * isPaginated: bool, + * entries: CoreUnifiedSearchResultEntry[], + * cursor: int|string|null, + * } + * + * @psalm-type CoreAutocompleteResult = array{ + * id: string, + * label: string, + * icon: string, + * source: string, + * status: string, + * subline: string, + * shareWithDisplayNameUnique: string, + * } + */ +class ResponseDefinitions { +} diff --git a/core/openapi.json b/core/openapi.json index 06e0047a190..89edc4114f2 100644 --- a/core/openapi.json +++ b/core/openapi.json @@ -64,7 +64,8 @@ ], "properties": { "id": { - "type": "string" + "type": "integer", + "format": "int64" }, "name": { "type": "string" @@ -72,10 +73,7 @@ "resources": { "type": "array", "items": { - "type": "object", - "additionalProperties": { - "type": "object" - } + "$ref": "#/components/schemas/OpenGraphObject" } } } @@ -225,7 +223,7 @@ } } }, - "Reference": { + "OpenGraphObject": { "type": "object", "required": [ "richObjectType", @@ -277,6 +275,32 @@ } } }, + "Reference": { + "type": "object", + "required": [ + "richObjectType", + "richObject", + "openGraphObject", + "accessible" + ], + "properties": { + "richObjectType": { + "type": "string" + }, + "richObject": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "openGraphObject": { + "$ref": "#/components/schemas/OpenGraphObject" + }, + "accessible": { + "type": "boolean" + } + } + }, "ReferenceProvider": { "type": "object", "required": [ @@ -485,11 +509,6 @@ "200": { "description": "Avatar returned", "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - }, "X-NC-IsCustomAvatar": { "schema": { "type": "integer", @@ -510,10 +529,7 @@ "description": "Avatar not found", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -561,11 +577,6 @@ "200": { "description": "Avatar returned", "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - }, "X-NC-IsCustomAvatar": { "schema": { "type": "integer", @@ -586,10 +597,7 @@ "description": "Avatar not found", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -635,13 +643,6 @@ "responses": { "200": { "description": "Custom avatar returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { "*/*": { "schema": { @@ -653,13 +654,6 @@ }, "201": { "description": "Avatar returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { "*/*": { "schema": { @@ -724,13 +718,6 @@ "responses": { "200": { "description": "Custom avatar returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { "*/*": { "schema": { @@ -742,13 +729,6 @@ }, "201": { "description": "Avatar returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { "*/*": { "schema": { @@ -806,10 +786,7 @@ "description": "Login flow not found or completed", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -869,7 +846,7 @@ "schema": { "type": "integer", "format": "int64", - "default": 1 + "default": -1 } }, { @@ -895,7 +872,7 @@ { "name": "a", "in": "query", - "description": "Not crop the preview", + "description": "Whether to not crop the preview", "schema": { "type": "integer", "default": 0 @@ -923,13 +900,6 @@ "responses": { "200": { "description": "Preview returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { "*/*": { "schema": { @@ -943,10 +913,7 @@ "description": "Getting preview is not possible", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } }, @@ -954,21 +921,15 @@ "description": "Getting preview is not allowed", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } }, "404": { - "description": "File not found", + "description": "Preview not found", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -978,7 +939,7 @@ "/index.php/core/preview.png": { "get": { "operationId": "preview-get-preview", - "summary": "Get a preview by file ID", + "summary": "Get a preview by file path", "tags": [ "preview" ], @@ -1023,7 +984,7 @@ { "name": "a", "in": "query", - "description": "Not crop the preview", + "description": "Whether to not crop the preview", "schema": { "type": "integer", "default": 0 @@ -1051,13 +1012,6 @@ "responses": { "200": { "description": "Preview returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { "*/*": { "schema": { @@ -1071,10 +1025,7 @@ "description": "Getting preview is not possible", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } }, @@ -1082,21 +1033,15 @@ "description": "Getting preview is not allowed", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } }, "404": { - "description": "File not found", + "description": "Preview not found", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -1133,15 +1078,8 @@ "responses": { "200": { "description": "Preview returned", - "headers": { - "Content-Disposition": { - "schema": { - "type": "string" - } - } - }, "content": { - "image/*": { + "*/*": { "schema": { "type": "string", "format": "binary" @@ -1212,10 +1150,7 @@ "description": "Device should not be wiped", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -1254,10 +1189,7 @@ "description": "Wipe finished successfully", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } }, @@ -1265,10 +1197,7 @@ "description": "Device should not be wiped", "content": { "application/json": { - "schema": { - "type": "object", - "additionalProperties": true - } + "schema": {} } } } @@ -1471,10 +1400,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -1574,10 +1500,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -1757,8 +1680,7 @@ "required": [ "changelogURL", "product", - "version", - "whatsNew" + "version" ], "properties": { "changelogURL": { @@ -1820,10 +1742,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -1888,10 +1807,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -1978,7 +1894,7 @@ } }, "403": { - "description": "Not allowed to create app password", + "description": "Creating app password is not allowed", "content": { "text/plain": { "schema": { @@ -2056,7 +1972,7 @@ } }, "403": { - "description": "Not allowed to rotate app password", + "description": "Rotating app password is not allowed", "content": { "text/plain": { "schema": { @@ -2115,10 +2031,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2127,7 +2040,7 @@ } }, "403": { - "description": "Not allowed to delete app password", + "description": "Deleting app password is not allowed", "content": { "text/plain": { "schema": { @@ -2244,10 +2157,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2347,10 +2257,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2448,10 +2355,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2479,10 +2383,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2587,10 +2488,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2618,10 +2516,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2735,10 +2630,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2766,10 +2658,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2883,10 +2772,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -2914,10 +2800,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -3026,10 +2909,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -3144,10 +3024,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -3175,10 +3052,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -3206,10 +3080,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -3374,7 +3245,15 @@ "references": { "type": "object", "additionalProperties": { - "$ref": "#/components/schemas/Reference" + "nullable": true, + "oneOf": [ + { + "$ref": "#/components/schemas/Reference" + }, + { + "type": "object" + } + ] } } } @@ -3473,8 +3352,15 @@ "references": { "type": "object", "additionalProperties": { - "$ref": "#/components/schemas/Reference", - "nullable": true + "nullable": true, + "oneOf": [ + { + "$ref": "#/components/schemas/Reference" + }, + { + "type": "object" + } + ] } } } @@ -3713,10 +3599,7 @@ "meta": { "$ref": "#/components/schemas/OCSMeta" }, - "data": { - "type": "object", - "additionalProperties": true - } + "data": {} } } } @@ -3963,8 +3846,7 @@ "$ref": "#/components/schemas/OCSMeta" }, "data": { - "type": "object", - "additionalProperties": true + "nullable": true } } } @@ -4318,10 +4200,6 @@ } }, "tags": [ - { - "name": "lost", - "description": "Class LostController\nSuccessfully changing a password will emit the post_passwordReset hook." - }, { "name": "avatar", "description": "Class AvatarController" diff --git a/lib/private/CapabilitiesManager.php b/lib/private/CapabilitiesManager.php index 9e63798475b..7885a98869d 100644 --- a/lib/private/CapabilitiesManager.php +++ b/lib/private/CapabilitiesManager.php @@ -50,7 +50,7 @@ class CapabilitiesManager { * * @param bool $public get public capabilities only * @throws \InvalidArgumentException - * @return array + * @return array */ public function getCapabilities(bool $public = false, bool $initialState = false) : array { $capabilities = []; diff --git a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php index 9fc021435a4..e0d3515f421 100644 --- a/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php +++ b/lib/private/Contacts/ContactsMenu/Actions/LinkAction.php @@ -76,6 +76,9 @@ class LinkAction implements ILinkAction { return $this->appId; } + /** + * @return array{title: string, icon: string, hyperlink: string, appId: string} + */ public function jsonSerialize(): array { return [ 'title' => $this->name, diff --git a/lib/private/Contacts/ContactsMenu/Entry.php b/lib/private/Contacts/ContactsMenu/Entry.php index 649c83ae7d8..f1cb4f9c52f 100644 --- a/lib/private/Contacts/ContactsMenu/Entry.php +++ b/lib/private/Contacts/ContactsMenu/Entry.php @@ -141,6 +141,9 @@ class Entry implements IEntry { return $this->properties[$key]; } + /** + * @return array{id: int|string|null, fullName: string, avatar: string|null, topAction: mixed, actions: array, lastMessage: '', emailAddresses: string[], profileTitle: string|null, profileUrl: string|null} + */ public function jsonSerialize(): array { $topAction = !empty($this->actions) ? $this->actions[0]->jsonSerialize() : null; $otherActions = array_map(function (IAction $action) { diff --git a/lib/private/Updater/ChangesCheck.php b/lib/private/Updater/ChangesCheck.php index 2c1eb321ee0..ee4d1f1fcee 100644 --- a/lib/private/Updater/ChangesCheck.php +++ b/lib/private/Updater/ChangesCheck.php @@ -51,6 +51,7 @@ class ChangesCheck { /** * @throws DoesNotExistException + * @return array{changelogURL: string, whatsNew: array} */ public function getChangesForVersion(string $version): array { $version = $this->normalizeVersion($version); diff --git a/lib/public/Collaboration/Reference/Reference.php b/lib/public/Collaboration/Reference/Reference.php index 6b92a0fae52..0dcb665713c 100644 --- a/lib/public/Collaboration/Reference/Reference.php +++ b/lib/public/Collaboration/Reference/Reference.php @@ -27,6 +27,7 @@ namespace OCP\Collaboration\Reference; /** * @since 25.0.0 + * @psalm-type OpenGraphObject = array{id: string, name: string, description: ?string, thumb: ?string, link: string} */ class Reference implements IReference { protected string $reference; @@ -176,6 +177,7 @@ class Reference implements IReference { /** * @inheritdoc * @since 25.0.0 + * @return array */ public function getRichObject(): array { if ($this->richObject === null) { @@ -187,6 +189,7 @@ class Reference implements IReference { /** * @inheritdoc * @since 25.0.0 + * @return OpenGraphObject */ public function getOpenGraphObject(): array { return [ @@ -237,6 +240,7 @@ class Reference implements IReference { /** * @inheritdoc * @since 25.0.0 + * @return array{richObjectType: string, richObject: array, openGraphObject: OpenGraphObject, accessible: bool} */ public function jsonSerialize() { return [ diff --git a/lib/public/Translation/LanguageTuple.php b/lib/public/Translation/LanguageTuple.php index 9defb17e4b6..27f932f0a64 100644 --- a/lib/public/Translation/LanguageTuple.php +++ b/lib/public/Translation/LanguageTuple.php @@ -45,6 +45,7 @@ class LanguageTuple implements JsonSerializable { /** * @since 26.0.0 + * @return array{from: string, fromLabel: string, to: string, toLabel: string} */ public function jsonSerialize(): array { return [ diff --git a/tests/Core/Controller/ClientFlowLoginV2ControllerTest.php b/tests/Core/Controller/ClientFlowLoginV2ControllerTest.php index a1f50e328dd..fac060262ed 100644 --- a/tests/Core/Controller/ClientFlowLoginV2ControllerTest.php +++ b/tests/Core/Controller/ClientFlowLoginV2ControllerTest.php @@ -106,7 +106,7 @@ class ClientFlowLoginV2ControllerTest extends TestCase { $result = $this->controller->poll('token'); - $this->assertSame($creds, $result->getData()); + $this->assertSame($creds->jsonSerialize(), $result->getData()); $this->assertSame(Http::STATUS_OK, $result->getStatus()); }