From a060b549bad3c5e18ed9587f0a661fb8d54e31fd Mon Sep 17 00:00:00 2001 From: rstefko Date: Thu, 12 Oct 2023 21:14:25 +0200 Subject: [PATCH 1/8] Also logout from OIDC, fixed redirect URL (need trailing slash) --- roundcube_oidc.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index 9f415fa..63b885f 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -23,6 +23,7 @@ function init() { $this->load_config('config.inc.php.dist'); $this->load_config('config.inc.php'); $this->add_hook('template_object_loginform', array($this, 'loginform')); + $this->add_hook('logout_after', array($this, 'logout_after')); } function altReturn($ERROR) { @@ -39,6 +40,19 @@ function altReturn($ERROR) { } } + function logout_after() { + $RCMAIL = rcmail::get_instance(); + + $oidc = new OpenIDConnectClient( + $RCMAIL->config->get('oidc_url'), + $RCMAIL->config->get('oidc_client'), + $RCMAIL->config->get('oidc_secret') + ); + + // TODO: We could save idToken during login and use it here + $oidc->signOut(null, null); + } + public function loginform($content) { // Add the login link $content['content'] .= "

Login with OIDC

"; @@ -65,6 +79,7 @@ public function loginform($content) { $RCMAIL->config->get('oidc_client'), $RCMAIL->config->get('oidc_secret') ); + $oidc->setRedirectURL($oidc->getRedirectURL() . '/'); $oidc->addScope($RCMAIL->config->get('oidc_scope')); // Get user information @@ -83,6 +98,12 @@ public function loginform($content) { $password = get($user[$RCMAIL->config->get('oidc_field_password')], $password); $imap_server = get($user[$RCMAIL->config->get('oidc_field_server')], $imap_server); + if (!$uid) { + $content['content'] .= "

User ID (mail) not provided.

"; + $this->altReturn($ERROR); + return $content; + } + // Check if master user is present $master = $RCMAIL->config->get('oidc_config_master_user'); if ($master != '') { From d78a7ad26929b4b2a82e5a3b1d97995f1fddc9ef Mon Sep 17 00:00:00 2001 From: rstefko Date: Thu, 12 Oct 2023 22:33:14 +0200 Subject: [PATCH 2/8] Set also mail during login. Fixed identity update. --- roundcube_oidc.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index 63b885f..242f28b 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -95,6 +95,7 @@ public function loginform($content) { // Parse fields $uid = $user[$RCMAIL->config->get('oidc_field_uid')]; + $mail = $uid; $password = get($user[$RCMAIL->config->get('oidc_field_password')], $password); $imap_server = get($user[$RCMAIL->config->get('oidc_field_server')], $imap_server); @@ -120,6 +121,19 @@ public function loginform($content) { // Login to IMAP if ($RCMAIL->login($auth['user'], $password, $imap_server, $auth['cookiecheck'])) { + // Update user profile + $iid = $RCMAIL->user->get_identity()['identity_id']; + if (isset($iid)) { + $data = array('email' => $mail); + + $claim_name = $user['name']; + if (isset($claim_name)) { + $data['name'] = $claim_name; + } + + $RCMAIL->user->update_identity($iid, $data); + } + $RCMAIL->session->remove('temp'); $RCMAIL->session->regenerate_id(false); $RCMAIL->session->set_auth_cookie(); @@ -132,13 +146,6 @@ public function loginform($content) { $redir = $RCMAIL->plugins->exec_hook('login_after', $query + array('_task' => 'mail')); $RCMAIL->session->set_auth_cookie(); - // Update user profile - $iid = $RCMAIL->user->get_identity()['identity_id']; - $claim_name = $user['name']; - if (isset($iid) && isset($claim_name)) { - $RCMAIL->user->update_identity($iid, array('name' => $claim_name)); - } - $OUTPUT->redirect($redir, 0, true); } else { $ERROR = 'IMAP authentication failed!'; From 2a8463150dec3401aff5d641357bb710c25ada78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0tefko?= Date: Fri, 13 Oct 2023 18:49:06 +0200 Subject: [PATCH 3/8] Added support for auto redirect on login page, update user identity when email equals mail with master accout or name is not defined --- config.inc.php.dist | 2 ++ roundcube_oidc.php | 26 ++++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/config.inc.php.dist b/config.inc.php.dist index 19e91a0..4cb6234 100644 --- a/config.inc.php.dist +++ b/config.inc.php.dist @@ -44,3 +44,5 @@ $config['oidc_field_server'] = 'imap_server'; // Any errors will be reported as $ERROR $config['oidc_login_page'] = ''; +// Automatically redirect on login page +$config['oidc_auto_redirect'] = false; \ No newline at end of file diff --git a/roundcube_oidc.php b/roundcube_oidc.php index 242f28b..d3d4c29 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -54,13 +54,22 @@ function logout_after() { } public function loginform($content) { - // Add the login link - $content['content'] .= "

Login with OIDC

"; + // Get mail object + $RCMAIL = rcmail::get_instance(); + $auto_redirect = $RCMAIL->config->get('oidc_auto_redirect'); - // Check if we are starting or resuming oidc auth - if (!isset($_GET['code']) && !isset($_GET['oidc'])) { - $this->altReturn(null); - return $content; + if ($auto_redirect === true) { + $content['content'] = ''; + } + else { + // Add the login link + $content['content'] .= "

Login with OIDC

"; + + // Check if we are starting or resuming oidc auth + if (!isset($_GET['code']) && !isset($_GET['oidc'])) { + $this->altReturn(null); + return $content; + } } // Define error for alt login @@ -122,8 +131,9 @@ public function loginform($content) { // Login to IMAP if ($RCMAIL->login($auth['user'], $password, $imap_server, $auth['cookiecheck'])) { // Update user profile - $iid = $RCMAIL->user->get_identity()['identity_id']; - if (isset($iid)) { + $user_identity = $RCMAIL->user->get_identity(); + $iid = $user_identity['identity_id']; + if (isset($iid) && (!$user_identity['name'] || $user_identity['email'] == $uid)) { $data = array('email' => $mail); $claim_name = $user['name']; From ed88ebf81ffd7446ff445b8146b6600690064b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0tefko?= Date: Sun, 15 Oct 2023 11:45:11 +0200 Subject: [PATCH 4/8] Use claims to be able to get preferred_username from Azure --- roundcube_oidc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index d3d4c29..1c77301 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -89,12 +89,12 @@ public function loginform($content) { $RCMAIL->config->get('oidc_secret') ); $oidc->setRedirectURL($oidc->getRedirectURL() . '/'); - $oidc->addScope($RCMAIL->config->get('oidc_scope')); + $oidc->addScope(explode(' ', $RCMAIL->config->get('oidc_scope'))); // Get user information try { $oidc->authenticate(); - $user = json_decode(json_encode($oidc->requestUserInfo()), true); + $user = json_decode(json_encode($oidc->getVerifiedClaims()), true); } catch (\Exception $e) { $ERROR = 'OIDC Authentication Failed
' . $e->getMessage(); $content['content'] .= "

$ERROR

"; From 91d180c59c2ca847c7c6e8bc2580b69a53e1d443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0tefko?= Date: Sun, 15 Oct 2023 21:00:55 +0200 Subject: [PATCH 5/8] Added login_hint --- roundcube_oidc.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index 1c77301..a609d0b 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -82,12 +82,19 @@ public function loginform($content) { $password = $RCMAIL->config->get('oidc_imap_master_password'); $imap_server = $RCMAIL->config->get('default_host'); + // Try to decrypt login_hint cookie + $login_hint = $RCMAIL->decrypt($_COOKIE['roundcube_oidc_login_hint']); + if ($login_hint === false) { + $login_hint = null; + } + // Build provider $oidc = new OpenIDConnectClient( $RCMAIL->config->get('oidc_url'), $RCMAIL->config->get('oidc_client'), $RCMAIL->config->get('oidc_secret') ); + $oidc->addAuthParam(['login_hint' => $login_hint]); $oidc->setRedirectURL($oidc->getRedirectURL() . '/'); $oidc->addScope(explode(' ', $RCMAIL->config->get('oidc_scope'))); @@ -130,6 +137,8 @@ public function loginform($content) { // Login to IMAP if ($RCMAIL->login($auth['user'], $password, $imap_server, $auth['cookiecheck'])) { + rcube_utils::setcookie('roundcube_oidc_login_hint', $RCMAIL->encrypt($mail)); + // Update user profile $user_identity = $RCMAIL->user->get_identity(); $iid = $user_identity['identity_id']; From a7c4f1e31bd74a79ae4bc13830931f5f307414c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0tefko?= Date: Sun, 15 Oct 2023 21:13:56 +0200 Subject: [PATCH 6/8] Better code structure --- roundcube_oidc.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index a609d0b..fd41387 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -82,22 +82,21 @@ public function loginform($content) { $password = $RCMAIL->config->get('oidc_imap_master_password'); $imap_server = $RCMAIL->config->get('default_host'); - // Try to decrypt login_hint cookie - $login_hint = $RCMAIL->decrypt($_COOKIE['roundcube_oidc_login_hint']); - if ($login_hint === false) { - $login_hint = null; - } - // Build provider $oidc = new OpenIDConnectClient( $RCMAIL->config->get('oidc_url'), $RCMAIL->config->get('oidc_client'), $RCMAIL->config->get('oidc_secret') ); - $oidc->addAuthParam(['login_hint' => $login_hint]); $oidc->setRedirectURL($oidc->getRedirectURL() . '/'); $oidc->addScope(explode(' ', $RCMAIL->config->get('oidc_scope'))); + // Try to decrypt login_hint cookie + $login_hint = $RCMAIL->decrypt($_COOKIE['roundcube_oidc_login_hint']); + if ($login_hint) { + $oidc->addAuthParam(['login_hint' => $login_hint]); + } + // Get user information try { $oidc->authenticate(); From 04570bccd31a2dc2936781a528858823caab73dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20=C5=A0tefko?= Date: Tue, 17 Oct 2023 07:12:27 +0200 Subject: [PATCH 7/8] Remove roundcube_oidc_login_hint on logout --- roundcube_oidc.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index fd41387..4ce1d7f 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -49,6 +49,8 @@ function logout_after() { $RCMAIL->config->get('oidc_secret') ); + rcube_utils::setcookie('roundcube_oidc_login_hint', ''); + // TODO: We could save idToken during login and use it here $oidc->signOut(null, null); } From b3e80e5c32b2248aeaf461536ba63729972ddf35 Mon Sep 17 00:00:00 2001 From: rstefko Date: Tue, 3 Feb 2026 17:48:38 +0100 Subject: [PATCH 8/8] Logout from OIDC only when logged using it --- roundcube_oidc.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roundcube_oidc.php b/roundcube_oidc.php index 4ce1d7f..54e2e09 100644 --- a/roundcube_oidc.php +++ b/roundcube_oidc.php @@ -43,6 +43,10 @@ function altReturn($ERROR) { function logout_after() { $RCMAIL = rcmail::get_instance(); + // OIDC login was not used + if (!$_COOKIE['roundcube_oidc_login_hint']) + return; + $oidc = new OpenIDConnectClient( $RCMAIL->config->get('oidc_url'), $RCMAIL->config->get('oidc_client'),