Skip to content

Conversation

@Killian-Aidalinfo
Copy link

@Killian-Aidalinfo Killian-Aidalinfo commented Oct 20, 2025

Refactors the Single Sign-On plugin to target GLPI 11 and PHP 8.2 while modernising its tooling and runtime flow.

  • Require PHP 8.2, adopt glpi-project/tools, and enable PSR‑4 autoloading for GlpiPlugin\Singlesignon (composer.json:2, composer.lock, setup.php:24).
  • Move legacy classes into thin shims that load the new namespaced implementations under src/, preserving backward compatibility for includes and hooks (inc/
    provider.class.php:1, src/Provider.php:1, src/Preference.php:1).
  • Replace the ad-hoc login markup with a Twig renderer and dedicated stylesheet that matches the GLPI 11 login layout, including popup handling for OAuth flows
    (src/LoginRenderer.php:10, templates/login/buttons.html.twig:1, css/login.css:1).
  • Harden the OAuth callback and media endpoints by switching to GLPI’s HTTP exceptions, validating session state, and persisting redirect targets through the
    authorization roundtrip (front/callback.php:1, src/Toolbox.php:18, front/picture.send.php:1).

Killian-Aidalinfo and others added 30 commits October 14, 2025 20:24
…-nouvelle-version-glpi

Migrate plugin to GLPI 11 tooling
…d toolbox files to check for existing classes before defining them
Update namespace references and class aliasing for Singlesignon plugin
Remove unnecessary template path addition in LoginRenderer
Refactor LoginRenderer to handle auto redirect URL in injectPopupScri…
Add title parameter for Single Sign-on in LoginRenderer template rend…
Sanitize auto redirect URL in injectPopupScript method using htmlspec…
Refactor getCallbackUrl method to use root_doc for constructing the c…
remove iframe, re use injectpopupscript
… lieu de /provider/

   2. `getCallbackParameters()` - Essaie d'abord $_GET, puis fallback vers PATH_INFO pour rétro-compatibilité
   1. `getCallbackUrl()` - Génère maintenant une URL avec ?provider= …
@fgendorf
Copy link

Another issue, miss add button at top
image

@Killian-Aidalinfo
Copy link
Author

Hi @fgendorf thanks for your feedback, I'll check that tomorrow!

@Killian-Aidalinfo
Copy link
Author

Killian-Aidalinfo commented Oct 23, 2025

Hi @fgendorf I didn't have time to look for the Google error, but I fixed three bugs, including the add provider button. Here is the version that fixes that
https://github.com/aidalinfo/glpi-singlesignon/releases/download/1.5.1/glpi-singlesignon-1.5.1.tar.bz2

@Killian-Aidalinfo
Copy link
Author

Hi, new version fix few bugs.

https://github.com/aidalinfo/glpi-singlesignon/releases/tag/1.5.1-alpha-02

thx @shmsh9

@fgendorf
Copy link

@Killian-Aidalinfo the version https://github.com/aidalinfo/glpi-singlesignon/releases/tag/1.5.1-alpha-02 fix the authentication with google, it's working now

@fgendorf
Copy link

It seems that option IsDefault: YES not have the same behavior in GLPI 10, that automatically try login in with the google session, with no necessity to click on the button

@Killian-Aidalinfo
Copy link
Author

It seems that option IsDefault: YES not have the same behavior in GLPI 10, that automatically try login in with the google session, with no necessity to click on the button

Hi @fgendorf please try https://github.com/aidalinfo/glpi-singlesignon/releases/download/1.5.1-alpha-03/glpi-singlesignon-1.5.1-alpha-03.tar.bz2 I fixed that problem a few hours ago.

@fgendorf
Copy link

Maybe miss something...

