mirror of
https://github.com/nextcloud/server.git
synced 2026-06-06 15:23:17 -04:00
Merge pull request #42801 from nextcloud/feat/appframework/route-attribute
This commit is contained in:
commit
fa8b4f32d2
56 changed files with 3517 additions and 3162 deletions
|
|
@ -177,6 +177,7 @@
|
|||
"name": "expirationTime",
|
||||
"in": "query",
|
||||
"description": "Duration until the link expires",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2020, Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.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/>.
|
||||
*
|
||||
*/
|
||||
return [
|
||||
'ocs' => [
|
||||
// Routes for querying statuses
|
||||
['name' => 'Statuses#findAll', 'url' => '/api/v1/statuses', 'verb' => 'GET'],
|
||||
['name' => 'Statuses#find', 'url' => '/api/v1/statuses/{userId}', 'verb' => 'GET'],
|
||||
// Routes for manipulating your own status
|
||||
['name' => 'UserStatus#getStatus', 'url' => '/api/v1/user_status', 'verb' => 'GET'],
|
||||
['name' => 'UserStatus#setStatus', 'url' => '/api/v1/user_status/status', 'verb' => 'PUT'],
|
||||
['name' => 'UserStatus#setPredefinedMessage', 'url' => '/api/v1/user_status/message/predefined', 'verb' => 'PUT'],
|
||||
['name' => 'UserStatus#setCustomMessage', 'url' => '/api/v1/user_status/message/custom', 'verb' => 'PUT'],
|
||||
['name' => 'UserStatus#clearMessage', 'url' => '/api/v1/user_status/message', 'verb' => 'DELETE'],
|
||||
['name' => 'UserStatus#revertStatus', 'url' => '/api/v1/user_status/revert/{messageId}', 'verb' => 'DELETE'],
|
||||
// Routes for listing default routes
|
||||
['name' => 'PredefinedStatus#findAll', 'url' => '/api/v1/predefined_statuses/', 'verb' => 'GET'],
|
||||
// Route for doing heartbeats
|
||||
['name' => 'Heartbeat#heartbeat', 'url' => '/api/v1/heartbeat', 'verb' => 'PUT'],
|
||||
],
|
||||
];
|
||||
|
|
@ -30,6 +30,7 @@ use OCA\UserStatus\Db\UserStatus;
|
|||
use OCA\UserStatus\ResponseDefinitions;
|
||||
use OCA\UserStatus\Service\StatusService;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
|
|
@ -81,6 +82,7 @@ class HeartbeatController extends OCSController {
|
|||
* 204: User has no status to keep alive
|
||||
* 400: Invalid status to update
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/api/v1/heartbeat')]
|
||||
public function heartbeat(string $status): DataResponse {
|
||||
if (!\in_array($status, [IUserStatus::ONLINE, IUserStatus::AWAY], true)) {
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OCA\UserStatus\Controller;
|
|||
use OCA\UserStatus\ResponseDefinitions;
|
||||
use OCA\UserStatus\Service\PredefinedStatusService;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -66,6 +67,7 @@ class PredefinedStatusController extends OCSController {
|
|||
*
|
||||
* 200: Predefined statuses returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/api/v1/predefined_statuses/')]
|
||||
public function findAll():DataResponse {
|
||||
// Filtering out the invisible one, that should only be set by API
|
||||
return new DataResponse(array_filter($this->predefinedStatusService->getDefaultStatuses(), function (array $status) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ use OCA\UserStatus\ResponseDefinitions;
|
|||
use OCA\UserStatus\Service\StatusService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSNotFoundException;
|
||||
use OCP\AppFramework\OCSController;
|
||||
|
|
@ -72,6 +73,7 @@ class StatusesController extends OCSController {
|
|||
*
|
||||
* 200: Statuses returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/api/v1/statuses')]
|
||||
public function findAll(?int $limit = null, ?int $offset = null): DataResponse {
|
||||
$allStatuses = $this->service->findAll($limit, $offset);
|
||||
|
||||
|
|
@ -91,6 +93,7 @@ class StatusesController extends OCSController {
|
|||
*
|
||||
* 200: Status returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/api/v1/statuses/{userId}')]
|
||||
public function find(string $userId): DataResponse {
|
||||
try {
|
||||
$userStatus = $this->service->findByUserId($userId);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ use OCA\UserStatus\ResponseDefinitions;
|
|||
use OCA\UserStatus\Service\StatusService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||
use OCP\AppFramework\OCS\OCSNotFoundException;
|
||||
|
|
@ -72,6 +73,7 @@ class UserStatusController extends OCSController {
|
|||
*
|
||||
* 200: The status was found successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/api/v1/user_status')]
|
||||
public function getStatus(): DataResponse {
|
||||
try {
|
||||
$this->calendarStatusService->processCalendarStatus($this->userId);
|
||||
|
|
@ -94,6 +96,7 @@ class UserStatusController extends OCSController {
|
|||
*
|
||||
* 200: The status was updated successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/api/v1/user_status/status')]
|
||||
public function setStatus(string $statusType): DataResponse {
|
||||
try {
|
||||
$status = $this->service->setStatus($this->userId, $statusType, null, true);
|
||||
|
|
@ -118,6 +121,7 @@ class UserStatusController extends OCSController {
|
|||
*
|
||||
* 200: The message was updated successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/api/v1/user_status/message/predefined')]
|
||||
public function setPredefinedMessage(string $messageId,
|
||||
?int $clearAt): DataResponse {
|
||||
try {
|
||||
|
|
@ -146,6 +150,7 @@ class UserStatusController extends OCSController {
|
|||
*
|
||||
* 200: The message was updated successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/api/v1/user_status/message/custom')]
|
||||
public function setCustomMessage(?string $statusIcon,
|
||||
?string $message,
|
||||
?int $clearAt): DataResponse {
|
||||
|
|
@ -179,6 +184,7 @@ class UserStatusController extends OCSController {
|
|||
*
|
||||
* 200: Message cleared successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'DELETE', url: '/api/v1/user_status/message')]
|
||||
public function clearMessage(): DataResponse {
|
||||
$this->service->clearMessage($this->userId);
|
||||
return new DataResponse([]);
|
||||
|
|
@ -195,6 +201,7 @@ class UserStatusController extends OCSController {
|
|||
*
|
||||
* 200: Status reverted
|
||||
*/
|
||||
#[ApiRoute(verb: 'DELETE', url: '/api/v1/user_status/revert/{messageId}')]
|
||||
public function revertStatus(string $messageId): DataResponse {
|
||||
$backupStatus = $this->service->revertUserStatus($this->userId, $messageId, true);
|
||||
if ($backupStatus) {
|
||||
|
|
|
|||
|
|
@ -206,6 +206,224 @@
|
|||
}
|
||||
},
|
||||
"paths": {
|
||||
"/ocs/v2.php/apps/user_status/api/v1/heartbeat": {
|
||||
"put": {
|
||||
"operationId": "heartbeat-heartbeat",
|
||||
"summary": "Keep the status alive",
|
||||
"tags": [
|
||||
"heartbeat"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "status",
|
||||
"in": "query",
|
||||
"description": "Only online, away",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Status successfully updated",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Private"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid status to update",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"204": {
|
||||
"description": "User has no status to keep alive",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/user_status/api/v1/predefined_statuses": {
|
||||
"get": {
|
||||
"operationId": "predefined_status-find-all",
|
||||
"summary": "Get all predefined messages",
|
||||
"tags": [
|
||||
"predefined_status"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Predefined statuses returned",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Predefined"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/user_status/api/v1/statuses": {
|
||||
"get": {
|
||||
"operationId": "statuses-find-all",
|
||||
|
|
@ -846,224 +1064,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/user_status/api/v1/predefined_statuses": {
|
||||
"get": {
|
||||
"operationId": "predefined_status-find-all",
|
||||
"summary": "Get all predefined messages",
|
||||
"tags": [
|
||||
"predefined_status"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Predefined statuses returned",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Predefined"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/ocs/v2.php/apps/user_status/api/v1/heartbeat": {
|
||||
"put": {
|
||||
"operationId": "heartbeat-heartbeat",
|
||||
"summary": "Keep the status alive",
|
||||
"tags": [
|
||||
"heartbeat"
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearer_auth": []
|
||||
},
|
||||
{
|
||||
"basic_auth": []
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "status",
|
||||
"in": "query",
|
||||
"description": "Only online, away",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OCS-APIRequest",
|
||||
"in": "header",
|
||||
"description": "Required to be true for the API request to pass",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Status successfully updated",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/Private"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid status to update",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"204": {
|
||||
"description": "User has no status to keep alive",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ocs"
|
||||
],
|
||||
"properties": {
|
||||
"ocs": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"meta",
|
||||
"data"
|
||||
],
|
||||
"properties": {
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/OCSMeta"
|
||||
},
|
||||
"data": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use OC\Authentication\Token\IProvider;
|
|||
use OC\Authentication\Token\IToken;
|
||||
use OC\User\Session;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||
|
|
@ -74,6 +75,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: App password returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/getapppassword', root: '/core')]
|
||||
public function getAppPassword(): DataResponse {
|
||||
// We do not allow the creation of new tokens if this is an app password
|
||||
if ($this->session->exists('app_password')) {
|
||||
|
|
@ -125,6 +127,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: App password deleted successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'DELETE', url: '/apppassword', root: '/core')]
|
||||
public function deleteAppPassword(): DataResponse {
|
||||
if (!$this->session->exists('app_password')) {
|
||||
throw new OCSForbiddenException('no app password in use');
|
||||
|
|
@ -152,6 +155,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: App password returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/apppassword/rotate', root: '/core')]
|
||||
public function rotateAppPassword(): DataResponse {
|
||||
if (!$this->session->exists('app_password')) {
|
||||
throw new OCSForbiddenException('no app password in use');
|
||||
|
|
@ -187,6 +191,7 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
|
|||
* 403: Password confirmation failed
|
||||
*/
|
||||
#[UseSession]
|
||||
#[ApiRoute(verb: 'PUT', url: '/apppassword/confirm', root: '/core')]
|
||||
public function confirmUserPassword(string $password): DataResponse {
|
||||
$loginName = $this->userSession->getLoginName();
|
||||
$loginResult = $this->userManager->checkPassword($loginName, $password);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\Collaboration\AutoComplete\AutoCompleteEvent;
|
||||
|
|
@ -72,6 +73,7 @@ class AutoCompleteController extends OCSController {
|
|||
*
|
||||
* 200: Autocomplete results returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/autocomplete/get', root: '/core')]
|
||||
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
|
||||
// result from search() – thus nothing else to do here.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ namespace OC\Core\Controller;
|
|||
use OC\AppFramework\Utility\TimeFactory;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\DataDisplayResponse;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
|
@ -82,6 +83,7 @@ class AvatarController extends Controller {
|
|||
* 200: Avatar returned
|
||||
* 404: Avatar not found
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/avatar/{userId}/{size}/dark')]
|
||||
public function getAvatarDark(string $userId, int $size) {
|
||||
if ($size <= 64) {
|
||||
if ($size !== 64) {
|
||||
|
|
@ -128,6 +130,7 @@ class AvatarController extends Controller {
|
|||
* 200: Avatar returned
|
||||
* 404: Avatar not found
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/avatar/{userId}/{size}')]
|
||||
public function getAvatar(string $userId, int $size) {
|
||||
if ($size <= 64) {
|
||||
if ($size !== 64) {
|
||||
|
|
@ -161,6 +164,7 @@ class AvatarController extends Controller {
|
|||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/avatar/')]
|
||||
public function postAvatar(?string $path = null): JSONResponse {
|
||||
$files = $this->request->getUploadedFile('files');
|
||||
|
||||
|
|
@ -283,6 +287,7 @@ class AvatarController extends Controller {
|
|||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'DELETE', url: '/avatar/')]
|
||||
public function deleteAvatar(): JSONResponse {
|
||||
try {
|
||||
$avatar = $this->avatarManager->getAvatar($this->userId);
|
||||
|
|
@ -299,6 +304,7 @@ class AvatarController extends Controller {
|
|||
*
|
||||
* @return JSONResponse|DataDisplayResponse
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/avatar/tmp')]
|
||||
public function getTmpAvatar() {
|
||||
$tmpAvatar = $this->cache->get('tmpAvatar');
|
||||
if (is_null($tmpAvatar)) {
|
||||
|
|
@ -325,6 +331,7 @@ class AvatarController extends Controller {
|
|||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/avatar/cropped')]
|
||||
public function postCroppedAvatar(?array $crop = null): JSONResponse {
|
||||
if (is_null($crop)) {
|
||||
return new JSONResponse(['data' => ['message' => $this->l10n->t("No crop data provided")]],
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace OC\Core\Controller;
|
|||
use OC\Security\CSRF\CsrfTokenManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -49,6 +50,7 @@ class CSRFTokenController extends Controller {
|
|||
* @NoCSRFRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/csrftoken')]
|
||||
public function index(): JSONResponse {
|
||||
if (!$this->request->passesStrictCookieCheck()) {
|
||||
return new JSONResponse([], Http::STATUS_FORBIDDEN);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ use OCA\OAuth2\Db\AccessTokenMapper;
|
|||
use OCA\OAuth2\Db\ClientMapper;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
|
|
@ -113,6 +114,7 @@ class ClientFlowLoginController extends Controller {
|
|||
* @NoCSRFRequired
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/flow')]
|
||||
public function showAuthPickerPage(string $clientIdentifier = '', string $user = '', int $direct = 0): StandaloneTemplateResponse {
|
||||
$clientName = $this->getClientName();
|
||||
$client = null;
|
||||
|
|
@ -180,6 +182,7 @@ class ClientFlowLoginController extends Controller {
|
|||
* @NoSameSiteCookieRequired
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/flow/grant')]
|
||||
public function grantPage(string $stateToken = '',
|
||||
string $clientIdentifier = '',
|
||||
int $direct = 0): StandaloneTemplateResponse {
|
||||
|
|
@ -232,6 +235,7 @@ class ClientFlowLoginController extends Controller {
|
|||
* @return Http\RedirectResponse|Response
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/flow')]
|
||||
public function generateAppPassword(string $stateToken,
|
||||
string $clientIdentifier = '') {
|
||||
if (!$this->isValidToken($stateToken)) {
|
||||
|
|
@ -323,6 +327,7 @@ class ClientFlowLoginController extends Controller {
|
|||
/**
|
||||
* @PublicPage
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/flow/apptoken')]
|
||||
public function apptokenRedirect(string $stateToken, string $user, string $password): Response {
|
||||
if (!$this->isValidToken($stateToken)) {
|
||||
return $this->stateTokenForbiddenResponse();
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use OC\Core\Service\LoginFlowV2Service;
|
|||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
|
@ -84,6 +85,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
* 200: Login flow credentials returned
|
||||
* 404: Login flow not found or completed
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/v2/poll')]
|
||||
public function poll(string $token): JSONResponse {
|
||||
try {
|
||||
$creds = $this->loginFlowV2Service->poll($token);
|
||||
|
|
@ -100,6 +102,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
*/
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/v2/flow/{token}')]
|
||||
public function landing(string $token, $user = ''): Response {
|
||||
if (!$this->loginFlowV2Service->startLoginFlow($token)) {
|
||||
return $this->loginTokenForbiddenResponse();
|
||||
|
|
@ -118,6 +121,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
*/
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/v2/flow')]
|
||||
public function showAuthPickerPage($user = ''): StandaloneTemplateResponse {
|
||||
try {
|
||||
$flow = $this->getFlowByLoginToken();
|
||||
|
|
@ -152,6 +156,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
*/
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/v2/grant')]
|
||||
public function grantPage(?string $stateToken): StandaloneTemplateResponse {
|
||||
if ($stateToken === null) {
|
||||
return $this->stateTokenMissingResponse();
|
||||
|
|
@ -187,6 +192,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
/**
|
||||
* @PublicPage
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/v2/apptoken')]
|
||||
public function apptokenRedirect(?string $stateToken, string $user, string $password) {
|
||||
if ($stateToken === null) {
|
||||
return $this->stateTokenMissingResponse();
|
||||
|
|
@ -234,6 +240,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
* @NoAdminRequired
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/v2/grant')]
|
||||
public function generateAppPassword(?string $stateToken): Response {
|
||||
if ($stateToken === null) {
|
||||
return $this->stateTokenMissingResponse();
|
||||
|
|
@ -291,6 +298,7 @@ class ClientFlowLoginV2Controller extends Controller {
|
|||
*
|
||||
* 200: Login flow init returned
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/v2')]
|
||||
public function init(): JSONResponse {
|
||||
// Get client user agent
|
||||
$userAgent = $this->request->getHeader('USER_AGENT');
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace OC\Core\Controller;
|
|||
use Exception;
|
||||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\Collaboration\Resources\CollectionException;
|
||||
|
|
@ -84,6 +85,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 200: Collection returned
|
||||
* 404: Collection not found
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/resources/collections/{collectionId}', root: '/collaboration')]
|
||||
public function listCollection(int $collectionId): DataResponse {
|
||||
try {
|
||||
$collection = $this->getCollection($collectionId);
|
||||
|
|
@ -105,6 +107,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 200: Collections returned
|
||||
* 404: Collection not found
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/resources/collections/search/{filter}', root: '/collaboration')]
|
||||
public function searchCollections(string $filter): DataResponse {
|
||||
try {
|
||||
$collections = $this->manager->searchCollections($this->userSession->getUser(), $filter);
|
||||
|
|
@ -128,6 +131,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 200: Collection returned
|
||||
* 404: Collection not found or resource inaccessible
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/resources/collections/{collectionId}', root: '/collaboration')]
|
||||
public function addResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
|
||||
try {
|
||||
$collection = $this->getCollection($collectionId);
|
||||
|
|
@ -162,6 +166,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 200: Collection returned
|
||||
* 404: Collection or resource not found
|
||||
*/
|
||||
#[ApiRoute(verb: 'DELETE', url: '/resources/collections/{collectionId}', root: '/collaboration')]
|
||||
public function removeResource(int $collectionId, string $resourceType, string $resourceId): DataResponse {
|
||||
try {
|
||||
$collection = $this->getCollection($collectionId);
|
||||
|
|
@ -192,6 +197,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 200: Collections returned
|
||||
* 404: Resource not accessible
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/resources/{resourceType}/{resourceId}', root: '/collaboration')]
|
||||
public function getCollectionsByResource(string $resourceType, string $resourceId): DataResponse {
|
||||
try {
|
||||
$resource = $this->manager->getResourceForUser($resourceType, $resourceId, $this->userSession->getUser());
|
||||
|
|
@ -220,6 +226,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 400: Creating collection is not possible
|
||||
* 404: Resource inaccessible
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/resources/{baseResourceType}/{baseResourceId}', root: '/collaboration')]
|
||||
public function createCollectionOnResource(string $baseResourceType, string $baseResourceId, string $name): DataResponse {
|
||||
if (!isset($name[0]) || isset($name[64])) {
|
||||
return new DataResponse([], Http::STATUS_BAD_REQUEST);
|
||||
|
|
@ -253,6 +260,7 @@ class CollaborationResourcesController extends OCSController {
|
|||
* 200: Collection returned
|
||||
* 404: Collection not found
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/resources/collections/{collectionId}', root: '/collaboration')]
|
||||
public function renameCollection(int $collectionId, string $collectionName): DataResponse {
|
||||
try {
|
||||
$collection = $this->getCollection($collectionId);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ use Exception;
|
|||
use OC\Contacts\ContactsMenu\Manager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserSession;
|
||||
|
|
@ -47,6 +48,7 @@ class ContactsMenuController extends Controller {
|
|||
* @return \JsonSerializable[]
|
||||
* @throws Exception
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/contactsmenu/contacts')]
|
||||
public function index(?string $filter = null): array {
|
||||
return $this->manager->getEntries($this->userSession->getUser(), $filter);
|
||||
}
|
||||
|
|
@ -57,6 +59,7 @@ class ContactsMenuController extends Controller {
|
|||
* @return JSONResponse|\JsonSerializable
|
||||
* @throws Exception
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/contactsmenu/findOne')]
|
||||
public function findOne(int $shareType, string $shareWith) {
|
||||
$contact = $this->manager->findOne($this->userSession->getUser(), $shareType, $shareWith);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,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\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\NotFoundResponse;
|
||||
|
|
@ -69,6 +70,7 @@ class CssController extends Controller {
|
|||
* @param string $appName css folder name
|
||||
* @return FileDisplayResponse|NotFoundResponse
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/css/{appName}/{fileName}')]
|
||||
public function getCss(string $fileName, string $appName): Response {
|
||||
try {
|
||||
$folder = $this->appData->getFolder($appName);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ declare(strict_types=1);
|
|||
namespace OC\Core\Controller;
|
||||
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
|
||||
|
|
@ -37,6 +38,7 @@ class ErrorController extends \OCP\AppFramework\Controller {
|
|||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: 'error/403')]
|
||||
public function error403(): TemplateResponse {
|
||||
$response = new TemplateResponse(
|
||||
'core',
|
||||
|
|
@ -52,6 +54,7 @@ class ErrorController extends \OCP\AppFramework\Controller {
|
|||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: 'error/404')]
|
||||
public function error404(): TemplateResponse {
|
||||
$response = new TemplateResponse(
|
||||
'core',
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\IAvatarManager;
|
||||
|
|
@ -61,6 +62,7 @@ class GuestAvatarController extends Controller {
|
|||
* 200: Custom avatar returned
|
||||
* 201: Avatar returned
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/avatar/guest/{guestName}/{size}')]
|
||||
public function getAvatar(string $guestName, string $size, ?bool $darkTheme = false) {
|
||||
$size = (int) $size;
|
||||
$darkTheme = $darkTheme ?? false;
|
||||
|
|
@ -113,6 +115,7 @@ class GuestAvatarController extends Controller {
|
|||
* 200: Custom avatar returned
|
||||
* 201: Avatar returned
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/avatar/guest/{guestName}/{size}/dark')]
|
||||
public function getAvatarDark(string $guestName, string $size) {
|
||||
return $this->getAvatar($guestName, $size, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ namespace OC\Core\Controller;
|
|||
use OC\Contacts\ContactsMenu\Manager;
|
||||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserSession;
|
||||
|
|
@ -56,6 +57,7 @@ class HoverCardController extends \OCP\AppFramework\OCSController {
|
|||
* 200: Account details returned
|
||||
* 404: Account not found
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/v1/{userId}', root: '/hovercard')]
|
||||
public function getUser(string $userId): DataResponse {
|
||||
$contact = $this->manager->findOne($this->userSession->getUser(), IShare::TYPE_USER, $userId);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,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\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\NotFoundResponse;
|
||||
|
|
@ -69,6 +70,7 @@ class JsController extends Controller {
|
|||
* @param string $appName js folder name
|
||||
* @return FileDisplayResponse|NotFoundResponse
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/js/{appName}/{fileName}')]
|
||||
public function getJs(string $fileName, string $appName): Response {
|
||||
try {
|
||||
$folder = $this->appData->getFolder($appName);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ use OC\User\Session;
|
|||
use OC_App;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
|
|
@ -91,6 +92,7 @@ class LoginController extends Controller {
|
|||
* @return RedirectResponse
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/logout')]
|
||||
public function logout() {
|
||||
$loginToken = $this->request->getCookie('nc_token');
|
||||
if (!is_null($loginToken)) {
|
||||
|
|
@ -127,6 +129,7 @@ class LoginController extends Controller {
|
|||
*/
|
||||
#[UseSession]
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login')]
|
||||
public function showLoginForm(string $user = null, string $redirect_url = null): Http\Response {
|
||||
if ($this->userSession->isLoggedIn()) {
|
||||
return new RedirectResponse($this->urlGenerator->linkToDefaultPageUrl());
|
||||
|
|
@ -276,6 +279,7 @@ class LoginController extends Controller {
|
|||
*/
|
||||
#[UseSession]
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login')]
|
||||
public function tryLogin(Chain $loginChain,
|
||||
string $user = '',
|
||||
string $password = '',
|
||||
|
|
@ -370,6 +374,7 @@ class LoginController extends Controller {
|
|||
*/
|
||||
#[UseSession]
|
||||
#[NoCSRFRequired]
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/confirm')]
|
||||
public function confirmPassword(string $password): DataResponse {
|
||||
$loginName = $this->userSession->getLoginName();
|
||||
$loginResult = $this->userManager->checkPassword($loginName, $password);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ use OC\Core\Exception\ResetPasswordException;
|
|||
use OC\Security\RateLimiting\Exception\RateLimitExceededException;
|
||||
use OC\Security\RateLimiting\Limiter;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
|
|
@ -108,6 +109,7 @@ class LostController extends Controller {
|
|||
* @BruteForceProtection(action=passwordResetEmail)
|
||||
* @AnonRateThrottle(limit=10, period=300)
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/lostpassword/reset/form/{token}/{userId}')]
|
||||
public function resetform(string $token, string $userId): TemplateResponse {
|
||||
try {
|
||||
$this->checkPasswordResetToken($token, $userId);
|
||||
|
|
@ -172,6 +174,7 @@ class LostController extends Controller {
|
|||
* @BruteForceProtection(action=passwordResetEmail)
|
||||
* @AnonRateThrottle(limit=10, period=300)
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/lostpassword/email')]
|
||||
public function email(string $user): JSONResponse {
|
||||
if ($this->config->getSystemValue('lost_password_link', '') !== '') {
|
||||
return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
|
||||
|
|
@ -205,6 +208,7 @@ class LostController extends Controller {
|
|||
* @BruteForceProtection(action=passwordResetEmail)
|
||||
* @AnonRateThrottle(limit=10, period=300)
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/lostpassword/set/{token}/{userId}')]
|
||||
public function setPassword(string $token, string $userId, string $password, bool $proceed): JSONResponse {
|
||||
if ($this->encryptionManager->isEnabled() && !$proceed) {
|
||||
$encryptionModules = $this->encryptionManager->getEncryptionModules();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\INavigationManager;
|
||||
|
|
@ -56,6 +57,7 @@ class NavigationController extends OCSController {
|
|||
* 200: Apps navigation returned
|
||||
* 304: No apps navigation changed
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/navigation/apps', root: '/core')]
|
||||
public function getAppsNavigation(bool $absolute = false): DataResponse {
|
||||
$navigation = $this->navigationManager->getAll();
|
||||
if ($absolute) {
|
||||
|
|
@ -83,6 +85,7 @@ class NavigationController extends OCSController {
|
|||
* 200: Apps navigation returned
|
||||
* 304: No apps navigation changed
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/navigation/settings', root: '/core')]
|
||||
public function getSettingsNavigation(bool $absolute = false): DataResponse {
|
||||
$navigation = $this->navigationManager->getAll('settings');
|
||||
if ($absolute) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ use OC\Template\JSConfigHelper;
|
|||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\DataDisplayResponse;
|
||||
use OCP\Defaults;
|
||||
|
|
@ -87,6 +88,7 @@ class OCJSController extends Controller {
|
|||
* @NoTwoFactorRequired
|
||||
* @PublicPage
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/core/js/oc.js')]
|
||||
public function getConfig(): DataDisplayResponse {
|
||||
$data = $this->helper->getConfig();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OC\Core\Controller;
|
|||
use Exception;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\Capabilities\ICapability;
|
||||
use OCP\IConfig;
|
||||
|
|
@ -64,6 +65,7 @@ class OCMController extends Controller {
|
|||
* 200: OCM Provider details returned
|
||||
* 500: OCM not supported
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/ocm-provider/')]
|
||||
public function discovery(): DataResponse {
|
||||
try {
|
||||
$cap = Server::get(
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ namespace OC\Core\Controller;
|
|||
use OC\CapabilitiesManager;
|
||||
use OC\Security\IdentityProof\Manager;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -53,6 +54,7 @@ class OCSController extends \OCP\AppFramework\OCSController {
|
|||
* @PublicPage
|
||||
*/
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[ApiRoute(verb: 'GET', url: '/config', root: '')]
|
||||
public function getConfig(): DataResponse {
|
||||
$data = [
|
||||
'version' => '1.7',
|
||||
|
|
@ -74,6 +76,7 @@ class OCSController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: Capabilities returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/capabilities', root: '/cloud')]
|
||||
public function getCapabilities(): DataResponse {
|
||||
$result = [];
|
||||
[$major, $minor, $micro] = \OCP\Util::getVersion();
|
||||
|
|
@ -102,6 +105,7 @@ class OCSController extends \OCP\AppFramework\OCSController {
|
|||
* @BruteForceProtection(action=login)
|
||||
*/
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[ApiRoute(verb: 'POST', url: '/check', root: '/person')]
|
||||
public function personCheck(string $login = '', string $password = ''): DataResponse {
|
||||
if ($login !== '' && $password !== '') {
|
||||
if ($this->userManager->checkPassword($login, $password)) {
|
||||
|
|
@ -123,6 +127,7 @@ class OCSController extends \OCP\AppFramework\OCSController {
|
|||
* @PublicPage
|
||||
*/
|
||||
#[OpenAPI(scope: OpenAPI::SCOPE_IGNORE)]
|
||||
#[ApiRoute(verb: 'GET', url: '/key/{cloudId}', root: '/identityproof')]
|
||||
public function getIdentityProof(string $cloudId): DataResponse {
|
||||
$userObject = $this->userManager->get($cloudId);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace OC\Core\Controller;
|
|||
use OCA\Files_Sharing\SharedStorage;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\FileDisplayResponse;
|
||||
use OCP\AppFramework\Http\RedirectResponse;
|
||||
|
|
@ -74,6 +75,7 @@ class PreviewController extends Controller {
|
|||
* 403: Getting preview is not allowed
|
||||
* 404: Preview not found
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/core/preview.png')]
|
||||
public function getPreview(
|
||||
string $file = '',
|
||||
int $x = 32,
|
||||
|
|
@ -117,6 +119,7 @@ class PreviewController extends Controller {
|
|||
* 403: Getting preview is not allowed
|
||||
* 404: Preview not found
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/core/preview')]
|
||||
public function getPreviewByFileId(
|
||||
int $fileId = -1,
|
||||
int $x = 32,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace OC\Core\Controller;
|
|||
use OC\Core\Db\ProfileConfigMapper;
|
||||
use OC\Profile\ProfileManager;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||
|
|
@ -68,6 +69,7 @@ class ProfileApiController extends OCSController {
|
|||
*
|
||||
* 200: Visibility updated successfully
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/{targetUserId}', root: '/profile')]
|
||||
public function setVisibility(string $targetUserId, string $paramId, string $visibility): DataResponse {
|
||||
$requestingUser = $this->userSession->getUser();
|
||||
$targetUser = $this->userManager->get($targetUserId);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OC\Profile\ProfileManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Services\IInitialState;
|
||||
|
|
@ -65,6 +66,7 @@ class ProfilePageController extends Controller {
|
|||
* @NoAdminRequired
|
||||
* @NoSubAdminRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/u/{targetUserId}')]
|
||||
public function index(string $targetUserId): TemplateResponse {
|
||||
$profileNotFoundTemplate = new TemplateResponse(
|
||||
'core',
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ declare(strict_types=1);
|
|||
namespace OC\Core\Controller;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Http\StandaloneTemplateResponse;
|
||||
|
|
@ -48,6 +49,7 @@ class RecommendedAppsController extends Controller {
|
|||
* @NoCSRFRequired
|
||||
* @return Response
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/core/apps/recommended')]
|
||||
public function index(): Response {
|
||||
$defaultPageUrl = $this->urlGenerator->linkToDefaultPageUrl();
|
||||
$this->initialStateService->provideInitialState('core', 'defaultPageUrl', $defaultPageUrl);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\Collaboration\Reference\IDiscoverableReferenceProvider;
|
||||
use OCP\Collaboration\Reference\IReferenceManager;
|
||||
|
|
@ -59,6 +60,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: References returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/extract', root: '/references')]
|
||||
public function extract(string $text, bool $resolve = false, int $limit = 1): DataResponse {
|
||||
$references = $this->referenceManager->extractReferences($text);
|
||||
|
||||
|
|
@ -87,6 +89,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: Reference returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/resolve', root: '/references')]
|
||||
public function resolveOne(string $reference): DataResponse {
|
||||
/** @var ?CoreReference $resolvedReference */
|
||||
$resolvedReference = $this->referenceManager->resolveReference(trim($reference))?->jsonSerialize();
|
||||
|
|
@ -107,6 +110,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: References returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/resolve', root: '/references')]
|
||||
public function resolve(array $references, int $limit = 1): DataResponse {
|
||||
$result = [];
|
||||
$index = 0;
|
||||
|
|
@ -132,6 +136,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: Providers returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/providers', root: '/references')]
|
||||
public function getProvidersInfo(): DataResponse {
|
||||
$providers = $this->referenceManager->getDiscoverableProviders();
|
||||
$jsonProviders = array_map(static function (IDiscoverableReferenceProvider $provider) {
|
||||
|
|
@ -151,6 +156,7 @@ class ReferenceApiController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: Provider touched
|
||||
*/
|
||||
#[ApiRoute(verb: 'PUT', url: '/provider/{providerId}', root: '/references')]
|
||||
public function touchProvider(string $providerId, ?int $timestamp = null): DataResponse {
|
||||
if ($this->userId !== null) {
|
||||
$success = $this->referenceManager->touchProvider($this->userId, $providerId, $timestamp);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\DataDownloadResponse;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\Collaboration\Reference\IReferenceManager;
|
||||
|
|
@ -57,6 +58,7 @@ class ReferenceController extends Controller {
|
|||
* 200: Preview returned
|
||||
* 404: Reference not found
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/core/references/preview/{referenceId}')]
|
||||
public function preview(string $referenceId): DataDownloadResponse|DataResponse {
|
||||
$reference = $this->referenceManager->getReferenceByCacheKey($referenceId);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ declare(strict_types=1);
|
|||
namespace OC\Core\Controller;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
use OCP\ISearch;
|
||||
|
|
@ -46,6 +47,7 @@ class SearchController extends Controller {
|
|||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/core/search')]
|
||||
public function search(string $query, array $inApps = [], int $page = 1, int $size = 30): JSONResponse {
|
||||
$results = $this->searcher->searchPaged($query, $inApps, $page, $size);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ use InvalidArgumentException;
|
|||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\PublicPage;
|
||||
use OCP\AppFramework\Http\Attribute\UserRateLimit;
|
||||
|
|
@ -72,6 +73,7 @@ class TextProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
* 200: Task types returned
|
||||
*/
|
||||
#[PublicPage]
|
||||
#[ApiRoute(verb: 'GET', url: '/tasktypes', root: '/textprocessing')]
|
||||
public function taskTypes(): DataResponse {
|
||||
$typeClasses = $this->textProcessingManager->getAvailableTaskTypes();
|
||||
$types = [];
|
||||
|
|
@ -113,6 +115,7 @@ class TextProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
#[PublicPage]
|
||||
#[UserRateLimit(limit: 20, period: 120)]
|
||||
#[AnonRateLimit(limit: 5, period: 120)]
|
||||
#[ApiRoute(verb: 'POST', url: '/schedule', root: '/textprocessing')]
|
||||
public function schedule(string $input, string $type, string $appId, string $identifier = ''): DataResponse {
|
||||
try {
|
||||
$task = new Task($type, $input, $appId, $this->userId, $identifier);
|
||||
|
|
@ -150,6 +153,7 @@ class TextProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
* 404: Task not found
|
||||
*/
|
||||
#[PublicPage]
|
||||
#[ApiRoute(verb: 'GET', url: '/task/{id}', root: '/textprocessing')]
|
||||
public function getTask(int $id): DataResponse {
|
||||
try {
|
||||
$task = $this->textProcessingManager->getUserTask($id, $this->userId);
|
||||
|
|
@ -177,6 +181,7 @@ class TextProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
* 404: Task not found
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[ApiRoute(verb: 'DELETE', url: '/task/{id}', root: '/textprocessing')]
|
||||
public function deleteTask(int $id): DataResponse {
|
||||
try {
|
||||
$task = $this->textProcessingManager->getUserTask($id, $this->userId);
|
||||
|
|
@ -207,6 +212,7 @@ class TextProcessingApiController extends \OCP\AppFramework\OCSController {
|
|||
* 200: Task list returned
|
||||
*/
|
||||
#[NoAdminRequired]
|
||||
#[ApiRoute(verb: 'GET', url: '/tasks/app/{appId}', root: '/textprocessing')]
|
||||
public function listTasksByApp(string $appId, ?string $identifier = null): DataResponse {
|
||||
try {
|
||||
$tasks = $this->textProcessingManager->getUserTasksByApp($this->userId, $appId, $identifier);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ use OC\Files\AppData\AppData;
|
|||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\AnonRateLimit;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\Attribute\BruteForceProtection;
|
||||
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
|
||||
use OCP\AppFramework\Http\Attribute\PublicPage;
|
||||
|
|
@ -69,6 +70,7 @@ class TextToImageApiController extends \OCP\AppFramework\OCSController {
|
|||
* 200: Returns availability status
|
||||
*/
|
||||
#[PublicPage]
|
||||
#[ApiRoute(verb: 'GET', url: '/is_available', root: '/text2image')]
|
||||
public function isAvailable(): DataResponse {
|
||||
return new DataResponse([
|
||||
'isAvailable' => $this->textToImageManager->hasProviders(),
|
||||
|
|
@ -91,6 +93,7 @@ class TextToImageApiController extends \OCP\AppFramework\OCSController {
|
|||
#[PublicPage]
|
||||
#[UserRateLimit(limit: 20, period: 120)]
|
||||
#[AnonRateLimit(limit: 5, period: 120)]
|
||||
#[ApiRoute(verb: 'POST', url: '/schedule', root: '/text2image')]
|
||||
public function schedule(string $input, string $appId, string $identifier = '', int $numberOfImages = 8): DataResponse {
|
||||
$task = new Task($input, $appId, $numberOfImages, $this->userId, $identifier);
|
||||
try {
|
||||
|
|
@ -125,6 +128,7 @@ class TextToImageApiController extends \OCP\AppFramework\OCSController {
|
|||
*/
|
||||
#[PublicPage]
|
||||
#[BruteForceProtection(action: 'text2image')]
|
||||
#[ApiRoute(verb: 'GET', url: '/task/{id}', root: '/text2image')]
|
||||
public function getTask(int $id): DataResponse {
|
||||
try {
|
||||
$task = $this->textToImageManager->getUserTask($id, $this->userId);
|
||||
|
|
@ -156,6 +160,7 @@ class TextToImageApiController extends \OCP\AppFramework\OCSController {
|
|||
*/
|
||||
#[PublicPage]
|
||||
#[BruteForceProtection(action: 'text2image')]
|
||||
#[ApiRoute(verb: 'GET', url: '/task/{id}/image/{index}', root: '/text2image')]
|
||||
public function getImage(int $id, int $index): DataResponse|FileDisplayResponse {
|
||||
try {
|
||||
$task = $this->textToImageManager->getUserTask($id, $this->userId);
|
||||
|
|
@ -195,6 +200,7 @@ class TextToImageApiController extends \OCP\AppFramework\OCSController {
|
|||
*/
|
||||
#[NoAdminRequired]
|
||||
#[BruteForceProtection(action: 'text2image')]
|
||||
#[ApiRoute(verb: 'DELETE', url: '/task/{id}', root: '/text2image')]
|
||||
public function deleteTask(int $id): DataResponse {
|
||||
try {
|
||||
$task = $this->textToImageManager->getUserTask($id, $this->userId);
|
||||
|
|
@ -228,6 +234,7 @@ class TextToImageApiController extends \OCP\AppFramework\OCSController {
|
|||
*/
|
||||
#[NoAdminRequired]
|
||||
#[AnonRateLimit(limit: 5, period: 120)]
|
||||
#[ApiRoute(verb: 'GET', url: '/tasks/app/{appId}', root: '/text2image')]
|
||||
public function listTasksByApp(string $appId, ?string $identifier = null): DataResponse {
|
||||
try {
|
||||
$tasks = $this->textToImageManager->getUserTasksByApp($this->userId, $appId, $identifier);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\IL10N;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -55,6 +56,7 @@ class TranslationApiController extends \OCP\AppFramework\OCSController {
|
|||
*
|
||||
* 200: Supported languages returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/languages', root: '/translation')]
|
||||
public function languages(): DataResponse {
|
||||
return new DataResponse([
|
||||
'languages' => array_map(fn ($lang) => $lang->jsonSerialize(), $this->translationManager->getLanguages()),
|
||||
|
|
@ -78,6 +80,7 @@ class TranslationApiController extends \OCP\AppFramework\OCSController {
|
|||
* 400: Language not detected or unable to translate
|
||||
* 412: Translating is not possible
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/translate', root: '/translation')]
|
||||
public function translate(string $text, ?string $fromLanguage, string $toLanguage): DataResponse {
|
||||
try {
|
||||
$translation = $this->translationManager->translate($text, $fromLanguage, $toLanguage);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OC\Core\Controller;
|
|||
use OC\Authentication\TwoFactorAuth\Manager;
|
||||
use OC_User;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
use OCP\AppFramework\Http\RedirectResponse;
|
||||
|
|
@ -89,6 +90,7 @@ class TwoFactorChallengeController extends Controller {
|
|||
* @param string $redirect_url
|
||||
* @return StandaloneTemplateResponse
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/selectchallenge')]
|
||||
public function selectChallenge($redirect_url) {
|
||||
$user = $this->userSession->getUser();
|
||||
$providerSet = $this->twoFactorManager->getProviderSet($user);
|
||||
|
|
@ -117,6 +119,7 @@ class TwoFactorChallengeController extends Controller {
|
|||
* @return StandaloneTemplateResponse|RedirectResponse
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/login/challenge/{challengeProviderId}')]
|
||||
public function showChallenge($challengeProviderId, $redirect_url) {
|
||||
$user = $this->userSession->getUser();
|
||||
$providerSet = $this->twoFactorManager->getProviderSet($user);
|
||||
|
|
@ -171,6 +174,7 @@ class TwoFactorChallengeController extends Controller {
|
|||
* @return RedirectResponse
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'POST', url: '/login/challenge/{challengeProviderId}')]
|
||||
public function solveChallenge($challengeProviderId, $challenge, $redirect_url = null) {
|
||||
$user = $this->userSession->getUser();
|
||||
$provider = $this->twoFactorManager->getProvider($user, $challengeProviderId);
|
||||
|
|
@ -208,6 +212,7 @@ class TwoFactorChallengeController extends Controller {
|
|||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge')]
|
||||
public function setupProviders(): StandaloneTemplateResponse {
|
||||
$user = $this->userSession->getUser();
|
||||
$setupProviders = $this->twoFactorManager->getLoginSetupProviders($user);
|
||||
|
|
@ -224,6 +229,7 @@ class TwoFactorChallengeController extends Controller {
|
|||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: 'login/setupchallenge/{providerId}')]
|
||||
public function setupProvider(string $providerId) {
|
||||
$user = $this->userSession->getUser();
|
||||
$providers = $this->twoFactorManager->getLoginSetupProviders($user);
|
||||
|
|
@ -257,6 +263,7 @@ class TwoFactorChallengeController extends Controller {
|
|||
*
|
||||
* @todo handle the extreme edge case of an invalid provider ID and redirect to the provider selection page
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: 'login/setupchallenge/{providerId}')]
|
||||
public function confirmProviderSetup(string $providerId) {
|
||||
return new RedirectResponse($this->urlGenerator->linkToRoute(
|
||||
'core.TwoFactorChallenge.showChallenge',
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ use OC\Search\SearchQuery;
|
|||
use OC\Search\UnsupportedFilter;
|
||||
use OCA\Core\ResponseDefinitions;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -69,6 +70,7 @@ class UnifiedSearchController extends OCSController {
|
|||
*
|
||||
* 200: Providers returned
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/providers', root: '/search')]
|
||||
public function getProviders(string $from = ''): DataResponse {
|
||||
[$route, $parameters] = $this->getRouteInformation($from);
|
||||
|
||||
|
|
@ -99,6 +101,7 @@ class UnifiedSearchController extends OCSController {
|
|||
* 200: Search entries returned
|
||||
* 400: Searching is not possible
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/providers/{providerId}/search', root: '/search')]
|
||||
public function search(
|
||||
string $providerId,
|
||||
// Unused parameter for OpenAPI spec generator
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ declare(strict_types=1);
|
|||
namespace OC\Core\Controller;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
|
|
@ -46,6 +47,7 @@ class UnsupportedBrowserController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: 'unsupported')]
|
||||
public function index(): Response {
|
||||
Util::addScript('core', 'unsupported-browser');
|
||||
Util::addStyle('core', 'icons');
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
namespace OC\Core\Controller;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserManager;
|
||||
|
|
@ -47,6 +48,7 @@ class UserController extends Controller {
|
|||
*
|
||||
* @return JSONResponse
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/displaynames')]
|
||||
public function getDisplayNames($users) {
|
||||
$result = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace OC\Core\Controller;
|
|||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
|
||||
|
|
@ -35,6 +36,7 @@ class WalledGardenController extends Controller {
|
|||
* @PublicPage
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '/204')]
|
||||
public function get(): Response {
|
||||
$resp = new Response();
|
||||
$resp->setStatus(Http::STATUS_NO_CONTENT);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use OC\Authentication\WebAuthn\Manager;
|
|||
use OC\URLGenerator;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\UseSession;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -62,6 +63,7 @@ class WebAuthnController extends Controller {
|
|||
* @PublicPage
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'POST', url: 'login/webauthn/start')]
|
||||
public function startAuthentication(string $loginName): JSONResponse {
|
||||
$this->logger->debug('Starting WebAuthn login');
|
||||
|
||||
|
|
@ -86,6 +88,7 @@ class WebAuthnController extends Controller {
|
|||
* @PublicPage
|
||||
*/
|
||||
#[UseSession]
|
||||
#[FrontpageRoute(verb: 'POST', url: 'login/webauthn/finish')]
|
||||
public function finishAuthentication(string $data): JSONResponse {
|
||||
$this->logger->debug('Validating WebAuthn login');
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OC\Core\Controller;
|
|||
use OC\Http\WellKnown\RequestManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
|
|
@ -49,6 +50,7 @@ class WellKnownController extends Controller {
|
|||
*
|
||||
* @return Response
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'GET', url: '.well-known/{service}')]
|
||||
public function handle(string $service): Response {
|
||||
$response = $this->requestManager->process(
|
||||
$service,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use OC\Security\IdentityProof\Manager;
|
|||
use OC\Updater\ChangesCheck;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\ApiRoute;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\Defaults;
|
||||
use OCP\IConfig;
|
||||
|
|
@ -63,6 +64,7 @@ class WhatsNewController extends OCSController {
|
|||
* 200: Changes returned
|
||||
* 204: No changes
|
||||
*/
|
||||
#[ApiRoute(verb: 'GET', url: '/whatsnew', root: '/core')]
|
||||
public function get():DataResponse {
|
||||
$user = $this->userSession->getUser();
|
||||
if ($user === null) {
|
||||
|
|
@ -110,6 +112,7 @@ class WhatsNewController extends OCSController {
|
|||
*
|
||||
* 200: Changes dismissed
|
||||
*/
|
||||
#[ApiRoute(verb: 'POST', url: '/whatsnew', root: '/core')]
|
||||
public function dismiss(string $version):DataResponse {
|
||||
$user = $this->userSession->getUser();
|
||||
if ($user === null) {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace OC\Core\Controller;
|
|||
use OC\Authentication\Token\RemoteWipe;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\Authentication\Exceptions\InvalidTokenException;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -58,6 +59,7 @@ class WipeController extends Controller {
|
|||
* 200: Device should be wiped
|
||||
* 404: Device should not be wiped
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/core/wipe/check')]
|
||||
public function checkWipe(string $token): JSONResponse {
|
||||
try {
|
||||
if ($this->remoteWipe->start($token)) {
|
||||
|
|
@ -89,6 +91,7 @@ class WipeController extends Controller {
|
|||
* 200: Wipe finished successfully
|
||||
* 404: Device should not be wiped
|
||||
*/
|
||||
#[FrontpageRoute(verb: 'POST', url: '/core/wipe/success')]
|
||||
public function wipeDone(string $token): JSONResponse {
|
||||
try {
|
||||
if ($this->remoteWipe->finish($token)) {
|
||||
|
|
|
|||
5483
core/openapi.json
5483
core/openapi.json
File diff suppressed because it is too large
Load diff
133
core/routes.php
133
core/routes.php
|
|
@ -35,139 +35,6 @@ declare(strict_types=1);
|
|||
*
|
||||
*/
|
||||
|
||||
use OC\Core\Application;
|
||||
|
||||
/** @var Application $application */
|
||||
$application = \OC::$server->query(Application::class);
|
||||
$application->registerRoutes($this, [
|
||||
'routes' => [
|
||||
['name' => 'lost#email', 'url' => '/lostpassword/email', 'verb' => 'POST'],
|
||||
['name' => 'lost#resetform', 'url' => '/lostpassword/reset/form/{token}/{userId}', 'verb' => 'GET'],
|
||||
['name' => 'lost#setPassword', 'url' => '/lostpassword/set/{token}/{userId}', 'verb' => 'POST'],
|
||||
['name' => 'ProfilePage#index', 'url' => '/u/{targetUserId}', 'verb' => 'GET'],
|
||||
['name' => 'user#getDisplayNames', 'url' => '/displaynames', 'verb' => 'POST'],
|
||||
['name' => 'avatar#getAvatarDark', 'url' => '/avatar/{userId}/{size}/dark', 'verb' => 'GET'],
|
||||
['name' => 'avatar#getAvatar', 'url' => '/avatar/{userId}/{size}', 'verb' => 'GET'],
|
||||
['name' => 'avatar#deleteAvatar', 'url' => '/avatar/', 'verb' => 'DELETE'],
|
||||
['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'],
|
||||
['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'],
|
||||
['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'],
|
||||
['name' => 'GuestAvatar#getAvatarDark', 'url' => '/avatar/guest/{guestName}/{size}/dark', 'verb' => 'GET'],
|
||||
['name' => 'GuestAvatar#getAvatar', 'url' => '/avatar/guest/{guestName}/{size}', 'verb' => 'GET'],
|
||||
['name' => 'CSRFToken#index', 'url' => '/csrftoken', 'verb' => 'GET'],
|
||||
['name' => 'login#tryLogin', 'url' => '/login', 'verb' => 'POST'],
|
||||
['name' => 'login#confirmPassword', 'url' => '/login/confirm', 'verb' => 'POST'],
|
||||
['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'],
|
||||
['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'],
|
||||
|
||||
// Original login flow used by all clients
|
||||
['name' => 'ClientFlowLogin#showAuthPickerPage', 'url' => '/login/flow', 'verb' => 'GET'],
|
||||
['name' => 'ClientFlowLogin#generateAppPassword', 'url' => '/login/flow', 'verb' => 'POST'],
|
||||
['name' => 'ClientFlowLogin#grantPage', 'url' => '/login/flow/grant', 'verb' => 'GET'],
|
||||
['name' => 'ClientFlowLogin#apptokenRedirect', 'url' => '/login/flow/apptoken', 'verb' => 'POST'],
|
||||
|
||||
// NG login flow used by desktop client in case of Kerberos/fancy 2fa (smart cards for example)
|
||||
['name' => 'ClientFlowLoginV2#poll', 'url' => '/login/v2/poll', 'verb' => 'POST'],
|
||||
['name' => 'ClientFlowLoginV2#showAuthPickerPage', 'url' => '/login/v2/flow', 'verb' => 'GET'],
|
||||
['name' => 'ClientFlowLoginV2#landing', 'url' => '/login/v2/flow/{token}', 'verb' => 'GET'],
|
||||
['name' => 'ClientFlowLoginV2#grantPage', 'url' => '/login/v2/grant', 'verb' => 'GET'],
|
||||
['name' => 'ClientFlowLoginV2#generateAppPassword', 'url' => '/login/v2/grant', 'verb' => 'POST'],
|
||||
['name' => 'ClientFlowLoginV2#init', 'url' => '/login/v2', 'verb' => 'POST'],
|
||||
['name' => 'ClientFlowLoginV2#apptokenRedirect', 'url' => '/login/v2/apptoken', 'verb' => 'POST'],
|
||||
['name' => 'TwoFactorChallenge#selectChallenge', 'url' => '/login/selectchallenge', 'verb' => 'GET'],
|
||||
['name' => 'TwoFactorChallenge#showChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'GET'],
|
||||
['name' => 'TwoFactorChallenge#solveChallenge', 'url' => '/login/challenge/{challengeProviderId}', 'verb' => 'POST'],
|
||||
['name' => 'TwoFactorChallenge#setupProviders', 'url' => 'login/setupchallenge', 'verb' => 'GET'],
|
||||
['name' => 'TwoFactorChallenge#setupProvider', 'url' => 'login/setupchallenge/{providerId}', 'verb' => 'GET'],
|
||||
['name' => 'TwoFactorChallenge#confirmProviderSetup', 'url' => 'login/setupchallenge/{providerId}', 'verb' => 'POST'],
|
||||
['name' => 'OCJS#getConfig', 'url' => '/core/js/oc.js', 'verb' => 'GET'],
|
||||
['name' => 'Preview#getPreviewByFileId', 'url' => '/core/preview', 'verb' => 'GET'],
|
||||
['name' => 'Preview#getPreview', 'url' => '/core/preview.png', 'verb' => 'GET'],
|
||||
['name' => 'RecommendedApps#index', 'url' => '/core/apps/recommended', 'verb' => 'GET'],
|
||||
['name' => 'Reference#preview', 'url' => '/core/references/preview/{referenceId}', 'verb' => 'GET'],
|
||||
['name' => 'Css#getCss', 'url' => '/css/{appName}/{fileName}', 'verb' => 'GET'],
|
||||
['name' => 'Js#getJs', 'url' => '/js/{appName}/{fileName}', 'verb' => 'GET'],
|
||||
['name' => 'contactsMenu#index', 'url' => '/contactsmenu/contacts', 'verb' => 'POST'],
|
||||
['name' => 'contactsMenu#findOne', 'url' => '/contactsmenu/findOne', 'verb' => 'POST'],
|
||||
['name' => 'WalledGarden#get', 'url' => '/204', 'verb' => 'GET'],
|
||||
['name' => 'Search#search', 'url' => '/core/search', 'verb' => 'GET'],
|
||||
['name' => 'Wipe#checkWipe', 'url' => '/core/wipe/check', 'verb' => 'POST'],
|
||||
['name' => 'Wipe#wipeDone', 'url' => '/core/wipe/success', 'verb' => 'POST'],
|
||||
|
||||
// Logins for passwordless auth
|
||||
['name' => 'WebAuthn#startAuthentication', 'url' => 'login/webauthn/start', 'verb' => 'POST'],
|
||||
['name' => 'WebAuthn#finishAuthentication', 'url' => 'login/webauthn/finish', 'verb' => 'POST'],
|
||||
|
||||
['name' => 'Error#error404', 'url' => 'error/404'],
|
||||
['name' => 'Error#error403', 'url' => 'error/403'],
|
||||
|
||||
// Well known requests https://tools.ietf.org/html/rfc5785
|
||||
['name' => 'WellKnown#handle', 'url' => '.well-known/{service}'],
|
||||
|
||||
// OCM Provider requests https://github.com/cs3org/OCM-API
|
||||
['name' => 'OCM#discovery', 'url' => '/ocm-provider/'],
|
||||
|
||||
// Unsupported browser
|
||||
['name' => 'UnsupportedBrowser#index', 'url' => 'unsupported'],
|
||||
],
|
||||
'ocs' => [
|
||||
['root' => '/cloud', 'name' => 'OCS#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
|
||||
['root' => '', 'name' => 'OCS#getConfig', 'url' => '/config', 'verb' => 'GET'],
|
||||
['root' => '/person', 'name' => 'OCS#personCheck', 'url' => '/check', 'verb' => 'POST'],
|
||||
['root' => '/identityproof', 'name' => 'OCS#getIdentityProof', 'url' => '/key/{cloudId}', 'verb' => 'GET'],
|
||||
['root' => '/core', 'name' => 'Navigation#getAppsNavigation', 'url' => '/navigation/apps', 'verb' => 'GET'],
|
||||
['root' => '/core', 'name' => 'Navigation#getSettingsNavigation', 'url' => '/navigation/settings', 'verb' => 'GET'],
|
||||
['root' => '/core', 'name' => 'AutoComplete#get', 'url' => '/autocomplete/get', 'verb' => 'GET'],
|
||||
['root' => '/core', 'name' => 'WhatsNew#get', 'url' => '/whatsnew', 'verb' => 'GET'],
|
||||
['root' => '/core', 'name' => 'WhatsNew#dismiss', 'url' => '/whatsnew', 'verb' => 'POST'],
|
||||
['root' => '/core', 'name' => 'AppPassword#getAppPassword', 'url' => '/getapppassword', 'verb' => 'GET'],
|
||||
['root' => '/core', 'name' => 'AppPassword#rotateAppPassword', 'url' => '/apppassword/rotate', 'verb' => 'POST'],
|
||||
['root' => '/core', 'name' => 'AppPassword#deleteAppPassword', 'url' => '/apppassword', 'verb' => 'DELETE'],
|
||||
['root' => '/core', 'name' => 'AppPassword#confirmUserPassword', 'url' => '/apppassword/confirm', 'verb' => 'PUT'],
|
||||
|
||||
['root' => '/hovercard', 'name' => 'HoverCard#getUser', 'url' => '/v1/{userId}', 'verb' => 'GET'],
|
||||
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#searchCollections', 'url' => '/resources/collections/search/{filter}', 'verb' => 'GET'],
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#listCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'GET'],
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#renameCollection', 'url' => '/resources/collections/{collectionId}', 'verb' => 'PUT'],
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#addResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'POST'],
|
||||
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#removeResource', 'url' => '/resources/collections/{collectionId}', 'verb' => 'DELETE'],
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#getCollectionsByResource', 'url' => '/resources/{resourceType}/{resourceId}', 'verb' => 'GET'],
|
||||
['root' => '/collaboration', 'name' => 'CollaborationResources#createCollectionOnResource', 'url' => '/resources/{baseResourceType}/{baseResourceId}', 'verb' => 'POST'],
|
||||
|
||||
['root' => '/references', 'name' => 'ReferenceApi#resolveOne', 'url' => '/resolve', 'verb' => 'GET'],
|
||||
['root' => '/references', 'name' => 'ReferenceApi#extract', 'url' => '/extract', 'verb' => 'POST'],
|
||||
['root' => '/references', 'name' => 'ReferenceApi#resolve', 'url' => '/resolve', 'verb' => 'POST'],
|
||||
['root' => '/references', 'name' => 'ReferenceApi#getProvidersInfo', 'url' => '/providers', 'verb' => 'GET'],
|
||||
['root' => '/references', 'name' => 'ReferenceApi#touchProvider', 'url' => '/provider/{providerId}', 'verb' => 'PUT'],
|
||||
|
||||
['root' => '/profile', 'name' => 'ProfileApi#setVisibility', 'url' => '/{targetUserId}', 'verb' => 'PUT'],
|
||||
|
||||
// Unified search
|
||||
['root' => '/search', 'name' => 'UnifiedSearch#getProviders', 'url' => '/providers', 'verb' => 'GET'],
|
||||
['root' => '/search', 'name' => 'UnifiedSearch#search', 'url' => '/providers/{providerId}/search', 'verb' => 'GET'],
|
||||
|
||||
['root' => '/translation', 'name' => 'TranslationApi#languages', 'url' => '/languages', 'verb' => 'GET'],
|
||||
['root' => '/translation', 'name' => 'TranslationApi#translate', 'url' => '/translate', 'verb' => 'POST'],
|
||||
|
||||
['root' => '/textprocessing', 'name' => 'TextProcessingApi#taskTypes', 'url' => '/tasktypes', 'verb' => 'GET'],
|
||||
['root' => '/textprocessing', 'name' => 'TextProcessingApi#schedule', 'url' => '/schedule', 'verb' => 'POST'],
|
||||
['root' => '/textprocessing', 'name' => 'TextProcessingApi#getTask', 'url' => '/task/{id}', 'verb' => 'GET'],
|
||||
['root' => '/textprocessing', 'name' => 'TextProcessingApi#deleteTask', 'url' => '/task/{id}', 'verb' => 'DELETE'],
|
||||
['root' => '/textprocessing', 'name' => 'TextProcessingApi#listTasksByApp', 'url' => '/tasks/app/{appId}', 'verb' => 'GET'],
|
||||
|
||||
['root' => '/text2image', 'name' => 'TextToImageApi#isAvailable', 'url' => '/is_available', 'verb' => 'GET'],
|
||||
['root' => '/text2image', 'name' => 'TextToImageApi#schedule', 'url' => '/schedule', 'verb' => 'POST'],
|
||||
['root' => '/text2image', 'name' => 'TextToImageApi#getTask', 'url' => '/task/{id}', 'verb' => 'GET'],
|
||||
['root' => '/text2image', 'name' => 'TextToImageApi#getImage', 'url' => '/task/{id}/image/{index}', 'verb' => 'GET'],
|
||||
['root' => '/text2image', 'name' => 'TextToImageApi#deleteTask', 'url' => '/task/{id}', 'verb' => 'DELETE'],
|
||||
['root' => '/text2image', 'name' => 'TextToImageApi#listTasksByApp', 'url' => '/tasks/app/{appId}', 'verb' => 'GET'],
|
||||
],
|
||||
]);
|
||||
|
||||
// Post installation check
|
||||
|
||||
/** @var $this OCP\Route\IRouter */
|
||||
// Core ajax actions
|
||||
// Routing
|
||||
|
|
|
|||
|
|
@ -38,15 +38,18 @@ return array(
|
|||
'OCP\\AppFramework\\Http' => $baseDir . '/lib/public/AppFramework/Http.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\ARateLimit' => $baseDir . '/lib/public/AppFramework/Http/Attribute/ARateLimit.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\AnonRateLimit' => $baseDir . '/lib/public/AppFramework/Http/Attribute/AnonRateLimit.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\ApiRoute' => $baseDir . '/lib/public/AppFramework/Http/Attribute/ApiRoute.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\AuthorizedAdminSetting' => $baseDir . '/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\BruteForceProtection' => $baseDir . '/lib/public/AppFramework/Http/Attribute/BruteForceProtection.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\CORS' => $baseDir . '/lib/public/AppFramework/Http/Attribute/CORS.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\FrontpageRoute' => $baseDir . '/lib/public/AppFramework/Http/Attribute/FrontpageRoute.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\IgnoreOpenAPI' => $baseDir . '/lib/public/AppFramework/Http/Attribute/IgnoreOpenAPI.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\NoAdminRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\NoCSRFRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\OpenAPI' => $baseDir . '/lib/public/AppFramework/Http/Attribute/OpenAPI.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\PasswordConfirmationRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\PublicPage' => $baseDir . '/lib/public/AppFramework/Http/Attribute/PublicPage.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\Route' => $baseDir . '/lib/public/AppFramework/Http/Attribute/Route.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\StrictCookiesRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\SubAdminRequired' => $baseDir . '/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\UseSession' => $baseDir . '/lib/public/AppFramework/Http/Attribute/UseSession.php',
|
||||
|
|
|
|||
|
|
@ -71,15 +71,18 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\AppFramework\\Http' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\ARateLimit' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/ARateLimit.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\AnonRateLimit' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/AnonRateLimit.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\ApiRoute' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/ApiRoute.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\AuthorizedAdminSetting' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/AuthorizedAdminSetting.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\BruteForceProtection' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/BruteForceProtection.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\CORS' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/CORS.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\FrontpageRoute' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/FrontpageRoute.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\IgnoreOpenAPI' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/IgnoreOpenAPI.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\NoAdminRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/NoAdminRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\NoCSRFRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/NoCSRFRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\OpenAPI' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/OpenAPI.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\PasswordConfirmationRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/PasswordConfirmationRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\PublicPage' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/PublicPage.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\Route' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/Route.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\StrictCookiesRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/StrictCookiesRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\SubAdminRequired' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/SubAdminRequired.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\UseSession' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/UseSession.php',
|
||||
|
|
|
|||
|
|
@ -136,7 +136,13 @@ class RouteConfig {
|
|||
$controllerName = $this->buildControllerName($controller);
|
||||
$actionName = $this->buildActionName($action);
|
||||
|
||||
$routeName = $routeNamePrefix . $this->appName . '.' . $controller . '.' . $action . $postfix;
|
||||
/*
|
||||
* The route name has to be lowercase, for symfony to match it correctly.
|
||||
* This is required because smyfony allows mixed casing for controller names in the routes.
|
||||
* To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
|
||||
* This is also safe on the PHP side because class and method names collide regardless of the casing.
|
||||
*/
|
||||
$routeName = strtolower($routeNamePrefix . $this->appName . '.' . $controller . '.' . $action . $postfix);
|
||||
|
||||
$router = $this->router->create($routeName, $url)
|
||||
->method($verb);
|
||||
|
|
|
|||
|
|
@ -100,7 +100,13 @@ class RouteParser {
|
|||
$controllerName = $this->buildControllerName($controller);
|
||||
$actionName = $this->buildActionName($action);
|
||||
|
||||
$routeName = $routeNamePrefix . $appName . '.' . $controller . '.' . $action . $postfix;
|
||||
/*
|
||||
* The route name has to be lowercase, for symfony to match it correctly.
|
||||
* This is required because smyfony allows mixed casing for controller names in the routes.
|
||||
* To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
|
||||
* This is also safe on the PHP side because class and method names collide regardless of the casing.
|
||||
*/
|
||||
$routeName = strtolower($routeNamePrefix . $appName . '.' . $controller . '.' . $action . $postfix);
|
||||
|
||||
$routeObject = new Route($url);
|
||||
$routeObject->method($verb);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
* @author Kate Döen <kate.doeen@nextcloud.com>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
|
|
@ -32,8 +33,10 @@
|
|||
*/
|
||||
namespace OC\Route;
|
||||
|
||||
use DirectoryIterator;
|
||||
use OC\AppFramework\Routing\RouteParser;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\Http\Attribute\Route as RouteAttribute;
|
||||
use OCP\Diagnostics\IEventLogger;
|
||||
use OCP\IConfig;
|
||||
use OCP\IRequest;
|
||||
|
|
@ -41,6 +44,9 @@ use OCP\Route\IRouter;
|
|||
use OCP\Util;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use ReflectionAttribute;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Exception\RouteNotFoundException;
|
||||
use Symfony\Component\Routing\Generator\UrlGenerator;
|
||||
|
|
@ -150,6 +156,22 @@ class Router implements IRouter {
|
|||
}
|
||||
}
|
||||
$this->eventLogger->start('route:load:' . $requestedApp, 'Loading Routes for ' . $requestedApp);
|
||||
|
||||
if ($requestedApp !== null) {
|
||||
$routes = $this->getAttributeRoutes($requestedApp);
|
||||
if (count($routes) > 0) {
|
||||
$this->useCollection($requestedApp);
|
||||
$this->setupRoutes($routes, $requestedApp);
|
||||
$collection = $this->getCollection($requestedApp);
|
||||
$this->root->addCollection($collection);
|
||||
|
||||
// Also add the OCS collection
|
||||
$collection = $this->getCollection($requestedApp . '.ocs');
|
||||
$collection->addPrefix('/ocsapp');
|
||||
$this->root->addCollection($collection);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($routingFiles as $app => $file) {
|
||||
if (!isset($this->loadedApps[$app])) {
|
||||
if (!\OC_App::isAppLoaded($app)) {
|
||||
|
|
@ -173,6 +195,7 @@ class Router implements IRouter {
|
|||
if (!isset($this->loadedApps['core'])) {
|
||||
$this->loadedApps['core'] = true;
|
||||
$this->useCollection('root');
|
||||
$this->setupRoutes($this->getAttributeRoutes('core'), 'core');
|
||||
require_once __DIR__ . '/../../../core/routes.php';
|
||||
|
||||
// Also add the OCS collection
|
||||
|
|
@ -360,6 +383,13 @@ class Router implements IRouter {
|
|||
if ($absolute === false) {
|
||||
$referenceType = UrlGenerator::ABSOLUTE_PATH;
|
||||
}
|
||||
/*
|
||||
* The route name has to be lowercase, for symfony to match it correctly.
|
||||
* This is required because smyfony allows mixed casing for controller names in the routes.
|
||||
* To avoid breaking all the existing route names, registering and matching will only use the lowercase names.
|
||||
* This is also safe on the PHP side because class and method names collide regardless of the casing.
|
||||
*/
|
||||
$name = strtolower($name);
|
||||
$name = $this->fixLegacyRootName($name);
|
||||
if (str_contains($name, '.')) {
|
||||
[$appName, $other] = explode('.', $name, 3);
|
||||
|
|
@ -385,33 +415,78 @@ class Router implements IRouter {
|
|||
}
|
||||
|
||||
protected function fixLegacyRootName(string $routeName): string {
|
||||
if ($routeName === 'files.viewcontroller.showFile') {
|
||||
return 'files.View.showFile';
|
||||
if ($routeName === 'files.viewcontroller.showfile') {
|
||||
return 'files.view.showfile';
|
||||
}
|
||||
if ($routeName === 'files_sharing.sharecontroller.showShare') {
|
||||
return 'files_sharing.Share.showShare';
|
||||
if ($routeName === 'files_sharing.sharecontroller.showshare') {
|
||||
return 'files_sharing.share.showshare';
|
||||
}
|
||||
if ($routeName === 'files_sharing.sharecontroller.showAuthenticate') {
|
||||
return 'files_sharing.Share.showAuthenticate';
|
||||
if ($routeName === 'files_sharing.sharecontroller.showauthenticate') {
|
||||
return 'files_sharing.share.showauthenticate';
|
||||
}
|
||||
if ($routeName === 'files_sharing.sharecontroller.authenticate') {
|
||||
return 'files_sharing.Share.authenticate';
|
||||
return 'files_sharing.share.authenticate';
|
||||
}
|
||||
if ($routeName === 'files_sharing.sharecontroller.downloadShare') {
|
||||
return 'files_sharing.Share.downloadShare';
|
||||
if ($routeName === 'files_sharing.sharecontroller.downloadshare') {
|
||||
return 'files_sharing.share.downloadshare';
|
||||
}
|
||||
if ($routeName === 'files_sharing.publicpreview.directLink') {
|
||||
return 'files_sharing.PublicPreview.directLink';
|
||||
if ($routeName === 'files_sharing.publicpreview.directlink') {
|
||||
return 'files_sharing.publicpreview.directlink';
|
||||
}
|
||||
if ($routeName === 'cloud_federation_api.requesthandlercontroller.addShare') {
|
||||
return 'cloud_federation_api.RequestHandler.addShare';
|
||||
if ($routeName === 'cloud_federation_api.requesthandlercontroller.addshare') {
|
||||
return 'cloud_federation_api.requesthandler.addshare';
|
||||
}
|
||||
if ($routeName === 'cloud_federation_api.requesthandlercontroller.receiveNotification') {
|
||||
return 'cloud_federation_api.RequestHandler.receiveNotification';
|
||||
if ($routeName === 'cloud_federation_api.requesthandlercontroller.receivenotification') {
|
||||
return 'cloud_federation_api.requesthandler.receivenotification';
|
||||
}
|
||||
return $routeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function getAttributeRoutes(string $app): array {
|
||||
$routes = [];
|
||||
|
||||
if ($app === 'core') {
|
||||
$appControllerPath = __DIR__ . '/../../../core/Controller';
|
||||
$appNameSpace = 'OC\\Core';
|
||||
} else {
|
||||
$appControllerPath = \OC_App::getAppPath($app) . '/lib/Controller';
|
||||
$appNameSpace = App::buildAppNamespace($app);
|
||||
}
|
||||
|
||||
if (!file_exists($appControllerPath)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$dir = new DirectoryIterator($appControllerPath);
|
||||
foreach ($dir as $file) {
|
||||
if (!str_ends_with($file->getPathname(), 'Controller.php')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$class = new ReflectionClass($appNameSpace . '\\Controller\\' . basename($file->getPathname(), '.php'));
|
||||
|
||||
foreach ($class->getMethods() as $method) {
|
||||
foreach ($method->getAttributes(RouteAttribute::class, ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
|
||||
$route = $attribute->newInstance();
|
||||
|
||||
$serializedRoute = $route->toArray();
|
||||
// Remove 'Controller' suffix
|
||||
$serializedRoute['name'] = substr($class->getShortName(), 0, -10) . '#' . $method->getName();
|
||||
|
||||
$key = $route->getType();
|
||||
|
||||
$routes[$key] ??= [];
|
||||
$routes[$key][] = $serializedRoute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* To isolate the variable scope used inside the $file it is required in it's own method
|
||||
*
|
||||
|
|
|
|||
63
lib/public/AppFramework/Http/Attribute/ApiRoute.php
Normal file
63
lib/public/AppFramework/Http/Attribute/ApiRoute.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2024 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 OCP\AppFramework\Http\Attribute;
|
||||
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* This attribute can be used to define API routes on controller methods.
|
||||
*
|
||||
* It works in addition to the traditional routes.php method and has the same parameters
|
||||
* (except for the `name` parameter which is not needed).
|
||||
*
|
||||
* @since 29.0.0
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
|
||||
class ApiRoute extends Route {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function __construct(
|
||||
protected string $verb,
|
||||
protected string $url,
|
||||
protected ?array $requirements = null,
|
||||
protected ?array $defaults = null,
|
||||
protected ?string $root = null,
|
||||
protected ?string $postfix = null,
|
||||
) {
|
||||
parent::__construct(
|
||||
Route::TYPE_API,
|
||||
$verb,
|
||||
$url,
|
||||
$requirements,
|
||||
$defaults,
|
||||
$root,
|
||||
$postfix,
|
||||
);
|
||||
}
|
||||
}
|
||||
63
lib/public/AppFramework/Http/Attribute/FrontpageRoute.php
Normal file
63
lib/public/AppFramework/Http/Attribute/FrontpageRoute.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2024 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 OCP\AppFramework\Http\Attribute;
|
||||
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* This attribute can be used to define Frontpage routes on controller methods.
|
||||
*
|
||||
* It works in addition to the traditional routes.php method and has the same parameters
|
||||
* (except for the `name` parameter which is not needed).
|
||||
*
|
||||
* @since 29.0.0
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
|
||||
class FrontpageRoute extends Route {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function __construct(
|
||||
protected string $verb,
|
||||
protected string $url,
|
||||
protected ?array $requirements = null,
|
||||
protected ?array $defaults = null,
|
||||
protected ?string $root = null,
|
||||
protected ?string $postfix = null,
|
||||
) {
|
||||
parent::__construct(
|
||||
Route::TYPE_FRONTPAGE,
|
||||
$verb,
|
||||
$url,
|
||||
$requirements,
|
||||
$defaults,
|
||||
$root,
|
||||
$postfix,
|
||||
);
|
||||
}
|
||||
}
|
||||
161
lib/public/AppFramework/Http/Attribute/Route.php
Normal file
161
lib/public/AppFramework/Http/Attribute/Route.php
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2024 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 OCP\AppFramework\Http\Attribute;
|
||||
|
||||
use Attribute;
|
||||
|
||||
/**
|
||||
* This attribute can be used to define routes on controller methods.
|
||||
*
|
||||
* It works in addition to the traditional routes.php method and has the same parameters
|
||||
* (except for the `name` parameter which is not needed).
|
||||
*
|
||||
* @since 29.0.0
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
|
||||
class Route {
|
||||
|
||||
/**
|
||||
* Corresponds to the `ocs` key in routes.php
|
||||
*
|
||||
* @see ApiRoute
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public const TYPE_API = 'ocs';
|
||||
|
||||
/**
|
||||
* Corresponds to the `routes` key in routes.php
|
||||
*
|
||||
* @see FrontpageRoute
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public const TYPE_FRONTPAGE = 'routes';
|
||||
|
||||
/**
|
||||
* @param string $type Either Route::TYPE_API or Route::TYPE_FRONTPAGE.
|
||||
* @psalm-param Route::TYPE_* $type
|
||||
* @param string $verb HTTP method of the route.
|
||||
* @psalm-param 'GET'|'HEAD'|'POST'|'PUT'|'DELETE'|'OPTIONS'|'PATCH' $verb
|
||||
* @param string $url The path of the route.
|
||||
* @param ?array<string, string> $requirements Array of regexes mapped to the path parameters.
|
||||
* @param ?array<string, mixed> $defaults Array of default values mapped to the path parameters.
|
||||
* @param ?string $root Custom root. For OCS all apps are allowed, but for index.php only some can use it.
|
||||
* @param ?string $postfix Postfix for the route name.
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function __construct(
|
||||
protected string $type,
|
||||
protected string $verb,
|
||||
protected string $url,
|
||||
protected ?array $requirements = null,
|
||||
protected ?array $defaults = null,
|
||||
protected ?string $root = null,
|
||||
protected ?string $postfix = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{
|
||||
* verb: string,
|
||||
* url: string,
|
||||
* requirements?: array<string, string>,
|
||||
* defaults?: array<string, mixed>,
|
||||
* root?: string,
|
||||
* postfix?: string,
|
||||
* }
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function toArray() {
|
||||
$route = [
|
||||
'verb' => $this->verb,
|
||||
'url' => $this->url,
|
||||
];
|
||||
|
||||
if ($this->requirements !== null) {
|
||||
$route['requirements'] = $this->requirements;
|
||||
}
|
||||
if ($this->defaults !== null) {
|
||||
$route['defaults'] = $this->defaults;
|
||||
}
|
||||
if ($this->root !== null) {
|
||||
$route['root'] = $this->root;
|
||||
}
|
||||
if ($this->postfix !== null) {
|
||||
$route['postfix'] = $this->postfix;
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getType(): string {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getVerb(): string {
|
||||
return $this->verb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getUrl(): string {
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getRequirements(): ?array {
|
||||
return $this->requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getDefaults(): ?array {
|
||||
return $this->defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getRoot(): ?string {
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 29.0.0
|
||||
*/
|
||||
public function getPostfix(): ?string {
|
||||
return $this->postfix;
|
||||
}
|
||||
}
|
||||
20
vendor-bin/openapi-extractor/composer.lock
generated
20
vendor-bin/openapi-extractor/composer.lock
generated
|
|
@ -8,16 +8,16 @@
|
|||
"packages": [
|
||||
{
|
||||
"name": "adhocore/cli",
|
||||
"version": "v1.6.1",
|
||||
"version": "v1.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/adhocore/php-cli.git",
|
||||
"reference": "25b5a93e5eebcdb70e20ee33313a011ea3a4f770"
|
||||
"reference": "34191315b0da20b9b4ecad783d91db992fa209a4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/adhocore/php-cli/zipball/25b5a93e5eebcdb70e20ee33313a011ea3a4f770",
|
||||
"reference": "25b5a93e5eebcdb70e20ee33313a011ea3a4f770",
|
||||
"url": "https://api.github.com/repos/adhocore/php-cli/zipball/34191315b0da20b9b4ecad783d91db992fa209a4",
|
||||
"reference": "34191315b0da20b9b4ecad783d91db992fa209a4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/adhocore/php-cli/issues",
|
||||
"source": "https://github.com/adhocore/php-cli/tree/v1.6.1"
|
||||
"source": "https://github.com/adhocore/php-cli/tree/v1.6.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-06-26T09:55:29+00:00"
|
||||
"time": "2024-01-22T22:37:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nextcloud/openapi-extractor",
|
||||
|
|
@ -82,12 +82,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nextcloud/openapi-extractor.git",
|
||||
"reference": "3b7b6ff9659a5f15612d4749e085bbcb83509049"
|
||||
"reference": "e15283dc655436460c531ce286b7f0bae3e0bf31"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nextcloud/openapi-extractor/zipball/3b7b6ff9659a5f15612d4749e085bbcb83509049",
|
||||
"reference": "3b7b6ff9659a5f15612d4749e085bbcb83509049",
|
||||
"url": "https://api.github.com/repos/nextcloud/openapi-extractor/zipball/e15283dc655436460c531ce286b7f0bae3e0bf31",
|
||||
"reference": "e15283dc655436460c531ce286b7f0bae3e0bf31",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -129,7 +129,7 @@
|
|||
"source": "https://github.com/nextcloud/openapi-extractor/tree/main",
|
||||
"issues": "https://github.com/nextcloud/openapi-extractor/issues"
|
||||
},
|
||||
"time": "2024-01-18T14:53:21+00:00"
|
||||
"time": "2024-02-21T11:05:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
|
|
|
|||
Loading…
Reference in a new issue