File Coverage

blib/lib/Dancer2/Plugin/CSRF.pm
Criterion Covered Total %
statement 17 33 51.5
branch 0 2 0.0
condition 0 2 0.0
subroutine 6 8 75.0
pod 2 2 100.0
total 25 47 53.1


line stmt bran cond sub pod time code
1             package Dancer2::Plugin::CSRF;
2 1     1   57820 use 5.010;
  1         3  
3 1     1   14 use strict;
  1         2  
  1         17  
4 1     1   4 use warnings;
  1         9  
  1         36  
5              
6             our $VERSION = '1.01';
7              
8 1     1   622 use Dancer2::Plugin;
  1         63875  
  1         7  
9 1     1   16447 use Crypt::SaltedHash;
  1         3252  
  1         33  
10 1     1   465 use Data::UUID;
  1         573  
  1         419  
11              
12             my $HASHER = Crypt::SaltedHash->new( algorithm => 'SHA-1' );
13             my $UUID = Data::UUID->new();
14              
15             has session_key_name => (
16             is => 'ro',
17             default => sub {
18             $_[0]->config->{session_key_name} || 'plugin.csrf';
19             }
20             );
21              
22             plugin_keywords qw( get_csrf_token validate_csrf_token );
23              
24             sub get_csrf_token {
25 0     0 1   my ($self) = @_;
26 0           my $config = $self->dsl->session( $self->session_key_name() );
27 0 0         unless ($config) {
28 0           $config = { token => $UUID->create_str(), };
29 0           $self->dsl->session( $self->session_key_name() => $config );
30             }
31              
32 0           ( my $path = $self->dsl->request->dispatch_path ) =~ s{^/}{};
33 0           my $form_url = $self->dsl->request->base . $path;
34 0           my $token = $HASHER->add( $config->{token}, $form_url )->generate();
35 0           $HASHER->clear();
36 0           return $token;
37             }
38              
39             sub validate_csrf_token {
40 0     0 1   my ( $self, $got_token ) = @_;
41 0           my $form_url = $self->dsl->request->header('referer');
42 0   0       my $config = $self->dsl->session( $self->session_key_name() ) // return;
43             my $expected_token
44 0           = $HASHER->add( $config->{token}, $form_url )->generate();
45 0           $HASHER->clear();
46 0           return $expected_token eq $got_token;
47             }
48              
49             1;
50              
51             __END__