pax_global_header00006660000000000000000000000064120546747010014520gustar00rootroot0000000000000052 comment=d46638215111556f79cabb3cdc85972ff5d70bf6 perl-Dancer-Session-Cookie-0.15/000075500000000000000000000000001205467470100164275ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/.gear/000075500000000000000000000000001205467470100174235ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/.gear/rules000064400000000000000000000000661205467470100205020ustar00rootroot00000000000000tar: . spec: altlinux/perl-Dancer-Session-Cookie.spec perl-Dancer-Session-Cookie-0.15/Changes000064400000000000000000000017251205467470100177270ustar00rootroot00000000000000Revision history for Dancer-Session-Cookie 0.15 2011-05-21 * skip test 02-configfile.t if YAML is not present FIX smoker test failure. (Alexis Sukrieh) 0.14 2011-03-12 [ Michael G. Schwern ] * Fix for Dancer > v1.3012 * Add support for session_secure to serve https only cookies. * Add missing MYMETA.yml * Make Dancer::Session::Cookie honor the session_name setting added to Dancer::Session::Abstract * Add session_cookie_path to control the path of the cookie. 0.13 Sun Nov 28 17:19:58 MSK 2010 Some documentation fixes. No functional change. 0.12 Thu Sep 16 13:29:09 MSD 2010 Fix a warning when testing against newer Dancer. No functional change. 0.11 Wed Feb 17 16:12:21 MSK 2010 Chase the ever-changing Dancer core :) No functional change. More tests. 0.1 Tue Feb 2 17:20:11 MSK 2010 First version separated from the Dancer core. No functional change. perl-Dancer-Session-Cookie-0.15/MANIFEST000064400000000000000000000005011205467470100175540ustar00rootroot00000000000000.gitignore Changes lib/Dancer/Session/Cookie.pm Makefile.PL MANIFEST MANIFEST.SKIP README t/00-load.t t/01-session.t t/02-configfile.t t/03-path.t t/03-server.t t/04-session_name.t t/05-session_secure.t t/data/config.yml t/manifest.t t/pod.t META.yml Module meta-data (added by MakeMaker) perl-Dancer-Session-Cookie-0.15/MANIFEST.SKIP000064400000000000000000000000771205467470100203310ustar00rootroot00000000000000^.git/ ^blib/ pm_to_blib ^Makefile$ \.old MANIFEST.bak t/logs/ perl-Dancer-Session-Cookie-0.15/META.yml000064400000000000000000000014161205467470100177020ustar00rootroot00000000000000--- #YAML:1.0 name: Dancer-Session-Cookie version: 0.15 abstract: Encrypted cookie-based session backend for Dancer author: - Alex Kapranoff license: perl distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: Test::Exception: 0 Test::More: 0 Test::NoWarnings: 0 requires: Crypt::CBC: 0 Crypt::Rijndael: 0 Dancer: 1.13 String::CRC32: 0 Test::Exception: 0 Test::More: 0 Test::NoWarnings: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.55_02 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 perl-Dancer-Session-Cookie-0.15/Makefile.PL000064400000000000000000000015431205467470100204040ustar00rootroot00000000000000use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Dancer::Session::Cookie', AUTHOR => q{Alex Kapranoff }, VERSION_FROM => 'lib/Dancer/Session/Cookie.pm', ABSTRACT_FROM => 'lib/Dancer/Session/Cookie.pm', ($ExtUtils::MakeMaker::VERSION >= 6.55 ? ('LICENSE'=> 'perl') : ()), PL_FILES => {}, BUILD_REQUIRES => { 'Test::More' => 0, 'Test::NoWarnings'=> 0, 'Test::Exception' => 0, }, PREREQ_PM => { 'Crypt::CBC' => 0, 'String::CRC32' => 0, 'Crypt::Rijndael' => 0, 'Dancer' => 1.130, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'Dancer-Session-Cookie-* t/logs' }, ); perl-Dancer-Session-Cookie-0.15/README000064400000000000000000000006551205467470100173150ustar00rootroot00000000000000Dancer::Session::Cookie - encrypted cookie-based session backend for Dancer framework. This module implements a session engine for sessions stored entirely in cookies. Usually only session id is stored in cookies and the session data itself is saved in a database. This module allows to avoid using external storage at all. Since we cannot trust any data provided by client in cookies, we use cryptography to ensure integrity. perl-Dancer-Session-Cookie-0.15/altlinux/000075500000000000000000000000001205467470100202675ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/altlinux/perl-Dancer-Session-Cookie.spec000064400000000000000000000012211205467470100261230ustar00rootroot00000000000000Name: perl-Dancer-Session-Cookie Version: 0.15 Release: alt1 Summary: Encrypted cookie-based session backend for Dancer Group: Development/Perl License: perl Url: %CPAN Dancer-Session-Cookie Source: %name-%version.tar BuildArch: noarch BuildRequires: perl-Crypt-CBC perl-devel perl-Test-Exception perl-Dancer perl-String-CRC32 perl-Test-NoWarnings perl-Crypt-Rijndael perl-YAML %description %summary %prep %setup -q %build %perl_vendor_build %install %perl_vendor_install %files %perl_vendor_privlib/Dancer/Session/Cookie* %doc Changes README %changelog * Mon Nov 26 2012 Vladimir Lettiev 0.15-alt1 - initial build for ALTLinux perl-Dancer-Session-Cookie-0.15/lib/000075500000000000000000000000001205467470100171755ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/lib/Dancer/000075500000000000000000000000001205467470100203715ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/lib/Dancer/Session/000075500000000000000000000000001205467470100220145ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/lib/Dancer/Session/Cookie.pm000064400000000000000000000116661205467470100235750ustar00rootroot00000000000000package Dancer::Session::Cookie; use strict; use warnings; use base 'Dancer::Session::Abstract'; use Crypt::CBC; use String::CRC32; use Crypt::Rijndael; use Dancer (); use Dancer::Config 'setting'; use Storable (); use MIME::Base64 (); use vars '$VERSION'; $VERSION = '0.15'; # crydec my $CIPHER = undef; sub init { my ($class) = @_; my $key = setting("session_cookie_key") # XXX default to smth with warning or die "The setting session_cookie_key must be defined"; $CIPHER = Crypt::CBC->new( -key => $key, -cipher => 'Rijndael', ); } sub new { my $self = Dancer::Object::new(@_); # id is not needed here because the whole serialized session is # the "id" return $self; } sub retrieve { my ($class, $id) = @_; my $ses = eval { # 1. decrypt and deserialize $id my $plain_text = _decrypt($id); # 2. deserialize $plain_text && Storable::thaw($plain_text); }; $ses and $ses->{id} = $id; return $ses; } sub create { my $class = shift; return Dancer::Session::Cookie->new(id => 'empty'); } # session_name was introduced to Dancer::Session::Abstract in 1.176 # we have 1.130 as the minimum sub session_name { my $self = shift; return eval { $self->SUPER::session_name } || setting("session_name") || "dancer.session"; } sub flush { my $self = shift; # 1. serialize and encrypt session delete $self->{id}; my $cipher_text = _encrypt(Storable::freeze($self)); my $session_name = $self->session_name; Dancer::set_cookie( $session_name => $cipher_text, path => setting("session_cookie_path") || "/", secure=> setting("session_secure"), ); $self->{id} = $cipher_text; return 1; } sub destroy { my $self = shift; delete Dancer::Cookies->cookies->{$self->session_name}; return 1; } sub _encrypt { my $plain_text = shift; my $crc32 = String::CRC32::crc32($plain_text); # XXX should gzip data if it grows too big. CRC32 won't be needed # then. my $res = MIME::Base64::encode($CIPHER->encrypt(pack('La*', $crc32, $plain_text)), q{}); $res =~ tr{=+/}{_*-}; # cookie-safe Base64 return $res; } sub _decrypt { my $cookie = shift; $cookie =~ tr{_*-}{=+/}; $SIG{__WARN__} = sub {}; my ($crc32, $plain_text) = unpack "La*", $CIPHER->decrypt(MIME::Base64::decode($cookie)); return $crc32 == String::CRC32::crc32($plain_text) ? $plain_text : undef; } 1; __END__ =pod =head1 NAME Dancer::Session::Cookie - Encrypted cookie-based session backend for Dancer =head1 SYNOPSIS Your F: session: "cookie" session_cookie_key: "this random key IS NOT very random" =head1 DESCRIPTION This module implements a session engine for sessions stored entirely in cookies. Usually only B is stored in cookies and the session data itself is saved in some external storage, e.g. database. This module allows to avoid using external storage at all. Since server cannot trust any data returned by client in cookies, this module uses cryptography to ensure integrity and also secrecy. The data your application stores in sessions is completely protected from both tampering and analysis on the client-side. =head1 CONFIGURATION The setting B should be set to C in order to use this session engine in a Dancer application. See L. A mandatory setting is needed as well: B, which should contain a random string of at least 16 characters (shorter keys are not cryptographically strong using AES in CBC mode). Here is an example configuration to use in your F: session: "cookie" session_cookie_key: "kjsdf07234hjf0sdkflj12*&(@*jk" Compromising B will disclose session data to clients and proxies or eavesdroppers and will also allow tampering, for example session theft. So, your F should be kept at least as secure as your database passwords or even more. Also, changing B will have an effect of immediate invalidation of all sessions issued with the old value of key. B can be used to control the path of the session cookie. The default is /. The global B setting is honoured and a secure (https only) cookie will be used if set. =head1 DEPENDENCY This module depends on L, L, L, L and L. =head1 AUTHOR This module has been written by Alex Kapranoff. =head1 SEE ALSO See L for details about session usage in route handlers. See L, L, L for alternative implementation of this mechanism. =head1 COPYRIGHT This module is copyright (c) 2009-2010 Alex Kapranoff . =head1 LICENSE This module is free software and is released under the same terms as Perl itself. =cut perl-Dancer-Session-Cookie-0.15/t/000075500000000000000000000000001205467470100166725ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/t/00-load.t000064400000000000000000000003141205467470100202110ustar00rootroot00000000000000#!perl -T use Test::More tests => 1; BEGIN { use_ok( 'Dancer::Session::Cookie' ) || print "Bail out! "; } diag( "Testing Dancer::Session::Cookie $Dancer::Session::Cookie::VERSION, Perl $], $^X" ); perl-Dancer-Session-Cookie-0.15/t/01-session.t000064400000000000000000000021011205467470100207520ustar00rootroot00000000000000use Test::More import => ['!pass']; use Test::Exception; use Test::NoWarnings; use strict; use warnings; use Dancer; use Dancer::ModuleLoader; BEGIN { plan tests => 12; use_ok 'Dancer::Session::Cookie' } my $session; throws_ok { $session = Dancer::Session::Cookie->create } qr/session_cookie_key must be defined/, 'requires session_cookie_key'; set session_cookie_key => 'test/secret*@?)'; lives_and { $session = Dancer::Session::Cookie->create } 'works'; is $@, '', 'Cookie session created'; isa_ok $session, 'Dancer::Session::Cookie'; can_ok $session, qw(init create retrieve destroy flush); my $eid; ok defined($eid = $session->id), 'session id is defined'; $session->{bar} = 'baz'; $session->flush; ok defined($session->id), 'id after storing a value is defined'; isnt $session->id, $eid, '...but changed'; ok length($session->id) > 20, 'new id is a long string'; my $s = Dancer::Session::Cookie->retrieve('XXX'); is $s, undef, 'unknown session is not found'; $s = Dancer::Session::Cookie->retrieve($session->id); is_deeply $s, $session, 'session is retrieved'; perl-Dancer-Session-Cookie-0.15/t/02-configfile.t000064400000000000000000000013741205467470100214100ustar00rootroot00000000000000use Test::More import => ['!pass']; use Test::Exception; #use Test::NoWarnings; use strict; use warnings; use Dancer; use Dancer::ModuleLoader; use FindBin; use File::Spec; eval "use YAML"; plan skip_all => "YAML is needed for this test" if $@; BEGIN { plan tests => 4; use_ok 'Dancer::Session::Cookie' } my $session; throws_ok { $session = Dancer::Session::Cookie->create } qr/session_cookie_key must be defined/, 'still requires session_cookie_key'; set confdir => "$FindBin::Bin/data"; ok(-r File::Spec->catfile(setting('confdir'), 'config.yml'), 'config.yml is available'); Dancer::Config::load(); lives_and { $session = Dancer::Session::Cookie->create } 'session key loaded from config.yml'; is $@, '', "Cookie session created"; perl-Dancer-Session-Cookie-0.15/t/03-path.t000064400000000000000000000011361205467470100202340ustar00rootroot00000000000000#!/usr/bin/env perl use Test::More import => ['!pass']; use strict; use warnings; use Dancer; my $CLASS = 'Dancer::Session::Cookie'; use_ok $CLASS; note "test setup"; { set session_cookie_key => "The dolphins are in the jacuzzi"; } note "default path"; { my $session = Dancer::Session::Cookie->create; $session->flush; is cookies->{"dancer.session"}->path, "/"; } note "set the path"; { set session_cookie_path => "/some/thing"; my $session = Dancer::Session::Cookie->create; $session->flush; is cookies->{"dancer.session"}->path, "/some/thing"; } done_testing; perl-Dancer-Session-Cookie-0.15/t/03-server.t000064400000000000000000000034631205467470100206130ustar00rootroot00000000000000#!/usr/bin/env perl use strict; use warnings; use Test::More import => ["!pass"]; plan skip_all => "Test::TCP required" unless eval { require Test::TCP; Test::TCP->import; 1; }; plan skip_all => "LWP required" unless eval { require LWP; }; test_tcp( client => sub { my $port = shift; require LWP::UserAgent; require HTTP::Cookies; my $ua = LWP::UserAgent->new; # Simulate two different browsers with two different jars my @jars = (HTTP::Cookies->new, HTTP::Cookies->new); for my $jar (@jars) { $ua->cookie_jar( $jar ); my $res = $ua->get("http://0.0:$port/foo"); is $res->content, "hits: 0, last_hit: "; $res = $ua->get("http://0.0:$port/bar"); is $res->content, "hits: 1, last_hit: foo"; $res = $ua->get("http://0.0:$port/baz"); is $res->content, "hits: 2, last_hit: bar"; } $ua->cookie_jar($jars[0]); my $res = $ua->get("http://0.0:$port/wibble"); is $res->content, "hits: 3, last_hit: baz", "session not overwritten"; }, server => sub { my $port = shift; use Dancer ':tests', ':syntax'; set port => $port; set appdir => ''; # quiet warnings not having an appdir set access_log => 0; # quiet startup banner set session_cookie_key => "John has a long mustache"; set session => "cookie"; get "/*" => sub { my $hits = session("hit_counter") || 0; my $last = session("last_hit") || ''; session hit_counter => $hits + 1; session last_hit => (splat)[0]; return "hits: $hits, last_hit: $last"; }; dance; } ); done_testing; perl-Dancer-Session-Cookie-0.15/t/04-session_name.t000064400000000000000000000012141205467470100217610ustar00rootroot00000000000000#!/usr/bin/env perl use Test::More import => ['!pass']; use strict; use warnings; use Dancer; my $CLASS = 'Dancer::Session::Cookie'; use_ok $CLASS; note "test setup"; { set session_cookie_key => "The dolphins are in the jacuzzi"; } note "default session_name"; { my $session = $CLASS->create; is $session->session_name, "dancer.session"; } note "honors session_name setting"; { my $session = $CLASS->create; my $session_name = "stuff.session"; set session_name => $session_name; is $session->session_name, $session_name; $session->flush; is cookies->{$session_name}->name, $session_name; } done_testing; perl-Dancer-Session-Cookie-0.15/t/05-session_secure.t000064400000000000000000000015361205467470100223370ustar00rootroot00000000000000#!/usr/bin/env perl use strict; use warnings; use Dancer ':syntax'; use Dancer::Session::Cookie; use Test::More import => ["!pass"]; plan skip_all => "Dancer::Cookie->secure not supported in this version of Dancer" unless Dancer::Cookie->can("secure"); plan tests => 2; my $Session_Name = Dancer::Session::Cookie->session_name; note "session_secure off"; { set session_cookie_key => "secret squirrel"; set session => "cookie"; session foo => "bar"; my $session_cookie = Dancer::Cookies->cookies->{ $Session_Name }; ok !$session_cookie->secure; } note "session_secure on"; { delete Dancer::Cookies->cookies->{ $Session_Name }; set session_secure => 1; set session => "cookie"; session up => "down"; my $session_cookie = Dancer::Cookies->cookies->{ $Session_Name }; ok $session_cookie->secure; } perl-Dancer-Session-Cookie-0.15/t/data/000075500000000000000000000000001205467470100176035ustar00rootroot00000000000000perl-Dancer-Session-Cookie-0.15/t/data/config.yml000064400000000000000000000000351205467470100215710ustar00rootroot00000000000000session_cookie_key: "secret" perl-Dancer-Session-Cookie-0.15/t/manifest.t000064400000000000000000000004061205467470100206650ustar00rootroot00000000000000#!perl -T use strict; use warnings; use Test::More; unless ( $ENV{RELEASE_TESTING} ) { plan( skip_all => "Author tests not required for installation" ); } eval "use Test::DistManifest"; plan skip_all => "Test::DistManifest required" if $@; manifest_ok(); perl-Dancer-Session-Cookie-0.15/t/pod.t000064400000000000000000000003501205467470100176370ustar00rootroot00000000000000#!perl -T use strict; use warnings; use Test::More; # Ensure a recent version of Test::Pod my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok();