use strict; use warnings; package Plack::Middleware::SimpleLogin; use feature ':5.10'; use parent qw/Plack::Middleware/; use Plack::Util::Accessor qw( secure check_pass pass_req ); use Plack::Response; use Plack::Request; sub call { my($self, $env) = @_; my $path = $env->{PATH_INFO}; if( $path eq '/login' ){ return $self->login( $env ); } elsif( $path eq '/logout' ){ return $self->logout( $env ); } return $self->app->( $env ); } sub login { my($self, $env) = @_; my $login_error; if( $self->secure && $env->{'psgi.url_scheme'} ne 'https' ){ my $res = Plack::Response->new; my $secure_url = 'https://' . $env->{SERVER_NAME} . $env->{PATH_INFO}; $res->redirect( $secure_url ); return $res->finalize; } my $params = Plack::Request->new( $env )->parameters; if( defined $env->{user} ){ return 'Already logged in'; } elsif( $env->{REQUEST_METHOD} eq 'POST' ){ my $user_id; ( $login_error, $user_id ) = $self->check_pass->( $params->get( 'username' ), $params->get( 'password' ) ); if( !$login_error ){ $env->{'psgix.session'}{user_id} = $user_id; $env->{'psgix.session'}{remember} = 1 if $params->get( 'remember' ); my $res = Plack::Response->new; my $redir_to = delete $env->{'psgix.session'}{redir_to}; $redir_to = '/' if URI->new( $redir_to )->path eq $env->{PATH_INFO} || !length( $redir_to ); $res->redirect( $redir_to ); return $res->finalize; } } $env->{'psgix.session'}{redir_to} ||= $env->{HTTP_REFERER}; my $form = $self->render_form( username => $params->get( 'username' ), login_error => $login_error, redir_to => $env->{'psgix.session'}{redir_to}, ); if( $self->pass_req ){ $env->{SimpleLoginForm} = $form; return $self->app( $env ); } else{ return [ 200, { 'Content-Type' => 'text/html', }, [ "
$form" ] ]; } } sub render_form { my $self = shift; my ( %params ) = @_; my $out = ''; if( $params{login_error} ){ $out .= "