Manager.pm 8.69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
# 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
11 12
package Lemonldap::NG::Manager;

13
use 5.10.0;
Xavier Guimard's avatar
Xavier Guimard committed
14
use utf8;
15
use Mouse;
16
use JSON;
17 18 19
use Lemonldap::NG::Common::Conf::Constants;
use Lemonldap::NG::Common::PSGI::Constants;

Xavier Guimard's avatar
Xavier Guimard committed
20
our $VERSION = '2.0.2';
21

22 23
extends 'Lemonldap::NG::Common::Conf::AccessLib',
  'Lemonldap::NG::Handler::PSGI::Router';
24

25 26
has csp => ( is => 'rw' );

27 28 29 30 31 32
## @method boolean init($args)
# Launch initialization method
#
# @param $args hashref to merge with object
# @return 0 in case of error, 1 else
sub init {
33
    my ( $self, $args ) = @_;
34 35
    $args ||= {};

36
    if ( my $localconf = $self->confAcc->getLocalConf(MANAGERSECTION) ) {
37 38
        foreach ( keys %$localconf ) {
            $args->{$_} //= $localconf->{$_};
Xavier Guimard's avatar
Xavier Guimard committed
39
            $self->{$_} = $args->{$_} unless (/^(?:l|userL)ogger$/);
40
        }
41 42
    }

43 44 45
    # Manager needs to keep new Ajax behaviour
    $args->{noAjaxHook} = 0;

Xavier Guimard's avatar
Xavier Guimard committed
46 47
    return 0
      unless ( $self->Lemonldap::NG::Handler::PSGI::Router::init($args) );
48

49 50
    # TODO: manage errors
    unless ( -r $self->{templateDir} ) {
Xavier Guimard's avatar
Xavier Guimard committed
51
        $self->error("Unable to read $self->{templateDir}");
52
        return 0;
Xavier Guimard's avatar
Xavier Guimard committed
53
    }
54

55
    $self->{enabledModules} ||= "conf, sessions, notifications, 2ndFA";
56 57 58 59
    my @links;
    my @enabledModules =
      map { push @links, $_; "Lemonldap::NG::Manager::" . ucfirst($_) }
      split( /[,\s]+/, $self->{enabledModules} );
60
    extends 'Lemonldap::NG::Handler::PSGI::Router', @enabledModules;
61
    my @working;
62
    my $conf = $self->confAcc->getConf;
63 64 65 66
    unless ($conf) {
        require Lemonldap::NG::Manager::Conf::Zero;
        $conf = Lemonldap::NG::Manager::Conf::Zero::zeroConf();
    }
Xavier Guimard's avatar
Xavier Guimard committed
67
    for ( my $i = 0 ; $i < @enabledModules ; $i++ ) {
68
        my $mod = $enabledModules[$i];
69
        no strict 'refs';
70 71
        if ( &{"${mod}::addRoutes"}( $self, $conf ) ) {
            $self->logger->debug("Module $mod enabled");
72 73 74
            push @working, $mod;
        }
        else {
75
            $links[$i] = undef;
76 77
            $self->logger->error(
                "Module $mod can not be enabled: " . $self->error );
78
        }
Xavier Guimard's avatar
Xavier Guimard committed
79
    }
80
    return 0 unless (@working);
Xavier Guimard's avatar
Xavier Guimard committed
81 82
    $self->addRoute( links     => 'links',  ['GET'] );
    $self->addRoute( 'psgi.js' => 'sendJs', ['GET'] );
83

84
    my $portal = $conf->{portal};
85
    $portal =~ s#https?://([^/]*).*#$1#;
86
    $self->csp(
Xavier Guimard's avatar
Tidy  
Xavier Guimard committed
87
        "default-src 'self' $portal;frame-ancestors 'none';form-action 'self';"
88 89
    );

90
    $self->defaultRoute( $working[0]->defaultRoute );
91

92
# Find out more glyphicones at https://www.w3schools.com/icons/bootstrap_icons_glyphicons.asp
Xavier Guimard's avatar
Tidy  
Xavier Guimard committed
93 94 95 96
    my $linksIcons = {
        'conf'          => 'cog',
        'sessions'      => 'duplicate',
        'notifications' => 'bell',
97
        '2ndFA'         => 'wrench'
Xavier Guimard's avatar
Tidy  
Xavier Guimard committed
98
    };
99

100 101
    $self->links( [] );
    for ( my $i = 0 ; $i < @links ; $i++ ) {
102
        next unless ( defined $links[$i] );
103
        push @{ $self->links },
104 105 106 107 108
          {
            target => $enabledModules[$i]->defaultRoute,
            title  => $links[$i],
            icon   => $linksIcons->{ $links[$i] }
          };
Xavier Guimard's avatar
Xavier Guimard committed
109
    }
110

111
    $self->menuLinks( [] );
dcoutadeur dcoutadeur's avatar
dcoutadeur dcoutadeur committed
112 113
    if (
        my $portal =
114 115
        $conf->{cfgNum}
        ? Lemonldap::NG::Handler::PSGI::Main->tsv->{portal}->()
dcoutadeur dcoutadeur's avatar
dcoutadeur dcoutadeur committed
116 117
        : $conf->{portal}
      )
118
    {
119 120 121 122 123 124 125 126 127 128 129 130
        push @{ $self->menuLinks },
          {
            target => $portal,
            title  => 'backtoportal',
            icon   => 'home'
          },
          {
            target => "$portal?logout=1",
            title  => 'logout',
            icon   => 'log-out'
          };
    }
131
    1;
Xavier Guimard's avatar
Xavier Guimard committed
132 133
}

