Subject: | Add session_data to supported features |
Hi, if would be nice if this could be added.
The model Catalyst::Plugin::Session::PerUser can use the 'session_data'
supported_feature in Catalyst::Authentication::User.pm subclasses.
The patch implements this. It was mostly copied from
Plugin::Session::Store::DBIC.
It works for case where user is not cached in session. For it work in
with session caching PerUser module needs a change to persist_user when
store_session_data called.
Subject: | session_data.patch |
diff -uNr b/MANIFEST a/MANIFEST
--- b/MANIFEST 2010-04-10 09:31:07.000000000 +0100
+++ a/MANIFEST 2010-05-19 15:53:21.000000000 +0100
@@ -25,6 +25,7 @@
t/07-authsessions-cached.t
t/08-simpledb-auth-roles-relationship.t
t/09-simpledb-auth-roles-column.t
+t/10-usersessions.t
t/lib/SetupDB.pm
t/lib/TestApp.pm
t/lib/TestApp/Controller/Root.pm
diff -uNr b/META.yml a/META.yml
--- b/META.yml 2010-04-10 09:31:03.000000000 +0100
+++ a/META.yml 2010-05-19 15:36:53.000000000 +0100
@@ -27,4 +27,4 @@
resources:
license: http://dev.perl.org/licenses/
repository: http://dev.catalystframework.org/repos/Catalyst/Catalyst-Authentication-Store-DBIx-Class
-version: 0.1200
+version: 0.1300
diff -uNr b/Makefile.PL a/Makefile.PL
--- b/Makefile.PL 2010-03-30 00:28:11.000000000 +0100
+++ a/Makefile.PL 2010-05-19 13:02:04.000000000 +0100
@@ -35,6 +35,8 @@
'Catalyst::Model::DBIC::Schema' => 0,
'DBIx::Class' => 0,
'Catalyst::Model::DBIC::Schema' => '0.18',
+ 'Storable' => 0,
+ 'MIME::Base64' => 0,
);
diff -uNr b/lib/Catalyst/Authentication/Store/DBIx/Class/User.pm a/lib/Catalyst/Authentication/Store/DBIx/Class/User.pm
--- b/lib/Catalyst/Authentication/Store/DBIx/Class/User.pm 2010-04-10 09:29:35.000000000 +0100
+++ a/lib/Catalyst/Authentication/Store/DBIx/Class/User.pm 2010-05-19 14:11:49.000000000 +0100
@@ -5,6 +5,8 @@
use List::MoreUtils qw(all);
use base qw/Catalyst::Authentication::User/;
use base qw/Class::Accessor::Fast/;
+use MIME::Base64();
+use Storable();
BEGIN {
__PACKAGE__->mk_accessors(qw/config resultset _user _roles/);
@@ -54,6 +56,17 @@
# ## presumably this is coming out of session storage.
# ## use $authinfo to fill in the user in that case?
# }
+
+ #Setup for session data
+ if(exists $self->config->{session_data_field}){
+
+ Catalyst::Exception->throw("session_data_field set to " .$self->config->{session_data_field} .
+ " but user table has no column of that name")
+ unless (!defined $self->config->{session_data_field}) || $self->{'resultset'}->result_source->has_column('session_data');
+ }else{
+ $self->config->{session_data_field} = 'session_data'
+ if $self->{'resultset'}->result_source->has_column('session_data');
+ }
return $self;
}
@@ -113,9 +126,34 @@
return {
session => 1,
roles => 1,
+ session_data => defined $self->config->{session_data_field},
};
}
+sub get_session_data {
+ my $self = shift;
+
+ my $data = $self->get($self->config->{session_data_field});
+ return undef unless $data;
+
+ $data = Storable::thaw(MIME::Base64::decode($data));
+
+ return $data;
+}
+
+
+sub store_session_data {
+ my ($self, $data) = @_;
+
+ my $d = MIME::Base64::encode(Storable::nfreeze($data));
+
+ if ($self->_user->can($self->config->{session_data_field})) {
+ $self->_user->set_column($self->config->{session_data_field},$d);
+ $self->_user->update();#Not sure about auto_update so force the update
+ }
+ 1;
+}
+
sub roles {
my ( $self ) = shift;
diff -uNr b/lib/Catalyst/Authentication/Store/DBIx/Class.pm a/lib/Catalyst/Authentication/Store/DBIx/Class.pm
--- b/lib/Catalyst/Authentication/Store/DBIx/Class.pm 2010-04-10 09:29:35.000000000 +0100
+++ a/lib/Catalyst/Authentication/Store/DBIx/Class.pm 2010-05-19 15:45:54.000000000 +0100
@@ -4,7 +4,7 @@
use warnings;
use base qw/Class::Accessor::Fast/;
-our $VERSION= "0.1200";
+our $VERSION = "0.1300";
BEGIN {
@@ -261,6 +261,14 @@
that if use_userdata_from_session is enabled, this config parameter
is not used at all.
+
+=item session_data_field
+
+The name of the field to store session data for a user. For use will PerUser sessions.
+Default value is session_data. If you have a field session_data and don't which to use it for
+storing of session data, then set session_data_field to undef. This will turn off session_data
+feature.
+
=back
=head1 USAGE
diff -uNr b/t/10-usersessions.t a/t/10-usersessions.t
--- b/t/10-usersessions.t 1970-01-01 01:00:00.000000000 +0100
+++ a/t/10-usersessions.t 2010-05-19 14:12:07.000000000 +0100
@@ -0,0 +1,127 @@
+#!perl
+
+use strict;
+use warnings;
+use DBI;
+use File::Path;
+use FindBin;
+use Test::More;
+use lib "$FindBin::Bin/lib";
+
+BEGIN {
+ eval { require Test::WWW::Mechanize::Catalyst }
+ or plan skip_all =>
+ "Test::WWW::Mechanize::Catalyst is required for this test";
+
+ eval { require DBD::SQLite }
+ or plan skip_all =>
+ "DBD::SQLite is required for this test";
+
+ eval { require DBIx::Class }
+ or plan skip_all =>
+ "DBIx::Class is required for this test";
+
+ eval { require Catalyst::Plugin::Session;
+ die unless $Catalyst::Plugin::Session::VERSION >= 0.02 }
+ or plan skip_all =>
+ "Catalyst::Plugin::Session >= 0.02 is required for this test";
+
+ eval { require Catalyst::Plugin::Session::State::Cookie; }
+ or plan skip_all =>
+ "Catalyst::Plugin::Session::State::Cookie is required for this test";
+
+ eval { require Catalyst::Plugin::Session::PerUser; }
+ or plan skip_all =>
+ "Catalyst::Plugin::Session::PerUser is required for this test";
+
+
+ plan tests => 16;
+
+ $ENV{TESTAPP_DB_FILE} = "$FindBin::Bin/auth.db" unless exists($ENV{TESTAPP_DB_FILE});
+
+ $ENV{TESTAPP_CONFIG} = {
+ name => 'TestApp',
+ authentication => {
+ default_realm => "users",
+ realms => {
+ users => {
+ credential => {
+ 'class' => "Password",
+ 'password_field' => 'password',
+ 'password_type' => 'clear'
+ },
+ store => {
+ 'class' => 'DBIx::Class',
+ 'user_model' => 'TestApp::User',
+ 'use_userdata_from_session' => 0,
+ },
+ },
+ },
+ },
+ };
+
+ $ENV{TESTAPP_PLUGINS} = [
+ qw/Authentication
+ Session
+ Session::Store::Dummy
+ Session::State::Cookie
+ Session::PerUser
+ /
+ ];
+}
+
+use SetupDB;
+
+use Test::WWW::Mechanize::Catalyst 'TestApp';
+my $m = Test::WWW::Mechanize::Catalyst->new;
+
+# log a user in
+{
+ $m->get_ok( 'http://localhost/user_login?username=joeuser&password=hackme', undef, 'request ok' );
+ $m->content_is( 'joeuser logged in', 'user logged in ok' );
+}
+
+# verify the user is still logged in
+{
+ $m->get_ok( 'http://localhost/get_session_user', undef, 'request ok' );
+ $m->content_is( 'joeuser', 'user still logged in' );
+}
+
+#Add Data user session store
+{
+ $m->get_ok( 'http://localhost/set_usersession/test_value', undef, 'request ok' );
+ $m->content_is( 'ok' );
+}
+
+# verify the user is still logged in
+{
+ $m->get_ok( 'http://localhost/get_session_user', undef, 'request ok' );
+ $m->content_is( 'joeuser', 'user still logged in' );
+}
+
+#Check value still in session
+{
+ $m->get_ok( 'http://localhost/get_usersession', undef, 'request ok' );
+ $m->content_is( 'test_value' );
+}
+
+# log the user out
+{
+ $m->get_ok( 'http://localhost/user_logout', undef, 'request ok' );
+ $m->content_is( 'logged out', 'user logged out ok' );
+}
+
+# log a user in
+{
+ $m->get_ok( 'http://localhost/user_login?username=joeuser&password=hackme', undef, 'request ok' );
+ $m->content_is( 'joeuser logged in', 'user logged in ok' );
+}
+
+#Check value still in session
+{
+ $m->get_ok( 'http://localhost/get_usersession/', undef, 'request ok' );
+ $m->content_is( 'test_value' );
+}
+
+# clean up
+unlink $ENV{TESTAPP_DB_FILE};