Merge pull request #39331 from nextcloud/feature/openapi/core

core: Add OpenAPI spec
pull/39291/head
Robin Appelman 11 months ago committed by GitHub
commit c988d782eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,6 +8,7 @@ declare(strict_types=1);
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Daniel Kesselberg <mail@danielkesselberg.de>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{apppassword: string}, array{}>
* @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<Http::STATUS_OK, array<empty>, 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<Http::STATUS_OK, array{apppassword: string}, array{}>
* @throws OCSForbiddenException Rotating app password is not allowed
*
* 200: App password returned
*/
public function rotateAppPassword(): DataResponse {
if (!$this->session->exists('app_password')) {

@ -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<Http::STATUS_OK, CoreAutocompleteResult[], array{}>
*/
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 ?? '',
];
}
}

@ -12,6 +12,7 @@
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <vincent@nextcloud.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{Content-Type: string, X-NC-IsCustomAvatar: int}>|JSONResponse<Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK, array{Content-Type: string, X-NC-IsCustomAvatar: int}>|JSONResponse<Http::STATUS_NOT_FOUND, array<empty>, array{}>
*
* 200: Avatar returned
* 404: Avatar not found
*/
public function getAvatar(string $userId, int $size) {
if ($size <= 64) {

@ -7,6 +7,7 @@ declare(strict_types=1);
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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,

@ -12,6 +12,7 @@
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author RussellAult <RussellAult@users.noreply.github.com>
* @author Sergej Nikolaev <kinolaev@gmail.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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';

@ -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<Http::STATUS_OK, CoreLoginFlowV2Credentials, array{}>|JSONResponse<Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK, CoreLoginFlowV2, array{}>
*/
public function init(): JSONResponse {
// Get client user agent

@ -8,6 +8,7 @@ declare(strict_types=1);
* @author Joas Schilling <coding@schilljs.com>
* @author Julius Härtl <jus@bitgrid.net>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, CoreCollection, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array<empty>, 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<Http::STATUS_OK, CoreCollection[], array{}>|DataResponse<Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK, CoreCollection, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array<empty>, 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<Http::STATUS_OK, CoreCollection, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array<empty>, 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<Http::STATUS_OK, CoreCollection[], array{}>|DataResponse<Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK, CoreCollection, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array<empty>, 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<Http::STATUS_OK, CoreCollection, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array<empty>, 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<Http::STATUS_OK, CoreCollection, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_INTERNAL_SERVER_ERROR, array<empty>, 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');

@ -11,6 +11,7 @@ declare(strict_types=1);
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Citharel <nextcloud@tcit.fr>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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;

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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

@ -3,6 +3,7 @@
* @copyright Copyright (c) 2019, Michael Weimann <mail@michael-weimann.eu>
*
* @author Michael Weimann <mail@michael-weimann.eu>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK|Http::STATUS_CREATED, array{Content-Type: string}>|Response<Http::STATUS_INTERNAL_SERVER_ERROR, array{}>
*
* 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<Http::STATUS_OK|Http::STATUS_CREATED, array{Content-Type: string}>|Response<Http::STATUS_INTERNAL_SERVER_ERROR, array{}>
*
* 200: Custom avatar returned
* 201: Avatar returned
*/
public function getAvatarDark(string $guestName, string $size) {
return $this->getAvatar($guestName, $size, true);

@ -5,6 +5,7 @@ declare(strict_types=1);
* @copyright 2021 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{userId: string, displayName: string, actions: CoreContactsAction[]}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array<empty>, 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);
}
}

@ -11,6 +11,7 @@ declare(strict_types=1);
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Citharel <nextcloud@tcit.fr>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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;

@ -16,6 +16,7 @@ declare(strict_types=1);
* @author Michael Weimann <mail@michael-weimann.eu>
* @author Rayn0r <andrew@ilpss8.myfirewall.org>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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';

@ -17,6 +17,7 @@
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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;

@ -3,6 +3,7 @@
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, CoreNavigationEntry[], array{}>|DataResponse<Http::STATUS_NOT_MODIFIED, array<empty>, 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<Http::STATUS_OK, CoreNavigationEntry[], array{}>|DataResponse<Http::STATUS_NOT_MODIFIED, array<empty>, array{}>
*
* 200: Apps navigation returned
* 304: No apps navigation changed
*/
public function getSettingsNavigation(bool $absolute = false): DataResponse {
$navigation = $this->navigationManager->getAll('settings');

@ -8,6 +8,7 @@
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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;

@ -8,6 +8,7 @@
* @author Julius Härtl <jus@bitgrid.net>
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{version: array{major: int, minor: int, micro: int, string: string, edition: '', extendedSupport: bool}, capabilities: array<string, mixed>}, 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);

@ -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<Http::STATUS_OK, array{Content-Type: string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK, array{Content-Type: string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK, array{Content-Type: string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, array<empty>, array{}>
*/
private function fetchPreview(
Node $node,

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright 2021 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array<empty>, 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();

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright 2021 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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,

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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,

@ -5,6 +5,7 @@ declare(strict_types=1);
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{references: array<string, CoreReference|mixed|null>}, 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<Http::STATUS_OK, array{references: array<string, ?CoreReference>}, 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<Http::STATUS_OK, array{references: array<string, CoreReference|mixed|null>}, 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<Http::STATUS_OK, CoreReferenceProvider[], array{}>
*/
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<Http::STATUS_OK, array{success: bool}, array{}>
*/
public function touchProvider(string $providerId, ?int $timestamp = null): DataResponse {
if ($this->userId !== null) {

@ -5,6 +5,7 @@ declare(strict_types=1);
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, string, array{}>|DataResponse<Http::STATUS_NOT_FOUND, '', array{}>
*
* 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 {

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{languages: array{from: string, fromLabel: string, to: string, toLabel: string}[], languageDetection: bool}, array{}>
*/
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<Http::STATUS_OK, array{text: string, from: ?string}, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_PRECONDITION_FAILED|Http::STATUS_INTERNAL_SERVER_ERROR, array{message: string, from?: ?string}, array{}>
*
* 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 {

@ -7,6 +7,7 @@
* @author Joas Schilling <coding@schilljs.com>
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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,

@ -8,6 +8,7 @@ declare(strict_types=1);
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Joas Schilling <coding@schilljs.com>
* @author John Molakvoæ <skjnldsv@protonmail.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, CoreUnifiedSearchProvider[], array{}>
*/
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<Http::STATUS_OK, CoreUnifiedSearchResult, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, null, array{}>
*
* @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()
);
}

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright 2021 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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);

@ -4,6 +4,7 @@
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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,

@ -4,6 +4,7 @@
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
@ -54,6 +55,13 @@ class WhatsNewController extends OCSController {
/**
* @NoAdminRequired
*
* Get the changes
*
* @return DataResponse<Http::STATUS_OK, array{changelogURL: string, product: string, version: string, whatsNew?: array{regular: string[], admin: string[]}}, array{}>|DataResponse<Http::STATUS_NO_CONTENT, array<empty>, 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<Http::STATUS_OK, array<empty>, array{}>
* @throws \OCP\PreConditionNotMetException
* @throws DoesNotExistException
*
* 200: Changes dismissed
*/
public function dismiss(string $version):DataResponse {
$user = $this->userSession->getUser();

@ -6,6 +6,7 @@ declare(strict_types=1);
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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<Http::STATUS_OK, array{wipe: bool}, array{}>|JSONResponse<Http::STATUS_NOT_FOUND, array<empty>, 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<Http::STATUS_OK|Http::STATUS_NOT_FOUND, array<empty>, array{}>
*
* @return JSONResponse
* 200: Wipe finished successfully
* 404: Device should not be wiped
*/
public function wipeDone(string $token): JSONResponse {
try {

@ -0,0 +1,131 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Kate Döen <kate.doeen@nextcloud.com>
*
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @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 <http://www.gnu.org/licenses/>.
*
*/
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<string, mixed>,
* 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<string, mixed>,
* 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 {
}

@ -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"

@ -50,7 +50,7 @@ class CapabilitiesManager {
*
* @param bool $public get public capabilities only
* @throws \InvalidArgumentException
* @return array
* @return array<string, mixed>
*/
public function getCapabilities(bool $public = false, bool $initialState = false) : array {
$capabilities = [];

@ -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,

@ -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) {

@ -51,6 +51,7 @@ class ChangesCheck {
/**
* @throws DoesNotExistException
* @return array{changelogURL: string, whatsNew: array<string, array{admin: string[], regular: string[]}>}
*/
public function getChangesForVersion(string $version): array {
$version = $this->normalizeVersion($version);

@ -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<string, mixed>
*/
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<string, mixed>, openGraphObject: OpenGraphObject, accessible: bool}
*/
public function jsonSerialize() {
return [

@ -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 [

@ -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());
}

Loading…
Cancel
Save