Commit | Line | Data |
642b19cf |
1 | package Catalyst::Plugin::Session::State::Stash; |
745a2421 |
2 | # ABSTRACT: Maintain session IDs using the stash |
3 | |
0c46f6c5 |
4 | use Moose; |
5 | use 5.008; |
642b19cf |
6 | use MRO::Compat; |
0c46f6c5 |
7 | use namespace::autoclean; |
8 | |
9 | extends 'Catalyst::Plugin::Session::State'; |
642b19cf |
10 | |
e4d291f5 |
11 | our $VERSION = '0.15'; |
642b19cf |
12 | |
0c46f6c5 |
13 | has _deleted_session_id => ( is => 'rw' ); |
14 | has _prepared => ( is => 'rw' ); |
642b19cf |
15 | |
e08a2683 |
16 | sub _stash_key_components { |
642b19cf |
17 | my ($c) = @_; |
643399c7 |
18 | my $config = $c->_session_plugin_config; |
effd6244 |
19 | return ($config->{stash_delim}) ? |
20 | split $config->{stash_delim}, $config->{stash_key} : |
21 | $config->{stash_key}; |
642b19cf |
22 | } |
23 | |
24 | sub _get_session { |
25 | my ($c) = @_; |
e08a2683 |
26 | # This turns the list of path components into a nested tree of hashrefs for obtaining info/storing in: 123/456 = {123}->{456} |
27 | my $ref = $c->stash; |
28 | $ref = ($ref->{$_} ||= {}) foreach $c->_stash_key_components; |
29 | $ref; |
642b19cf |
30 | } |
31 | |
32 | sub _set_session { |
33 | my ( $c,$key,$value) = @_; |
e08a2683 |
34 | $c->_get_session->{$key} = $value; |
642b19cf |
35 | } |
36 | |
37 | sub setup_session { |
38 | my $c = shift; |
07571d90 |
39 | |
40 | $c->maybe::next::method(@_); |
41 | |
643399c7 |
42 | $c->_session_plugin_config->{stash_key} ||= '_session'; |
642b19cf |
43 | } |
44 | |
45 | sub prepare_action { |
46 | my $c = shift; |
47 | my $id = $c->get_session_id; |
48 | $c->_prepared(1); |
49 | if ( $id ) { |
50 | $c->sessionid( $id ); |
51 | } |
52 | $c->maybe::next::method( @_ ); |
53 | } |
54 | |
55 | sub get_session_id { |
56 | my $c = shift; |
57 | if(!$c->_deleted_session_id and my $session = $c->_get_session) { |
58 | my $sid = $session->{id}; |
59 | return $sid if $sid; |
60 | } |
61 | $c->maybe::next::method(@_); |
62 | } |
63 | |
64 | sub set_session_id { |
65 | my ( $c, $sid ) = @_; |
66 | $c->_set_session(id => $sid); |
67 | $c->maybe::next::method($sid); |
68 | } |
69 | |
70 | sub get_session_expires { |
71 | my $c = shift; |
72 | my $session = $c->_get_session; |
73 | defined $session->{expires} ? $session->{expires} : undef; |
74 | } |
75 | |
76 | sub set_session_expires { |
77 | my ( $c, $expires ) = @_; |
642b19cf |
78 | $c->_set_session(expires => time() + $expires); |
79 | $c->maybe::next::method($expires) |
80 | } |
81 | |
82 | sub delete_session_id { |
83 | my ($c, $sid ) = @_; |
84 | $c->_deleted_session_id(1); |
e08a2683 |
85 | #Empty the tip |
86 | %{$c->_get_session} = (); |
642b19cf |
87 | $c->maybe::next::method($sid); |
88 | } |
89 | |
90 | |
91 | 1; |
92 | __END__ |
93 | |
94 | =pod |
95 | |
642b19cf |
96 | =head1 SYNOPSIS |
97 | |
98 | use Catalyst qw/Session Session::State::Stash Session::Store::Foo/; |
99 | |
100 | =head1 DESCRIPTION |
101 | |
102 | An alternative state storage plugin that allows you some more flexibility in |
103 | dealing with session storage. This plugin loads and saves the session ID from |
104 | and to the stash. |
105 | |
106 | =head1 METHODS |
107 | |
108 | =over 4 |
109 | |
110 | =item delete_session_id |
111 | |
112 | Deletes the session. Unfortunately I've been unable to squash a bug that will |
113 | stop you from opening a new session in the same execution, however. |
114 | Patches welcome! |
115 | |
116 | =item get_session_id |
117 | |
118 | Gets the current session id. |
119 | |
120 | =item set_session_id |
121 | |
122 | Sets the session id to the C<shift>. |
123 | |
124 | =item get_session_expires |
125 | |
126 | Gets when the current session expires. |
127 | |
128 | =item set_session_expires |
129 | |
130 | Sets how many seconds from now the session should expire. |
131 | |
132 | =back |
133 | |
134 | =head1 EXTENDED METHODS |
135 | |
136 | =over 4 |
137 | |
138 | =item prepare_action |
139 | |
140 | Loads the id off the stash. |
141 | |
142 | =item setup_session |
143 | |
144 | Defaults the C<stash_key> parameter to C<_session>. |
145 | |
146 | =back |
147 | |
148 | =head1 CONFIGURATION |
149 | |
150 | =over 4 |
151 | |
152 | =item stash_key |
153 | |
154 | The name of the hash key to use. Defaults to C<_session>. |
155 | |
e08a2683 |
156 | =item stash_delim |
157 | |
4edfd3af |
158 | If present, splits C<stash_key> at this character to nest. E.g. a C<delim> of '/' |
159 | and C<stash_key> of '123/456' will store it as $c->stash->{123}->{456} |
e08a2683 |
160 | |
642b19cf |
161 | =item expires |
ff999ad1 |
162 | |
642b19cf |
163 | How long the session should last in seconds. |
164 | |
165 | =back |
166 | |
4edfd3af |
167 | For example, you could stick this in F<MyApp.pm>: |
642b19cf |
168 | |
effd6244 |
169 | __PACKAGE__->config( 'Plugin::Session' => { |
642b19cf |
170 | stash_key => 'session_id', |
171 | }); |
172 | |
2bf7b1a2 |
173 | =head1 CAVEATS |
642b19cf |
174 | |
175 | You can't delete a session then create a new one. If this is important to you, |
745a2421 |
176 | patches welcome! |
642b19cf |
177 | |
4edfd3af |
178 | =for stopwords stateful |
179 | |
642b19cf |
180 | If you are writing a stateful web service with |
ff999ad1 |
181 | L<Catalyst::Plugin::Server::XMLRPC>, you will probably only have to deal with |
642b19cf |
182 | loading, as when saving, the ID will already be on the stash. |
183 | |
184 | =head1 SEE ALSO |
185 | |
186 | L<Catalyst>, L<Catalyst::Plugin::Session>, L<Catalyst::Plugin::Session::State>, |
187 | L<Catalyst::Plugin::Session::State::Cookie> (what you probably want). |
188 | |
642b19cf |
189 | =head1 CONTRIBUTORS |
190 | |
4125e201 |
191 | =begin :list |
642b19cf |
192 | |
4125e201 |
193 | * This module is derived from L<Catalyst::Plugin::Session::State::Cookie> code. |
194 | Thanks to anyone who wrote code for that. |
642b19cf |
195 | |
4125e201 |
196 | * Thanks to Kent Fredric for a patch for nested keys |
e08a2683 |
197 | |
4125e201 |
198 | =end :list |
642b19cf |
199 | |
200 | =cut |