134
sub tplParams {
135 136 137 138 139 140 141 142
    return ( VERSION => $VERSION, );
}

sub javascript {
    my ($self) = @_;
    return
      'var formPrefix=staticPrefix+"forms/";var confPrefix=scriptname+"confs/";'
      . ( $self->links ? 'var links=' . to_json( $self->links ) . ';' : '' )
143 144
      . (
        $self->menuLinks
145
        ? 'var menulinks=' . to_json( $self->menuLinks ) . ';'
146 147
        : ''
      );
148 149
}

150 151 152 153 154 155 156 157 158 159 160
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;
}

Xavier Guimard's avatar
Xavier Guimard committed
161
1;
162 163 164 165
__END__

=head1 NAME

Xavier Guimard's avatar
Xavier Guimard committed
166 167
=encoding utf8

168 169 170 171 172
Lemonldap::NG::Manager - Perl extension for managing Lemonldap::NG Web-SSO
system.

=head1 SYNOPSIS

Xavier Guimard's avatar
Xavier Guimard committed
173 174 175
Use any of Plack launcher. Example:

  #!/usr/bin/env plackup
176 177 178 179 180
  
  use Lemonldap::NG::Manager;
  
  # This must be the last instruction ! See PSGI for more
  Lemonldap::NG::Manager->run($opts);
181 182 183 184 185 186

=head1 DESCRIPTION

Lemonldap::NG::Manager provides a web interface to manage Lemonldap::NG Web-SSO
system.

