summaryrefslogtreecommitdiffstats
path: root/modules-available
diff options
context:
space:
mode:
authorSimon Rettberg2024-07-16 14:42:38 +0200
committerSimon Rettberg2024-07-16 14:42:38 +0200
commit74dff6a6961e19b1f02614fa5161d5262af875a7 (patch)
tree95439d0772865f56de817f575c6df280c2cb3ff6 /modules-available
parent[sysconfig] shibauth: Add field to enable/disable traditional login (diff)
downloadslx-admin-74dff6a6961e19b1f02614fa5161d5262af875a7.tar.gz
slx-admin-74dff6a6961e19b1f02614fa5161d5262af875a7.tar.xz
slx-admin-74dff6a6961e19b1f02614fa5161d5262af875a7.zip
[sysconfig] Add module to customize login screen (slxgreeter)
Diffstat (limited to 'modules-available')
-rw-r--r--modules-available/sysconfig/addmodule_loginscreen.inc.php143
-rw-r--r--modules-available/sysconfig/inc/configmodule/loginscreen.inc.php86
-rw-r--r--modules-available/sysconfig/lang/de/config-module.json3
-rw-r--r--modules-available/sysconfig/lang/de/messages.json1
-rw-r--r--modules-available/sysconfig/lang/de/module.json12
-rw-r--r--modules-available/sysconfig/lang/de/template-tags.json3
-rw-r--r--modules-available/sysconfig/lang/en/config-module.json3
-rw-r--r--modules-available/sysconfig/lang/en/messages.json1
-rw-r--r--modules-available/sysconfig/lang/en/module.json12
-rw-r--r--modules-available/sysconfig/lang/en/template-tags.json3
-rw-r--r--modules-available/sysconfig/templates/loginscreen-start.html38
11 files changed, 303 insertions, 2 deletions
diff --git a/modules-available/sysconfig/addmodule_loginscreen.inc.php b/modules-available/sysconfig/addmodule_loginscreen.inc.php
new file mode 100644
index 00000000..c2867834
--- /dev/null
+++ b/modules-available/sysconfig/addmodule_loginscreen.inc.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * Wizard for configuring login screen (lightdm greeter)
+ */
+
+const SCRN_SESSION_DATA = 'lgnscrndata';
+
+const FIELDS = [
+ 'clock-text-style' => ['default' => 'border:none; color:#fff; font-size:14pt; qproperty-alignment:AlignRight'],
+ 'clock-background-style' => ['default' => 'border:none; background:#888687'],
+ 'clock-shadow' => ['default' => '1 1 #555 1', 'regex' => '\s*([0-9-]+(\s+[0-9-]+(\s+[#0-9a-zA-Z]+(\s+[0-9-]+)?)?)?)?\s*'],
+ 'username-placeholder' => ['default' => 'user id'],
+ 'password-placeholder' => ['default' => 'password'],
+ 'shib-session-button-text' => ['default' => 'Shibboleth-Login'],
+ 'qr-session-button-text' => ['default' => 'QR-Code Login'],
+ 'user-session-button-text' => ['default' => 'Campus-Login'],
+ 'guest-session-button-text' => ['default' => 'Gastsitzung'],
+ 'guest-session-start-text' => ['default' => 'Gast-Sitzungen sind möglicherweise auf einzelne' .
+ ' (z.B. ausschließlich interne) Webseiten beschränkt.'],
+ 'guest-session-start-button-text' => ['default' => 'Starten einer Gastsitzung'],
+ 'reset-timeout' => ['default' => 30, 'regex' => '[0-9]*'],
+];
+
+/* For translation scanner
+ Dictionary::translate('ls_clock-text-style'),
+ Dictionary::translate('ls_clock-background-style'),
+ Dictionary::translate('ls_clock-shadow'),
+ Dictionary::translate('ls_username-placeholder'),
+ Dictionary::translate('ls_password-placeholder'),
+ Dictionary::translate('ls_shib-session-button-text'),
+ Dictionary::translate('ls_qr-session-button-text'),
+ Dictionary::translate('ls_user-session-button-text'),
+ Dictionary::translate('ls_guest-session-button-text'),
+ Dictionary::translate('ls_guest-session-start-text'),
+ Dictionary::translate('ls_guest-session-start-button-text'),
+ Dictionary::translate('ls_reset-timeout'),
+*/
+
+class LoginScreen_Start extends AddModule_Base
+{
+
+ protected function renderInternal()
+ {
+ /* Load or initialise session data */
+ if (Request::get('back', 'false', 'string') !== 'false') {
+ /* If coming via the back button, load the session data */
+ $session_data = Session::get(SCRN_SESSION_DATA);
+ if (!is_array($session_data)) {
+ $session_data = [];
+ }
+ } elseif ($this->edit !== null) {
+ $session_data = $this->edit->getData(null);
+ Session::set(SCRN_SESSION_DATA, $session_data);
+ } else {
+ $session_data = [];
+ Session::set(SCRN_SESSION_DATA, false);
+ }
+ if (empty($session_data)) {
+ $session_data = [];
+ foreach (FIELDS as $key => $value) {
+ $session_data[$key] = $value['default'];
+ }
+ }
+ $data = [];
+ foreach (FIELDS as $key => $opts) {
+ $data[] = [
+ 'field' => $key,
+ 'value' => $session_data[$key] ?? '',
+ 'caption' => Dictionary::translate('ls_' . $key),
+ 'regex' => $opts['regex'] ?? null,
+ ];
+ }
+ Render::addDialog(Dictionary::translateFile('config-module', 'loginscreen_title'),
+ false, 'loginscreen-start', [
+ 'next' => 'LoginScreen_Finish',
+ 'edit' => $this->edit !== null ? $this->edit->id() : 0,
+ 'fields' => $data,
+ 'title' => $this->edit->title(),
+ ]);
+ }
+
+}
+
+class LoginScreen_Finish extends AddModule_Base
+{
+
+ protected function preprocessInternal()
+ {
+ $title = trim(Request::post('title', '', 'string'));
+ if (empty($title)) {
+ Util::redirect('?do=sysconfig&action=addmodule&step=LoginScreen_Start&back=true');
+ }
+ $session_data = Session::get(SCRN_SESSION_DATA);
+ if (!is_array($session_data)) {
+ $session_data = [];
+ }
+ $session_data['title'] = $title;
+
+ /* Only create an instance if it's a new one */
+ if ($this->edit !== null) {
+ $module = $this->edit;
+ } else {
+ $module = ConfigModule::getInstance('LoginScreen');
+ }
+
+ $err = false;
+ foreach (FIELDS as $key => $field) {
+ $val = Request::post($key, '', 'string');
+ if (isset($field['regex']) && !preg_match("/{$field['regex']}/", $val)) {
+ Message::addError('regex-mismatch', $val, $field['regex']);
+ $err = true;
+ }
+ $session_data[$key] = $val;
+ $module->setData($key, $val);
+ }
+ if ($err) {
+ Session::set(SCRN_SESSION_DATA, $session_data);
+ Util::redirect('?do=sysconfig&action=addmodule&step=LoginScreen_Start&back=true');
+ }
+
+ /* Insert or update database entries */
+ if ($this->edit !== null) {
+ $module->update($session_data['title']);
+ } else {
+ $module->insert($session_data['title']);
+ }
+
+ $task = $module->generate($this->edit === null);
+
+ // Yay
+ Session::set(SCRN_SESSION_DATA, false);
+ if ($task !== false && $this->edit !== null) {
+ Message::addSuccess('module-edited');
+ } elseif ($task !== false) {
+ Message::addSuccess('module-added');
+ AddModule_Base::setStep('AddModule_Assign', $module->id());
+ return;
+ }
+ Util::redirect('?do=SysConfig');
+ }
+
+} \ No newline at end of file
diff --git a/modules-available/sysconfig/inc/configmodule/loginscreen.inc.php b/modules-available/sysconfig/inc/configmodule/loginscreen.inc.php
new file mode 100644
index 00000000..1ceb2c32
--- /dev/null
+++ b/modules-available/sysconfig/inc/configmodule/loginscreen.inc.php
@@ -0,0 +1,86 @@
+<?php
+
+ConfigModule::registerModule(
+ ConfigModule_LoginScreen::MODID, // ID
+ Dictionary::translateFile('config-module', 'loginscreen_title'), // Title
+ Dictionary::translateFile('config-module', 'loginscreen_description'), // Description
+ Dictionary::translateFile('config-module', 'group_loginscreen'), // Group
+ true, // Only one per config?
+ 310 // Sort order
+);
+
+class ConfigModule_LoginScreen extends ConfigModule
+{
+ const MODID = 'LoginScreen';
+ const VERSION = 1;
+
+ const VALID_FIELDS = [
+ 'clock-text-style',
+ 'clock-background-style',
+ 'clock-shadow',
+ 'username-placeholder',
+ 'password-placeholder',
+ 'shib-session-button-text',
+ 'qr-session-button-text',
+ 'user-session-button-text',
+ 'guest-session-button-text',
+ 'guest-session-start-text',
+ 'guest-session-start-button-text',
+ 'reset-timeout',
+ ];
+
+ protected function generateInternal(string $tgz, ?string $parent)
+ {
+ /* Validate if all data are available */
+ if (!$this->validateConfig())
+ return false;
+
+ return Taskmanager::submit('MakeTarball', array(
+ 'files' => $this->getFileArray(),
+ 'destination' => $tgz,
+ 'parentTask' => $parent,
+ ), false);
+ }
+
+ protected function moduleVersion(): int
+ {
+ return self::VERSION;
+ }
+
+ protected function validateConfig(): bool
+ {
+ return true;
+ }
+
+ public function setData(string $key, $value): bool
+ {
+ if (!in_array($key, self::VALID_FIELDS))
+ return false;
+ $this->moduleData[$key] = $value;
+ return true;
+ }
+
+ public function allowDownload(): bool
+ {
+ return false;
+ }
+
+ /**
+ * Creates a map with filepath => file content
+ * @return array{"/etc/lightdm/qt-lightdm-greeter.conf.d/80-$id-customization.conf": string}
+ */
+ private function getFileArray(): array
+ {
+ $id = $this->id();
+ $content = "[General]\n";
+ foreach (self::VALID_FIELDS as $field) {
+ if (!isset($this->moduleData[$field]))
+ continue;
+ $content .= $field . '=' . $this->moduleData[$field] . "\n";
+ }
+ return [
+ "/etc/lightdm/qt-lightdm-greeter.conf.d/80-$id-customization.conf" => $content,
+ ];
+ }
+
+}
diff --git a/modules-available/sysconfig/lang/de/config-module.json b/modules-available/sysconfig/lang/de/config-module.json
index 6d38565b..80eb852a 100644
--- a/modules-available/sysconfig/lang/de/config-module.json
+++ b/modules-available/sysconfig/lang/de/config-module.json
@@ -8,11 +8,14 @@
"group_authentication": "Authentifizierung",
"group_branding": "Einrichtungsspezifisches Logo",
"group_generic": "Generisch",
+ "group_loginscreen": "Anmeldebildschirm Styling",
"group_screensaver": "Bildschirmschoner Styling",
"group_sshconfig": "SSH-D\u00e4mon",
"group_sshkey": "SSH-Key",
"ldapAuth_description": "Mit diesem Modul l\u00e4sst sich eine generische LDAP-Authentifizierung einrichten.",
"ldapAuth_title": "LDAP-Authentifizierung",
+ "loginscreen_description": "Mit diesem Module k\u00f6nnen Sie Texte und einige Einstellungen des Anmeldebildschirms anpassen.",
+ "loginscreen_title": "Design\/Texte Anmeldebildschrim",
"screensaver_description": "Mit diesem Modul k\u00f6nnen sie den Style (QSS) und die Texte des Bildschirmschoners anpassen.",
"screensaver_title": "Design\/Texte Bildschirmschoner",
"shibauth_description": "Mit diesem Modul l\u00e4sst sich die Authentifizierung mittels Shibboleth\/SSO am Client einrichten.",
diff --git a/modules-available/sysconfig/lang/de/messages.json b/modules-available/sysconfig/lang/de/messages.json
index 5e8423df..81cdb0f9 100644
--- a/modules-available/sysconfig/lang/de/messages.json
+++ b/modules-available/sysconfig/lang/de/messages.json
@@ -16,6 +16,7 @@
"no-noconfig-active": "Es wurde noch keine Systemkonfiguration ausgew\u00e4hlt",
"no-organization-selected": "Keine Organisation ausgew\u00e4hlt",
"no-session-data": "Keine Sitzungsdaten zum Editieren. Bitte erneut beginnen.",
+ "regex-mismatch": "Regex stimmt nicht \u00fcberein: {{0}} -> {{1}}",
"remote-timeout": "Konnte Ressource {{0}} nicht herunterladen ({{1}})",
"replacing-config": "Ersetzen von Konfiguration {{0}}",
"replacing-module": "Ersetzen von Modul {{0}}",
diff --git a/modules-available/sysconfig/lang/de/module.json b/modules-available/sysconfig/lang/de/module.json
index 3d244bf3..71eb70cc 100644
--- a/modules-available/sysconfig/lang/de/module.json
+++ b/modules-available/sysconfig/lang/de/module.json
@@ -6,6 +6,18 @@
"lang_noModuleFromThisGroup": "(Kein Modul dieser Gruppe)",
"lang_unknwonTaskManager": "Unbekannter Taskmanager-Fehler",
"location-column-header": "Lokalisierung",
+ "ls_clock-background-style": "Hintergrund-Style (QSS) f\u00fcr die Statusleiste der Uhr (oben)",
+ "ls_clock-shadow": "Schatten der Uhrzeit (X-Versatz, Y-Versatz, Farbe, Unsch\u00e4rfe)",
+ "ls_clock-text-style": "Style (QSS) f\u00fcr die Uhrzeit (oben)",
+ "ls_guest-session-button-text": "Beschriftung der Schaltfl\u00e4che, mit der die Gastsitzung ausgew\u00e4hlt wird",
+ "ls_guest-session-start-button-text": "Beschriftung der Schaltfl\u00e4che, mit der die Gastsitzung gestartet wird",
+ "ls_guest-session-start-text": "Hinweistext \u00fcber der Gastsitzungsstartschaltfl\u00e4che",
+ "ls_password-placeholder": "Platzhalter f\u00fcr das Kennwortseingabefeld",
+ "ls_qr-session-button-text": "Beschriftung der Schaltfl\u00e4che, mit der der Login via QR-Code ausgew\u00e4hlt wird",
+ "ls_reset-timeout": "Zeit in Sekunden, nach der bei Inaktivit\u00e4t wieder zur Auswahl zur\u00fcckgekehrt wird",
+ "ls_shib-session-button-text": "Beschriftung der Schaltfl\u00e4che, mit der der Login via Shibboleth\/bwIDM ausgew\u00e4hlt wird",
+ "ls_user-session-button-text": "Beschriftung der Schaltfl\u00e4che, mit der der Login via einfacher Nutzer\/Kennwort-Maske ausgew\u00e4hlt wird",
+ "ls_username-placeholder": "Platzhalter f\u00fcr das Nutzernamenseingabefeld",
"module_name": "Lokalisierung + Integration",
"page_title": "Lokalisierung + Integration",
"saver_DescriptionIdleKill": "Wenn der Bildschirmschoner aktiv ist, und ein gesetztes Inaktivit\u00e4tstimeout bevorsteht, wird dieser Text unter dem Countdown angezeigt. Sie k\u00f6nnen den Text unterschiedlich formulieren abh\u00e4ngig davon, ob zum Beenden des Bildschirmschoners das Nutzerpassword eingegeben werden muss.",
diff --git a/modules-available/sysconfig/lang/de/template-tags.json b/modules-available/sysconfig/lang/de/template-tags.json
index fd268ead..ff7215c7 100644
--- a/modules-available/sysconfig/lang/de/template-tags.json
+++ b/modules-available/sysconfig/lang/de/template-tags.json
@@ -67,6 +67,7 @@
"lang_legend": "Legende",
"lang_listenPort": "Listen port",
"lang_listenPortInfo": "Der Port, auf dem der sshd lauscht. Der offizielle Standard ist 22.",
+ "lang_loginScreenIntroText": "Hiermit lassen sich Texte sowie einige Einstellungen des Anmeldebildschirms anpassen.",
"lang_mapModeNative": "Nativ direkt in der VM einbinden [openslx.exe]",
"lang_mapModeNativeFallback": "Nativ in der VM einbinden; Fallback auf VMware Shared Folders",
"lang_mapModeNone": "Verzeichnisse nicht durchreichen",
@@ -96,7 +97,7 @@
"lang_onProblemSearchBase": "Werden keine Benutzer gefunden, dann \u00fcberpr\u00fcfen Sie bitte die Suchbasis",
"lang_or": "oder",
"lang_pwlogin_user_only": "Alle au\u00dfer root",
- "lang_qssInfoText": "QSS sind Qt-spezifische Stylesheets, die an CSS angelehnt sind. Damit ist es m\u00f6glich, das Design des Bildschirmschoners anzupassen.",
+ "lang_qssInfoText": "QSS sind Qt-spezifische Stylesheets, die an CSS angelehnt sind. Damit ist es m\u00f6glich, das Design anzupassen.",
"lang_rebuild": "Neu generieren",
"lang_rebuildLong": "Modul oder Konfiguration neu generieren. Das entsprechende Modul bzw. Konfiguration ist aktuell und sollte nicht neu generiert werden m\u00fcssen.",
"lang_rebuildOutdatedLong": "Modul oder Konfiguration neu generieren. Das entsprechende Modul bzw. Konfiguration ist veraltet oder nicht vorhanden.",
diff --git a/modules-available/sysconfig/lang/en/config-module.json b/modules-available/sysconfig/lang/en/config-module.json
index bd7f1803..7c17cf80 100644
--- a/modules-available/sysconfig/lang/en/config-module.json
+++ b/modules-available/sysconfig/lang/en/config-module.json
@@ -8,11 +8,14 @@
"group_authentication": "Authentication",
"group_branding": "Branding",
"group_generic": "Generic",
+ "group_loginscreen": "Login screen styling",
"group_screensaver": "Screen saver styling",
"group_sshconfig": "SSH config",
"group_sshkey": "SSH key",
"ldapAuth_description": "This module enables you to create a simple LDAP authentication module.",
"ldapAuth_title": "LDAP authentication",
+ "loginscreen_description": "Here you can customize texts and labels of the login screen, as well as a few settings.",
+ "loginscreen_title": "Login screen customization",
"screensaver_description": "With this module you can customize the style (QSS) and texts of the screensaver.",
"screensaver_title": "Screensaver customization",
"shibauth_description": "Using this module you can enable Shibboleth\/SSO login on the client.",
diff --git a/modules-available/sysconfig/lang/en/messages.json b/modules-available/sysconfig/lang/en/messages.json
index e74a0e61..ea20695d 100644
--- a/modules-available/sysconfig/lang/en/messages.json
+++ b/modules-available/sysconfig/lang/en/messages.json
@@ -16,6 +16,7 @@
"no-noconfig-active": "No system configuration created\/selected yet.",
"no-organization-selected": "No irganization selected",
"no-session-data": "No session data, please start over",
+ "regex-mismatch": "Regex mismatch: {{0}} -> {{1}}",
"remote-timeout": "Could not download resource {{0}} ({{1}})",
"replacing-config": "Replace config {{0}}",
"replacing-module": "Replace module {{0}}",
diff --git a/modules-available/sysconfig/lang/en/module.json b/modules-available/sysconfig/lang/en/module.json
index c65cad28..3a379660 100644
--- a/modules-available/sysconfig/lang/en/module.json
+++ b/modules-available/sysconfig/lang/en/module.json
@@ -6,6 +6,18 @@
"lang_noModuleFromThisGroup": "(No module from this group)",
"lang_unknwonTaskManager": "Unknown Task Manager error",
"location-column-header": "SysConfig",
+ "ls_clock-background-style": "Background style (QSS) for the status bar of the clock (top)",
+ "ls_clock-shadow": "Shadow of the clock (X-offset, Y-offset, color, blur)",
+ "ls_clock-text-style": "Style (QSS) for the clock time (top)",
+ "ls_guest-session-button-text": "Label of the button to select the guest session",
+ "ls_guest-session-start-button-text": "Label of the button to start the guest session",
+ "ls_guest-session-start-text": "Hint above the guest session start button",
+ "ls_password-placeholder": "Placeholder for the password input field",
+ "ls_qr-session-button-text": "Label of the button to select login via QR code",
+ "ls_reset-timeout": "Time in seconds after which it returns to the selection screen due to inactivity",
+ "ls_shib-session-button-text": "Label of the button to select login via Shibboleth\/bwIDM",
+ "ls_user-session-button-text": "Label of the button to select login via simple user\/password mask",
+ "ls_username-placeholder": "Placeholder for the username input field",
"module_name": "Localization",
"page_title": "Localize and integrate",
"saver_DescriptionIdleKill": "If the screen saver is active and a set inactivity timeout is pending, this text is displayed below the countdown. You can phrase the text differently depending on whether the user's password must be entered to unlock the screensaver. ",
diff --git a/modules-available/sysconfig/lang/en/template-tags.json b/modules-available/sysconfig/lang/en/template-tags.json
index 615d38d9..c20db1fc 100644
--- a/modules-available/sysconfig/lang/en/template-tags.json
+++ b/modules-available/sysconfig/lang/en/template-tags.json
@@ -67,6 +67,7 @@
"lang_legend": "Legend",
"lang_listenPort": "Listen port",
"lang_listenPortInfo": "Listen port for the sshd. Default is 22.",
+ "lang_loginScreenIntroText": "Here you can customize texts\/labels of the login screen, as well as a few settings.",
"lang_mapModeNative": "Natively map inside the VM [openslx.exe]",
"lang_mapModeNativeFallback": "Natively map inside VM; fallback to VMware Shared Folders",
"lang_mapModeNone": "Don't map shares at all",
@@ -96,7 +97,7 @@
"lang_onProblemSearchBase": "If no users are found, please check the search base",
"lang_or": "or",
"lang_pwlogin_user_only": "Everyone except root",
- "lang_qssInfoText": "QSS are Qt-specific style sheets, similar to CSS. You can use it to customize the general design of the screensaver.",
+ "lang_qssInfoText": "QSS are Qt-specific style sheets, similar to CSS. You can use it to customize the general design.",
"lang_rebuild": "Rebuild",
"lang_rebuildLong": "Rebuild module or configuration.",
"lang_rebuildOutdatedLong": "Rebuild module or configuration. The module\/configuration is outdated or missing and should be regenerated.",
diff --git a/modules-available/sysconfig/templates/loginscreen-start.html b/modules-available/sysconfig/templates/loginscreen-start.html
new file mode 100644
index 00000000..e5c8a13e
--- /dev/null
+++ b/modules-available/sysconfig/templates/loginscreen-start.html
@@ -0,0 +1,38 @@
+<form role="form" method="post" action="?do=SysConfig&amp;action=addmodule&amp;step={{next}}">
+<input type="hidden" name="token" value="{{token}}">
+<input type="hidden" name="edit" value="{{edit}}">
+
+<div>{{lang_loginScreenIntroText}}</div>
+<div class="slx-space"></div>
+
+<div class="input-group">
+ <span class="input-group-addon">{{lang_moduleTitle}}</span>
+ <input tabindex="1" name="title" value="{{title}}" type="text" class="form-control" autofocus required>
+</div>
+<div class="slx-space"></div>
+
+{{#fields}}
+ <div class="slx-smallspace"></div>
+<div>
+ <label for="id-{{field}}">{{caption}}</label>
+ <input id="id-{{field}}" name="{{field}}" value="{{value}}" type="text" class="form-control" {{#regex}}pattern="{{regex}}"{{/regex}}>
+</div>
+{{/fields}}
+
+<div class="slx-space"></div>
+
+<div>
+ <i>{{lang_qssInfoText}}</i>
+</div>
+<div class="slx-space">
+ <a href="https://www.bwlehrpool.de/wiki/doku.php/satellite/qss" target="_blank">
+ QSS
+ <span class="glyphicon glyphicon-new-window"></span>
+ </a>
+</div>
+
+<div class="pull-right">
+ <button type="submit" class="btn btn-primary">{{lang_next}} &raquo;</button>
+</div>
+<div class="clearfix"></div>
+</form> \ No newline at end of file