From 8a224ca06b0e905228fe50a0971f09746e8b77a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Noack?= <noack@data-quest.de>
Date: Fri, 1 Dec 2023 10:46:53 +0000
Subject: [PATCH] =?UTF-8?q?Resolve=20#2751=20=20"GET-Requests=20f=C3=BCr?=
 =?UTF-8?q?=20Profileinstellungen=20in=20POST=20=C3=A4ndern"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #2751

Merge request studip/studip!1905
---
 lib/phplib/Seminar_Auth.class.php             |  2 +-
 lib/seminar_open.php                          |  6 +-
 public/index.php                              | 24 ++++----
 public/logout.php                             |  7 ++-
 .../assets/stylesheets/highcontrast.scss      |  5 +-
 .../assets/stylesheets/scss/buttons.scss      | 18 ++++--
 resources/assets/stylesheets/scss/index.scss  |  2 +-
 templates/index_nobody.php                    | 61 ++++++++++---------
 8 files changed, 72 insertions(+), 53 deletions(-)

diff --git a/lib/phplib/Seminar_Auth.class.php b/lib/phplib/Seminar_Auth.class.php
index c628e0a2683..e4f9e36495b 100644
--- a/lib/phplib/Seminar_Auth.class.php
+++ b/lib/phplib/Seminar_Auth.class.php
@@ -417,7 +417,7 @@ class Seminar_Auth
         $_language_path = init_i18n($_SESSION['_language']);
         include 'config.inc.php';
 
-        if (isset($_SESSION['contrast'])) {
+        if (!empty($_SESSION['contrast'])) {
             PageLayout::addStylesheet('accessibility.css');
         }
     }
