Lemonld...::Plugin(3)
π NAME π
okay so this is the manual page for Lemonld...::Plugin(3), filed under User Contributed Perl Documentation, and it's all about Lemonldap::NG::Portal::Main::Plugin π
It's the base class for Lemonldap::NG::Portal modules β plugins, authentication modules, the whole squad. everything. periodt. π
β¨ SYNOPSIS β¨
here's the vibe, bestie β this is what a plugin actually looks like in the wild π¦
package Lemonldap::NG::Portal::My::Plugin;
use Mouse;
extends 'Lemonldap::NG::Portal::Main::Plugin';
use constant beforeAuth => 'verifyIP';
sub init {
my ($self) = @_;
$self->addUnauthRoute( mypath => 'hello', [ 'GET', 'PUT' ] );
$self->addAuthRoute( mypath => 'welcome', [ 'GET', 'PUT' ] );
return 1;
}
sub verifyIP {
my ($self, $req) = @_;
return PE_ERROR if($req->address !~ /^10/);
return PE_OK;
}
sub hello {
my ($self, $req) = @_;
...
return $self->p->sendJSONresponse($req, { hello => 1 });
}
sub welcome {
my ($self, $req) = @_;
...
return $self->p->sendHtml($req, 'template', params => { WELCOME => 1 });
}
πΈ DESCRIPTION πΈ
Lemonldap::NG::Portal::Main::Plugin hands you so many methods so you can write Lemonldap::NG addons without wanting to scream. iconic behavior honestly π
init() gets called for each and every plugin. And listen β if a plugin's initialization fails (aka init() returns 0), then the portal responds with a 500 status code for every single request. yeah. every one.
bestie, seriously: a0out ofinit()is a whole portal-wide situation π no cap.
π§© Writing plugins
Custom plugins can get inserted into the portal by declaring them in the lemonldap-ng.ini file, section [portal], key customPlugins:
[portal]
customPlugins = ::My::Plugin1, ::My::Plugin2
And the rules? Plugins must be valid packages that are well found in @INC. that's the bar, and it's the only bar π«Ά
πͺ Plugin entry points
π Entry point based on PATH_INFO
Plugins can declare unauthRoutes / authRoutes during initialization β those are =/path/info style. Methods declared this way must be declared in the plugin class. They get called with the $req argument, and $req is the HTTP request (peep Lemonldap::NG::Portal::Main::Request for that one, iykyk).
These methods must return a valid PSGI response. You can also use the sendJSONresponse() or sendHtml() methods instead (see Lemonldap::NG::Common::PSGI) β very handy, very slay.
Example:
sub init {
my ($self) = @_;
$self->addUnauthRoute( mypath => 'hello', [ 'GET', 'PUT' ] );
$self->addAuthRoute( mypath => 'welcome', [ 'GET', 'PUT' ] );
return 1;
}
sub hello {
my ($self, $req) = @_;
...
return $self->p->sendJSONresponse($req, { hello => 1 });
}
sub welcome {
my ($self, $req) = @_;
...
return $self->p->sendHtml($req, 'template', params => { WELLCOME => 1 });
}
Now β if you want that "protected application" behavior, you can use addAuthRouteWithRedirect. What it does is call addAuthRoute with the given arguments, and it builds an "unAuth" route that builds a redirection <em>after</em> authentication. cute, right? π
π Entry point in auth process
A plugin that wants to be inserted into the authentication process has to declare constants set with the method name to run. These are the entry points available to you:
"beforeAuth"β method called before authentication process"betweenAuthAndData"β method called after authentication and before setting"sessionInfo"provisionning"afterData"β method called after"sessionInfo"provisionning (macros, groups,...). This entry point is called after'storeHistory'if login process fails and before'validSession'if succeeds."endAuth"β method called when session is validated (after cookie build)"authCancel"β method called when user click on"cancel"during auth process"forAuthUser"β method called for already authenticated users"beforeLogout"β method called before logout
Note: methods inserted this way must return aPE_*constant. Go look atLemonldap::NG::Portal::Main::Constantsfor the menu β¨
πͺ Advanced entry points
These entry points are not stored in "$req->step" β they're launched on the fly:
"afterSub"β hash ref that gives methods to call <em>after</em> a given main method is called. Example:
use constant afterSub => {
getUser => 'mysub',
};
sub mysub {
my ( $self ,$req ) = @_;
# Do something
return PE_OK;
}
"aroundSub"β hash ref that gives methods to call <em>instead of</em> a given main method. Example:
use constant aroundSub => {
getUser => 'mysub',
};
sub mysub {
my ( $self, $sub, $req ) = @_;
# Do something before
my $ret = $sub->($req);
# Do something after
return $ret;
}
Do not launch"getUser"but use the given$sub. This permits multiple plugins to use"aroundSub"in the same time. teamwork makes the dream work π
"hook"β hash ref that gives methods to call when a hook is triggered in the LemonLDAP::NG code. Example:
use constant hook => {
oidcGenerateIDToken => 'addClaimToIDToken'
};
sub addClaimToIDToken {
my ( $self, $req, $payload, $rp ) = @_;
$payload->{"id_token_hook"} = 1;
return PE_OK;
}
π οΈ Registering new entrypoints
Use the "addEntryPoint" method to register a new entrypoint for future plugin loads. This can be useful if you would like to extend your plugin with other plugins, or interact with existing LemonLDAP::NG services in some way β very main character of you, honestly π
"addEntryPoint" takes a hash of options, for example:
$self->addEntryPoint(
isa => "My::Base::Class",
callback => sub {
my ($plugin) = @_;
$self->do_domething_with($plugin);
}
);
And here's what those options mean:
"can"β trigger the entry point when the newly loaded plugin has a given method"does"β trigger the entry point when the newly loaded plugin consumes a given role"isa"β trigger the entry point when the newly loaded plugin extends a given class"callback"β when triggered, run the given code reference, with the new plugin instance as first argument, and optional extra arguments"service"and"method"β when triggered, run the given method of the given portal service, with the new plugin instance as first argument, and optional extra arguments"args"β optional array reference of extra arguments to pass to the callback or service
π LOGGING π
Logging is provided by $self->logger and $self->userLogger. And the following rules must be applied β no freestyling here bestie:
logger->debug: technical debugging messageslogger->info: simple technical informationlogger->notice: technical information that could interest administratorslogger->warn: technical warninglogger->error: error that must be reported to administratoruserLogger->info: simple information about user's actionuserLogger->notice: information that may be registered (auth success,...)userLogger->warn: bad action of a user (auth failure). Auth/Combination transform it to"info"when another authentication scheme is availableuserLogger->error: bad action of a user that must be reported, (even if another backend is available with Combination)
π SEE ALSO π
<http://lemonldap-ng.org> β go peek, it's giving documentation π
π 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
the reading list is stacked fr fr πβ¨
π«Ά AUTHORS π«Ά
LemonLDAP::NG team <http://lemonldap-ng.org/team> β absolute legends, we love them, no notes π
π BUG REPORT π
Use the OW2 system to report bug or ask for features: <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
found a bug? don't just sit there bestie, tell the OW2 system π€
β¬οΈ DOWNLOAD β¬οΈ
Lemonldap::NG is available at <https://lemonldap-ng.org/download> π
βοΈ COPYRIGHT AND LICENSE βοΈ
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 was perl v5.42.3, dated 2026-09-24, and it's the Lemonld...::Plugin(3) manual β you ate that reading session, so proud of you π₯Ήπ go forth and write plugins, mwah πβ¨
π¦ where this page comes from
- fedora 43: lemonldap-ng-portal 2.23.4-1.fc43 Β· GPL-2.0-or-later AND MIT AND GPL-3.0-or-later AND OFL-1.1-RFN
- fedora 44: lemonldap-ng-portal 2.23.4-1.fc44 Β· GPL-2.0-or-later AND MIT AND GPL-3.0-or-later AND OFL-1.1-RFN
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms