diff options
author | John Molakvoæ <skjnldsv@protonmail.com> | 2022-10-13 14:22:04 +0200 |
---|---|---|
committer | John Molakvoæ <skjnldsv@protonmail.com> | 2022-10-19 12:57:35 +0200 |
commit | ef760e0337018c8a45bb380d1a1d50f912ca23ee (patch) | |
tree | ea1f93502826804c837e8c7834396cf40c33e5c7 /apps/theming | |
parent | bbbc1d4a163400eb79cfac3e839769f2e54d7f0a (diff) | |
download | nextcloud-server-ef760e0337018c8a45bb380d1a1d50f912ca23ee.tar.gz nextcloud-server-ef760e0337018c8a45bb380d1a1d50f912ca23ee.zip |
Add admin user customization kill switch
Signed-off-by: John Molakvoæ <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/theming')
-rw-r--r-- | apps/theming/css/default.css | 1 | ||||
-rw-r--r-- | apps/theming/css/settings-admin.css | 16 | ||||
-rw-r--r-- | apps/theming/css/settings-admin.css.map | 2 | ||||
-rw-r--r-- | apps/theming/css/settings-admin.scss | 20 | ||||
-rw-r--r-- | apps/theming/js/settings-admin.js | 5 | ||||
-rw-r--r-- | apps/theming/lib/Command/UpdateConfig.php | 2 | ||||
-rw-r--r-- | apps/theming/lib/Controller/ThemingController.php | 5 | ||||
-rw-r--r-- | apps/theming/lib/Settings/Admin.php | 1 | ||||
-rw-r--r-- | apps/theming/lib/Settings/Personal.php | 7 | ||||
-rw-r--r-- | apps/theming/lib/Themes/DefaultTheme.php | 12 | ||||
-rw-r--r-- | apps/theming/lib/ThemingDefaults.php | 11 | ||||
-rw-r--r-- | apps/theming/src/UserThemes.vue | 17 | ||||
-rw-r--r-- | apps/theming/templates/settings-admin.php | 13 |
13 files changed, 96 insertions, 16 deletions
diff --git a/apps/theming/css/default.css b/apps/theming/css/default.css index 1f0a241307b..226f7ccc43f 100644 --- a/apps/theming/css/default.css +++ b/apps/theming/css/default.css @@ -1,6 +1,5 @@ :root { --color-main-background: #ffffff; - --color-main-background-not-plain: #0082c9; --color-main-background-rgb: 255,255,255; --color-main-background-translucent: rgba(var(--color-main-background-rgb), .97); --color-main-background-blur: rgba(var(--color-main-background-rgb), .8); diff --git a/apps/theming/css/settings-admin.css b/apps/theming/css/settings-admin.css index 00d4e2414fa..283d76e4305 100644 --- a/apps/theming/css/settings-admin.css +++ b/apps/theming/css/settings-admin.css @@ -26,6 +26,8 @@ } #theming form.uploadButton { width: 411px; + display: flex; + align-items: center; } #theming form .theme-undo, #theming .theme-remove-bg { @@ -41,6 +43,10 @@ visibility: visible; height: 32px; width: 32px; + margin-left: auto; +} +#theming form .theme-undo:not([style*="display:"]) ~ .theme-remove-bg { + margin-left: 0; } #theming input[type=text]:hover + .theme-undo, #theming input[type=text] + .theme-undo:hover, @@ -55,6 +61,8 @@ #theming label span { display: inline-block; min-width: 175px; + max-width: 175px; + white-space: wrap; padding: 8px 0px; vertical-align: top; } @@ -120,6 +128,14 @@ #theming #theming-preview-favicon { background-image: var(--image-favicon); } +#theming #user-theming { + margin-top: 44px; + display: flex; +} +#theming #user-theming > div { + max-width: 400px; + margin-bottom: 44px; +} /* transition effects for theming value changes */ #header { diff --git a/apps/theming/css/settings-admin.css.map b/apps/theming/css/settings-admin.css.map index b5e657a4e30..bb1b36671de 100644 --- a/apps/theming/css/settings-admin.css.map +++ b/apps/theming/css/settings-admin.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["settings-admin.scss"],"names":[],"mappings":"AACI;EACI;;AAGJ;AAAA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;EACI;;AAEJ;AAAA;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQI;;AAGJ;EACI;EACA;EACA;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAGP;EAEO;;AAGP;EACO;;;AAIR;AACA;EACI;;AACA;EACI","file":"settings-admin.css"}
\ No newline at end of file +{"version":3,"sourceRoot":"","sources":["settings-admin.scss"],"names":[],"mappings":"AACI;EACI;;AAGJ;AAAA;EAEI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;AAAA;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEJ;EAEI;;AAGJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAQI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAGJ;AAAA;EAEI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIR;EACI;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAGP;EAEO;;AAGP;EACO;;AAGJ;EACI;EACA;;AACD;EACK;EACA;;;AAKZ;AACA;EACI;;AACA;EACI","file":"settings-admin.css"}
\ No newline at end of file diff --git a/apps/theming/css/settings-admin.scss b/apps/theming/css/settings-admin.scss index f43d3b8c417..60d9a823a0b 100644 --- a/apps/theming/css/settings-admin.scss +++ b/apps/theming/css/settings-admin.scss @@ -31,6 +31,8 @@ } form.uploadButton { width: 411px; + display: flex; + align-items: center; } form .theme-undo, .theme-remove-bg { @@ -46,7 +48,14 @@ visibility: visible; height: 32px; width: 32px; + // right align + margin-left: auto; } + form .theme-undo:not([style*="display:"]) ~ .theme-remove-bg { + // Only align the undo button if both are shown + margin-left: 0; + } + input[type='text']:hover + .theme-undo, input[type='text'] + .theme-undo:hover, input[type='text']:focus + .theme-undo, @@ -61,6 +70,8 @@ label span { display: inline-block; min-width: 175px; + max-width: 175px; + white-space: wrap; padding: 8px 0px; vertical-align: top; } @@ -137,6 +148,15 @@ #theming-preview-favicon { background-image: var(--image-favicon); } + + #user-theming { + margin-top: 44px; + display: flex; + & > div { + max-width: 400px; + margin-bottom: 44px; + } + } } /* transition effects for theming value changes */ diff --git a/apps/theming/js/settings-admin.js b/apps/theming/js/settings-admin.js index 9fd1639ec3e..5617f7b67c8 100644 --- a/apps/theming/js/settings-admin.js +++ b/apps/theming/js/settings-admin.js @@ -173,6 +173,11 @@ window.addEventListener('DOMContentLoaded', function () { var el = $(this); }); + $('#userThemingDisabled').change(function(e) { + var checked = e.target.checked + setThemingValue('disable-user-theming', checked ? 'yes' : 'no') + }); + function onChange(e) { var el = $(this); var setting = el.parent().find('div[data-setting]').data('setting'); diff --git a/apps/theming/lib/Command/UpdateConfig.php b/apps/theming/lib/Command/UpdateConfig.php index bb226668943..c327c92492f 100644 --- a/apps/theming/lib/Command/UpdateConfig.php +++ b/apps/theming/lib/Command/UpdateConfig.php @@ -33,7 +33,7 @@ use Symfony\Component\Console\Output\OutputInterface; class UpdateConfig extends Command { public const SUPPORTED_KEYS = [ - 'name', 'url', 'imprintUrl', 'privacyUrl', 'slogan', 'color' + 'name', 'url', 'imprintUrl', 'privacyUrl', 'slogan', 'color', 'disable-user-theming' ]; public const SUPPORTED_IMAGE_KEYS = [ diff --git a/apps/theming/lib/Controller/ThemingController.php b/apps/theming/lib/Controller/ThemingController.php index e671c2d53e8..2cac9a345a4 100644 --- a/apps/theming/lib/Controller/ThemingController.php +++ b/apps/theming/lib/Controller/ThemingController.php @@ -151,6 +151,11 @@ class ThemingController extends Controller { $error = $this->l10n->t('The given color is invalid'); } break; + case 'disable-user-theming': + if ($value !== "yes" && $value !== "no") { + $error = $this->l10n->t('Disable-user-theming should be true or false'); + } + break; } if ($error !== null) { return new DataResponse([ diff --git a/apps/theming/lib/Settings/Admin.php b/apps/theming/lib/Settings/Admin.php index e89ea6b6fe9..4576bea1df4 100644 --- a/apps/theming/lib/Settings/Admin.php +++ b/apps/theming/lib/Settings/Admin.php @@ -82,6 +82,7 @@ class Admin implements IDelegatedSettings { 'images' => $this->imageManager->getCustomImages(), 'imprintUrl' => $this->themingDefaults->getImprintUrl(), 'privacyUrl' => $this->themingDefaults->getPrivacyUrl(), + 'userThemingDisabled' => $this->themingDefaults->isUserThemingDisabled(), ]; return new TemplateResponse($this->appName, 'settings-admin', $parameters, ''); diff --git a/apps/theming/lib/Settings/Personal.php b/apps/theming/lib/Settings/Personal.php index 5da72bf0158..7ba4da15191 100644 --- a/apps/theming/lib/Settings/Personal.php +++ b/apps/theming/lib/Settings/Personal.php @@ -27,6 +27,7 @@ namespace OCA\Theming\Settings; use OCA\Theming\ITheme; use OCA\Theming\Service\ThemesService; +use OCA\Theming\ThemingDefaults; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\IConfig; @@ -39,15 +40,18 @@ class Personal implements ISettings { private IConfig $config; private ThemesService $themesService; private IInitialState $initialStateService; + private ThemingDefaults $themingDefaults; public function __construct(string $appName, IConfig $config, ThemesService $themesService, - IInitialState $initialStateService) { + IInitialState $initialStateService, + ThemingDefaults $themingDefaults) { $this->appName = $appName; $this->config = $config; $this->themesService = $themesService; $this->initialStateService = $initialStateService; + $this->themingDefaults = $themingDefaults; } public function getForm(): TemplateResponse { @@ -72,6 +76,7 @@ class Personal implements ISettings { $this->initialStateService->provideInitialState('themes', array_values($themes)); $this->initialStateService->provideInitialState('enforceTheme', $enforcedTheme); + $this->initialStateService->provideInitialState('isUserThemingDisabled', $this->themingDefaults->isUserThemingDisabled()); Util::addScript($this->appName, 'theming-settings'); return new TemplateResponse($this->appName, 'settings-personal'); diff --git a/apps/theming/lib/Themes/DefaultTheme.php b/apps/theming/lib/Themes/DefaultTheme.php index aae4c4eca4c..ec985abdb18 100644 --- a/apps/theming/lib/Themes/DefaultTheme.php +++ b/apps/theming/lib/Themes/DefaultTheme.php @@ -109,11 +109,9 @@ class DefaultTheme implements ITheme { $colorBoxShadowRGB = join(',', $this->util->hexToRGB($colorBoxShadow)); $hasCustomLogoHeader = $this->imageManager->hasImage('logo') || $this->imageManager->hasImage('logoheader'); - $hasCustomPrimaryColour = !empty($this->config->getAppValue(Application::APP_ID, 'color')); $variables = [ '--color-main-background' => $colorMainBackground, - '--color-main-background-not-plain' => $this->themingDefaults->getColorPrimary(), '--color-main-background-rgb' => $colorMainBackgroundRGB, '--color-main-background-translucent' => 'rgba(var(--color-main-background-rgb), .97)', '--color-main-background-blur' => 'rgba(var(--color-main-background-rgb), .8)', @@ -202,7 +200,9 @@ class DefaultTheme implements ITheme { '--background-invert-if-dark' => 'no', '--background-invert-if-bright' => 'invert(100%)', + // Default last fallback values '--image-main-background' => "url('" . $this->urlGenerator->imagePath('core', 'app-background.jpg') . "')", + '--color-main-background-plain' => $this->defaultPrimaryColor, ]; // Primary variables @@ -211,8 +211,9 @@ class DefaultTheme implements ITheme { $backgroundDeleted = $this->config->getAppValue(Application::APP_ID, 'backgroundMime', '') === 'backgroundColor'; // If primary as background has been request or if we have a custom primary colour // let's not define the background image - if ($backgroundDeleted || $hasCustomPrimaryColour) { - $variables["--image-background-plain"] = 'true'; + if ($backgroundDeleted && $this->themingDefaults->isUserThemingDisabled()) { + $variables['--image-background-plain'] = 'true'; + $variables['--color-main-background-plain'] = $this->themingDefaults->getColorPrimary(); } // Register image variables only if custom-defined @@ -237,10 +238,11 @@ class DefaultTheme implements ITheme { $appManager = Server::get(IAppManager::class); $user = $this->userSession->getUser(); - if ($appManager->isEnabledForUser(Application::APP_ID) && $user !== null) { + if (!$this->themingDefaults->isUserThemingDisabled() && $appManager->isEnabledForUser(Application::APP_ID) && $user !== null) { $themingBackground = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'background', 'default'); $currentVersion = (int)$this->config->getUserValue($user->getUID(), Application::APP_ID, 'userCacheBuster', '0'); + if ($themingBackground === 'custom') { $cacheBuster = substr(sha1($user->getUID() . '_' . $currentVersion), 0, 8); $variables['--image-main-background'] = "url('" . $this->urlGenerator->linkToRouteAbsolute('theming.userTheme.getBackground') . "?v=$cacheBuster')"; diff --git a/apps/theming/lib/ThemingDefaults.php b/apps/theming/lib/ThemingDefaults.php index 9d5183a6504..eee44e81fda 100644 --- a/apps/theming/lib/ThemingDefaults.php +++ b/apps/theming/lib/ThemingDefaults.php @@ -220,6 +220,10 @@ class ThemingDefaults extends \OC_Defaults { // admin-defined primary color $defaultColor = $this->getDefaultColorPrimary(); + + if ($this->isUserThemingDisabled()) { + return $defaultColor; + } // user-defined primary color $themingBackground = ''; @@ -494,4 +498,11 @@ class ThemingDefaults extends \OC_Defaults { public function getTextColorPrimary() { return $this->util->invertTextColor($this->getColorPrimary()) ? '#000000' : '#ffffff'; } + + /** + * Has the admin disabled user customization + */ + public function isUserThemingDisabled(): bool { + return $this->config->getAppValue('theming', 'disable-user-theming', 'no') === 'yes'; + } } diff --git a/apps/theming/src/UserThemes.vue b/apps/theming/src/UserThemes.vue index c65b19bed7e..4c92e75199d 100644 --- a/apps/theming/src/UserThemes.vue +++ b/apps/theming/src/UserThemes.vue @@ -64,11 +64,16 @@ <NcSettingsSection :title="t('theming', 'Background')" class="background"> - <p>{{ t('theming', 'Set a custom background') }}</p> - <BackgroundSettings class="background__grid" - :background="background" - :theming-default-background="themingDefaultBackground" - @update:background="updateBackground" /> + <template v-if="isUserThemingDisabled"> + <p>{{ t('theming', 'Customization has been disabled by your administrator') }}</p> + </template> + <template v-else> + <p>{{ t('theming', 'Set a custom background') }}</p> + <BackgroundSettings class="background__grid" + :background="background" + :theming-default-background="themingDefaultBackground" + @update:background="updateBackground" /> + </template> </NcSettingsSection> </section> </template> @@ -90,6 +95,7 @@ const shortcutsDisabled = loadState('theming', 'shortcutsDisabled', false) const background = loadState('theming', 'background') const themingDefaultBackground = loadState('theming', 'themingDefaultBackground') const shippedBackgroundList = loadState('theming', 'shippedBackgrounds') +const isUserThemingDisabled = loadState('theming', 'isUserThemingDisabled') console.debug('Available themes', availableThemes) @@ -109,6 +115,7 @@ export default { shortcutsDisabled, background, themingDefaultBackground, + isUserThemingDisabled, } }, diff --git a/apps/theming/templates/settings-admin.php b/apps/theming/templates/settings-admin.php index 6014f0e8579..acaa7b168e8 100644 --- a/apps/theming/templates/settings-admin.php +++ b/apps/theming/templates/settings-admin.php @@ -81,7 +81,7 @@ style('theming', 'settings-admin'); <form class="uploadButton" method="post" action="<?php p($_['uploadLogoRoute']) ?>" data-image-key="background"> <input type="hidden" id="theming-backgroundMime" value="<?php p($_['images']['background']['mime']); ?>" /> <input type="hidden" name="key" value="background" /> - <label for="upload-login-background"><span><?php p($l->t('Login image')) ?></span></label> + <label for="upload-login-background"><span><?php p($l->t('Background and login image')) ?></span></label> <input id="upload-login-background" class="fileupload" name="image" type="file"> <label for="upload-login-background" class="button icon-upload svg" id="upload-login-background" title="<?php p($l->t("Upload new login background")) ?>"></label> <div data-setting="backgroundMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div> @@ -93,7 +93,6 @@ style('theming', 'settings-admin'); </div> <h3 class="inlineblock"><?php p($l->t('Advanced options')); ?></h3> - <div class="advanced-options"> <div> <label> @@ -131,6 +130,16 @@ style('theming', 'settings-admin'); <div data-setting="faviconMime" data-toggle="tooltip" data-original-title="<?php p($l->t('Reset to default')); ?>" class="theme-undo icon icon-history"></div> </form> </div> + <div class="advanced-options" id="user-theming"> + <label><span><?php p($l->t('User settings')); ?></span></label> + <div> + <p class="info"> + <?php p($l->t('Although you can select and customize your instance, users can change their background and colors. If you want to enforce your customization, you can check this box.')); ?> + </p> + <input id="userThemingDisabled" class="checkbox" type="checkbox" <?php p($_['userThemingDisabled'] ? 'checked="checked"' : ''); ?> /> + <label for="userThemingDisabled"><?php p($l->t('Disable user theming')) ?></label> + </div> + </div> </div> <div class="theming-hints"> |