From 938b9e212706ce9162ca660b55b16fbb4de01a89 Mon Sep 17 00:00:00 2001
From: BaranekD <0Baranek.dominik0@gmail.com>
Date: Wed, 15 Jun 2022 13:40:03 +0200
Subject: [PATCH] fix: Adds support for UserPassBase subclasses

---
 lib/Auth/Source/Campusidp.php                | 40 +++++++++++++++++---
 themes/campusThemes/default/_header.twig     |  4 +-
 themes/campusThemes/default/local-login.twig |  2 +-
 www/selectsource.php                         | 25 +++++++-----
 4 files changed, 53 insertions(+), 18 deletions(-)

diff --git a/lib/Auth/Source/Campusidp.php b/lib/Auth/Source/Campusidp.php
index a8880d9..e28619e 100644
--- a/lib/Auth/Source/Campusidp.php
+++ b/lib/Auth/Source/Campusidp.php
@@ -7,10 +7,12 @@ namespace SimpleSAML\Module\campusMultiauth\Auth\Source;
 use Exception;
 use SimpleSAML\Auth;
 use SimpleSAML\Auth\Source;
+use SimpleSAML\Auth\State;
 use SimpleSAML\Configuration;
 use SimpleSAML\Error;
 use SimpleSAML\Logger;
 use SimpleSAML\Module;
+use SimpleSAML\Module\core\Auth\UserPassBase;
 use SimpleSAML\Session;
 use SimpleSAML\Utils;
 
@@ -20,7 +22,7 @@ class Campusidp extends Source
     public const STAGEID_USERPASS = '\SimpleSAML\Module\core\Auth\UserPassBase.state';
     public const SOURCESID = '\SimpleSAML\Module\campusidp\Auth\Source\Campusidp.SourceId';
     public const SESSION_SOURCE = 'campusMultiauth:selectedSource';
-    public const WAYF_CONFIG = 'wayf_config';
+    public const USER_PASS_SOURCE_NAME = 'userPassSourceName';
     public const COOKIE_PREFIX = 'campusidp_';
     public const COOKIE_IDP_ENTITY_ID = 'idpentityid';
     public const COOKIE_INSTITUTION_NAME = 'institution_name';
@@ -30,13 +32,15 @@ class Campusidp extends Source
     public const COOKIE_PASSWORD = 'password';
 
     private $sources;
