File Coverage

blib/lib/Mojolicious/Sessions/Storable.pm
Criterion Covered Total %
statement 59 62 95.1
branch 26 38 68.4
condition 14 35 40.0
subroutine 11 11 100.0
pod 3 6 50.0
total 113 152 74.3


line stmt bran cond sub pod time code
1             package Mojolicious::Sessions::Storable;
2              
3 1     1   5 use strict;
  1         1  
  1         51  
4 1     1   4 use warnings;
  1         2  
  1         38  
5              
6             our $VERSION = '0.05';
7              
8 1     1   4 use Mojo::Base 'Mojolicious::Sessions';
  1         1  
  1         5  
9 1     1   604 use Digest::SHA1 ();
  1         598  
  1         856  
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 2 my $class = shift;
21 1         10 my $self = $class->SUPER::new(@_);
22              
23 1 50 33     38 if ( $self->session_store
24             && !Mojolicious::Controller->can('session_options') )
25             {
26             Mojolicious::Controller->attr(
27             session_options => sub {
28 15   100 15   34306 $_[0]->stash->{'mojox.session.options'} ||= {};
29             },
30 1         42 );
31             }
32              
33 1         138 return $self;
34             }
35              
36             sub load {
37 13     13 1 216207 my ( $self, $c ) = @_;
38              
39 13 50       233 return $self->SUPER::load($c) unless ( $self->session_store );
40              
41 13         108 my $stash = $c->stash;
42              
43 13         124 my ( $session_id, $session ) = $self->get_session($c);
44 13 100 66     325 unless ( $session_id && $session ) {
45 1         5 $session_id = $self->generate_id( $c->req->env );
46             }
47 13         62 $stash->{'mojox.session.options'} = { id => $session_id };
48 13 100       39 return unless $session;
49              
50             # "expiration" value is inherited
51 12   33     380 my $expiration = $session->{expiration} // $self->default_expiration;
52 12 50 33     275 return if !(my $expires = delete $session->{expires}) && $expiration;
53 12 50 33     60 return if defined $expires && $expires <= time;
54              
55 12 50       52 return unless $stash->{'mojo.active_session'} = keys %$session;
56 12         32 $stash->{'mojo.session'} = $session;
57 12 100       46 $session->{flash} = delete $session->{new_flash} if $session->{new_flash};
58             }
59              
60             sub store {
61 15     15 1 14554 my ( $self, $c ) = @_;
62              
63 15 50       234 return $self->SUPER::store($c) unless ( $self->session_store );
64              
65             # Make sure session was active
66 15         109 my $stash = $c->stash;
67 15 100       143 return unless my $session = $stash->{'mojo.session'};
68 13 50 33     52 return unless keys %$session || $stash->{'mojo.active_session'};
69              
70             # Don't reset flash for static files
71 13         27 my $old = delete $session->{flash};
72 13 50       28 @{ $session->{new_flash} }{ keys %$old } = values %$old
  0         0  
73             if $stash->{'mojo.static'};
74 13 100       21 delete $session->{new_flash} unless keys %{ $session->{new_flash} };
  13         64  
75              
76             # Generate "expires" value from "expiration" if necessary
77 13   33     253 my $expiration = $session->{expiration} // $self->default_expiration;
78 13         89 my $default = delete $session->{expires};
79 13 50 33     76 $session->{expires} = $default || time + $expiration
      33        
80             if $expiration || $default;
81              
82 13 50       222 $self->set_session( $c, $session ) unless $c->session_options->{no_store};
83              
84 13         4032 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 13         933 $c->signed_cookie(
92             $self->cookie_name,
93             $c->session_options->{id},
94             $options,
95             );
96             }
97              
98             sub generate_id {
99 5     5 0 364 my ( $self, $env ) = @_;
100 5         98 $self->sid_generator->($env);
101             }
102              
103             sub get_session {
104 13     13 0 21 my ( $self, $c ) = @_;
105              
106 13 100       240 my $session_id = $c->signed_cookie( $self->cookie_name ) or return;
107 12 50       3932 my $session = $self->session_store->fetch($session_id) or return;
108              
109 12         2460 return ( $session_id, $session );
110             }
111              
112             sub set_session {
113 13     13 0 161 my ( $self, $c, $session ) = @_;
114              
115 13 50 33     199 if ( $c->session_options->{expire} || ( defined $session->{expires} && $session->{expires} <= time ) ) {
    100 33        
116 0         0 $session->{expires} = 1;
117 0         0 $self->session_store->remove( $c->session_options->{id} );
118             }
119             elsif ( $c->session_options->{change_id} ) {
120 4         187 $self->session_store->remove( $c->session_options->{id} );
121 4         593 $c->session_options->{id} = $self->generate_id( $c->req->env );
122 4         100 $self->session_store->store( $c->session_options->{id}, $session );
123             }
124             else {
125 9         370 $self->session_store->store( $c->session_options->{id}, $session );
126             }
127             }
128              
129             1;
130             __END__