[cgiapp] Proposal: CGI::Application::Plugin::ValidateQuery

2009-04-11 Thread Mark Stosberg

I'm considering producing a CGI::Application plugin for light weight query
validation using Params::Validate. I've drafted the POD for it, and
that's below.  

The implementation would include one novel technical concept that I
haven't notice in use before in a CGI::Application project.

We wanted to clean up the API, so that instead of this:

 my $err_page = $self-validate_query;
 return $err_page if $err_page

We could just do this:

 $self-validate_query;

This means we had to find some other way to interrupt the flow and
return our error page. The solution is to write a suicide note and then
pull the trigger. Or rather, in validate_query(), if validation fails,
we do a just-in-time setting of error_mode(), and then die, which
interrupts the flow and triggers the error_mode to be called.

The solution seems reasonable, as a general error_mode() would still
remain in effect, and if some reason you don't want interrupt the flow,
just trap the exception the usual way:

 eval { $self-validate_query; }

I hadn't considered it until now, but perhaps we could also use
Exception::Class so users could easily distinquish between
death-by-validation failure and unexpected-death.

Now that I've thought of this approach, it makes me want to apply to to
the ::ValidateRM interface.  Anyone see a reason not to take this
approach for this plugin, or ValidateRM?




=head1 NAME

CGI::Application::Plugin::ValidateQuery

=head1 SYNOPSIS

 sub setup {
 my $self = shift;
 
 $self-validate_query_config(
# define a page to show for invalid queries, or default to
# serving a plain, internal page
error_mode =  'my_invalid_query_run_mode',
log_level  = 'notice',
 );

 }

 sub my_run_mode {
my $self = shift;

# validate the query and return a standard error page on failure.
$self-validate_query(
pet_id= SCALAR,
direction = { type = SCALAR, default = 'up' },
);

# go on with life...

 }

=head1 DESCRIPTION

This plugin is for small query validation tasks. For example, perhaps
you link to a page where a pet_id is required, and you need to reality
check that this exists or return essentially a generic error message to
the user.

Even if your application generates the link, it may become altered
through tampering, malware, or other unanticipated events. 

This plugin uses Params::Validate to validate the query string.  You
can define your own error page to return on failure, or we'll supply a
plain default one internally. 

You may also define a Clog_level, if you do, we will also log each
validation failure at the chosen level like this:

 $self-log-$loglevel(Query validation failed: $@);

LCGI::Application::Plugin::LogDispatch is one plugin which implements
this logging API.

=head2 validate_query 

$self-validate_query(
pet_id = SCALAR,
type   = { type = SCALAR, default = 'food' },
log_level = 'critical', # optional
 );

Validates C $self-query  using LParams::Validate. If any required
query param is missing or invalid, the  run mode defined with C
validate_query_config  will be used, or a plain internal page will be
returned by default. C validate_query_config  is usually called in
C setup() , or a in a project super-class.

If log_level is defined, it will override the the log file provided in
C validate_query_config  and log a validation failure at that log
evel 

If you set a default, the query will be modified with the new value.

=cut

sub validate_query {

}

=head2 IMPLENTATION NOTES

We set local $Params::Validate::NO_VALIDATION = 0; to be sure that
Params::Validate works for us, even if is globally disabled.

To alter the application flow when validation fails, we set
'error_mode()' at the last minute, and then die, so the error mode is
triggered. Other uses of error_mode() should continue to work as normal.

This module is intended to be use for simple query validation tasks,
such as a link with  query string with a small number of arguments. For
larger validation tasks, especially for processing for submissions using
L Data::FormValidator  is recommended, along with L
CGI::Application::ValidateRM  if you using CGI::Application. 

=head2 FUTURE

This concept could be extended to all check values set through
$self-param(), or through $ENV{PATH_INFO} .

This plugin does handle file upload validations, and won't in the
future.

Providing untainting is not a goal of this module, but if it's easy and
someone else provides a patch, perhaps support will be added. 

=head1 AUTHOR

Mark Stosberg C m...@summersault.com 



#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
##  

Re: [cgiapp] Proposal: CGI::Application::Plugin::ValidateQuery

2009-04-11 Thread Michael Peters

Mark Stosberg wrote:


This means we had to find some other way to interrupt the flow and
return our error page. The solution is to write a suicide note and then
pull the trigger. Or rather, in validate_query(), if validation fails,
we do a just-in-time setting of error_mode(), and then die, which
interrupts the flow and triggers the error_mode to be called.



Now that I've thought of this approach, it makes me want to apply to to
the ::ValidateRM interface.  Anyone see a reason not to take this
approach for this plugin, or ValidateRM?


Some people feel that exceptions shouldn't be used for flow control (I'm not 
usually one of them) but some of them are very opinionated. Just wanted to bring 
that up.


--
Michael Peters
Plus Three, LP


#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####