Skip to content

Instantly share code, notes, and snippets.

@wchristian
Created November 10, 2011 16:55
Show Gist options
  • Save wchristian/1355387 to your computer and use it in GitHub Desktop.
Save wchristian/1355387 to your computer and use it in GitHub Desktop.
sessions and auth in web simple
use strictures;
package Web::SimpleX::Helper::ActionWithRender;
use Sub::Exporter::Simple 'action';
use Try::Tiny;
use Scalar::Util 'blessed';
sub action {
my ( $action, $view ) = @_;
return sub {
my ( $self, @args ) = @_;
$view ||= do {
if ( my $meth = $self->can( 'default_view' ) ) {
$self->$meth;
}
else {
'template';
}
};
my $view_args = try {
while ( ref $action and ref $action eq 'CODE' ) {
$action = $action->( $self, $view );
}
$self->$action( @args );
}
catch {
my $action_error = "action_error_$view";
$self->$action_error( $_ );
};
my $plack_response = try {
return $view_args->finalize if blessed( $view_args ) and $view_args->isa( "Plack::Response" );
my $render = "render_$view";
return $self->$render( $view_args );
}
catch {
my $error_view = "view_error_$view";
$self->$error_view( $_ );
};
return $plack_response;
};
}
1;
sub dispatch_request {
my ( $self, $env ) = @_;
if ( DEBUG ) {
require Carp;
$SIG{__WARN__} = \&Carp::cluck;
$SIG{__DIE__} = \&Carp::confess;
}
$self->req( Plack::Request->new( $env ) );
(
'' => sub { Plack::Middleware::Session->new( store => $self->session_store ) },
GET => sub {
(
'/' => action( 'root_page' ),
'/reset_password' => action( 'reset_password_form' ),
'/passwort' => auth_action( 'password_form' ),
'/kundenkonto' => auth_action( 'account_overview' ),
'/dokumente' => auth_action( 'documents_page' ),
'/rechnungen' => auth_action( 'bill_overview' ),
'/produkte' => auth_action( 'product_overview' ),
'/logout' => auth_action( 'handle_logout' ),
'/welcome' => auth_action( 'welcome_page' ),
'/password_check' => auth_action( 'password_check_form' ),
'/zahlung' => auth_action( 'payment_option_page' ),
'/zahlungsdetails' => auth_action( 'payment_details' ),
'/adressdaten' => auth_action( 'adress_data' ),
'/bestellen' => auth_action( 'main_order_form' ),
'/rechnungen/*' => auth_action( 'bill_download', 'download' ),
);
},
POST => sub {
(
'/reset_password' => action( 'reset_password' ),
'/login' => action( 'handle_login', 'json' ),
'/send_reset_code' => action( 'send_reset_code', 'json' ),
'/zahlungsdetails' => auth_action( 'send_payment_detail_change', 'json' ),
'/adressdaten' => auth_action( 'adress_data_change', 'json' ),
'/get_phone_pass' => double_auth_action( 'get_phone_pass', 'json' ),
'/passwort' => double_auth_action( 'set_password', 'json' ),
);
},
'' => action( 'error_404' ),
);
}
sub action_error_json {
my ( $self, $error ) = @_;
warn $self->req->address . ": $error";
return { error => "unknown" };
}
sub action_error_template {
my ( $self, $error ) = @_;
warn $self->req->address . ": $error";
return [ "handle_uri_error.xml", {}, 500 ];
}
sub error_404 {
my ( $self ) = @_;
warn "DEBUG/NOTICE: handle_uri: " . $self->req->path_info . " isn't handled here\n" if ( DEBUG );
return [ "index.xml", {}, 404 ];
}
sub root_page { ["index.xml"] }
sub base_url {
my ( $self ) = @_;
return {
url => ( ( $self->req->port == 443 ) ? "https://" : "http://" ) . $self->req->env->{SERVER_NAME},
ssl => ( ( $self->config->{cms}{ssl_available} ) ? "https://" : "http://" ) . $self->req->env->{SERVER_NAME},
nossl => "http://" . $self->req->env->{SERVER_NAME},
};
}
sub auth_action {
my ( $action, $view ) = @_;
my $guard = sub {
my ( $self, $real_view ) = @_;
return "auth_failure_$real_view" if !$self->is_logged_in;
return $action;
};
return action( $guard, $view );
}
sub auth_failure_template { $_[0]->redirect( '/' ) }
sub auth_failure_json { { error => "Zugriff verweigert." } }
sub double_auth_action {
my ( $action, $view ) = @_;
my $guard = sub {
my ( $self, $real_view ) = @_;
my $pw = $self->req->param( "password_check" );
return "auth_failure_$real_view" if !$pw or !$self->servicepw_ok( $self->is_logged_in, $pw );
return $action;
};
return auth_action( $guard, $view );
}
sub is_logged_in { $_[0]->req->session->{kdnr} }
sub redirect {
my ( $self, $url ) = @_;
my $res = Plack::Response->new;
$res->redirect( $url );
return $res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment