mirror of
https://github.com/nextcloud/server.git
synced 2026-02-18 18:28:50 -05:00
theming: Add OpenAPI spec
Signed-off-by: jld3103 <jld3103yt@gmail.com>
This commit is contained in:
parent
c0f3588098
commit
b58ef2c0b1
8 changed files with 149 additions and 71 deletions
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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', '');
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
Normal file
36
apps/theming/lib/ResponseDefinitions.php
Normal file
|
|
@ -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 {
|
||||
}
|
||||
|
|
@ -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…
Reference in a new issue