diff --git a/lib/seminar_open.php b/lib/seminar_open.php
index e79d39c5645..c3e15c35fbc 100644
--- a/lib/seminar_open.php
+++ b/lib/seminar_open.php
@@ -101,8 +101,8 @@ if ($auth->is_authenticated() && is_object($user) && $user->id != "nobody") {
         if (UserConfig::get($user->id)->PERSONAL_STARTPAGE > 0 && $i_page == "index.php" && !$perm->have_perm("root")) {
             $seminar_open_redirected = TRUE;
         }
-        if (!empty($_SESSION['contrast'])) {
-            UserConfig::get($GLOBALS['user']->id)->store('USER_HIGH_CONTRAST', 1);
+        if (isset($_SESSION['contrast'])) {
+            UserConfig::get($GLOBALS['user']->id)->store('USER_HIGH_CONTRAST', $_SESSION['contrast']);
             unset($_SESSION['contrast']);
         }
         $user_did_login = true;
@@ -111,7 +111,7 @@ if ($auth->is_authenticated() && is_object($user) && $user->id != "nobody") {
     TwoFactorAuth::get()->secureSession();
 }
 
-if (isset($_SESSION['contrast']) || UserConfig::get($GLOBALS['user']->id)->USER_HIGH_CONTRAST) {
+if (!empty($_SESSION['contrast']) || UserConfig::get($GLOBALS['user']->id)->USER_HIGH_CONTRAST) {
     PageLayout::addStylesheet('accessibility.css');
 }
 
diff --git a/public/index.php b/public/index.php
index 429a35e9b0c..5ef37a7ea19 100644
--- a/public/index.php
+++ b/public/index.php
@@ -24,22 +24,24 @@ page_open(['sess' => 'Seminar_Session', 'auth' => 'Seminar_Default_Auth', 'perm'
 $auth->login_if(Request::get('again') && ($auth->auth['uid'] == 'nobody'));
 
 // if desired, switch to high contrast stylesheet and store when user logs in
-if (Request::get('unset_contrast')) {
-    unset($_SESSION['contrast']);
-}
-if (Request::get('set_contrast') ) {
-    $_SESSION['contrast'] = true;
-}
+if (Request::submitted('user_config_submitted')) {
+    CSRFProtection::verifyUnsafeRequest();
+    if (Request::submitted('unset_contrast')) {
+        $_SESSION['contrast'] = 0;
+    }
+    if (Request::submitted('set_contrast')) {
+        $_SESSION['contrast'] = 1;
+    }
 
 // evaluate language clicks
 // has to be done before seminar_open to get switching back to german (no init of i18n at all))
-if (Request::get('set_language')) {
-    if(array_key_exists(Request::get('set_language'), $GLOBALS['INSTALLED_LANGUAGES'])) {
-        $_SESSION['forced_language'] = Request::get('set_language');
-        $_SESSION['_language'] = Request::get('set_language');
+    foreach (array_keys($GLOBALS['INSTALLED_LANGUAGES']) as $language_key) {
+        if (Request::submitted('set_language_' . $language_key)) {
+            $_SESSION['forced_language'] = $language_key;
+            $_SESSION['_language'] = $language_key;
+        }
     }
 }
-
 // store user-specific language preference
 if ($auth->is_authenticated() && $user->id != 'nobody') {
     // store last language click
diff --git a/public/logout.php b/public/logout.php
index a4064ded7fd..e18a8586fe5 100644
--- a/public/logout.php
+++ b/public/logout.php
@@ -62,9 +62,14 @@ if ($auth->auth["uid"]!="nobody") {
     if (!empty($docaslogout)) {
         $casauth->logout();
     }
+    $sess->start();
+    $_SESSION['_language'] = $_language;
+    if ($contrast) {
+        $_SESSION['contrast'] = $contrast;
+    }
 } else {
     $sess->delete();
     page_close();
 }
 
-header("Location:" . URLHelper::getURL("index.php?logout=true&set_language=$_language&set_contrast=$contrast"));
+header("Location:" . URLHelper::getURL("index.php?logout=true"));
diff --git a/resources/assets/stylesheets/highcontrast.scss b/resources/assets/stylesheets/highcontrast.scss
index 0d240d83bc6..85c5159c2cb 100644
--- a/resources/assets/stylesheets/highcontrast.scss
+++ b/resources/assets/stylesheets/highcontrast.scss
@@ -1547,5 +1547,8 @@ button.skiplink {
             }
         }
     }
-
+}
+button.as-link {
+    text-decoration: underline;
+    color: $contrast-blue;
 }
diff --git a/resources/assets/stylesheets/scss/buttons.scss b/resources/assets/stylesheets/scss/buttons.scss
index 539a2a3e0c4..f29a983cc90 100644
--- a/resources/assets/stylesheets/scss/buttons.scss
+++ b/resources/assets/stylesheets/scss/buttons.scss
@@ -141,14 +141,20 @@ button.styleless {
     background-color: unset;
     border: 0;
 }
+
 button.as-link {
+    border: 0;
     background-color: transparent;
-    border: none;
-    color: $base-color;
+    color: var(--base-color);
     cursor: pointer;
-    margin: 0px;
-    padding: 0px;
-    &:hover {
-        color: $active-color;
+    line-height: 1em;
+    padding: 0;
+    &:hover,
+    &:active {
+        color: var(--active-color);
+    }
+
+    @media not prefers-reduced-motion {
+        transition: color $transition-duration;
     }
 }
diff --git a/resources/assets/stylesheets/scss/index.scss b/resources/assets/stylesheets/scss/index.scss
index a1b55c478e4..4d4ecbf868c 100644
--- a/resources/assets/stylesheets/scss/index.scss
+++ b/resources/assets/stylesheets/scss/index.scss
@@ -87,7 +87,7 @@ $gap-between-boxes: calc($login-page-margin / 2);
             font-size: 0.9em;
             padding: 10px;
 
-            a {
+            button {
                 text-decoration: underline;
             }
         }
diff --git a/templates/index_nobody.php b/templates/index_nobody.php
index 519f2e18695..6e857eb63c3 100644
--- a/templates/index_nobody.php
+++ b/templates/index_nobody.php
@@ -62,28 +62,31 @@ if ($bg_mobile) {
                     <?= $GLOBALS['UNI_LOGIN_ADD'] ?>
                 </div>
             <? endif; ?>
-
-            <div id="languages">
-                <? foreach ($GLOBALS['INSTALLED_LANGUAGES'] as $temp_language_key => $temp_language): ?>
-                    <?= Assets::img('languages/' . $temp_language['picture'], ['alt' => $temp_language['name'], 'size' => '24']) ?>
-                    <a href="index.php?set_language=<?= $temp_language_key ?>">
-                        <?= htmlReady($temp_language['name']) ?>
-                    </a>
-                <? endforeach; ?>
-            </div>
-
-            <div id="contrast">
-                <? if (isset($_SESSION['contrast'])) : ?>
-                    <?= Icon::create('accessibility')->asImg(24) ?>
-                    <a href="index.php?unset_contrast=1"><?= _('Normalen Kontrast aktivieren') ?></a>
-                    <?= tooltipIcon(_('Aktiviert standardmäßige, nicht barrierefreie Kontraste.')); ?>
-                <? else : ?>
-                    <?= Icon::create('accessibility')->asImg(24) ?>
-                    <a href="index.php?set_contrast=1" id="highcontrastlink"><?= _('Hohen Kontrast aktivieren')?></a>
-                    <?= tooltipIcon(_('Aktiviert einen hohen Kontrast gemäß WCAG 2.1. Diese Einstellung wird nach dem Login übernommen.
-                    Sie können sie in Ihren persönlichen Einstellungen ändern.')); ?>
-                <? endif ?>
-            </div>
+            <form method="POST" action="index.php">
+                <?=CSRFProtection::tokenTag()?>
+                <input type="hidden" name="user_config_submitted" value="1">
+                <div id="languages">
+                    <? foreach ($GLOBALS['INSTALLED_LANGUAGES'] as $temp_language_key => $temp_language): ?>
+                        <?= Assets::img('languages/' . $temp_language['picture'], ['alt' => $temp_language['name'], 'size' => '24']) ?>
+                        <button class="as-link" name="set_language_<?=$temp_language_key?>">
+                            <?= htmlReady($temp_language['name']) ?>
+                        </button>
+                    <? endforeach; ?>
+                </div>
+                <div id="contrast">
+                    <?=CSRFProtection::tokenTag()?>
+                    <? if (!empty($_SESSION['contrast'])) : ?>
+                        <?= Icon::create('accessibility')->asImg(24) ?>
+                        <button class="as-link" name="unset_contrast"><?= _('Normalen Kontrast aktivieren') ?></button>
+                        <?= tooltipIcon(_('Aktiviert standardmäßige, nicht barrierefreie Kontraste.')); ?>
+                    <? else : ?>
+                        <?= Icon::create('accessibility')->asImg(24) ?>
+                        <button class="as-link" name="set_contrast"><?= _('Hohen Kontrast aktivieren') ?></button>
+                        <?= tooltipIcon(_('Aktiviert einen hohen Kontrast gemäß WCAG 2.1. Diese Einstellung wird nach dem Login übernommen.
+                        Sie können sie in Ihren persönlichen Einstellungen ändern.')); ?>
+                    <? endif ?>
+                </div>
+            </form>
 
             <div class="login_info">
                 <div>
@@ -110,11 +113,11 @@ if ($bg_mobile) {
         </footer>
     </article>
 
-<? if (count($plugin_contents) > 0): ?>
-    <div id="login-plugin-contents">
-    <? foreach ($plugin_contents as $content): ?>
-        <?= $content ?>
-    <? endforeach; ?>
-    </div>
-<? endif; ?>
+    <? if (count($plugin_contents) > 0): ?>
+        <div id="login-plugin-contents">
+            <? foreach ($plugin_contents as $content): ?>
+                <?= $content ?>
+            <? endforeach; ?>
+        </div>
+    <? endif; ?>
 </main>
-- 
GitLab