Browse Source

theming: Add OpenAPI spec

Signed-off-by: jld3103 <jld3103yt@gmail.com>
pull/39287/head
jld3103 3 years ago
parent
commit
b58ef2c0b1
No known key found for this signature in database GPG Key ID: 9062417B9E8EB7B3
  1. 1
      apps/theming/composer/composer/autoload_classmap.php
  2. 1
      apps/theming/composer/composer/autoload_static.php
  3. 20
      apps/theming/lib/Capabilities.php
  4. 26
      apps/theming/lib/Controller/IconController.php
  5. 37
      apps/theming/lib/Controller/ThemingController.php
  6. 44
      apps/theming/lib/Controller/UserThemeController.php
  7. 36
      apps/theming/lib/ResponseDefinitions.php
  8. 55
      apps/theming/openapi.json

1
apps/theming/composer/composer/autoload_classmap.php

@ -22,6 +22,7 @@ return array(
'OCA\\Theming\\Migration\\InitBackgroundImagesMigration' => $baseDir . '/../lib/Migration/InitBackgroundImagesMigration.php',
'OCA\\Theming\\Migration\\MigrateAdminConfig' => $baseDir . '/../lib/Migration/MigrateAdminConfig.php',
'OCA\\Theming\\Migration\\MigrateUserConfig' => $baseDir . '/../lib/Migration/MigrateUserConfig.php',
'OCA\\Theming\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
'OCA\\Theming\\Service\\BackgroundService' => $baseDir . '/../lib/Service/BackgroundService.php',
'OCA\\Theming\\Service\\JSDataService' => $baseDir . '/../lib/Service/JSDataService.php',
'OCA\\Theming\\Service\\ThemeInjectionService' => $baseDir . '/../lib/Service/ThemeInjectionService.php',

1
apps/theming/composer/composer/autoload_static.php

@ -37,6 +37,7 @@ class ComposerStaticInitTheming
'OCA\\Theming\\Migration\\InitBackgroundImagesMigration' => __DIR__ . '/..' . '/../lib/Migration/InitBackgroundImagesMigration.php',
'OCA\\Theming\\Migration\\MigrateAdminConfig' => __DIR__ . '/..' . '/../lib/Migration/MigrateAdminConfig.php',
'OCA\\Theming\\Migration\\MigrateUserConfig' => __DIR__ . '/..' . '/../lib/Migration/MigrateUserConfig.php',
'OCA\\Theming\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
'OCA\\Theming\\Service\\BackgroundService' => __DIR__ . '/..' . '/../lib/Service/BackgroundService.php',
'OCA\\Theming\\Service\\JSDataService' => __DIR__ . '/..' . '/../lib/Service/JSDataService.php',
'OCA\\Theming\\Service\\ThemeInjectionService' => __DIR__ . '/..' . '/../lib/Service/ThemeInjectionService.php',

20
apps/theming/lib/Capabilities.php

@ -7,6 +7,7 @@
* @author Julien Veyssier <eneiluj@posteo.net>
* @author Julius Härtl <jus@bitgrid.net>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
@ -64,6 +65,25 @@ class Capabilities implements IPublicCapability {
/**
* Return this classes capabilities
*
* @return array{
* theming: array{
* name: string,
* url: string,
* slogan: string,
* color: string,
* color-text: string,
* color-element: string,
* color-element-bright: string,
* color-element-dark: string,
* logo: string,
* background: string,
* background-plain: bool,
* background-default: bool,
* logoheader: string,
* favicon: string,
* },
* }
*/
public function getCapabilities() {
$backgroundLogo = $this->config->getAppValue('theming', 'backgroundMime', '');

26
apps/theming/lib/Controller/IconController.php

@ -8,6 +8,7 @@
* @author Julius Härtl <jus@bitgrid.net>
* @author Michael Weimann <mail@michael-weimann.eu>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
@ -80,10 +81,15 @@ class IconController extends Controller {
* @PublicPage
* @NoCSRFRequired
*
* @param $app string app name
* @param $image string image file name (svg required)
* @return FileDisplayResponse|NotFoundResponse
* Get a themed icon
*
* @param string $app ID of the app
* @param string $image image file name (svg required)
* @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: 'image/svg+xml'}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
* @throws \Exception
*
* 200: Themed icon returned
* 404: Themed icon not found
*/
public function getThemedIcon(string $app, string $image): Response {
$color = $this->themingDefaults->getColorPrimary();
@ -107,9 +113,12 @@ class IconController extends Controller {
* @PublicPage
* @NoCSRFRequired
*
* @param $app string app name
* @return FileDisplayResponse|DataDisplayResponse|NotFoundResponse
* @param string $app ID of the app
* @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{}>
* @throws \Exception
*
* 200: Favicon returned
* 404: Favicon not found
*/
public function getFavicon(string $app = 'core'): Response {
$response = null;
@ -146,9 +155,12 @@ class IconController extends Controller {
* @PublicPage
* @NoCSRFRequired
*
* @param $app string app name
* @return DataDisplayResponse|FileDisplayResponse|NotFoundResponse
* @param string $app ID of the app
* @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{}>
* @throws \Exception
*
* 200: Touch icon returned
* 404: Touch icon not found
*/
public function getTouchIcon(string $app = 'core'): Response {
$response = null;

37
apps/theming/lib/Controller/ThemingController.php

@ -18,6 +18,7 @@
* @author Robin Appelman <robin@icewind.nl>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Citharel <nextcloud@tcit.fr>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
@ -46,6 +47,7 @@ use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataDisplayResponse;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\FileDisplayResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
@ -314,10 +316,15 @@ class ThemingController extends Controller {
* @NoCSRFRequired
* @NoSameSiteCookieRequired
*
* @param string $key
* @param bool $useSvg
* @return FileDisplayResponse|NotFoundResponse
* Get an image
*
* @param string $key Key of the image
* @param bool $useSvg Return image as SVG
* @return FileDisplayResponse<Http::STATUS_OK, array{}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
* @throws NotPermittedException
*
* 200: Image returned
* 404: Image not found
*/
public function getImage(string $key, bool $useSvg = true) {
try {
@ -347,7 +354,15 @@ class ThemingController extends Controller {
* @NoSameSiteCookieRequired
* @NoTwoFactorRequired
*
* @return DataDisplayResponse|NotFoundResponse
* Get the CSS stylesheet for a theme
*
* @param string $themeId ID of the theme
* @param bool $plain Let the browser decide the CSS priority
* @param bool $withCustomCss Include custom CSS
* @return DataDisplayResponse<Http::STATUS_OK, array{Content-Type: 'text/css'}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
*
* 200: Stylesheet returned
* 404: Theme not found
*/
public function getThemeStylesheet(string $themeId, bool $plain = false, bool $withCustomCss = false) {
$themes = $this->themesService->getThemes();
@ -387,9 +402,13 @@ class ThemingController extends Controller {
* @NoCSRFRequired
* @PublicPage
*
* @return Http\JSONResponse
* Get the manifest for an app
*
* @param string $app ID of the app
* @psalm-suppress LessSpecificReturnStatement The content of the Manifest doesn't need to be described in the return type
* @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{}>
*/
public function getManifest($app) {
public function getManifest(string $app) {
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
if ($app === 'core' || $app === 'settings') {
$name = $this->themingDefaults->getName();
@ -407,6 +426,10 @@ class ThemingController extends Controller {
}
$description = $info['summary'] ?? '';
}
/**
* @var string $description
* @var string $shortName
*/
$responseJS = [
'name' => $name,
'short_name' => $shortName,
@ -431,7 +454,7 @@ class ThemingController extends Controller {
],
'display' => 'standalone'
];
$response = new Http\JSONResponse($responseJS);
$response = new JSONResponse($responseJS);
$response->cacheFor(3600);
return $response;
}

44
apps/theming/lib/Controller/UserThemeController.php

@ -11,6 +11,7 @@ declare(strict_types=1);
* @author Janis Köhr <janis.koehr@novatec-gmbh.de>
* @author John Molakvoæ <skjnldsv@protonmail.com>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
@ -32,6 +33,7 @@ namespace OCA\Theming\Controller;
use OCA\Theming\AppInfo\Application;
use OCA\Theming\ITheme;
use OCA\Theming\ResponseDefinitions;
use OCA\Theming\Service\BackgroundService;
use OCA\Theming\Service\ThemesService;
use OCA\Theming\ThemingDefaults;
@ -48,10 +50,13 @@ use OCP\IRequest;
use OCP\IUserSession;
use OCP\PreConditionNotMetException;
/**
* @psalm-import-type ThemingBackground from ResponseDefinitions
*/
class UserThemeController extends OCSController {
protected ?string $userId = null;
private IConfig $config;
private IUserSession $userSession;
private ThemesService $themesService;
@ -84,8 +89,11 @@ class UserThemeController extends OCSController {
* Enable theme
*
* @param string $themeId the theme ID
* @return DataResponse
* @throws OCSBadRequestException|PreConditionNotMetException
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @throws OCSBadRequestException Enabling theme is not possible
* @throws PreConditionNotMetException
*
* 200: Theme enabled successfully
*/
public function enableTheme(string $themeId): DataResponse {
$theme = $this->validateTheme($themeId);
@ -101,8 +109,11 @@ class UserThemeController extends OCSController {
* Disable theme
*
* @param string $themeId the theme ID
* @return DataResponse
* @throws OCSBadRequestException|PreConditionNotMetException
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
* @throws OCSBadRequestException Disabling theme is not possible
* @throws PreConditionNotMetException
*
* 200: Theme disabled successfully
*/
public function disableTheme(string $themeId): DataResponse {
$theme = $this->validateTheme($themeId);
@ -119,7 +130,8 @@ class UserThemeController extends OCSController {
*
* @param string $themeId the theme ID
* @return ITheme
* @throws OCSBadRequestException|PreConditionNotMetException
* @throws OCSBadRequestException
* @throws PreConditionNotMetException
*/
private function validateTheme(string $themeId): ITheme {
if ($themeId === '' || !$themeId) {
@ -143,6 +155,12 @@ class UserThemeController extends OCSController {
/**
* @NoAdminRequired
* @NoCSRFRequired
*
* Get the background image
* @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: string}>|NotFoundResponse<Http::STATUS_NOT_FOUND, array{}>
*
* 200: Background image returned
* 404: Background image not found
*/
public function getBackground(): Http\Response {
$file = $this->backgroundService->getBackground();
@ -156,6 +174,10 @@ class UserThemeController extends OCSController {
/**
* @NoAdminRequired
*
* Delete the background
*
* @return JSONResponse<Http::STATUS_OK, ThemingBackground, array{}>
*/
public function deleteBackground(): JSONResponse {
$currentVersion = (int)$this->config->getUserValue($this->userId, Application::APP_ID, 'userCacheBuster', '0');
@ -169,6 +191,16 @@ class UserThemeController extends OCSController {
/**
* @NoAdminRequired
*
* Set the background
*
* @param string $type Type of background
* @param string $value Path of the background image
* @param string|null $color Color for the background
* @return JSONResponse<Http::STATUS_OK, ThemingBackground, array{}>|JSONResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_INTERNAL_SERVER_ERROR, array{error: string}, array{}>
*
* 200: Background set successfully
* 400: Setting background is not possible
*/
public function setBackground(string $type = BackgroundService::BACKGROUND_DEFAULT, string $value = '', string $color = null): JSONResponse {
$currentVersion = (int)$this->config->getUserValue($this->userId, Application::APP_ID, 'userCacheBuster', '0');

36
apps/theming/lib/ResponseDefinitions.php

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Kate Döen <kate.doeen@nextcloud.com>
*
* @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Theming;
/**
* @psalm-type ThemingBackground = array{
* backgroundImage: ?string,
* backgroundColor: string,
* version: int,
* }
*/
class ResponseDefinitions {
}

55
apps/theming/openapi.json

@ -187,13 +187,6 @@
"responses": {
"200": {
"description": "Stylesheet returned",
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
}
}
},
"content": {
"text/css": {
"schema": {
@ -255,13 +248,6 @@
"responses": {
"200": {
"description": "Image returned",
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
}
}
},
"content": {
"*/*": {
"schema": {
@ -368,7 +354,8 @@
],
"properties": {
"src": {
"type": "string"
"type": "string",
"minLength": 1
},
"type": {
"type": "string"
@ -421,13 +408,6 @@
"responses": {
"200": {
"description": "Favicon returned",
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
}
}
},
"content": {
"image/x-icon": {
"schema": {
@ -491,13 +471,6 @@
"responses": {
"200": {
"description": "Touch icon returned",
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
}
}
},
"content": {
"image/png": {
"schema": {
@ -576,13 +549,6 @@
"responses": {
"200": {
"description": "Themed icon returned",
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
}
}
},
"content": {
"image/svg+xml": {
"schema": {
@ -644,13 +610,6 @@
"responses": {
"200": {
"description": "Background image returned",
"headers": {
"Content-Disposition": {
"schema": {
"type": "string"
}
}
},
"content": {
"*/*": {
"schema": {
@ -872,10 +831,7 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"additionalProperties": true
}
"data": {}
}
}
}
@ -962,10 +918,7 @@
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"additionalProperties": true
}
"data": {}
}
}
}

Loading…
Cancel
Save