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   602 use Mojo::Base -base;
  25         42  
  25         183  
3 25     25   4145 use Mojo::JSON;
  25         64035  
  25         18406  
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 6189 return Mojo::Util::sha1_hex(rand() . $$ . {} . time);
12             }
13              
14             sub session_id {
15 211     211 1 351 my ($self, $c) = @_;
16              
17             #once
18 211         380 state $cookie_name = $self->cookie_name;
19              
20             return
21 211   100     995 $c->param($cookie_name)
22             || $c->cookie($cookie_name)
23             || '';
24             }
25              
26             sub get_instance {
27 16     16 1 3769 my $config = shift;
28 16   50     103 my $options = $config->{session}{options} || {};
29 16   50     92 my $type = lc($config->{session}{type} || 'mojo'); #sane default
30              
31 16 100       121 if ($type eq 'mojo') {
    100          
    50          
32 1         9 return Mojolicious::Sessions->new(%$options);
33             }
34             elsif ($type eq 'file') {
35 2         956 require Ado::Sessions::File;
36 2         30 return Ado::Sessions::File->new(%$options);
37             }
38             elsif ($type eq 'database') {
39 13         7191 require Ado::Sessions::Database;
40 13         227 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 328 my ($self, $c, $session) = @_;
49              
50             # "expiration" value is inherited
51 128   33     849 my $expiration = $session->{expiration} // $self->default_expiration;
52 128 100 66     1529 return if !(my $expires = delete $session->{expires}) && $expiration;
53 66 50 33     494 return if defined $expires && $expires <= time;
54              
55 66         312 my $stash = $c->stash;
56 66 50       1034 return unless $stash->{'mojo.active_session'} = keys %$session;
57 66         228 $stash->{'mojo.session'} = $session;
58 66 100       216 $session->{flash} = delete $session->{new_flash} if $session->{new_flash};
59              
60 66         204 return;
61             }
62              
63             sub prepare_store {
64 116     116 1 234 my ($self, $c) = @_;
65              
66             # Make sure session was active
67 116         413 my $stash = $c->stash;
68 116 100       1239 return unless my $session = $stash->{'mojo.session'};
69 83 0 33     343 return unless keys %$session || $stash->{'mojo.active_session'};
70              
71             # Don't reset flash for static files
72 83         178 my $old = delete $session->{flash};
73 0         0 @{$session->{new_flash}}{keys %$old} = values %$old
74 83 50       318 if $stash->{'mojo.static'};
75 83 100       124 delete $session->{new_flash} unless keys %{$session->{new_flash}};
  83         514  
76              
77             # Generate "expires" value from "expiration" if necessary
78 83   33     682 my $expiration = $session->{expiration} // $self->default_expiration;
79 83         686 my $default = delete $session->{expires};
80 83 50 66     753 $session->{expires} = $default || time + $expiration
      33        
81             if $expiration || $default;
82              
83 83   66     338 my $id = $self->session_id($c) || $self->generate_id();
84             my $options = {
85             domain => $self->cookie_domain,
86             expires => $session->{expires},
87 83         10350 httponly => 1,
88             path => $self->cookie_path,
89             secure => $self->secure
90             };
91              
92             #once
93 83         1536 state $cookie_name = $self->cookie_name;
94 83         340 $c->cookie($cookie_name => $id, $options);
95              
96 83         20104 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