File Coverage

blib/lib/MVC/Neaf/X/Session/Cookie.pm
Criterion Covered Total %
statement 32 32 100.0
branch 5 6 83.3
condition 1 2 50.0
subroutine 10 10 100.0
pod 4 4 100.0
total 52 54 96.3


line stmt bran cond sub pod time code
1             package MVC::Neaf::X::Session::Cookie;
2              
3 4     4   68778 use strict;
  4         34  
  4         149  
4 4     4   24 use warnings;
  4         10  
  4         199  
5             our $VERSION = '0.29';
6              
7             =head1 NAME
8              
9             MVC::Neaf::X::Session::Cookie - Stateless cookie-based session for Neaf
10              
11             =head1 DESCRIPTION
12              
13             Use this module as a session handler in a Neaf app.
14              
15             The session data is stored within user's cookies without encryption.
16             However, it is signed with a key only known to the application owner.
17             So the session can be read, but not tampered with.
18              
19             Please take these concern into account, or better use server-side storage.
20              
21             =head1 METHODS
22              
23             =cut
24              
25 4     4   450 use MVC::Neaf::Util qw( encode_b64 decode_b64 );
  4         9  
  4         271  
26 4     4   1799 use Digest::SHA qw( hmac_sha224 );
  4         9513  
  4         292  
27              
28 4     4   29 use parent qw( MVC::Neaf::X::Session::Base );
  4         25  
  4         35  
29              
30             =head2 new( %options )
31              
32             %options may include:
33              
34             =over
35              
36             =item * key (required) - a secret text string used to sign session data.
37             This should be the same throughout the application.
38              
39             =item * hmac_function - HMAC to be used, default is hmac_sha224_base64
40              
41             =back
42              
43             =cut
44              
45             sub new {
46 3     3 1 108 my ($class, %opt) = @_;
47              
48 3 50       17 $opt{key} or $class->my_croak( "key option is required" );
49              
50 3   50 7   48 $opt{hmac_function} ||= sub { encode_b64( hmac_sha224( @_ ) ) };
  7         102  
51              
52 3         30 return $class->SUPER::new( %opt );
53             };
54              
55             =head2 store( $id, $data )
56              
57             Create a cookie from $data hash. Given $id is ignored.
58              
59             =cut
60              
61             sub store {
62 3     3 1 12 my ($self, $id, $data) = @_;
63              
64             # TODO 0.90 Make universal HMAC mechanism for ALL cookies
65 3         10 my $str = encode_b64($data);
66 3         60 $str =~ s/\s//gs;
67 3         21 $str .= "~".$self->get_expire;
68 3         10 my $sum = $self->{hmac_function}->( $str, $self->{key} );
69              
70 3         49 return { id => "$str~$sum" };
71             };
72              
73             =head2 fetch
74              
75             Restore session data from cookie.
76              
77             =cut
78              
79             sub fetch {
80 5     5 1 13 my ($self, $id) = @_;
81              
82 5         26 my ($str, $time, $key) = split /~/, $id, 3;
83              
84 5 100       19 return unless $key;
85 4 100       20 return unless $self->{hmac_function}->( "$str~$time", $self->{key} ) eq $key;
86              
87 3         85 return { strfy => decode_b64($str), expire => $time };
88             };
89              
90             =head2 get_session_id
91              
92             Replaced by a stub - we'll generate ID from data anyway.
93              
94             =cut
95              
96 2     2 1 9 sub get_session_id { return 'Cookie Session Need No Id' };
97              
98             =head1 LICENSE AND COPYRIGHT
99              
100             This module is part of L suite.
101              
102             Copyright 2016-2023 Konstantin S. Uvarin C.
103              
104             This program is free software; you can redistribute it and/or modify it
105             under the terms of either: the GNU General Public License as published
106             by the Free Software Foundation; or the Artistic License.
107              
108             See L for more information.
109              
110             =cut
111              
112             1;