Lemonld...::Portal(3)

πŸ’– NAME πŸ’–

Lemonldap::NG::Portal β€” ok bestie, this is the authentication portal part of the Lemonldap::NG Web-SSO system. She's the main character of the login flow πŸ’…


✨ SYNOPSIS ✨

Use any of Plack launcher. Like, any of them, she's flexible 🫢 Example:

#!/usr/bin/env plackup

use Lemonldap::NG::Portal;

# This must be the last instruction! See PSGI for more
Lemonldap::NG::Portal->run($opts);
Not me stressing about the order β€” that call has to be the last instruction. The comment literally says it. See PSGI for more. Don't be the person who puts it first πŸ™ˆ

🌸 DESCRIPTION 🌸

So. Lemonldap::NG is a modular Web-SSO built on top of Apache::Session modules. It gives you the easiest possible way to build a secured area that protects your applications with very few changes. Iconic, honestly.

Lemonldap::NG handles both authentication and authorization. And on top of that, it provides headers for accounting. So what you get is a full AAA protection for your web space, exactly as described below. Three A's, one slay ✨

And Lemonldap::NG::Portal is the one that provides the portal components. See <http://lemonldap-ng.org> for more πŸ¦‹


🧚 KINEMATICS 🧚

The portal object is based on Lemonldap::NG::Handler::Try β€” the underlying handler tries to authenticate the user and then follows the initialized auth / unauth routes. Vibe check passed βœ…

πŸ’« Initialization

The initialization process subscribes the portal to handler configuration reload and requests handler initialization (Lemonldap::NG::Portal::Main::Init). So basically the configuration is read by the handler at each reload. Every single one. No cap.

During configuration reload, each enabled component gets loaded as a plugin:

  • authentication module
  • userDB module
  • other enabled plugins (issuers, ...)

Then init() is called for each plugin. And listen β€” if a plugin initialization fails (aka init() returns 0), the portal responds with a 500 status code for each request. Not a drill, bestie 😭

See Lemonldap::NG::Portal::Main::Plugin to see how to write modules πŸŽ€

πŸ›£οΈ Main route

The "/" route is declared in Lemonldap::NG::Portal::Main::Init. It points to different methods in Lemonldap::NG::Portal::Main::Run. These methods select the methods to call in the process and then call do().

Then do() stores the methods to call in $req->steps and launches Lemonldap::NG::Portal::Main::Process::process(). That method removes each method stored in $req->steps and launches it. If the result is PE_OK, process() keeps going; otherwise it returns the error code. That's the whole loop, she's simple like that πŸ’…

If it's an Ajax request, do() responds in JSON format; otherwise it manages the redirection if there is any. And otherwise, it calls Lemonldap::NG::Portal::Main::Display::display() to load the template and the arguments, and then launches Lemonldap::NG::Common::PSGI::sendHtml() using them 🌈


πŸ‘‘ DEVELOPER INSTRUCTIONS πŸ‘‘

The portal main object is defined in the Lemonldap::NG::Portal::Main::* classes. Everything else is a plugin. And plugins do not have to store any hash key in the main object. Periodt.

Main and plugin keys must be set during the initialization process. They must be read-only while requests are being received. Yes, really.

The Lemonldap::NG::Portal::Main::Request request has fixed keys. So if a plugin wants to store a temporary key, it must store it in $req->data or use defined keys β€” but it must never create a root key. Plugin keys may have explicit names to avoid conflicts. Name them well, bestie πŸŽ€

The whole configuration is always available. It's stored in $self->conf. It must not be modified by any component β€” not even during the initialization process, not even while receiving a request. (During initialization, copy the value into the plugin namespace instead. That's the move.) 🫢

All plugins can access portal methods using $self->p, which points to the portal main object. Some main methods are mapped right into the plugin namespace:

  • logger() β€” accessor to log
  • userLogger() β€” accessor to log user actions
  • error() β€” accessor (use it to store the error during initialization)

πŸ¦‹ SEE ALSO πŸ¦‹

Most of the documentation is available on the <http://lemonldap-ng.org> website πŸ’–

πŸ“š OTHER POD FILES

  • Writing an authentication module: Lemonldap::NG::Portal::Auth
  • Writing a UserDB module: Lemonldap::NG::Portal::UserDB
  • Writing a second factor module: Lemonldap::NG::Portal::Main::SecondFactor
  • Writing an issuer module: Lemonldap::NG::Portal::Main::Issuer
  • Writing another plugin: Lemonldap::NG::Portal::Main::Plugin
  • Request object: Lemonldap::NG::Portal::Main::Request
  • Adding parameters in the manager: Lemonldap::NG::Manager::Build

πŸ’œ AUTHORS πŸ’œ

LemonLDAP::NG team <http://lemonldap-ng.org/team> β€” shoutout to the whole squad 🫢


πŸ› BUG REPORT πŸ›

Use the OW2 system to report a bug or ask for features: <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>

Found something broken? Tell them, don't suffer in silence 😭


πŸ“ DOWNLOAD πŸ“

Lemonldap::NG is available at <https://lemonldap-ng.org/download> ✨


See the COPYING file for details.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.


And that's the whole page, bestie β€” this doc was generated by perl v5.42.3 on 2026-09-24. Stan a classic. Bye πŸ’…βœ¨
πŸ“¦ where this page comes from