[2025-10-28 14:05:46] glpi.CRITICAL:   *** Uncaught PHP Exception Twig\Error\RuntimeError: "An exception has been thrown during the rendering of a template ("") in "pages/login.html.twig" at line 112." at login.html.twig line 112
  Backtrace :
  ./templates/pages/login.html.twig:112              
  ...tes/7f/7f802e05af47c550149afa2287b0cdb4.php:142 Twig\Template->yieldBlock()
  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_417c8f2e464a1abe2580ecac32afc271->doDisplay()
  ...ates/4b/4b66ec6b8b8e3ebd0b3caa197f3ff1ec.php:49 Twig\Template->yield()
  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_b5ad243fbba65bedc4dcbf0c8eafed39->doDisplay()
  ./vendor/twig/twig/src/Template.php:358            Twig\Template->yield()
  ./vendor/twig/twig/src/Template.php:373            Twig\Template->display()
  ./vendor/twig/twig/src/TemplateWrapper.php:51      Twig\Template->render()
  .../Glpi/Application/View/TemplateRenderer.php:170 Twig\TemplateWrapper->render()
  ./src/Glpi/Controller/AbstractController.php:68    Glpi\Application\View\TemplateRenderer->render()
  ./src/Glpi/Controller/IndexController.php:112      Glpi\Controller\AbstractController->render()
  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\IndexController->__invoke()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()
  Previous: 
  ./src/Html.php:459                                 
  ...ketplace/singlesignon/src/LoginRenderer.php:146 Html::redirect()
  ...rketplace/singlesignon/src/LoginRenderer.php:33 GlpiPlugin\Singlesignon\LoginRenderer::redirectToProvider()
  ./src/Plugin.php:1735                              GlpiPlugin\Singlesignon\LoginRenderer::display()
  ...plication/View/Extension/PluginExtension.php:74 Plugin::doHook()
  ...tes/4b/4b66ec6b8b8e3ebd0b3caa197f3ff1ec.php:214 Glpi\Application\View\Extension\PluginExtension->callPluginHook()
  ./vendor/twig/twig/src/Template.php:446            __TwigTemplate_b5ad243fbba65bedc4dcbf0c8eafed39->block_content_block()
  ...tes/7f/7f802e05af47c550149afa2287b0cdb4.php:142 Twig\Template->yieldBlock()
  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_417c8f2e464a1abe2580ecac32afc271->doDisplay()
  ...ates/4b/4b66ec6b8b8e3ebd0b3caa197f3ff1ec.php:49 Twig\Template->yield()
  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_b5ad243fbba65bedc4dcbf0c8eafed39->doDisplay()
  ./vendor/twig/twig/src/Template.php:358            Twig\Template->yield()
  ./vendor/twig/twig/src/Template.php:373            Twig\Template->display()
  ./vendor/twig/twig/src/TemplateWrapper.php:51      Twig\Template->render()
  .../Glpi/Application/View/TemplateRenderer.php:170 Twig\TemplateWrapper->render()
  ./src/Glpi/Controller/AbstractController.php:68    Glpi\Application\View\TemplateRenderer->render()
  ./src/Glpi/Controller/IndexController.php:112      Glpi\Controller\AbstractController->render()
  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\IndexController->__invoke()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

@Killian-Aidalinfo
Copy link
Author

Maybe miss something...


