Validate input
This commit is contained in:
parent
84182fe25b
commit
e4aad2ccbd
|
@ -49,6 +49,6 @@ Add the `-v` option for more verbose output
|
|||
|
||||
## TODOs
|
||||
|
||||
1. Input validation
|
||||
1. More tests
|
||||
1. /spam route would be interesting
|
||||
1. Include the total number of visitors or messages
|
||||
|
|
|
@ -132,7 +132,7 @@ h1#top {
|
|||
}
|
||||
|
||||
.error {
|
||||
border-style: solid;
|
||||
border-style: dashed;
|
||||
border-color: red;
|
||||
color: red;
|
||||
padding: 1em;
|
||||
|
@ -140,6 +140,12 @@ h1#top {
|
|||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.field-with-error {
|
||||
border-style: dotted;
|
||||
border-color: red;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1023px) {
|
||||
.inner {
|
||||
max-width: 95%;
|
||||
|
|
|
@ -46,6 +46,9 @@ under sub ($c) {
|
|||
|
||||
$c->session(expiration => 604800);
|
||||
|
||||
$c->stash(status => 403)
|
||||
if $c->flash('error') eq 'This message was flagged as spam';
|
||||
|
||||
1;
|
||||
};
|
||||
|
||||
|
@ -64,7 +67,9 @@ get '/' => sub ($c) {
|
|||
} => 'index';
|
||||
|
||||
any [qw{GET POST}], '/sign' => sub ($c) {
|
||||
if ($c->req->method() eq 'POST') {
|
||||
my $v = $c->validation();
|
||||
|
||||
if ($c->req->method eq 'POST' && $v->has_data) {
|
||||
my $name = $c->param('name') || 'Anonymous';
|
||||
my $url = $c->param('url');
|
||||
my $message = $c->param('message');
|
||||
|
@ -73,37 +78,37 @@ any [qw{GET POST}], '/sign' => sub ($c) {
|
|||
$message =~ /$RE{URI}{HTTP}{-scheme => qr<https?>}/ ? 1 :
|
||||
0;
|
||||
|
||||
if ($message) {
|
||||
$v->required('name' )->size(1, 63);
|
||||
$v->required('message')->size(2, 2000);
|
||||
$v->optional('url', 'not_empty')->size(1, 255)
|
||||
->like(qr/$RE{URI}{HTTP}{-scheme => qr<https?>}/);
|
||||
|
||||
unless ($v->has_error) {
|
||||
$c->message->create_post($name, $message, $url, $spam);
|
||||
|
||||
$c->flash(error => 'This message was flagged as spam') if $spam;
|
||||
$c->redirect_to('index');
|
||||
}
|
||||
else {
|
||||
$c->flash(error => 'Message cannot be blank');
|
||||
$c->redirect_to('sign');
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Try to randomize things for the CAPTCHA challenge. The
|
||||
# string 'false' actually evaluates to true so this is an
|
||||
# attempt to confuse a (hypothetical) bot that would try to
|
||||
# select what it thinks is the right answer
|
||||
my @answers = shuffle(0, 'false', undef);
|
||||
my $right_answer_label = 'I\'m ready to sign (choose this one)';
|
||||
my @wrong_answer_labels = shuffle(
|
||||
'I don\'t want to sign (wrong answer)',
|
||||
'This is spam/I\'m a bot, do not sign'
|
||||
);
|
||||
|
||||
$c->stash(
|
||||
answers => \@answers,
|
||||
right_answer_label => $right_answer_label,
|
||||
wrong_answer_labels => \@wrong_answer_labels
|
||||
);
|
||||
# Try to randomize things for the CAPTCHA challenge. The
|
||||
# string 'false' actually evaluates to true so this is an
|
||||
# attempt to confuse a (hypothetical) bot that would try to
|
||||
# select what it thinks is the right answer
|
||||
my @answers = shuffle(0, 'false', undef);
|
||||
my $right_answer_label = 'I\'m ready to sign (choose this one)';
|
||||
my @wrong_answer_labels = shuffle(
|
||||
'I don\'t want to sign (wrong answer)',
|
||||
'This is spam/I\'m a bot, do not sign'
|
||||
);
|
||||
|
||||
$c->render();
|
||||
}
|
||||
$c->stash(
|
||||
answers => \@answers,
|
||||
right_answer_label => $right_answer_label,
|
||||
wrong_answer_labels => \@wrong_answer_labels
|
||||
);
|
||||
|
||||
$c->render();
|
||||
};
|
||||
|
||||
# Send it
|
||||
|
|
|
@ -4,27 +4,36 @@
|
|||
<form method="post">
|
||||
<div class="name field">
|
||||
<%= label_for name => 'Name' %>
|
||||
<%= input_tag name =>'Anonymous', maxlength => 63, minlength => 1 %>
|
||||
<%= text_field name =>'Anonymous', maxlength => 63, minlength => 1 %>
|
||||
</div>
|
||||
<div class="url field">
|
||||
<%= label_for url => 'Homepage URL' %>
|
||||
<%= input_tag 'url', maxlength => 255 %>
|
||||
<%= text_field 'url', maxlength => 255 %>
|
||||
<% if (my $error = validation->error('url')) { =%>
|
||||
<p class="field-with-error">URL does not appear to be
|
||||
<%= link_to 'RFC 2616',
|
||||
'https://datatracker.ietf.org/doc/html/rfc2616/#section-3.2.2' %>
|
||||
compliant.</p>
|
||||
<% } =%>
|
||||
</div>
|
||||
<div class="message field">
|
||||
<%= label_for message => 'Message' %>
|
||||
<textarea
|
||||
name="message"
|
||||
maxlength="2000"
|
||||
minlength="2"
|
||||
required="true"
|
||||
rows="6"></textarea>
|
||||
<%= label_for message => 'Message' %>
|
||||
<%= text_area 'message',
|
||||
maxlength => 2000,
|
||||
minlength => 2,
|
||||
required => 'true',
|
||||
rows => 6 %>
|
||||
<% if (my $error = validation->error('message')) { =%>
|
||||
<p class="field-with-error">Message must be less than 2,000
|
||||
characters and cannot be blank.</p>
|
||||
<% } =%>
|
||||
</div>
|
||||
<h3>SwaggCAPTCHA™</h3>
|
||||
<div class="captcha field">
|
||||
<% for my $answer (@$answers) { =%>
|
||||
<%= radio_button answer => $answer %>
|
||||
<%= label_for answer =>
|
||||
$answer ? $right_answer_label : pop @$wrong_answer_labels %>
|
||||
<%= radio_button answer => $answer %>
|
||||
<%= label_for answer =>
|
||||
$answer ? $right_answer_label : pop @$wrong_answer_labels %>
|
||||
<% } =%>
|
||||
</div>
|
||||
<%= submit_button 'Sign it', class => 'win95button' %>
|
||||
|
|
Loading…
Reference in a new issue