Validate input
This commit is contained in:
parent
84182fe25b
commit
e4aad2ccbd
@ -49,6 +49,6 @@ Add the `-v` option for more verbose output
|
|||||||
|
|
||||||
## TODOs
|
## TODOs
|
||||||
|
|
||||||
1. Input validation
|
1. More tests
|
||||||
1. /spam route would be interesting
|
1. /spam route would be interesting
|
||||||
1. Include the total number of visitors or messages
|
1. Include the total number of visitors or messages
|
||||||
|
@ -132,7 +132,7 @@ h1#top {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
border-style: solid;
|
border-style: dashed;
|
||||||
border-color: red;
|
border-color: red;
|
||||||
color: red;
|
color: red;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
@ -140,6 +140,12 @@ h1#top {
|
|||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.field-with-error {
|
||||||
|
border-style: dotted;
|
||||||
|
border-color: red;
|
||||||
|
padding-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1023px) {
|
@media screen and (max-width: 1023px) {
|
||||||
.inner {
|
.inner {
|
||||||
max-width: 95%;
|
max-width: 95%;
|
||||||
|
@ -46,6 +46,9 @@ under sub ($c) {
|
|||||||
|
|
||||||
$c->session(expiration => 604800);
|
$c->session(expiration => 604800);
|
||||||
|
|
||||||
|
$c->stash(status => 403)
|
||||||
|
if $c->flash('error') eq 'This message was flagged as spam';
|
||||||
|
|
||||||
1;
|
1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,7 +67,9 @@ get '/' => sub ($c) {
|
|||||||
} => 'index';
|
} => 'index';
|
||||||
|
|
||||||
any [qw{GET POST}], '/sign' => sub ($c) {
|
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 $name = $c->param('name') || 'Anonymous';
|
||||||
my $url = $c->param('url');
|
my $url = $c->param('url');
|
||||||
my $message = $c->param('message');
|
my $message = $c->param('message');
|
||||||
@ -73,37 +78,37 @@ any [qw{GET POST}], '/sign' => sub ($c) {
|
|||||||
$message =~ /$RE{URI}{HTTP}{-scheme => qr<https?>}/ ? 1 :
|
$message =~ /$RE{URI}{HTTP}{-scheme => qr<https?>}/ ? 1 :
|
||||||
0;
|
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->message->create_post($name, $message, $url, $spam);
|
||||||
|
|
||||||
$c->flash(error => 'This message was flagged as spam') if $spam;
|
$c->flash(error => 'This message was flagged as spam') if $spam;
|
||||||
$c->redirect_to('index');
|
$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(
|
# Try to randomize things for the CAPTCHA challenge. The
|
||||||
answers => \@answers,
|
# string 'false' actually evaluates to true so this is an
|
||||||
right_answer_label => $right_answer_label,
|
# attempt to confuse a (hypothetical) bot that would try to
|
||||||
wrong_answer_labels => \@wrong_answer_labels
|
# 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
|
# Send it
|
||||||
|
@ -4,27 +4,36 @@
|
|||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="name field">
|
<div class="name field">
|
||||||
<%= label_for name => 'Name' %>
|
<%= label_for name => 'Name' %>
|
||||||
<%= input_tag name =>'Anonymous', maxlength => 63, minlength => 1 %>
|
<%= text_field name =>'Anonymous', maxlength => 63, minlength => 1 %>
|
||||||
</div>
|
</div>
|
||||||
<div class="url field">
|
<div class="url field">
|
||||||
<%= label_for url => 'Homepage URL' %>
|
<%= 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>
|
||||||
<div class="message field">
|
<div class="message field">
|
||||||
<%= label_for message => 'Message' %>
|
<%= label_for message => 'Message' %>
|
||||||
<textarea
|
<%= text_area 'message',
|
||||||
name="message"
|
maxlength => 2000,
|
||||||
maxlength="2000"
|
minlength => 2,
|
||||||
minlength="2"
|
required => 'true',
|
||||||
required="true"
|
rows => 6 %>
|
||||||
rows="6"></textarea>
|
<% 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>
|
</div>
|
||||||
<h3>SwaggCAPTCHA™</h3>
|
<h3>SwaggCAPTCHA™</h3>
|
||||||
<div class="captcha field">
|
<div class="captcha field">
|
||||||
<% for my $answer (@$answers) { =%>
|
<% for my $answer (@$answers) { =%>
|
||||||
<%= radio_button answer => $answer %>
|
<%= radio_button answer => $answer %>
|
||||||
<%= label_for answer =>
|
<%= label_for answer =>
|
||||||
$answer ? $right_answer_label : pop @$wrong_answer_labels %>
|
$answer ? $right_answer_label : pop @$wrong_answer_labels %>
|
||||||
<% } =%>
|
<% } =%>
|
||||||
</div>
|
</div>
|
||||||
<%= submit_button 'Sign it', class => 'win95button' %>
|
<%= submit_button 'Sign it', class => 'win95button' %>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user