Skip to content

Commit 0f2509e

Browse files
Merge pull request #39287 from nextcloud/feature/openapi/theming
theming: Add OpenAPI spec
2 parents ed27f04 + b58ef2c commit 0f2509e

8 files changed

+149
-71
lines changed

apps/theming/composer/composer/autoload_classmap.php

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'OCA\\Theming\\Migration\\InitBackgroundImagesMigration' => $baseDir . '/../lib/Migration/InitBackgroundImagesMigration.php',
2323
'OCA\\Theming\\Migration\\MigrateAdminConfig' => $baseDir . '/../lib/Migration/MigrateAdminConfig.php',
2424
'OCA\\Theming\\Migration\\MigrateUserConfig' => $baseDir . '/../lib/Migration/MigrateUserConfig.php',
25+
'OCA\\Theming\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
2526
'OCA\\Theming\\Service\\BackgroundService' => $baseDir . '/../lib/Service/BackgroundService.php',
2627
'OCA\\Theming\\Service\\JSDataService' => $baseDir . '/../lib/Service/JSDataService.php',
2728
'OCA\\Theming\\Service\\ThemeInjectionService' => $baseDir . '/../lib/Service/ThemeInjectionService.php',

apps/theming/composer/composer/autoload_static.php

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ComposerStaticInitTheming
3737
'OCA\\Theming\\Migration\\InitBackgroundImagesMigration' => __DIR__ . '/..' . '/../lib/Migration/InitBackgroundImagesMigration.php',
3838
'OCA\\Theming\\Migration\\MigrateAdminConfig' => __DIR__ . '/..' . '/../lib/Migration/MigrateAdminConfig.php',
3939
'OCA\\Theming\\Migration\\MigrateUserConfig' => __DIR__ . '/..' . '/../lib/Migration/MigrateUserConfig.php',
40+
'OCA\\Theming\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
4041
'OCA\\Theming\\Service\\BackgroundService' => __DIR__ . '/..' . '/../lib/Service/BackgroundService.php',
4142
'OCA\\Theming\\Service\\JSDataService' => __DIR__ . '/..' . '/../lib/Service/JSDataService.php',
4243
'OCA\\Theming\\Service\\ThemeInjectionService' => __DIR__ . '/..' . '/../lib/Service/ThemeInjectionService.php',

apps/theming/lib/Capabilities.php