[2025-10-28 14:05:46] glpi.CRITICAL:   *** Uncaught PHP Exception Twig\Error\RuntimeError: "An exception has been thrown during the rendering of a template ("") in "pages/login.html.twig" at line 112." at login.html.twig line 112

  Backtrace :

  ./templates/pages/login.html.twig:112              

  ...tes/7f/7f802e05af47c550149afa2287b0cdb4.php:142 Twig\Template->yieldBlock()

  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_417c8f2e464a1abe2580ecac32afc271->doDisplay()

  ...ates/4b/4b66ec6b8b8e3ebd0b3caa197f3ff1ec.php:49 Twig\Template->yield()

  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_b5ad243fbba65bedc4dcbf0c8eafed39->doDisplay()

  ./vendor/twig/twig/src/Template.php:358            Twig\Template->yield()

  ./vendor/twig/twig/src/Template.php:373            Twig\Template->display()

  ./vendor/twig/twig/src/TemplateWrapper.php:51      Twig\Template->render()

  .../Glpi/Application/View/TemplateRenderer.php:170 Twig\TemplateWrapper->render()

  ./src/Glpi/Controller/AbstractController.php:68    Glpi\Application\View\TemplateRenderer->render()

  ./src/Glpi/Controller/IndexController.php:112      Glpi\Controller\AbstractController->render()

  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\IndexController->__invoke()

  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()

  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()

  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

  Previous: 

  ./src/Html.php:459                                 

  ...ketplace/singlesignon/src/LoginRenderer.php:146 Html::redirect()

  ...rketplace/singlesignon/src/LoginRenderer.php:33 GlpiPlugin\Singlesignon\LoginRenderer::redirectToProvider()

  ./src/Plugin.php:1735                              GlpiPlugin\Singlesignon\LoginRenderer::display()

  ...plication/View/Extension/PluginExtension.php:74 Plugin::doHook()

  ...tes/4b/4b66ec6b8b8e3ebd0b3caa197f3ff1ec.php:214 Glpi\Application\View\Extension\PluginExtension->callPluginHook()

  ./vendor/twig/twig/src/Template.php:446            __TwigTemplate_b5ad243fbba65bedc4dcbf0c8eafed39->block_content_block()

  ...tes/7f/7f802e05af47c550149afa2287b0cdb4.php:142 Twig\Template->yieldBlock()

  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_417c8f2e464a1abe2580ecac32afc271->doDisplay()

  ...ates/4b/4b66ec6b8b8e3ebd0b3caa197f3ff1ec.php:49 Twig\Template->yield()

  ./vendor/twig/twig/src/Template.php:402            __TwigTemplate_b5ad243fbba65bedc4dcbf0c8eafed39->doDisplay()

  ./vendor/twig/twig/src/Template.php:358            Twig\Template->yield()

  ./vendor/twig/twig/src/Template.php:373            Twig\Template->display()

  ./vendor/twig/twig/src/TemplateWrapper.php:51      Twig\Template->render()

  .../Glpi/Application/View/TemplateRenderer.php:170 Twig\TemplateWrapper->render()

  ./src/Glpi/Controller/AbstractController.php:68    Glpi\Application\View\TemplateRenderer->render()

  ./src/Glpi/Controller/IndexController.php:112      Glpi\Controller\AbstractController->render()

  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\IndexController->__invoke()

  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()

  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()

  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

I don't have these messages on my GLPI, but I'll see if I can reproduce them. Do you have multiple authentication providers configured?

@fgendorf
Copy link

Hi, there are ldap authentication too

@Sheykoe
Copy link

Sheykoe commented Oct 30, 2025

Trying to login using SSO type = Generic -> Unexpected error

On GLPI 10.0.12 and plugin version 1.3.4 everything working well

In php-errors.log:

glpi.CRITICAL:   *** Uncaught PHP Exception RuntimeException: "MySQL query error: Table 'glpidb.glpi_plugin_singlesignon_providers_users' doesn't exist (1146) in SQL query "SELECT * FROM `glpi_plugin_singlesignon_providers_users` WHERE (`remote_id` = '8110' AND `plugin_singlesignon_providers_id` = 1)"." at DBmysql.php line 371
  Backtrace :
  ./src/DBmysql.php:371                              
  ./src/DBmysqlIterator.php:123                      DBmysql->doQuery()
  ./src/DBmysql.php:1040                             DBmysqlIterator->execute()
  ./src/CommonDBTM.php:629                           DBmysql->request()
  ./plugins/singlesignon/src/Provider.php:1220       CommonDBTM->find()
  ./plugins/singlesignon/src/Provider.php:1436       GlpiPlugin\Singlesignon\Provider->findUser()
  ./plugins/singlesignon/front/callback.php:96       GlpiPlugin\Singlesignon\Provider->login()
  ...Glpi/Controller/LegacyFileLoadController.php:64 require()
  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\LegacyFileLoadController->__invoke()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

