lemonldap-ng/lemonldap-ng-manager/lib/Lemonldap/NG/Manager.pm

311 lines
8.5 KiB
Perl

# Manager main component
#
# This package contains these parts:
# - Properties and private methods
# - Initialization method (launched by Lemonldap::NG::Common::PSGI)
# that declares routes
# - Upload methods (launched by Lemonldap::NG::Common::PSGI::Router)
#
# It inherits from Conf.pm to responds to display methods and from
# Sessions.pm to manage sessions
package Lemonldap::NG::Manager;
use 5.10.0;
use utf8;
use Mouse;
use JSON;
use Lemonldap::NG::Common::Conf::Constants;
use Lemonldap::NG::Common::PSGI::Constants;
our $VERSION = '2.0.0';
extends 'Lemonldap::NG::Common::Conf::AccessLib',
'Lemonldap::NG::Handler::PSGI::Router';
has csp => ( is => 'rw' );
## @method boolean init($args)
# Launch initialization method
#
# @param $args hashref to merge with object
# @return 0 in case of error, 1 else
sub init {
my ( $self, $args ) = @_;
$args ||= {};
if ( my $localconf = $self->confAcc->getLocalConf(MANAGERSECTION) ) {
foreach ( keys %$localconf ) {
$args->{$_} //= $localconf->{$_};
$self->{$_} = $args->{$_} unless (/^(?:l|userL)ogger$/);
}
}
# Manager needs to keep new Ajax behaviour
$args->{noAjaxHook} = 0;
return 0
unless ( $self->Lemonldap::NG::Handler::PSGI::Router::init($args) );
# TODO: manage errors
unless ( -r $self->{templateDir} ) {
$self->error("Unable to read $self->{templateDir}");
return 0;
}
$self->{enabledModules} ||= "conf, sessions, notifications";
my @links;
my @enabledModules =
map { push @links, $_; "Lemonldap::NG::Manager::" . ucfirst($_) }
split( /[,\s]+/, $self->{enabledModules} );
extends 'Lemonldap::NG::Handler::PSGI::Router', @enabledModules;
my @working;
my $conf = $self->confAcc->getConf;
unless ($conf) {
require Lemonldap::NG::Manager::Conf::Zero;
$conf = Lemonldap::NG::Manager::Conf::Zero::zeroConf();
}
for ( my $i = 0 ; $i < @enabledModules ; $i++ ) {
my $mod = $enabledModules[$i];
no strict 'refs';
if ( &{"${mod}::addRoutes"}( $self, $conf ) ) {
$self->logger->debug("Module $mod enabled");
push @working, $mod;
}
else {
$links[$i] = undef;
$self->logger->error(
"Module $mod can not be enabled: " . $self->error );
}
}
return 0 unless (@working);
$self->addRoute( links => 'links', ['GET'] );
$self->addRoute( 'psgi.js' => 'sendJs', ['GET'] );
my $portal = $conf->{portal};
$portal =~ s#https?://([^/]*).*#$1#;
$self->csp(
"default-src 'self' $portal;frame-ancestors 'none';form-action 'self';"
);
$self->defaultRoute( $working[0]->defaultRoute );
my $linksIcons =
{ 'conf' => 'cog', 'sessions' => 'duplicate', 'notifications' => 'bell' };
$self->links( [] );
for ( my $i = 0 ; $i < @links ; $i++ ) {
next unless ( defined $links[$i] );
push @{ $self->links },
{
target => $enabledModules[$i]->defaultRoute,
title => $links[$i],
icon => $linksIcons->{ $links[$i] }
};
}
$self->menuLinks( [] );
if (
my $portal =
$conf->{cfgNum}
? Lemonldap::NG::Handler::PSGI::Main->tsv->{portal}->()
: $conf->{portal}
)
{
push @{ $self->menuLinks },
{
target => $portal,
title => 'backtoportal',
icon => 'home'
},
{
target => "$portal?logout=1",
title => 'logout',
icon => 'log-out'
};
}
1;
}
sub tplParams {
return ( VERSION => $VERSION, );
}
sub javascript {
my ($self) = @_;
return
'var formPrefix=staticPrefix+"forms/";var confPrefix=scriptname+"confs/";'
. ( $self->links ? 'var links=' . to_json( $self->links ) . ';' : '' )
. (
$self->menuLinks
? 'var menulinks=' . to_json( $self->menuLinks ) . ';'
: ''
);
}
sub sendHtml {
my ( $self, $req, $template, %args ) = @_;
my $res = $self->SUPER::sendHtml( $req, $template, %args );
push @{ $res->[1] },
'Content-Security-Policy' => $self->csp,
'X-Content-Type-Options' => 'nosniff',
'X-Frame-Options' => 'DENY',
'X-XSS-Protection' => '1; mode=block';
return $res;
}
1;
__END__
=head1 NAME
=encoding utf8
Lemonldap::NG::Manager - Perl extension for managing Lemonldap::NG Web-SSO
system.
=head1 SYNOPSIS
Use any of Plack launcher. Example:
#!/usr/bin/env plackup
use Lemonldap::NG::Manager;
# This must be the last instruction ! See PSGI for more
Lemonldap::NG::Manager->run($opts);
=head1 DESCRIPTION
Lemonldap::NG::Manager provides a web interface to manage Lemonldap::NG Web-SSO
system.
The Perl part of Lemonldap::NG::Manager is the REST server. Web interface is
written in Javascript, using AngularJS framework and can be found in `site`
directory. The REST API is described in REST-API.md file given in source tree.
Lemonldap::NG Manager uses L<Plack> to be compatible with CGI, FastCGI,... It
inherits of L<Lemonldap::NG::Handler::PSGI::Router>
=head1 ORGANIZATION
Lemonldap::NG Manager contains 5 parts:
=over
=item Configuration management
=item Session explorer
=item Notification explorer
=item Configuration builder (see L<Lemonldap::NG::Manager::Build>
=item Command line (see L<Lemonldap::NG::Manager::Cli>
=back
=head2 Generation of static files
The `scripts/jsongenerator.pl` file uses Lemonldap::NG::Manager::Build::Attributes,
Lemonldap::NG::Manager::Build::Tree and Lemonldap::NG::Manager::Build::CTrees to generate
=over
=item `site/htdocs/static/struct.json`:
the main file that contains the tree view;
=item `site/htdocs/static/js/conftree.js`:
generates sub tree for virtualhosts and SAML and OpenID-Connect partners;
=item `Lemonldap::NG::Common::Conf::ReConstants`:
constants used by all Perl manager components;
=item `Lemonldap::NG::Common::Conf::DefaultValues`:
constants used to read configuration.
=back
=head1 PARAMETERS
You can use a hash ref to override any LemonLDAP::NG parameter. Currently, you
can specify where your lemonldap-ng.ini file is:
Lemonldap::NG::Manager->run( { confFile => '/path/to/lemonldap-ng.ini' } );
=head2 lemonldap-ng.ini parameters
You can override any configuration parameter in lemonldap-ng.ini, but some are
required and can't be set to global configuration (as any Lemonldap::NG module,
you can also fix them in $opts hash ref passed as argument to run() or new()).
[manager]
;protection: choose one of none, authenticate, manager as explain in
; Lemonldap::NG::Handler::PSGI::Router doc.
protection = manager
;enabledModules: Modules to display. Default to `conf, sessions, notifications`
enabledModules = conf, sessions, notifications
;logLevel: choose one of error, warn, notice, info, debug
; See Lemonldap::NG::Common::PSGI doc for more
logLevel = notice
;staticPrefix: set here the URI path to static content
; See Lemonldap::NG::Common::PSGI doc for more
staticPrefix = static/
;languages: Available interface languages
languages = en, fr
;templateDir: the path to the directory containing HTML templates
; See Lemonldap::NG::Common::PSGI doc for more
templateDir = /usr/share/lemonldap-ng/manager/
=head1 SEE ALSO
L<http://lemonldap-ng.org/>
=head1 AUTHORS
=over
=item LemonLDAP::NG team L<http://lemonldap-ng.org/team>
=back
=head1 BUG REPORT
Use OW2 system to report bug or ask for features:
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
Note that if you want to post a ticket for a conf upload problem, please
see L<Lemonldap::NG::Manager::Conf::Parser> before.
=head1 DOWNLOAD
Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
=head1 COPYRIGHT AND LICENSE
See 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 L<http://www.gnu.org/licenses/>.
=cut