Write a custom plugin ===================== Presentation ------------ Portal plugins let you customize LemonLDAP::NG's behavior. Common use cases for plugins are: * Looking up session information in an additional backend * Implementing additional controls or steps during login * Adjusting the behavior of SAML, OIDC or CAS protocols to work around application bugs Plugin API ---------- Authentication entry points ~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can now write a custom portal plugin that will hook in the authentication process: - ``beforeAuth``: method called before authentication process - ``betweenAuthAndData``: method called after authentication and before setting "sessionInfo" provisionning - ``afterData``: method called after "sessionInfo" provisionning - ``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 Generic entry points ~~~~~~~~~~~~~~~~~~~~ If you need to call a method just after any standard method in authentication process, then use ``afterSub``, for example: .. code-block:: perl use constant afterSub => { getUser => 'mysub', }; sub mysub { my ( $self ,$req ) = @_; # Do something return PE_OK; } If you need to call a method instead any standard method in authentication process, then use ``aroundSub``, for example: .. code-block:: perl use constant aroundSub => { getUser => 'mysub', }; sub mysub { my ( $self, $sub, $req ) = @_; # Do something before my $ret = $sub->($req); # Do something after return $ret; } Hooks ~~~~~ .. versionadded:: 2.0.10 Your plugin can also register itself to be called at some points of interest within the main LemonLDAP::NG code. .. toctree:: :maxdepth: 1 hooks Routes ~~~~~~ The plugin can also define new routes and call actions on them. See also ``Lemonldap::NG::Portal::Main::Plugin`` man page. Configuration ~~~~~~~~~~~~~ The current LemonLDAP::NG configuration can be accessed in the ``$self->conf`` hash. This variable is only meant to be read. Don't try changing its content, or *Bad Things* may happen. You can set your own parameters in ``General Parameters`` » ``Plugins`` » ``Custom plugins`` » ``Additional parameters`` and reach them through ``customPluginsParams`` .. code-block:: perl sub my_function { my ($self, $req) = @_; # Get a standard LLNG option my $llng_logo = $self->conf->{portalMainLogo}; # Get your custom LLNG option my $myvar = $self->conf->{customPluginsParams}->{myvar}; } Logs ~~~~ You can use the ``$self->logger`` and ``$self->userLogger`` objects to log information during your plugin execution. Use ``logger`` for technical logs and ``userLogger`` for accounting and tracability events. .. code-block:: perl sub my_function { my ($self, $req) = @_; $self->logger->debug("Debug message"); if (my_custom_test($req->user)) { $self->userLogger->debug("User ". $req->user . " is not allowed because XXX"); return PE_ERROR; } return PE_OK; } Remembering data ~~~~~~~~~~~~~~~~ In order to remember data between different steps, you can use the ``$req->data`` hash. Data will not be remembered in between requests, only in between methods that process the same HTTP request. Example ------- Plugin Perl module ~~~~~~~~~~~~~~~~~~ Create for example the MyPlugin module: :: vi /usr/share/perl5/Lemonldap/NG/Portal/MyPlugin.pm .. tip:: If you do not want to mix files from the distribution with your own work, put your own code in ``/usr/local/lib/site_perl/Lemonldap/NG/Portal/MyPlugin.pm``\ .. code-block:: perl # The package name must match the file path # This file must be in Lemonldap/NG/Portal/MyPlugin.pm package Lemonldap::NG::Portal::MyPlugin; use Mouse; use Lemonldap::NG::Portal::Main::Constants; extends 'Lemonldap::NG::Portal::Main::Plugin'; use constant beforeAuth => 'verifyIP'; sub init { # Every plugin must have an init function that returns 1 # You can define your custom initialization here 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) = @_; my $userid = $req->user; $self->p->logger->debug("Call welcome for $userid"); ... return $self->p->sendHtml($req, 'template', params => { WELCOME => 1 }); } # Your file must return 1, or Perl will complain. 1; Enabling your plugin ~~~~~~~~~~~~~~~~~~~~ Declare the plugin in lemonldap-ng.ini: :: vi /etc/lemonldap-ng/lemonldap-ng.ini .. code-block:: perl [portal] customPlugins = Lemonldap::NG::Portal::MyPlugin ;customPlugins = Lemonldap::NG::Portal::MyPlugin1, Lemonldap::NG::Portal::MyPlugin2, ... Since 2.0.7, it can also be configured in Manager, in General Parameters > Plugins > Custom Plugins.