Skip to content

Commit b150521

Browse files
fixup! feat: OCS Calendar Export + Import
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
1 parent 58821dd commit b150521

5 files changed

Lines changed: 78 additions & 39 deletions

File tree

apps/dav/lib/Controller/CalendarExportController.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,19 @@ public function __construct(
4343
*
4444
* @param string $id calendar id
4545
* @param string|null $type data format
46-
* @param array{rangeStart:string,rangeCount:int<1,max>} $options configuration options
46+
* @param array{rangeStart:string,rangeCount:positive-int} $options configuration options
4747
* @param string|null $user system user id
4848
*
49-
* @return StreamGeneratorResponse<Http::STATUS_OK, array{Content-Type:string}> | DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED, array{error?: non-empty-string}, array{}>
49+
* @return StreamGeneratorResponse<Http::STATUS_OK, array{Content-Type:'text/calendar; charset=UTF-8'|'application/calendar+json; charset=UTF-8'|'application/calendar+xml; charset=UTF-8'}> | DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED, array{error?: non-empty-string}, array{}>
5050
*
5151
* 200: data in requested format
5252
* 400: invalid parameters
5353
* 401: user not authorized
5454
*/
55-
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT)]
5655
#[ApiRoute(verb: 'POST', url: '/export', root: '/calendar')]
57-
#[UserRateLimit(limit: 60, period: 60)]
56+
#[UserRateLimit(limit: 1, period: 60)]
5857
#[NoAdminRequired]
59-
public function index(string $id, ?string $type = null, ?array $options = null, ?string $user = null) {
60-
$userId = $user;
58+
public function export(string $id, ?string $type = null, ?array $options = null, ?string $user = null) {
6159
$calendarId = $id;
6260
$format = $type ?? 'ical';
6361
$rangeStart = isset($options['rangeStart']) ? (string)$options['rangeStart'] : null;
@@ -66,12 +64,12 @@ public function index(string $id, ?string $type = null, ?array $options = null,
6664
if (!$this->userSession->isLoggedIn()) {
6765
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
6866
}
69-
if ($userId !== null) {
70-
if ($this->userSession->getUser()->getUID() !== $userId
67+
if ($user !== null) {
68+
if ($this->userSession->getUser()->getUID() !== $user
7169
&& $this->groupManager->isAdmin($this->userSession->getUser()->getUID()) === false) {
7270
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
7371
}
74-
if (!$this->userManager->userExists($userId)) {
72+
if (!$this->userManager->userExists($user)) {
7573
return new DataResponse(['error' => 'user not found'], Http::STATUS_BAD_REQUEST);
7674
}
7775
} else {

apps/dav/lib/Controller/CalendarImportController.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
namespace OCA\DAV\Controller;
99

1010
use InvalidArgumentException;
11+
12+
/**
13+
* @psalm-type CalendarImportResult = array{items: list<string>, total: non-negative-int}
14+
*/
1115
use OCA\DAV\AppInfo\Application;
1216
use OCA\DAV\CalDAV\CalendarImpl;
1317
use OCA\DAV\CalDAV\Import\ImportService;
1418
use OCP\AppFramework\Http;
1519
use OCP\AppFramework\Http\Attribute\ApiRoute;
1620
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
17-
use OCP\AppFramework\Http\Attribute\OpenAPI;
1821
use OCP\AppFramework\Http\Attribute\UserRateLimit;
1922
use OCP\AppFramework\Http\DataResponse;
2023
use OCP\AppFramework\OCSController;
@@ -44,22 +47,20 @@ public function __construct(
4447
* Import calendar data
4548
*
4649
* @param string $id calendar id
47-
* @param array{format?:string, validation?:int<0,2>, errors?:int<0,1>, supersede?:bool, showCreated?:bool, showUpdated?:bool, showSkipped?:bool, showErrors?:bool} $options configuration options
50+
* @param array{format?:string, validation?:0|1|2, errors?:0|1, supersede?:bool, showCreated?:bool, showUpdated?:bool, showSkipped?:bool, showErrors?:bool} $options configuration options
4851
* @param string $data calendar data
4952
* @param string|null $user system user id
5053
*
51-
* @return DataResponse<Http::STATUS_OK|Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED|Http::STATUS_INTERNAL_SERVER_ERROR, array{error?: string, time?: float, created?: array{items: list<string>, total: int<0,max>}, updated?: array{items: list<string>, total: int<0,max>}, skipped?: array{items: list<string>, total: int<0, max>}, errors?: array{items: list<string>, total: int<0, max>}}, array{}>
54+
* @return DataResponse<Http::STATUS_OK|Http::STATUS_BAD_REQUEST|Http::STATUS_UNAUTHORIZED|Http::STATUS_INTERNAL_SERVER_ERROR, array{error?: string, time?: float, created?: array{items: list<string>, total: non-negative-int}, updated?: array{items: list<string>, total: non-negative-int}, skipped?: array{items: list<string>, total: non-negative-int}, errors?: array{items: list<string>, total: non-negative-int}}, array{}>
5255
*
5356
* 200: calendar data
5457
* 400: invalid request
5558
* 401: user not authorized
5659
*/
57-
#[OpenAPI(scope: OpenAPI::SCOPE_DEFAULT)]
5860
#[ApiRoute(verb: 'POST', url: '/import', root: '/calendar')]
5961
#[UserRateLimit(limit: 1, period: 60)]
6062
#[NoAdminRequired]
61-
public function index(string $id, array $options, string $data, ?string $user = null): DataResponse {
62-
$userId = $user;
63+
public function import(string $id, array $options, string $data, ?string $user = null): DataResponse {
6364
$calendarId = $id;
6465
$format = isset($options['format']) ? $options['format'] : null;
6566
$validation = isset($options['validation']) ? (int)$options['validation'] : null;
@@ -73,12 +74,12 @@ public function index(string $id, array $options, string $data, ?string $user =
7374
if (!$this->userSession->isLoggedIn()) {
7475
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
7576
}
76-
if ($userId !== null) {
77-
if ($this->userSession->getUser()->getUID() !== $userId
77+
if ($user !== null) {
78+
if ($this->userSession->getUser()->getUID() !== $user
7879
&& $this->groupManager->isAdmin($this->userSession->getUser()->getUID()) === false) {
7980
return new DataResponse([], Http::STATUS_UNAUTHORIZED);
8081
}
81-
if (!$this->userManager->userExists($userId)) {
82+
if (!$this->userManager->userExists($user)) {
8283
return new DataResponse(['error' => 'user not found'], Http::STATUS_BAD_REQUEST);
8384
}
8485
} else {

apps/dav/openapi.json

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@
11551155
},
11561156
"/ocs/v2.php/calendar/export": {
11571157
"post": {
1158-
"operationId": "calendar_export-index",
1158+
"operationId": "calendar_export-export",
11591159
"summary": "Export calendar data",
11601160
"tags": [
11611161
"calendar_export"
@@ -1232,7 +1232,24 @@
12321232
],
12331233
"responses": {
12341234
"200": {
1235-
"description": "data in requested format"
1235+
"description": "data in requested format",
1236+
"content": {
1237+
"text/calendar; charset=UTF-8": {
1238+
"schema": {
1239+
"anyOf": []
1240+
}
1241+
},
1242+
"application/calendar+json; charset=UTF-8": {
1243+
"schema": {
1244+
"anyOf": []
1245+
}
1246+
},
1247+
"application/calendar+xml; charset=UTF-8": {
1248+
"schema": {
1249+
"anyOf": []
1250+
}
1251+
}
1252+
}
12361253
},
12371254
"400": {
12381255
"description": "invalid parameters",
@@ -1336,7 +1353,7 @@
13361353
},
13371354
"/ocs/v2.php/calendar/import": {
13381355
"post": {
1339-
"operationId": "calendar_import-index",
1356+
"operationId": "calendar_import-import",
13401357
"summary": "Import calendar data",
13411358
"tags": [
13421359
"calendar_import"
@@ -1375,14 +1392,19 @@
13751392
"validation": {
13761393
"type": "integer",
13771394
"format": "int64",
1378-
"minimum": 0,
1379-
"maximum": 2
1395+
"enum": [
1396+
0,
1397+
1,
1398+
2
1399+
]
13801400
},
13811401
"errors": {
13821402
"type": "integer",
13831403
"format": "int64",
1384-
"minimum": 0,
1385-
"maximum": 1
1404+
"enum": [
1405+
0,
1406+
1
1407+
]
13861408
},
13871409
"supersede": {
13881410
"type": "boolean"

lib/public/AppFramework/Http/StreamGeneratorResponse.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
declare(strict_types=1);
44

55
/**
6-
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
7-
* SPDX-License-Identifier: AGPL-3.0-only
6+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
88
*/
99
namespace OCP\AppFramework\Http;
1010

1111
use Generator;
1212
use OCP\AppFramework\Http;
1313

1414
/**
15-
* @since 32.0.0
15+
* @since 33.0.0
1616
*
1717
* @template S of Http::STATUS_*
1818
* @template H of array<string, mixed>
@@ -22,8 +22,6 @@ class StreamGeneratorResponse extends Response implements ICallbackResponse {
2222
protected $generator;
2323

2424
/**
25-
* @since 32.0.0
26-
*
2725
* @param Generator $generator the function to call to generate the response
2826
* @param string $contentType http response content type e.g. 'application/json; charset=UTF-8'
2927
* @param S $status http response status
@@ -45,8 +43,6 @@ public function __construct(Generator $generator, string $contentType, int $stat
4543
/**
4644
* Streams content directly to client
4745
*
48-
* @since 32.0.0
49-
*
5046
* @param IOutput $output a small wrapper that handles output
5147
*/
5248
public function callback(IOutput $output) {

openapi.json

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17860,7 +17860,7 @@
1786017860
},
1786117861
"/ocs/v2.php/calendar/export": {
1786217862
"post": {
17863-
"operationId": "dav-calendar_export-index",
17863+
"operationId": "dav-calendar_export-export",
1786417864
"summary": "Export calendar data",
1786517865
"tags": [
1786617866
"dav/calendar_export"
@@ -17937,7 +17937,24 @@
1793717937
],
1793817938
"responses": {
1793917939
"200": {
17940-
"description": "data in requested format"
17940+
"description": "data in requested format",
17941+
"content": {
17942+
"text/calendar; charset=UTF-8": {
17943+
"schema": {
17944+
"anyOf": []
17945+
}
17946+
},
17947+
"application/calendar+json; charset=UTF-8": {
17948+
"schema": {
17949+
"anyOf": []
17950+
}
17951+
},
17952+
"application/calendar+xml; charset=UTF-8": {
17953+
"schema": {
17954+
"anyOf": []
17955+
}
17956+
}
17957+
}
1794117958
},
1794217959
"400": {
1794317960
"description": "invalid parameters",
@@ -18041,7 +18058,7 @@
1804118058
},
1804218059
"/ocs/v2.php/calendar/import": {
1804318060
"post": {
18044-
"operationId": "dav-calendar_import-index",
18061+
"operationId": "dav-calendar_import-import",
1804518062
"summary": "Import calendar data",
1804618063
"tags": [
1804718064
"dav/calendar_import"
@@ -18080,14 +18097,19 @@
1808018097
"validation": {
1808118098
"type": "integer",
1808218099
"format": "int64",
18083-
"minimum": 0,
18084-
"maximum": 2
18100+
"enum": [
18101+
0,
18102+
1,
18103+
2
18104+
]
1808518105
},
1808618106
"errors": {
1808718107
"type": "integer",
1808818108
"format": "int64",
18089-
"minimum": 0,
18090-
"maximum": 1
18109+
"enum": [
18110+
0,
18111+
1
18112+
]
1809118113
},
1809218114
"supersede": {
1809318115
"type": "boolean"

0 commit comments

Comments
 (0)