+20
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* @author Julien Veyssier <eneiluj@posteo.net>
88
* @author Julius Härtl <jus@bitgrid.net>
99
* @author Morris Jobke <hey@morrisjobke.de>
10+
* @author Kate Döen <kate.doeen@nextcloud.com>
1011
*
1112
* @license GNU AGPL version 3 or any later version
1213
*
@@ -64,6 +65,25 @@ public function __construct(ThemingDefaults $theming, Util $util, IURLGenerator
6465

6566
/**
6667
* Return this classes capabilities
68+
*
69+
* @return array{
70+
* theming: array{
71+
* name: string,
72+
* url: string,
73+
* slogan: string,
74+
* color: string,
75+
* color-text: string,
76+
* color-element: string,
77+
* color-element-bright: string,
78+
* color-element-dark: string,
79+
* logo: string,
80+
* background: string,
81+
* background-plain: bool,
82+
* background-default: bool,
83+
* logoheader: string,
84+
* favicon: string,
85+
* },
86+
* }
6787
*/
6888
public function getCapabilities() {
6989
$backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime', '');

apps/theming/lib/Controller/IconController.php

+19-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* @author Julius Härtl <jus@bitgrid.net>
99
* @author Michael Weimann <mail@michael-weimann.eu>
1010
* @author Roeland Jago Douma <roeland@famdouma.nl>
11+
* @author Kate Döen <kate.doeen@nextcloud.com>
1112
*
1213
* @license GNU AGPL version 3 or any later version
1314
*
@@ -80,10 +81,15 @@ public function __construct(
8081
* @PublicPage
8182
* @NoCSRFRequired
8283
*
83-
* @param $app string app name
84-
* @param $image string image file name (svg required)
85-
* @return FileDisplayResponse|NotFoundResponse
84+
* Get a themed icon
85+
*
86+
* @param string $app ID of the app
87+
* @param string $image image file name (svg required)
88+
* @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: 'image/svg+xml'}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
8689
* @throws \Exception
90+
*
91+
* 200: Themed icon returned
92+
* 404: Themed icon not found
8793
*/
8894
public function getThemedIcon(string $app, string $image): Response {
8995
$color = $this->themingDefaults->getColorPrimary();
@@ -107,9 +113,12 @@ public function getThemedIcon(string $app, string $image): Response {
107113
* @PublicPage
108114
* @NoCSRFRequired
109115
*
110-
* @param $app string app name
111-
* @return FileDisplayResponse|DataDisplayResponse|NotFoundResponse
116+
* @param string $app ID of the app
117+
* @return DataDisplayResponse<Http::STATUS_OK, array{Content-Type: 'image/x-icon'}>|FileDisplayResponse<Http::STATUS_OK, array{Content-Type: 'image/x-icon'}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
112118
* @throws \Exception
119+
*
120+
* 200: Favicon returned
121+
* 404: Favicon not found
113122
*/
114123
public function getFavicon(string $app = 'core'): Response {
115124
$response = null;
@@ -146,9 +155,12 @@ public function getFavicon(string $app = 'core'): Response {
146155
* @PublicPage
147156
* @NoCSRFRequired
148157
*
149-
* @param $app string app name
150-
* @return DataDisplayResponse|FileDisplayResponse|NotFoundResponse
158+
* @param string $app ID of the app
159+
* @return DataDisplayResponse<Http::STATUS_OK, array{Content-Type: 'image/png'}>|FileDisplayResponse<Http::STATUS_OK, array{Content-Type: 'image/x-icon'|'image/png'}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
151160
* @throws \Exception
161+
*
162+
* 200: Touch icon returned
163+
* 404: Touch icon not found
152164
*/
153165
public function getTouchIcon(string $app = 'core'): Response {
154166
$response = null;

apps/theming/lib/Controller/ThemingController.php

+30-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* @author Robin Appelman <robin@icewind.nl>
1919
* @author Roeland Jago Douma <roeland@famdouma.nl>
2020
* @author Thomas Citharel <nextcloud@tcit.fr>
21+
* @author Kate Döen <kate.doeen@nextcloud.com>
2122
*
2223
* @license GNU AGPL version 3 or any later version
2324
*
@@ -46,6 +47,7 @@
4647
use OCP\AppFramework\Http\DataDisplayResponse;
4748
use OCP\AppFramework\Http\DataResponse;
4849
use OCP\AppFramework\Http\FileDisplayResponse;
50+
use OCP\AppFramework\Http\JSONResponse;
4951
use OCP\AppFramework\Http\NotFoundResponse;
5052
use OCP\Files\IAppData;
5153
use OCP\Files\NotFoundException;
@@ -314,10 +316,15 @@ public function undoAll(): DataResponse {
314316
* @NoCSRFRequired
315317
* @NoSameSiteCookieRequired
316318
*
317-
* @param string $key
318-
* @param bool $useSvg
319-
* @return FileDisplayResponse|NotFoundResponse
319+
* Get an image
320+
*
321+
* @param string $key Key of the image
322+
* @param bool $useSvg Return image as SVG
323+
* @return FileDisplayResponse<Http::STATUS_OK, array{}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
320324
* @throws NotPermittedException
325+
*
326+
* 200: Image returned
327+
* 404: Image not found
321328
*/
322329
public function getImage(string $key, bool $useSvg = true) {
323330
try {
@@ -347,7 +354,15 @@ public function getImage(string $key, bool $useSvg = true) {
347354
* @NoSameSiteCookieRequired
348355
* @NoTwoFactorRequired
349356
*
350-
* @return DataDisplayResponse|NotFoundResponse
357+
* Get the CSS stylesheet for a theme
358+
*
359+
* @param string $themeId ID of the theme
360+
* @param bool $plain Let the browser decide the CSS priority
361+
* @param bool $withCustomCss Include custom CSS
362+
* @return DataDisplayResponse<Http::STATUS_OK, array{Content-Type: 'text/css'}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
363+
*
364+
* 200: Stylesheet returned
365+
* 404: Theme not found
351366
*/
352367
public function getThemeStylesheet(string $themeId, bool $plain = false, bool $withCustomCss = false) {
353368
$themes = $this->themesService->getThemes();
@@ -387,9 +402,13 @@ public function getThemeStylesheet(string $themeId, bool $plain = false, bool $w
387402
* @NoCSRFRequired
388403
* @PublicPage
389404
*
390-
* @return Http\JSONResponse
405+
* Get the manifest for an app
406+
*
407+
* @param string $app ID of the app
408+
* @psalm-suppress LessSpecificReturnStatement The content of the Manifest doesn't need to be described in the return type
409+
* @return JSONResponse<Http::STATUS_OK, array{name: string, short_name: string, start_url: string, theme_color: string, background_color: string, description: string, icons: array{src: non-empty-string, type: string, sizes: string}[], display: string}, array{}>
391410
*/
392-
public function getManifest($app) {
411+
public function getManifest(string $app) {
393412
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
394413
if ($app === 'core' || $app === 'settings') {
395414
$name = $this->themingDefaults->getName();
@@ -407,6 +426,10 @@ public function getManifest($app) {
407426
}
408427
$description = $info['summary'] ?? '';
409428
}
429+
/**
430+
* @var string $description
431+
* @var string $shortName
432+
*/
410433
$responseJS = [
411434
'name' => $name,
412435
'short_name' => $shortName,
@@ -431,7 +454,7 @@ public function getManifest($app) {
431454
],
432455
'display' => 'standalone'
433456
];
434-
$response = new Http\JSONResponse($responseJS);
457+
$response = new JSONResponse($responseJS);
435458
$response->cacheFor(3600);
436459
return $response;
437460
}

apps/theming/lib/Controller/UserThemeController.php

+38-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* @author Janis Köhr <janis.koehr@novatec-gmbh.de>
1212
* @author John Molakvoæ <skjnldsv@protonmail.com>
1313
* @author Roeland Jago Douma <roeland@famdouma.nl>
14+
* @author Kate Döen <kate.doeen@nextcloud.com>
1415
*
1516
* @license GNU AGPL version 3 or any later version
1617
*
@@ -32,6 +33,7 @@
3233

3334
use OCA\Theming\AppInfo\Application;
3435
use OCA\Theming\ITheme;
36+
use OCA\Theming\ResponseDefinitions;
3537
use OCA\Theming\Service\BackgroundService;
3638
use OCA\Theming\Service\ThemesService;
3739
use OCA\Theming\ThemingDefaults;
@@ -48,10 +50,13 @@
4850
use OCP\IUserSession;
4951
use OCP\PreConditionNotMetException;
5052

53+
/**
54+
* @psalm-import-type ThemingBackground from ResponseDefinitions
55+
*/
5156
class UserThemeController extends OCSController {
5257

5358
protected ?string $userId = null;
54-
59+
5560
private IConfig $config;
5661
private IUserSession $userSession;
5762
private ThemesService $themesService;
@@ -84,8 +89,11 @@ public function __construct(string $appName,
8489
* Enable theme
8590
*
8691
* @param string $themeId the theme ID
87-
* @return DataResponse
88-
* @throws OCSBadRequestException|PreConditionNotMetException
92+
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
93+
* @throws OCSBadRequestException Enabling theme is not possible
94+
* @throws PreConditionNotMetException
95+
*
96+
* 200: Theme enabled successfully
8997
*/
9098
public function enableTheme(string $themeId): DataResponse {
9199
$theme = $this->validateTheme($themeId);
@@ -101,8 +109,11 @@ public function enableTheme(string $themeId): DataResponse {
101109
* Disable theme
102110
*
103111
* @param string $themeId the theme ID
104-
* @return DataResponse
105-
* @throws OCSBadRequestException|PreConditionNotMetException
112+
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
113+
* @throws OCSBadRequestException Disabling theme is not possible
114+
* @throws PreConditionNotMetException
115+
*
116+
* 200: Theme disabled successfully
106117
*/
107118
public function disableTheme(string $themeId): DataResponse {
108119
$theme = $this->validateTheme($themeId);
@@ -119,7 +130,8 @@ public function disableTheme(string $themeId): DataResponse {
119130
*
120131
* @param string $themeId the theme ID
121132
* @return ITheme
122-
* @throws OCSBadRequestException|PreConditionNotMetException
133+
* @throws OCSBadRequestException
134+
* @throws PreConditionNotMetException
123135
*/
124136
private function validateTheme(string $themeId): ITheme {
125137
if ($themeId === '' || !$themeId) {
@@ -143,6 +155,12 @@ private function validateTheme(string $themeId): ITheme {
143155
/**
144156
* @NoAdminRequired
145157
* @NoCSRFRequired
158+
*
159+
* Get the background image
160+
* @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: string}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
161+
*
162+
* 200: Background image returned
163+
* 404: Background image not found
146164
*/
147165
public function getBackground(): Http\Response {
148166
$file = $this->backgroundService->getBackground();
@@ -156,6 +174,10 @@ public function getBackground(): Http\Response {
156174

157175
/**
158176
* @NoAdminRequired
177+
*
178+
* Delete the background
179+
*
180+
* @return JSONResponse<Http::STATUS_OK, ThemingBackground, array{}>
159181
*/
160182
public function deleteBackground(): JSONResponse {
161183
$currentVersion = (int)$this->config->getUserValue($this->userId, Application::APP_ID, 'userCacheBuster', '0');
@@ -169,6 +191,16 @@ public function deleteBackground(): JSONResponse {
169191

170192
/**
171193
* @NoAdminRequired
194+
*
195+
* Set the background
196+
*
197+
* @param string $type Type of background
198+
* @param string $value Path of the background image
199+
* @param string|null $color Color for the background
200+
* @return JSONResponse<Http::STATUS_OK, ThemingBackground, array{}>|JSONResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_INTERNAL_SERVER_ERROR, array{error: string}, array{}>
201+
*
202+
* 200: Background set successfully
203+
* 400: Setting background is not possible
172204
*/
173205
public function setBackground(string $type = BackgroundService::BACKGROUND_DEFAULT, string $value = '', string $color = null): JSONResponse {
174206
$currentVersion = (int)$this->config->getUserValue($this->userId, Application::APP_ID, 'userCacheBuster', '0');
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
/**
5+
* @copyright Copyright (c) 2023 Kate Döen <kate.doeen@nextcloud.com>
6+
*
7+
* @author Kate Döen <kate.doeen@nextcloud.com>
8+
*
9+
* @license GNU AGPL version 3 or any later version
10+
*
11+
* This program is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Affero General Public License as
13+
* published by the Free Software Foundation, either version 3 of the
14+
* License, or (at your option) any later version.
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*
24+
*/
25+
26+
namespace OCA\Theming;
27+
28+
/**
29+
* @psalm-type ThemingBackground = array{
30+
* backgroundImage: ?string,
31+
* backgroundColor: string,
32+
* version: int,
33+
* }
34+
*/
35+
class ResponseDefinitions {
36+
}

0 commit comments

Comments
 (0)