@Killian-Aidalinfo
Copy link
Author

Hi, there are ldap authentication too

Hi ! The problem is solved here:

Auto login is forced when you log out, we don't have noAuto login. I'll look into that later, but you can test this version, auto login should work: https://github.com/aidalinfo/glpi-singlesignon/releases/download/1.5.1-alpha-04/glpi-singlesignon-1.5.1-alpha-04.tar.bz2

@Killian-Aidalinfo
Copy link
Author

Killian-Aidalinfo commented Oct 30, 2025

Hi @Sheykoe with alpha 03 ?

@Killian-Aidalinfo
Copy link
Author

@Sheykoe I ship you quickly an alpha 5 that should fix your problem

@Sheykoe
Copy link

Sheykoe commented Oct 30, 2025

Hi @Sheykoe with alpha 03 ?

Tried on alpha 03 and 04

I ship you quickly an alpha 5 that should fix your problem

It's awesome! Thank you!

@Killian-Aidalinfo
Copy link
Author

Killian-Aidalinfo commented Oct 30, 2025

@Killian-Aidalinfo
Copy link
Author

Killian-Aidalinfo commented Oct 30, 2025

@Sheykoe @fgendorf If you haven't installed version 05 yet, you can go straight to version 06. I've fixed the UI issue on noAuto.

https://github.com/aidalinfo/glpi-singlesignon/releases/download/1.5.1-alpha-06/glpi-singlesignon-1.5.1-alpha-06.tar.bz2

Sorry for the multiple versions. I don't have a test flow yet, so I'm testing directly on an instance used by my company.

@fgendorf
Copy link

HI @Killian-Aidalinfo , great job, don't worry about multiples versions, thats the meaning of alpha!
But... 06, I guess the noAuto fix create another one issue:
image
caused by insert tags script on function:

function plugin_singlesignon_post_init()
{
    global $CFG_GLPI;

    // If user logged in via SSO, redirect logout to plugin's logout to preserve noAUTO
    if (isset($_SESSION['glpi_sso_login']) && $_SESSION['glpi_sso_login']) {
        $plugin_logout = Plugin::getWebDir('singlesignon') . '/front/logout.php';
        echo "<script type='text/javascript'>
        document.addEventListener('DOMContentLoaded', function() {
            // Modify all logout links to use plugin logout
            document.querySelectorAll('a[href*=\"/front/logout.php\"]').forEach(function(link) {
                var href = link.getAttribute('href');
                if (href && href.indexOf('plugins/singlesignon') === -1) {
                    link.setAttribute('href', '{$plugin_logout}');
                }
            });
        });
        </script>";
    }
}

Thanks for your time!

@Sheykoe
Copy link

Sheykoe commented Oct 30, 2025

@Sheykoe @fgendorf If you haven't installed version 05 yet, you can go straight to version 06. I've fixed the UI issue on noAuto.

GLPI 11.0.1 clean installation - only default users (glpi, normal, post-only and others)

I tried alpha-06: now after choosing SSO provider on GLPI login page it redirects me to my SSO provider page, I'm passing authorization on it and it redirects me back to GLPI. In GLPI I receive "Unexpected error" and no user was created in GLPI from SSO provider.

Errors in php-errors.log

glpi.CRITICAL:   *** Uncaught PHP Exception TypeError: "preg_split(): Argument #2 ($subject) must be of type string, null given" at Provider.php line 1357
  Backtrace :
  ./plugins/singlesignon/src/Provider.php:1357       
  ./plugins/singlesignon/src/Provider.php:1357       preg_split()
  ./plugins/singlesignon/src/Provider.php:1436       GlpiPlugin\Singlesignon\Provider->findUser()
  ./plugins/singlesignon/front/callback.php:96       GlpiPlugin\Singlesignon\Provider->login()
  ...Glpi/Controller/LegacyFileLoadController.php:64 require()
  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\LegacyFileLoadController->__invoke()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