Xavier Guimard's avatar
Xavier Guimard committed
187 188
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`
Christophe Maudoux's avatar
Christophe Maudoux committed
189
directory. The REST API is described in REST-API.md file provided in source tree.
Xavier Guimard's avatar
Xavier Guimard committed
190

Christophe Maudoux's avatar
Christophe Maudoux committed
191 192
Lemonldap::NG Manager uses L<Plack> to be CGI, FastCGI and so on compatible.
It inherits of L<Lemonldap::NG::Handler::PSGI::Router>
Xavier Guimard's avatar
Xavier Guimard committed
193 194 195

=head1 ORGANIZATION

Christophe Maudoux's avatar
Christophe Maudoux committed
196
Lemonldap::NG Manager contains 6 parts:
Xavier Guimard's avatar
Xavier Guimard committed
197 198 199

=over

Xavier Guimard's avatar
Xavier Guimard committed
200
=item Configuration management
Xavier Guimard's avatar
Xavier Guimard committed
201

Xavier Guimard's avatar
Xavier Guimard committed
202
=item Session explorer
Xavier Guimard's avatar
Xavier Guimard committed
203

Xavier Guimard's avatar
Xavier Guimard committed
204
=item Notification explorer
Xavier Guimard's avatar
Xavier Guimard committed
205

Christophe Maudoux's avatar
Christophe Maudoux committed
206 207
=item Second Factors manager

Xavier Guimard's avatar
Xavier Guimard committed
208
=item Configuration builder (see L<Lemonldap::NG::Manager::Build>
Xavier Guimard's avatar
Xavier Guimard committed
209

Christophe Maudoux's avatar
Christophe Maudoux committed
210
=item Command line interface (see L<Lemonldap::NG::Manager::Cli>
Xavier Guimard's avatar
Xavier Guimard committed
211 212 213

=back

Christophe Maudoux's avatar
Christophe Maudoux committed
214
=head2 Static files generation
Xavier Guimard's avatar
Xavier Guimard committed
215

Christophe Maudoux's avatar
Christophe Maudoux committed
216
`scripts/jsongenerator.pl` file uses Lemonldap::NG::Manager::Build::Attributes,
217
Lemonldap::NG::Manager::Build::Tree and Lemonldap::NG::Manager::Build::CTrees to generate
Xavier Guimard's avatar
Xavier Guimard committed
218 219 220

=over

Xavier Guimard's avatar
Xavier Guimard committed
221
=item `site/htdocs/static/struct.json`:
Xavier Guimard's avatar
Xavier Guimard committed
222

Christophe Maudoux's avatar
Christophe Maudoux committed
223
main file containing the tree view;
Xavier Guimard's avatar
Xavier Guimard committed
224

Xavier Guimard's avatar
Xavier Guimard committed
225
=item `site/htdocs/static/js/conftree.js`:
Xavier Guimard's avatar
Xavier Guimard committed
226

Christophe Maudoux's avatar
Christophe Maudoux committed
227
generates Virtualhosts, SAML and OpenID-Connect partners sub-trees;
Xavier Guimard's avatar
Xavier Guimard committed
228

229
=item `Lemonldap::NG::Common::Conf::ReConstants`:
Xavier Guimard's avatar
Xavier Guimard committed
230

Xavier Guimard's avatar
Xavier Guimard committed
231
constants used by all Perl manager components;
Xavier Guimard's avatar
Xavier Guimard committed
232

Xavier Guimard's avatar
Xavier Guimard committed
233
=item `Lemonldap::NG::Common::Conf::DefaultValues`:
Xavier Guimard's avatar
Xavier Guimard committed
234

Xavier Guimard's avatar
Xavier Guimard committed
235
constants used to read configuration.
Xavier Guimard's avatar
Xavier Guimard committed
236 237

=back
238 239 240 241 242 243 244 245

=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' } );

Xavier Guimard's avatar
Xavier Guimard committed
246 247 248 249 250 251 252 253
=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
254
  ;                Lemonldap::NG::Handler::PSGI::Router doc.
Xavier Guimard's avatar
Xavier Guimard committed
255 256
  protection     = manager
  
Christophe Maudoux's avatar
Christophe Maudoux committed
257
  ;enabledModules: Modules to display. Default to `conf, sessions, notifications, 2ndFA`
Christophe Maudoux's avatar
Christophe Maudoux committed
258
  enabledModules = conf, sessions, notifications, 2ndFA
Xavier Guimard's avatar
Xavier Guimard committed
259 260 261 262 263 264 265 266 267 268 269 270
  
  ;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
  
Christophe Maudoux's avatar
Christophe Maudoux committed
271
  ;templateDir:    path to the directory containing HTML templates
Xavier Guimard's avatar
Xavier Guimard committed
272 273 274
  ;                See Lemonldap::NG::Common::PSGI doc for more
  templateDir    = /usr/share/lemonldap-ng/manager/

275 276
=head1 SEE ALSO

Xavier Guimard's avatar
Xavier Guimard committed
277
L<http://lemonldap-ng.org/>
278

279
=head1 AUTHORS
280

281 282
=over

Xavier Guimard's avatar
Xavier Guimard committed
283
=item LemonLDAP::NG team L<http://lemonldap-ng.org/team>
284 285

=back
286 287 288 289

=head1 BUG REPORT

Use OW2 system to report bug or ask for features:
Xavier Guimard's avatar
Xavier Guimard committed
290
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
291

Xavier Guimard's avatar
Xavier Guimard committed
292 293 294
Note that if you want to post a ticket for a conf upload problem, please
see L<Lemonldap::NG::Manager::Conf::Parser> before.

295 296 297 298 299 300 301
=head1 DOWNLOAD

Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>

=head1 COPYRIGHT AND LICENSE

Xavier Guimard's avatar
Xavier Guimard committed
302
See COPYING file for details.
303 304

This library is free software; you can redistribute it and/or modify
305 306 307 308 309 310 311 312 313 314 315
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/>.
316 317

=cut