diff options
Diffstat (limited to 'lib/FPanel/Login.pm')
| -rw-r--r-- | lib/FPanel/Login.pm | 194 | 
1 files changed, 194 insertions, 0 deletions
| diff --git a/lib/FPanel/Login.pm b/lib/FPanel/Login.pm new file mode 100644 index 0000000..8f0af21 --- /dev/null +++ b/lib/FPanel/Login.pm @@ -0,0 +1,194 @@ +package FPanel::Login; + +use strict; +use warnings; +use utf8; + +use base 'CGI::Application'; + +use CGI::Application::Plugin::AutoRunmode; +use CGI::Application::Plugin::Session; +use CGI::Application::Plugin::Authentication; +use CGI::Application::Plugin::Redirect; +use CGI::Application::Plugin::ConfigAuto qw/cfg/; + +use Net::LDAP; +use Authen::SASL; + + +# This method is called right before the 'setup' method below. It +# initializes the session and authentication configurations. +sub cgiapp_init { +    my $self = shift; + +    $self->session_config( +        # TODO: Use a Berkeley DB instead +        CGI_SESSION_OPTIONS => [ 'driver:File' +                               , $self->query +                               , { Directory => '/tmp/fpanel-cgisess' } +                               ], +        DEFAULT_EXPIRY      => '+24h', +        COOKIE_PARAMS       => { -path    => '/index.cgi/' +                               , -httponly => 1 +#       # TODO: Turn the secure flag for HTTPS connections +                               , -secure  => 0 +                               }, +       SEND_COOKIE         => 1, +    ); +   +    # Configure authentication parameters +    $self->authen->config( +        DRIVER                => [ 'Generic' +                                 , \&authenticate ], +        STORE                 => 'Session', +        LOGOUT_RUNMODE        => 'logout', +        LOGIN_RUNMODE         => 'login', +        RENDER_LOGIN          => \&login_box, +        LOGIN_SESSION_TIMEOUT => { IDLE_FOR => '30m' },  +    ); +   +    # The run modes that require authentication +    $self->authen->protected_runmodes( qw /okay error_rm/ ); +} + + +# This method is called by the inherited new() constructor method. +sub setup { +    my $self = shift; + +    $self->tmpl_path( 'template/' ); +    $self->mode_param( \&mymode_param ); +} + + +# This method choses the Run Mode depending on the URL and query string. +sub mymode_param { +    my $self = shift; +    my $q = $self->query; +    my @path = split /\//, $ENV{PATH_INFO}; +    pop @path if $#path > 0 and $path[$#path] eq ''; + +    my $mode = 'DomainList'; + +      if (defined $q->param('authen_username') and +         defined $q->param('authen_password')) { +    $mode = 'okay' +    } +    elsif (defined $q->param('a')) { +        my $a = $q->param('a'); +        if ($a eq 'login') { +            $mode = 'login'; +        } +        elsif ($a eq 'logout') { +            $mode = 'logout'; +        } +        elsif ($a eq 'AddDomain') { +            $mode = 'AddDomain'; +        } +    } +    elsif ($#path < 0) { +        $mode = 'DomainList'; +    } +    elsif ($path[1] ne '') { +      # $domain = $path[1]; +      $mode = 'index'; +    } +    print STDERR $ENV{PATH_INFO} . '?' . $q->query_string +                . " -> " +                . $mode +                . "\n"; +    return $mode; +} + + +sub okay : Runmode { +    my $self = shift; +    my $destination = $self->query->param('destination') // +                      $self->query->url; +    return $self->redirect($destination); +} + +sub login : Runmode { +  my $self   = shift; +  my $url = $self->query->url; + +  # Do not come back here afterwards +  $self->query->delete( 'a' ) +      if (defined $self->query->param('a')) and +         $self->query->param('a') eq 'login'; + +  # A logged user has no reason to ask for a relogin +  $self->authen->logout() if defined $self->authen->username; + +  $self->query->param( destination => $self->query->self_url) +    unless (defined $self->query->param('destination')); + +  return $self->login_box; +} + +sub login_box { +  my $self = shift; + +  my $template = $self->load_tmpl('login.html'); + +  my $destination = $self->query->param('destination') // +                    $self->mymode_param(); + +  $template->param(ERROR => $self->authen->login_attempts); +  $template->param(DESTINATION => $destination); + +  return $template->output; +} + +sub logout : Runmode { +  my $self = shift; + +  if ($self->authen->username) { +    $self->authen->logout; +    $self->session->delete; +  } +  return $self->redirect($self->query->url . '/'); +} + +sub error_rm : ErrorRunmode { +  my $self = shift; +  my $error = shift; +  my $template = $self->load_tmpl("template/error.html"); +  $template->param(NAME => 'ERROR'); +  $template->param(MESSAGE => $error); +  $template->param(URL => $self->query->url); +  return $template->output; +} + +#sub AUTOLOAD : Runmode { +#  my $self = shift; +#  my $rm = shift; +#  my $template = $self->load_tmpl("template/error.html"); +#  $template->param(NAME => 'AUTOLOAD'); +#  $template->param(MESSAGE => +#    "Error: could not find run mode \'$rm\'\n"); +#  $template->param(URL => $self->query->url); +#  return $template->output; +#} + +sub authenticate { +#    my $self = shift; + +    my ($u, $p) = @_; +    my ($l,$d) = split /@/, $u, 2; + + +#    my %CFG = $self->cfg; + +    unless (defined $d) { +      $d  = 'fripost.org'; +      $u .= '@'.$d; +    } +    my $ldap = Net::LDAP->new( 'ldap://127.0.0.1:389' ); +    my $mesg = $ldap->bind ( "fvu=$l,fvd=$d,ou=virtual,o=mailHosting,dc=fripost,dc=dev" +                           , password => $p ); +    $mesg->code ? 0 : $u; +} + +1; + | 
