Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add admin user customization kill switch
Signed-off-by: John Molakvoæ <[email protected]>
  • Loading branch information
skjnldsv committed Oct 19, 2022
commit ef760e0337018c8a45bb380d1a1d50f912ca23ee
1 change: 0 additions & 1 deletion apps/theming/css/default.css
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
16 changes: 16 additions & 0 deletions apps/theming/css/settings-admin.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/theming/css/settings-admin.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions apps/theming/css/settings-admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
}
form.uploadButton {
width: 411px;
display: flex;
align-items: center;
}
form .theme-undo,
.theme-remove-bg {
Expand All @@ -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,
Expand All @@ -61,6 +70,8 @@
label span {
display: inline-block;
min-width: 175px;
max-width: 175px;
white-space: wrap;
padding: 8px 0px;
vertical-align: top;
}
Expand Down Expand Up @@ -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 */
Expand Down
5 changes: 5 additions & 0 deletions apps/theming/js/settings-admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
2 changes: 1 addition & 1 deletion apps/theming/lib/Command/UpdateConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

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 = [
Expand Down
5 changes: 5 additions & 0 deletions apps/theming/lib/Controller/ThemingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ public function updateStylesheet($setting, $value) {
$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([
Expand Down
1 change: 1 addition & 0 deletions apps/theming/lib/Settings/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public function getForm(): TemplateResponse {
'images' => $this->imageManager->getCustomImages(),
'imprintUrl' => $this->themingDefaults->getImprintUrl(),
'privacyUrl' => $this->themingDefaults->getPrivacyUrl(),
'userThemingDisabled' => $this->themingDefaults->isUserThemingDisabled(),
];

return new TemplateResponse($this->appName, 'settings-admin', $parameters, '');
Expand Down
7 changes: 6 additions & 1 deletion apps/theming/lib/Settings/Personal.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

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;
Expand All @@ -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 {
Expand All @@ -72,6 +76,7 @@ public function getForm(): TemplateResponse {

$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');
Expand Down
12 changes: 7 additions & 5 deletions apps/theming/lib/Themes/DefaultTheme.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,9 @@ public function getCSSVariables(): array {
$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)',
Expand Down Expand Up @@ -202,7 +200,9 @@ public function getCSSVariables(): array {
'--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
Expand All @@ -211,8 +211,9 @@ public function getCSSVariables(): array {
$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
Expand All @@ -237,10 +238,11 @@ public function getCSSVariables(): array {

$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')";
Expand Down
11 changes: 11 additions & 0 deletions apps/theming/lib/ThemingDefaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ public function getColorPrimary(): string {

// admin-defined primary color
$defaultColor = $this->getDefaultColorPrimary();

if ($this->isUserThemingDisabled()) {
return $defaultColor;
}

// user-defined primary color
$themingBackground = '';
Expand Down Expand Up @@ -494,4 +498,11 @@ public function undo($setting) {
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';
}
}
17 changes: 12 additions & 5 deletions apps/theming/src/UserThemes.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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)

Expand All @@ -109,6 +115,7 @@ export default {
shortcutsDisabled,
background,
themingDefaultBackground,
isUserThemingDisabled,
}
},

Expand Down
13 changes: 11 additions & 2 deletions apps/theming/templates/settings-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
<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>
Expand All @@ -93,7 +93,6 @@
</div>

<h3 class="inlineblock"><?php p($l->t('Advanced options')); ?></h3>

<div class="advanced-options">
<div>
<label>
Expand Down Expand Up @@ -131,6 +130,16 @@
<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">
Expand Down
2 changes: 1 addition & 1 deletion core/css/apps.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/css/apps.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ html {

body {
background-color: var(--color-main-background-plain, var(--color-main-background));
background-image: var(--image-main-background);
background-image: var(--image-background-plain, var(--image-main-background));
background-size: cover;
background-position: center;
position: fixed;
Expand Down
2 changes: 1 addition & 1 deletion core/css/server.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/comments-comments-app.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/files-sidebar.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-admin-basic-settings.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-personal-info.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/theming-theming-settings.js

Large diffs are not rendered by default.

Loading