-    private $wayfConfig;
+    private $userPassSourceName;
 
 
     public function __construct($info, $config)
     {
         parent::__construct($info, $config);
 
+        $this->userPassSourceName = !empty($config['userPassSourceName']) ? $config['userPassSourceName'] : 'campus-userpass';
+
         if (!array_key_exists('sources', $config)) {
             throw new Exception('The required "sources" config option was not found');
         }
@@ -66,10 +70,10 @@ class Campusidp extends Source
     {
         $state[self::AUTHID] = $this->authId;
         $state[self::SOURCESID] = $this->sources;
-        $state[self::WAYF_CONFIG] = $this->wayfConfig;
+        $state[self::USER_PASS_SOURCE_NAME] = $this->userPassSourceName;
 
         // Save the $state array, so that we can restore if after a redirect
-        $id = Auth\State::saveState($state, self::STAGEID_USERPASS);
+        $id = State::saveState($state, self::STAGEID_USERPASS);
 
         /* Redirect to the select source page. We include the identifier of the
          * saved state array as a parameter to the login form
@@ -106,7 +110,33 @@ class Campusidp extends Source
         );
 
         try {
-            $as->authenticate($state);
+            if (!empty($_POST['username']) && !empty($_POST['password']) && is_subclass_of($as, '\SimpleSAML\Module\core\Auth\UserPassBase')) {
+                $state[UserPassBase::AUTHID] = $authId;
+
+                try {
+                    UserPassBase::handleLogin(
+                        State::saveState($state, UserPassBase::STAGEID),
+                        $_POST['username'],
+                        $_POST['password']
+                    );
+                } catch (\SimpleSAML\Error\Error $e) {
+                    if ($e->getMessage() === 'WRONGUSERPASS') {
+                        $id = State::saveState($state, self::STAGEID_USERPASS);
+                        $url = Module::getModuleURL('campusMultiauth/selectsource.php');
+                        $params = [
+                            'AuthState' => $id,
+                            'wrongUserPass' => true
+                        ];
+
+                        Utils\HTTP::redirectTrustedURL($url, $params);
+                    } else {
+                        throw $e;
+                    }
+                }
+
+            } else {
+                $as->authenticate($state);
+            }
         } catch (Error\Exception $e) {
             Auth\State::throwException($state, $e);
         } catch (Exception $e) {
diff --git a/themes/campusThemes/default/_header.twig b/themes/campusThemes/default/_header.twig
index a261764..980f408 100644
--- a/themes/campusThemes/default/_header.twig
+++ b/themes/campusThemes/default/_header.twig
@@ -1,4 +1,4 @@
-{% if wayf_config.languages is not defined %}
+{% if wayf_config is defined and wayf_config.languages is not defined %}
     {% set wayf_config = wayf_config|merge({'languages': {'en': 'English'}}) %}
 {% endif %}
 
@@ -66,7 +66,7 @@
             <img src="{% if wayf_config.logo is defined %}{{ wayf_config.logo }}{% endif %}" class="header-img-jvs" alt="{% if wayf_config.name is defined %}{{ wayf_config.name }}{% endif %}"/>
         </div>
     </header>
-{% else %}
+{% elseif wayf_config is defined %}
     <header class="header border-top border-primary border-5">
         <div class="header-container">
             {% if wayf_config.languages | length > 2 %}
diff --git a/themes/campusThemes/default/local-login.twig b/themes/campusThemes/default/local-login.twig
index eeb145f..051de0c 100644
--- a/themes/campusThemes/default/local-login.twig
+++ b/themes/campusThemes/default/local-login.twig
@@ -135,7 +135,7 @@
         {% endif %}
     </div>
     <input type="hidden" id="authstate" name="authstate" value="{{ authstate }}" />
-    <input type="hidden" id="source" name="source" value="campus-userpass" />
+    <input type="hidden" id="source" name="source" value="{{ user_pass_source_name }}" />
 </form>
 
 {% if wayf_config.css_framework is defined and wayf_config.css_framework == 'muni_jvs'  %}
diff --git a/www/selectsource.php b/www/selectsource.php
index bfaeb13..080ca55 100644
--- a/www/selectsource.php
+++ b/www/selectsource.php
@@ -34,16 +34,20 @@ if (array_key_exists('source', $_POST)) {
         $state['saml:idp'] = $_POST['idpentityid'];
         Campusidp::delegateAuthentication($_POST['source'], $state);
     } elseif (array_key_exists('username', $_POST) && array_key_exists('password', $_POST)) {
-        if (
-            array_key_exists('remember_me', $_POST) &&
-            $_POST['remember_me'] === 'Yes' &&
-            Configuration::getInstance()->getBoolean('session.rememberme.enable', false)
-        ) {
-            Campusidp::setCookie(Campusidp::COOKIE_USERNAME, $_POST['username']);
-            Campusidp::setCookie(Campusidp::COOKIE_PASSWORD, $_POST['password']);
-        }
+        if (empty($_POST['username']) || empty($_POST['password'])) {
+            $_REQUEST['wrongUserPass'] = true;
+        } else {
+            if (
+                array_key_exists('remember_me', $_POST) &&
+                $_POST['remember_me'] === 'Yes' &&
+                Configuration::getInstance()->getBoolean('session.rememberme.enable', false)
+            ) {
+                Campusidp::setCookie(Campusidp::COOKIE_USERNAME, $_POST['username']);
+                Campusidp::setCookie(Campusidp::COOKIE_PASSWORD, $_POST['password']);
+            }
 
-        Campusidp::delegateAuthentication($_POST['source'], $state);
+            Campusidp::delegateAuthentication($_POST['source'], $state);
+        }
     }
 }
 
@@ -82,7 +86,8 @@ $t->data['authstate'] = $authStateId;
 $t->data['currentUrl'] = htmlentities($_SERVER['PHP_SELF']);
 $t->data['wayf_config'] = $wayfConfig;
 $t->data['idps'] = $idps;
-$t->data['no_js_display_index'] = $_POST['componentIndex'];
+$t->data['no_js_display_index'] = !empty($_POST['componentIndex']) ? $_POST['componentIndex'] : null;
+$t->data['user_pass_source_name'] = $state[Campusidp::USER_PASS_SOURCE_NAME];
 $t->data['cookie_idpentityid'] = Campusidp::getCookie(Campusidp::COOKIE_IDP_ENTITY_ID);
 $t->data['cookie_institution_name'] = json_decode(Campusidp::getCookie(Campusidp::COOKIE_INSTITUTION_NAME), true);
 $t->data['cookie_institution_img'] = Campusidp::getCookie(Campusidp::COOKIE_INSTITUTION_IMG);
-- 
GitLab