@Killian-Aidalinfo
Copy link
Author

@Killian-Aidalinfo
Copy link
Author

@Sheykoe @fgendorf If you haven't installed version 05 yet, you can go straight to version 06. I've fixed the UI issue on noAuto.

GLPI 11.0.1 clean installation - only default users (glpi, normal, post-only and others)

I tried alpha-06: now after choosing SSO provider on GLPI login page it redirects me to my SSO provider page, I'm passing authorization on it and it redirects me back to GLPI. In GLPI I receive "Unexpected error" and no user was created in GLPI from SSO provider.

Errors in php-errors.log

glpi.CRITICAL:   *** Uncaught PHP Exception TypeError: "preg_split(): Argument #2 ($subject) must be of type string, null given" at Provider.php line 1357
  Backtrace :
  ./plugins/singlesignon/src/Provider.php:1357       
  ./plugins/singlesignon/src/Provider.php:1357       preg_split()
  ./plugins/singlesignon/src/Provider.php:1436       GlpiPlugin\Singlesignon\Provider->findUser()
  ./plugins/singlesignon/front/callback.php:96       GlpiPlugin\Singlesignon\Provider->login()
  ...Glpi/Controller/LegacyFileLoadController.php:64 require()
  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\LegacyFileLoadController->__invoke()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

Did your user not have a first or last name? Try the new version; this error should no longer appear.

@renan-redel
Copy link

@Killian-Aidalinfo I tried the alpha 07 in my environment (GLPI 11 upgraded from 10), and got "The action you have requested is not allowed.".

Full log:

CSRF check failed for User ID

User ID: `Anonymous` tried to execute an invalid request on `/plugins/singlesignon/front/callback.php/provider/1?code=1.ASY...`.

  Backtrace :
  ./src/Session.php:1783                             
  ./plugins/singlesignon/src/Provider.php:1036       Session::checkCSRF()
  ./plugins/singlesignon/front/callback.php:64       GlpiPlugin\Singlesignon\Provider->checkAuthorization()
  ...Glpi/Controller/LegacyFileLoadController.php:64 require()
  ./vendor/symfony/http-kernel/HttpKernel.php:181    Glpi\Controller\LegacyFileLoadController->__invoke()
  ./vendor/symfony/http-kernel/HttpKernel.php:76     Symfony\Component\HttpKernel\HttpKernel->handleRaw()
  ./vendor/symfony/http-kernel/Kernel.php:197        Symfony\Component\HttpKernel\HttpKernel->handle()
  ./public/index.php:70                              Symfony\Component\HttpKernel\Kernel->handle()

My user have first and last name.

@fgendorf
Copy link

@fgendorf yup and no profil picture :(

@fgendorf & @Sheykoe please try : https://github.com/aidalinfo/glpi-singlesignon/releases/download/1.5.1-alpha-07/glpi-singlesignon-1.5.1-alpha-07.tar.bz2

Everything working now on my environment, if I can help in some test, just ask.

@Sheykoe
Copy link

Sheykoe commented Oct 31, 2025

Hi @Killian-Aidalinfo,

I've tried the alpha-07 version, and everything seems to be working well! Authorization is successful (using Generic SSO), and new users are created correctly. I'm going to test it on my server next.

Thank you for your work! If you need any help with testing, just let me know.

P.S.: There's a known issue in the plugin – after authorization, it only redirects to the main page instead of the originally requested URL. Is it possible to fix this?

Example:

I'm not logged into GLPI.

I try to open a specific page, e.g., http://glpi-address/front/ticket.php.

The authorization page opens.

I complete the authorization.

Instead of being redirected to the page from step 2 (http://glpi-address/front/ticket.php), I'm redirected to the main page (http://glpi-address/Helpdesk).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants