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   664 use Mojo::Base -base;
  25         38  
  25         182  
3 25     25   3844 use Mojo::JSON;
  25         71247  
  25         16638  
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 5989 return Mojo::Util::sha1_hex(rand() . $$ . {} . time);
12             }
13              
14             sub session_id {
15 211     211 1 358 my ($self, $c) = @_;
16              
17             #once
18 211         406 state $cookie_name = $self->cookie_name;
19              
20             return
21 211   100     1125 $c->param($cookie_name)
22             || $c->cookie($cookie_name)
23             || '';
24             }
25              
26             sub get_instance {
27 16     16 1 3515 my $config = shift;
28 16   50     98 my $options = $config->{session}{options} || {};
29 16   50     82 my $type = lc($config->{session}{type} || 'mojo'); #sane default
30              
31 16 100       136 if ($type eq 'mojo') {
    100          
    50          
32 1         12 return Mojolicious::Sessions->new(%$options);
33             }
34             elsif ($type eq 'file') {
35 2         1069 require Ado::Sessions::File;
36 2         22 return Ado::Sessions::File->new(%$options);
37             }
38             elsif ($type eq 'database') {
39 13         6802 require Ado::Sessions::Database;
40 13         182 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 307 my ($self, $c, $session) = @_;
49              
50             # "expiration" value is inherited
51 128   33     895 my $expiration = $session->{expiration} // $self->default_expiration;
52 128 100 66     1615 return if !(my $expires = delete $session->{expires}) && $expiration;
53 66 50 33     462 return if defined $expires && $expires <= time;
54              
55 66         269 my $stash = $c->stash;
56 66 50       814 return unless $stash->{'mojo.active_session'} = keys %$session;
57 66         202 $stash->{'mojo.session'} = $session;
58 66 100       210 $session->{flash} = delete $session->{new_flash} if $session->{new_flash};
59              
60 66         185 return;
61             }
62              
63             sub prepare_store {
64 116     116 1 218 my ($self, $c) = @_;
65              
66             # Make sure session was active
67 116         402 my $stash = $c->stash;
68 116 100       1250 return unless my $session = $stash->{'mojo.session'};
69 83 0 33     381 return unless keys %$session || $stash->{'mojo.active_session'};
70              
71             # Don't reset flash for static files
72 83         198 my $old = delete $session->{flash};
73 0         0 @{$session->{new_flash}}{keys %$old} = values %$old
74 83 50       295 if $stash->{'mojo.static'};
75 83 100       143 delete $session->{new_flash} unless keys %{$session->{new_flash}};
  83         541  
76              
77             # Generate "expires" value from "expiration" if necessary
78 83   33     689 my $expiration = $session->{expiration} // $self->default_expiration;
79 83         692 my $default = delete $session->{expires};
80 83 50 66     730 $session->{expires} = $default || time + $expiration
      33        
81             if $expiration || $default;
82              
83 83   66     310 my $id = $self->session_id($c) || $self->generate_id();
84             my $options = {
85             domain => $self->cookie_domain,
86             expires => $session->{expires},
87 83         9906 httponly => 1,
88             path => $self->cookie_path,
89             secure => $self->secure
90             };
91              
92             #once
93 83         1514 state $cookie_name = $self->cookie_name;
94 83         315 $c->cookie($cookie_name => $id, $options);
95              
96 83         20638 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