diff options
Diffstat (limited to 'lib/FPanel/Login.pm')
-rw-r--r-- | lib/FPanel/Login.pm | 245 |
1 files changed, 117 insertions, 128 deletions
diff --git a/lib/FPanel/Login.pm b/lib/FPanel/Login.pm index 55188f6..506a7b8 100644 --- a/lib/FPanel/Login.pm +++ b/lib/FPanel/Login.pm @@ -14,6 +14,7 @@ use CGI::Application::Plugin::ConfigAuto qw/cfg/; use Net::LDAP; use Authen::SASL; +use File::Spec::Functions qw/catfile catdir/; # This method is called right before the 'setup' method below. It @@ -21,21 +22,22 @@ use Authen::SASL; sub cgiapp_init { my $self = shift; + my %CFG = $self->cfg; + $self->session_config( CGI_SESSION_OPTIONS => [ 'driver:DB_File;serializer:freezethaw' , $self->query - , { FileName => '/tmp/fpanel-cgisessions.db', + , { FileName => $CFG{session_db_filename}, UMask => 0600 } - , { name => 'FripostAdminPanel_SessAuth' } + , { name => $CFG{session_authname} } ], - DEFAULT_EXPIRY => '+24h', - COOKIE_PARAMS => { -name => 'FripostAdminPanel_SessAuth' - , -path => '/cgi-bin/' + DEFAULT_EXPIRY => $CFG{session_expire}, + COOKIE_PARAMS => { -name => $CFG{session_authname} + , -path => $CFG{'cgi-bin'} # Expires when the browser quits , -expires => -1 ,'-max-age' => -1 - # TODO: Turn the secure flag for HTTPS connections - , -secure => 0 + , -secure => $CFG{secure_cookie} # We are not using JavaScript in this framework , -httponly => 1 }, @@ -44,12 +46,25 @@ sub cgiapp_init { # Configure authentication parameters $self->authen->config( - DRIVER => [ 'Generic' - , sub { &authenticate(@_) } ], + DRIVER => [ 'Generic', sub { + my ($u,$p) = @_; + my ($l,$d) = split /@/, $u, 2; + + unless (defined $d) { + $CFG{default_realm} // return 0; + $d = $CFG{default_realm}; + $u .= '@'.$d; + } + my $bind_dn = "fvu=$l,fvd=$d,". join (',', @{$CFG{ldap_suffix}}); + + my $ldap = Net::LDAP->new( $CFG{ldap_uri} ); + my $mesg = $ldap->bind ( $bind_dn, password => $p ); + $mesg->code ? 0 : $u; + } ], STORE => 'Session', LOGIN_RUNMODE => 'login', RENDER_LOGIN => \&login_box, - LOGIN_SESSION_TIMEOUT => { IDLE_FOR => '30m' }, + LOGIN_SESSION_TIMEOUT => { IDLE_FOR => $CFG{timeout} }, LOGOUT_RUNMODE => 'logout', ); @@ -59,55 +74,58 @@ sub cgiapp_init { # This method is called by the inherited new() constructor method. +# It defines the path for templates and chooses the Run Mode depending +# on the URL and query string. sub setup { my $self = shift; - $self->tmpl_path( 'template/' ); - $self->mode_param( \&mymode_param ); -} + $self->tmpl_path( catdir ( $self->cfg('pwd'), $self->cfg('tmpl_path') ) ); + $self->mode_param( sub { + my $self = shift; + my $q = $self->query; + print STDERR $ENV{PATH_INFO} . '?' . $q->query_string, "\n"; -# This method chooses 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 ''; + # The user just logged in + return 'okay' if (defined $q->param('authen_username')) and + (defined $q->param('authen_password')); + my $a = $q->param('a'); - my $mode = 'DomainList'; + return 'login' if defined $a and $a eq 'login'; + return 'logout' if defined $a and $a eq 'logout'; - 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'; + # /domain/{user,alias,list}/?requests + my ($null,$domain,$local,$crap) = split /\//, $ENV{PATH_INFO}; + + return 'DomainList' unless (defined $null) and $null eq ''; + + unless (defined $domain and $domain ne '') { + if (defined $a) { + return 'AddDomain' if $a eq 'AddDomain'; + } + return 'DomainList'; } - elsif ($a eq 'logout') { - $mode = 'logout'; + + unless (defined $local and $local ne '') { + if (defined $a) { + return 'EditDomain' if $a eq 'edit'; + return 'AddAccount' if $a eq 'AddAccount'; + return 'AddAlias' if $a eq 'AddAlias'; + } + return 'LocalList'; } - elsif ($a eq 'AddDomain') { - $mode = 'AddDomain'; + + unless (defined $crap and $crap ne '') { + return 'LocalEdit'; } - } - elsif ($#path < 0) { - $mode = 'DomainList'; - } - elsif ($path[1] ne '') { - # $domain = $path[1]; - $mode = 'index'; - } - print STDERR $q->self_url, "\n"; - print STDERR $ENV{PATH_INFO} . '?' . $q->query_string - . " -> " - . $mode - . "\n"; - return $mode; + + return 'DomainList'; + }); } +# This Run Mode redirects the freshly logged in user to the URL s/he +# wanted to visit. sub okay : Runmode { my $self = shift; my $destination = $self->query->param('destination') // @@ -115,100 +133,71 @@ sub okay : Runmode { 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 $self->authen->is_authenticated; - - $self->query->param( destination => $self->query->self_url) - unless (defined $self->query->param('destination')); - return $self->login_box; +# This is the login Run Mode. +sub login : Runmode { + my $self = shift; + + # A logged user has no reason to ask for a relogin, so s/he is seen as + # an intruder + $self->authen->logout if $self->authen->is_authenticated; + + # Do not come back here on the next Run Mode + $self->query->delete('a') if (defined $self->query->param('a')) and + $self->query->param('a') eq 'login'; + + # Where the users wants to go + $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' - , cache => 1 - , utf8 => 1 ); - - my $destination = $self->query->param('destination') // - $self->mymode_param(); - - $template->param(ERROR => $self->authen->login_attempts); - $template->param(DESTINATION => $destination); - return $template->output; +# This method loads the login form. +sub login_box { + my $self = shift; + + my $template = $self->load_tmpl( 'login.html', cache => 1, utf8 => 1 ); + $template->param( ERROR => $self->authen->login_attempts ); + $template->param( DESTINATION => $self->query->param('destination') ); + + return $template->output; } + +# This is the logout Run Mode. sub logout : Runmode { - my $self = shift; - - if ($self->authen->is_authenticated) { - $self->authen->logout; - $self->session->delete; - $self->session->flush; - } - - # Do not come back here afterwards - $self->query->delete( 'a' ) - if (defined $self->query->param('a')) and - $self->query->param('a') eq 'logout'; - - return $self->redirect($self->query->self_url); + my $self = shift; + + if ($self->authen->is_authenticated) { + # Log out the user, delete the session and flush it off the disk + $self->authen->logout; + $self->session->delete; + $self->session->flush; + } + + # Do not come back here on the next Run Mode + $self->query->delete('a') if (defined $self->query->param('a')) and + $self->query->param('a') eq 'logout'; + + return $self->redirect($self->query->self_url); } +# This is the error Run Mode. Users are not suppose to see that unless +# the CGI crashes :P sub error_rm : ErrorRunmode { - my $self = shift; - my $error = shift; - - my $template = $self->load_tmpl('error.html' - , cache => 1 - , utf8 => 1 ); - $template->param(NAME => 'ERROR'); - $template->param(MESSAGE => $error); - $template->param(URL => $self->query->url); - - return $template->output; + my $self = shift; + my $error = shift; + + my $template = $self->load_tmpl( 'error.html', cache => 1, utf8 => 1 ); + $template->param( EMAIL => $self->cfg('report_email') ); + $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; |