File Coverage

blib/lib/Ado/Sessions.pm
Criterion Covered Total %
statement 44 47 93.6
branch 17 24 70.8
condition 15 30 50.0
subroutine 7 7 100.0
pod 5 5 100.0
total 88 113 77.8


line stmt bran cond sub pod time code
1             package Ado::Sessions;
2 25     25   611 use Mojo::Base -base;
  25         45  
  25         130  
3 25     25   3137 use Mojo::JSON;
  25         98369  
  25         14295  
4              
5             has [qw(cookie_domain secure)];
6             has cookie_name => 'ado';
7             has cookie_path => '/';
8             has default_expiration => 3600;
9              
10             sub generate_id {
11 19     19 1 4739 return Mojo::Util::sha1_hex(rand() . $$ . {} . time);
12             }
13              
14             sub session_id {
15 211     211 1 450 my ($self, $c) = @_;
16              
17             #once
18 211         367 state $cookie_name = $self->cookie_name;
19              
20             return
21 211   100     869 $c->param($cookie_name)
22             || $c->cookie($cookie_name)
23             || '';
24             }
25              
26             sub get_instance {
27 16     16 1 2845 my $config = shift;
28 16   50     81 my $options = $config->{session}{options} || {};
29 16   50     73 my $type = lc($config->{session}{type} || 'mojo'); #sane default
30              
31 16 100       103 if ($type eq 'mojo') {
    100          
    50          
32 1         7 return Mojolicious::Sessions->new(%$options);
33             }
34             elsif ($type eq 'file') {
35 2         551 require Ado::Sessions::File;
36 2         31 return Ado::Sessions::File->new(%$options);
37             }
38             elsif ($type eq 'database') {
39 13         4313 require Ado::Sessions::Database;
40 13         157 return Ado::Sessions::Database->new(%$options);
41             }
42              
43 0         0 Carp::croak('Please provide valid session type:(mojo,file,database)');
44 0         0 return;
45             }
46              
47             sub prepare_load {
48 128     128 1 341 my ($self, $c, $session) = @_;
49              
50             # "expiration" value is inherited
51 128   33     710 my $expiration = $session->{expiration} // $self->default_expiration;
52 128 100 66     1180 return if !(my $expires = delete $session->{expires}) && $expiration;
53 66 50 33     348 return if defined $expires && $expires <= time;
54              
55 66         224 my $stash = $c->stash;
56 66 50       821 return unless $stash->{'mojo.active_session'} = keys %$session;
57 66         175 $stash->{'mojo.session'} = $session;
58 66 100       205 $session->{flash} = delete $session->{new_flash} if $session->{new_flash};
59              
60 66         164 return;
61             }
62              
63             sub prepare_store {
64 116     116 1 283 my ($self, $c) = @_;
65              
66             # Make sure session was active
67 116         335 my $stash = $c->stash;
68 116 100       1089 return unless my $session = $stash->{'mojo.session'};
69 83 0 33     301 return unless keys %$session || $stash->{'mojo.active_session'};
70              
71             # Don't reset flash for static files
72 83         171 my $old = delete $session->{flash};
73 0         0 @{$session->{new_flash}}{keys %$old} = values %$old
74 83 50       255 if $stash->{'mojo.static'};
75 83 100       127 delete $session->{new_flash} unless keys %{$session->{new_flash}};
  83         409  
76              
77             # Generate "expires" value from "expiration" if necessary
78 83   33     543 my $expiration = $session->{expiration} // $self->default_expiration;
79 83         517 my $default = delete $session->{expires};
80 83 50 66     493 $session->{expires} = $default || time + $expiration
      33        
81             if $expiration || $default;
82              
83 83   66     289 my $id = $self->session_id($c) || $self->generate_id();
84             my $options = {
85             domain => $self->cookie_domain,
86             expires => $session->{expires},
87 83         9406 httponly => 1,
88             path => $self->cookie_path,
89             secure => $self->secure
90             };
91              
92             #once
93 83         1330 state $cookie_name = $self->cookie_name;
94 83         314 $c->cookie($cookie_name => $id, $options);
95              
96 83         17760 return ($id, $session);
97             }
98              
99             1;
100              
101             =pod
102              
103             =encoding UTF-8
104              
105             =head1 NAME
106              
107             Ado::Sessions - A factory for HTTP Sessions in Ado
108              
109             =head1 DESCRIPTION
110              
111             Ado::Sessions chooses the desired type of session storage and loads it.
112              
113             =head1 SYNOPSIS
114              
115             #in ado.conf
116             session => {
117             type => 'database',
118             options => {
119             cookie_name => 'ado',
120             default_expiration => 86400,
121             }
122             }
123              
124             #In Ado.pm:
125             has sessions => sub { Ado::Sessions::get_instance(shift->config) };
126              
127              
128             =head2 cookie_domain
129              
130             Cookie domain accessor
131              
132             =head2 cookie_name
133              
134             Cookie name accessor
135              
136             =head2 cookie_path
137              
138             Cookie path accessor
139              
140             =head2 default_expiration
141              
142             Cookie default expiration accessor
143              
144             =head2 generate_id
145              
146             Session id generator
147              
148             =head2 get_instance
149              
150             Factory method for creating Ado session instance
151              
152             =head2 prepare_load
153              
154             Shares common logic which is compatible with L.
155             The storage implementation class should call this method after it loads
156             the session from the respective storage.
157              
158             $self->prepare_load($c, $session);
159              
160             =head2 secure
161              
162             Cookie is secure, flag
163              
164             =head2 prepare_store
165              
166             Shares common logic which is compatible with L.
167             The storage implementation class should call this method before it stores
168             the session to the the respective storage.
169             Returns the session id and the session ready to be serialized
170             and base 64 encoded.
171              
172             my ($id, $session) = $self->prepare_store($c);
173              
174             =head2 session_id
175              
176             Retrieves the session id from a parameter or cookie defaulting to L.
177             The C can be set in C section C.
178              
179             my $id = $self->session_id($c);
180              
181              
182             =head1 SEE ALSO
183              
184             L, L, L,
185             L
186              
187             =cut
188              
189