Implement CSRF for post_thread
This commit is contained in:
parent
66bbd9da67
commit
32393fd8f3
|
@ -15,8 +15,15 @@ sub create($self) {
|
||||||
$v->required('title' )->size(1, 127);
|
$v->required('title' )->size(1, 127);
|
||||||
$v->required('body' )->size(2, $body_limit);
|
$v->required('body' )->size(2, $body_limit);
|
||||||
$v->optional('preview');
|
$v->optional('preview');
|
||||||
|
$v->csrf_protect;
|
||||||
|
|
||||||
if ($v->has_error) {
|
if ($v->has_error('csrf_token')) {
|
||||||
|
$self->stash(
|
||||||
|
status => 403,
|
||||||
|
error => 'Something went wrong, please try again. 🥺'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elsif ($v->has_error) {
|
||||||
$self->stash(status => 400)
|
$self->stash(status => 400)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
27
t/post.t
27
t/post.t
|
@ -51,12 +51,15 @@ $t->post_ok($bump_thread_url, form => \%good_captcha)
|
||||||
$t->ua->max_redirects(1);
|
$t->ua->max_redirects(1);
|
||||||
|
|
||||||
subtest 'Post new thread', sub {
|
subtest 'Post new thread', sub {
|
||||||
|
my $csrf_token;
|
||||||
|
|
||||||
# GET
|
# GET
|
||||||
$t->get_ok('/human/thread/post')->status_is(200)
|
$t->get_ok('/human/thread/post')->status_is(200)
|
||||||
->element_exists('form input[name="author"]' )
|
->element_exists('form input[name="author"]' )
|
||||||
->element_exists('form input[name="title"]' )
|
->element_exists('form input[name="title"]' )
|
||||||
->element_exists('form textarea[name="body"]')
|
->element_exists('form textarea[name="body"]' )
|
||||||
->element_exists('form button[type="submit"]' )
|
->element_exists('form button[type="submit"]' )
|
||||||
|
->element_exists('form input[name="csrf_token"]')
|
||||||
->text_like(h2 => qr/New Thread/);
|
->text_like(h2 => qr/New Thread/);
|
||||||
|
|
||||||
# POST
|
# POST
|
||||||
|
@ -64,17 +67,31 @@ subtest 'Post new thread', sub {
|
||||||
->element_exists('form input[name="author"]' )
|
->element_exists('form input[name="author"]' )
|
||||||
->element_exists('form input[name="title"]' )
|
->element_exists('form input[name="title"]' )
|
||||||
->element_exists('form textarea[name="body"]')
|
->element_exists('form textarea[name="body"]')
|
||||||
->element_exists('form button[type="submit"]' )
|
->element_exists('form button[type="submit"]')
|
||||||
->text_like(h2 => qr/New Thread/);
|
->text_like(h2 => qr/New Thread/);
|
||||||
|
|
||||||
|
# No CSRF token
|
||||||
|
$t->post_ok('/human/thread/post', form => \%valid_thread)
|
||||||
|
->status_is(403)
|
||||||
|
->text_like(p => qr/Something went wrong/);
|
||||||
|
|
||||||
|
$invalid_title{'csrf_token'} =
|
||||||
|
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||||
|
|
||||||
$t->post_ok('/human/thread/post', form => \%invalid_title)
|
$t->post_ok('/human/thread/post', form => \%invalid_title)
|
||||||
->status_is(400)
|
->status_is(400)
|
||||||
->text_like(p => qr/Must be between/);
|
->text_like(p => qr/Must be between/);
|
||||||
|
|
||||||
|
$invalid_thread{'csrf_token'} =
|
||||||
|
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||||
|
|
||||||
$t->post_ok('/human/thread/post', form => \%invalid_thread)
|
$t->post_ok('/human/thread/post', form => \%invalid_thread)
|
||||||
->status_is(400)
|
->status_is(400)
|
||||||
->text_like(p => qr/Must be between/);
|
->text_like(p => qr/Must be between/);
|
||||||
|
|
||||||
|
$valid_thread{'csrf_token'} =
|
||||||
|
$t->tx->res->dom->at('input[name="csrf_token"]')->val;
|
||||||
|
|
||||||
$t->post_ok('/human/thread/post', form => \%valid_thread)
|
$t->post_ok('/human/thread/post', form => \%valid_thread)
|
||||||
->status_is(200)
|
->status_is(200)
|
||||||
->text_like(h2 => qr/Thread #\d+/);
|
->text_like(h2 => qr/Thread #\d+/);
|
||||||
|
@ -85,14 +102,14 @@ subtest 'Post new remark', sub {
|
||||||
$t->get_ok('/human/remark/post/1')->status_is(200)
|
$t->get_ok('/human/remark/post/1')->status_is(200)
|
||||||
->element_exists('form input[name="author"]' )
|
->element_exists('form input[name="author"]' )
|
||||||
->element_exists('form textarea[name="body"]')
|
->element_exists('form textarea[name="body"]')
|
||||||
->element_exists('form button[type="submit"]' )
|
->element_exists('form button[type="submit"]')
|
||||||
->text_like(h2 => qr/Remark on Thread #/);
|
->text_like(h2 => qr/Remark on Thread #/);
|
||||||
$t->get_ok('/human/remark/post/65536')->status_is(404)
|
$t->get_ok('/human/remark/post/65536')->status_is(404)
|
||||||
->text_like(p => qr/Thread not found/);
|
->text_like(p => qr/Thread not found/);
|
||||||
# Test the remark-to-remark thing
|
# Test the remark-to-remark thing
|
||||||
$t->get_ok('/human/remark/post/1/1')->status_is(200)
|
$t->get_ok('/human/remark/post/1/1')->status_is(200)
|
||||||
->element_exists('form input[name="author"]' )
|
->element_exists('form input[name="author"]' )
|
||||||
->element_exists('form textarea[name="body"]')
|
->element_exists('form textarea[name="body"]' )
|
||||||
->element_exists('form button[type="submit"]' )
|
->element_exists('form button[type="submit"]' )
|
||||||
->element_exists('a[href$="/remark/single/1"]')
|
->element_exists('a[href$="/remark/single/1"]')
|
||||||
->text_like(h3 => qr/Last Remark/);
|
->text_like(h3 => qr/Last Remark/);
|
||||||
|
@ -100,7 +117,7 @@ subtest 'Post new remark', sub {
|
||||||
# POST
|
# POST
|
||||||
$t->post_ok('/human/remark/post/1')->status_is(200)
|
$t->post_ok('/human/remark/post/1')->status_is(200)
|
||||||
->element_exists('form input[name="author"]' )
|
->element_exists('form input[name="author"]' )
|
||||||
->element_exists('form textarea[name="body"]')
|
->element_exists('form textarea[name="body"]' )
|
||||||
->element_exists('form button[type="submit"]' )
|
->element_exists('form button[type="submit"]' )
|
||||||
->text_like(h2 => qr/Remark on Thread #/);
|
->text_like(h2 => qr/Remark on Thread #/);
|
||||||
|
|
||||||
|
|
|
@ -61,5 +61,6 @@
|
||||||
<%= check_box preview => 1, id => 'preview' %>
|
<%= check_box preview => 1, id => 'preview' %>
|
||||||
<%= label_for preview => 'Preview' %>
|
<%= label_for preview => 'Preview' %>
|
||||||
</div>
|
</div>
|
||||||
|
<%= csrf_field %>
|
||||||
<button type="submit" class="form-button">Post</button>
|
<button type="submit" class="form-button">Post</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
Loading…
Reference in a new issue