$c->session_expire_key
Yuval Kogman [Mon, 28 Nov 2005 22:45:39 +0000 (22:45 +0000)]
lib/Catalyst/Plugin/Session.pm
t/02_session_data.t

index b061820..49da39e 100644 (file)
@@ -75,6 +75,14 @@ sub finalize {
 sub prepare_action {
     my $c = shift;
 
+    $c->_load_session;
+
+    $c->NEXT::prepare_action(@_);
+}
+
+sub _load_session {
+    my $c = shift;
+
     if ( my $sid = $c->sessionid ) {
                no warnings 'uninitialized'; # ne __address
 
@@ -98,9 +106,22 @@ sub prepare_action {
         else {
             $c->log->debug(qq/Restored session "$sid"/) if $c->debug;
         }
+
+        $c->_expire_ession_keys;
+
     }
+}
 
-    $c->NEXT::prepare_action(@_);
+sub _expire_ession_keys {
+    my ( $c, $data ) = @_;
+
+    my $now = time;
+
+    my $expiry = ($data || $c->_session || {})->{__expire_keys} || {};
+    foreach my $key (grep { $expiry->{$_} < $now } keys %$expiry ) {
+        delete $c->_session->{$key};
+        delete $expiry->{$key};
+    }
 }
 
 sub delete_session {
@@ -151,6 +172,13 @@ sub session {
        };
 }
 
+sub session_expire_key {
+    my ( $c, %keys ) = @_;
+
+    my $now = time;
+    @{ $c->session->{__expire_keys} }{keys %keys} = map { $now + $_ } values %keys;
+}
+
 sub initialize_session_data {
     my $c = shift;
 
@@ -339,6 +367,24 @@ C<session expired>
 
 =back
 
+=item session_expire_key $key, $ttl
+
+Mark a key to expire at a certain time (only useful when shorter than the
+expiry time for the whole session).
+
+For example:
+
+    __PACKAGE__->config->{session}{expires} = 1000000000000; # forever
+
+    # later
+
+    $c->session_expire_key( __user => 3600 );
+
+Will make the session data survive, but the user will still be logged out after
+an hour.
+
+Note that these values are not auto extended.
+
 =back
 
 =item INTERNAL METHODS
index 6331b17..3049d55 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 20;
+use Test::More tests => 25;
 use Test::MockObject;
 use Test::Deep;
 use Test::Exception;
@@ -179,9 +179,43 @@ $req->set_always( address => "127.0.0.1" );
         $now + 2000,
         "session expires time extended"
     );
+}
+
+{
+    my $c = MockCxt->new;
+    $c->setup;
 
        dies_ok {
                $c->sessionid("user:foo");
        } "can't set invalid sessionid string";
 }
 
+{
+    %session = (
+        %session,
+        __expire_keys => {
+            foo => time - 1000,
+            bar => time + 1000,
+        },
+        foo => 1,
+        bar => 2,
+        gorch => 3,
+    );
+
+    my $c = MockCxt->new;
+    $c->setup;
+
+    $c->sessionid("decafbad");
+    $c->prepare_action;
+    $c->finalize;
+
+    ok( !$c->session->{foo}, "foo was deleted, expired");
+    ok( $c->session->{bar}, "bar not deleted - still valid");
+    ok( $c->session->{gorch}, "gorch not deleted - no expiry");
+
+    is_deeply( [ sort keys %{ $c->session->{__expire_keys} } ], [qw/bar/], "expiry entry only for bar");
+
+    $c->session_expire_key( gorch => 10 );
+
+    is_deeply( [ sort keys %{ $c->session->{__expire_keys} } ], [qw/bar gorch/], "expiry entries for bar and gorch");
+}