File Coverage

blib/lib/Mojolicious/Sessions/Storable.pm
Criterion Covered Total %
statement 61 62 98.3
branch 26 38 68.4
condition 13 33 39.3
subroutine 11 11 100.0
pod 3 6 50.0
total 114 150 76.0


line stmt bran cond sub pod time code
1             package Mojolicious::Sessions::Storable;
2              
3 1     1   8 use strict;
  1         2  
  1         50  
4 1     1   6 use warnings;
  1         1  
  1         50  
5              
6             our $VERSION = '0.04';
7              
8 1     1   5 use Mojo::Base 'Mojolicious::Sessions';
  1         2  
  1         7  
9 1     1   5920 use Digest::SHA1 ();
  1         5922  
  1         1084  
10              
11             has sid_generator => sub {
12             sub {
13             Digest::SHA1::sha1_hex( rand() . $$ . {} . time );
14             };
15             };
16              
17             has 'session_store';
18              
19             sub new {
20 1     1 1 1 my $class = shift;
21 1         7 my $self = $class->SUPER::new(@_);
22              
23 1 50 33     25 if ( $self->session_store
24             && !Mojolicious::Controller->can('session_options') )
25             {
26             Mojolicious::Controller->attr(
27             session_options => sub {
28 15     15   23286 $_[0]->stash->{'mojox.session.options'}
29             },
30 1         44 );
31             }
32              
33 1         137 return $self;
34             }
35              
36             sub load {
37 15     15 1 372847 my ( $self, $c ) = @_;
38              
39 15 50       463 return $self->SUPER::load($c) unless ( $self->session_store );
40              
41 15         201 my $stash = $c->stash;
42              
43 15         274 my ( $session_id, $session ) = $self->get_session($c);
44 15 100 66     796 unless ( $session_id && $session ) {
45 3         12 $session_id = $self->generate_id( $c->req->env );
46             }
47 15         81 $stash->{'mojox.session.options'} = { id => $session_id };
48 15 100       53 return unless $session;
49              
50             # "expiration" value is inherited
51 12   33     390 my $expiration = $session->{expiration} // $self->default_expiration;
52 12 50 33     158 return if !(my $expires = delete $session->{expires}) && $expiration;
53 12 50 33     86 return if defined $expires && $expires <= time;
54              
55 12 50       66 return unless $stash->{'mojo.active_session'} = keys %$session;
56 12         33 $stash->{'mojo.session'} = $session;
57 12 100       62 $session->{flash} = delete $session->{new_flash} if $session->{new_flash};
58             }
59              
60             sub store {
61 15     15 1 52221 my ( $self, $c ) = @_;
62              
63 15 50       434 return $self->SUPER::store($c) unless ( $self->session_store );
64              
65             # Make sure session was active
66 15         146 my $stash = $c->stash;
67 15 50       170 return unless my $session = $stash->{'mojo.session'};
68 15 50 33     63 return unless keys %$session || $stash->{'mojo.active_session'};
69              
70             # Don't reset flash for static files
71 15         39 my $old = delete $session->{flash};
72 15 50       45 @{ $session->{new_flash} }{ keys %$old } = values %$old
  0         0  
73             if $stash->{'mojo.static'};
74 15 100       21 delete $session->{new_flash} unless keys %{ $session->{new_flash} };
  15         82  
75              
76             # Generate "expires" value from "expiration" if necessary
77 15   33     450 my $expiration = $session->{expiration} // $self->default_expiration;
78 15         149 my $default = delete $session->{expires};
79 15 50 33     128 $session->{expires} = $default || time + $expiration
      33        
80             if $expiration || $default;
81              
82 15 50       388 $self->set_session( $c, $session ) unless $c->session_options->{no_store};
83              
84 15         6672 my $options = {
85             domain => $self->cookie_domain,
86             expires => $session->{expires},
87             httponly => 1,
88             path => $self->cookie_path,
89             secure => $self->secure
90             };
91 15         1589 $c->signed_cookie(
92             $self->cookie_name,
93             $c->session_options->{id},
94             $options,
95             );
96             }
97              
98             sub generate_id {
99 7     7 0 699 my ( $self, $env ) = @_;
100 7         260 $self->sid_generator->($env);
101             }
102              
103             sub get_session {
104 15     15 0 36 my ( $self, $c ) = @_;
105              
106 15 100       424 my $session_id = $c->signed_cookie( $self->cookie_name ) or return;
107 12 50       6041 my $session = $self->session_store->fetch($session_id) or return;
108              
109 12         3220 return ( $session_id, $session );
110             }
111              
112             sub set_session {
113 15     15 0 207 my ( $self, $c, $session ) = @_;
114              
115 15 100 33     640 if ( $c->session_options->{expire} || ( defined $session->{expires} && $session->{expires} <= time ) ) {
    100 66        
116 2         21 $session->{expires} = 1;
117 2         43 $self->session_store->remove( $c->session_options->{id} );
118             }
119             elsif ( $c->session_options->{change_id} ) {
120 4         235 $self->session_store->remove( $c->session_options->{id} );
121 4         681 $c->session_options->{id} = $self->generate_id( $c->req->env );
122 4         121 $self->session_store->store( $c->session_options->{id}, $session );
123             }
124             else {
125 9         604 $self->session_store->store( $c->session_options->{id}, $session );
126             }
127             }
128              
129             1;
130             __END__