Apache2-ASP
view release on metacpan or search on metacpan
lib/Apache2/ASP/Manual/BestPractices.pod view on Meta::CPAN
C<site1::user::logout>
=back
=head1 FILE UPLOADS
Just inherit from L<Apache2::ASP::MediaManager> unless you need more control.
See the documentation for L<Apache2::ASP::MediaManager> for more information.
=head1 VALIDATION
Apache2::ASP supports - but does not provide - server-side validation. In fact,
it is recommended that all validation is performed on the server, in one way or
another.
AJAX may be your preferred means of doing form validations and such, which Apache2::ASP
fully supports. Apache2::ASP simply does not B<require> the use of AJAX or any other
idiom.
=head2 How-To
The recommended form validation idiom for Apache2::ASP is as follows:
B<The Form>:
<%
if( my $args = delete($Session->{__lastArgs}) )
{
$Form->{$_} = $args->{$_} foreach keys(%$args);
}# end if()
my $errors = delete($Session->{validation_errors}) || { };
my $errLabel = sub {
my $name = shift;
return unless $errors->{$name};
%><span class="field_error"><%= $Server->HTMLEncode( $errors->{$name} ) %></span><%
};
%>
<%
if( my $msg = delete($Session->{msg}) ) {
%>
<div class="message"><%= $Server->HTMLEncode( $msg ) %></div>
<%
}# end if()
%>
<%
if( $errors->{general} ) {
%>
<div class="general_error"><%= $Server->HTMLEncode( $errors->{general} ) %></div>
<%
}# end if()
%>
<form action="/handlers/site1.user.login" method="post">
<input type="text" name="username" value="<%= $Server->HTMLEncode( $Form->{username} ) %>" />
<% $errLabel->( 'username' ); %>
<br />
<input type="password" name="password" />
<% $errLabel->( 'password' ); %>
<br />
<input type="submit" value="Submit" />
</form>
The form submits to the URI C</handlers/site1.user.login> which maps to the package
C<site1::user::login>.
It is recommended that inside your C</etc> folder you have a YAML file, C</etc/properties.yaml>:
B<The YAML File>: (C</etc/properties.yaml>)
---
user_login:
username:
is_missing: Required
is_invalid: Invalid username
password:
is_missing: Required
is_invalid: Invalid password
general:
success: Successfully Logged In
fail: Invalid username and/or password. Please try again.
B<The Handler>: (C</handlers/site1/user/login.pm>)
package site1::user::login;
use strict;
use warnings 'all';
use base 'Apache2::ASP::FormHandler';
use vars __PACKAGE__->VARS;
use Data::Properties::YAML;
#============================================================================
sub run
{
my ($s, $context) = @_;
if( my $errors = $s->validate( $context ) )
{
# We found some kind of validation error:
$Session->{__lastArgs} = $Form;
$Session->{validation_errors} = $errors;
return $Response->Redirect( $ENV{HTTP_REFERER} );
}# end if()
# Success! - no validation errors:
my ($user) = find_user( ... );
$Session->{user} = $user;
# Find our success message:
my $props = Data::Properties::YAML->new(
properties_file => $Config->web->application_root . '/etc/properties.yaml'
)->user_login;
$Session->{msg} = $props->general->success;
# Redirect the user to the logged-in page:
return $Response->Redirect("/logged-in.asp");
}# end run()
#============================================================================
sub validate
{
my ($s, $context) = @_;
# Remove leading and trailing whitespace:
map {
$Form->{$_} =~ s/^\s+//;
$Form->{$_} =~ s/\s+$//;
} keys(%$Form);
my $props = Data::Properties::YAML->new(
properties_file => $Config->web->application_root . '/etc/properties.yaml'
)->user_login;
my $errors = { };
no warnings 'uninitialized';
# username:
if( length($Form->{username}) )
{
# Username cannot contain whitespace:
if( $Form->{username} =~ m/\s/ )
{
$errors->{username} = $props->username->is_invalid;
}# end if()
}
else
{
$errors->{username} = $props->username->is_missing;
}# end if()
# password:
if( length($Form->{password}) )
{
# Password cannot contain whitespace:
if( $Form->{password} =~ m/\s/ )
{
$errors->{password} = $props->password->is_invalid;
}# end if()
}
else
{
$errors->{password} = $props->password->is_missing;
}# end if()
# Only check to see if the user exists if we haven't encountered other errors:
unless( keys(%$errors) )
{
if( ! find_user( ... ) )
{
$errors->{general} = $props->general->fail;
}# end if()
}# end unless()
return unless keys(%$errors);
return $errors;
}# end validate()
1;# return true:
=head1 UNIT TESTING
Unit testing was the number one reason behind the development of Apache2::ASP.
Apache2::ASP offers a unit testing environment that is not dependent on Apache
or any other server.
Unit tests are made possible via instances of L<Apache2::ASP::Test::Base> and
use L<Apache2::ASP::Test::UserAgent> to make "requests" to ASP scripts and handlers
in your Apache2::ASP web application.
=head2 Example
Supposing your website is at C</var/www/www.example.com>, create a folder C</t>
at C</var/www/www.example.com/t>.
Inside C</t> create C</t/00-basic.t> which contains:
#!/usr/bin/env perl -w
use strict;
use warnings 'all';
use Test::More 'no_plan';
use base 'Apache2::ASP::Test::Base';
# Create our base test object:
my $s = __PACKAGE__->SUPER::new();
# Make a request:
my $res = $s->ua->get("/index.asp");
# $res is a normal HTTP::Response object:
ok( $res->is_success => "Got /index.asp" );
like $res->content, qr/Hello, World/, "Contents look right";
is( $res->header('content-type') => 'text/html' );
Run your tests with:
prove t
All of your tests will be run.
=head1 CODE COVERAGE
( run in 1.339 second using v1.01-cache-2.11-cpan-39bf76dae61 )