package t::CSRFDefender::CustomTemplate;
use strict;
use warnings;
use Test::More tests => 15;
use Mojolicious::Lite;
use Test::Mojo;
# configure routing
get '/get' => 'get';
any [qw(get post)] => '/post' => 'post';
# load plugin
plugin 'Mojolicious::Plugin::CSRFDefender' => {
error_template => '403.html',
};
# forbidden unless session
my $t = Test::Mojo->new;
$t->post_ok('/post')->status_is(403)->content_like(qr{^403 Forbidden$});
# no csrf_token if form method is get
$t->get_ok('/get')->status_is(200)->content_like(qr{(?!csrftoken)});
# set csrf_token param and session if form method is post
$t->get_ok('/post')->status_is(200)->element_exists('form input[name="csrftoken"]');
my $body = $t->tx->res->body;
my ($token_param) = $body =~ /name="csrftoken" value="(.*?)"/;
like $token_param, qr{^[a-zA-Z0-9_]{32}$}, 'valid token';
# forbidden unless csrf_token parameter
$t->post_ok('/post')->status_is(403)->content_like(qr{^403 Forbidden$});
# can access if exists csrf_token session and parameter
$t->post_form_ok('/post' => {'csrftoken' => $token_param})
->status_is(200);
__DATA__;
@@ get.html.ep
<html>
<body>
<form action="/get">
<input name="text" />
<input type="submit" value="send" />
</form>
</body>
</html>
@@ post.html.ep
<html>
<body>
<form action="/post" method="post">
<input name="text" />
<input type="submit" value="send" />
</form>
</body>
</html>