From 4344f4e30035852c6f28d78623511ad770010e08 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Mon, 2 May 2011 17:24:04 +0200 Subject: [PATCH] =?utf8?q?Session-basierte=20Dateien=20(die=20also=20bei?= =?utf8?q?=20Ablauf=20gel=C3=B6scht=20werden)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Conflicts: SL/Auth.pm --- SL/Auth.pm | 32 +++++---- SL/SessionFile.pm | 173 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 13 deletions(-) create mode 100644 SL/SessionFile.pm diff --git a/SL/Auth.pm b/SL/Auth.pm index adf58106e..784b185b4 100644 --- a/SL/Auth.pm +++ b/SL/Auth.pm @@ -12,6 +12,7 @@ use SL::Auth::Constants qw(:all); use SL::Auth::DB; use SL::Auth::LDAP; +use SL::SessionFile; use SL::User; use SL::DBConnect; use SL::DBUpgrade2; @@ -555,6 +556,8 @@ sub destroy_session { $dbh->commit(); + SL::SessionFile->destroy_session($session_id); + $session_id = undef; $self->{SESSION} = { }; } @@ -571,24 +574,27 @@ sub expire_sessions { my $dbh = $self->dbconnect(); - $dbh->begin_work; + my $query = qq|SELECT id + FROM auth.session + WHERE (mtime < (now() - '$self->{session_timeout}m'::interval))|; - my $query = - qq|DELETE FROM auth.session_content - WHERE session_id IN - (SELECT id - FROM auth.session - WHERE (mtime < (now() - '$self->{session_timeout}m'::interval)))|; + my @ids = selectall_array_query($::form, $dbh, $query); - do_query($main::form, $dbh, $query); + if (@ids) { + $dbh->begin_work; - $query = - qq|DELETE FROM auth.session - WHERE (mtime < (now() - '$self->{session_timeout}m'::interval))|; + SL::SessionFile->destroy_session($_) for @ids; - do_query($main::form, $dbh, $query); + $query = qq|DELETE FROM auth.session_content + WHERE session_id IN (| . join(', ', ('?') x scalar(@ids)) . qq|)|; + do_query($main::form, $dbh, $query, @ids); - $dbh->commit(); + $query = qq|DELETE FROM auth.session + WHERE id IN (| . join(', ', ('?') x scalar(@ids)) . qq|)|; + do_query($main::form, $dbh, $query, @ids); + + $dbh->commit(); + } $main::lxdebug->leave_sub(); } diff --git a/SL/SessionFile.pm b/SL/SessionFile.pm new file mode 100644 index 000000000..12f498465 --- /dev/null +++ b/SL/SessionFile.pm @@ -0,0 +1,173 @@ +package SL::SessionFile; + +use strict; + +use parent qw(Rose::Object); + +use Carp; +use File::Path qw(make_path remove_tree); +use English qw(-no_match_vars); +use IO::File; +use POSIX qw(strftime); + +use Rose::Object::MakeMethods::Generic +( + scalar => [ qw(fh file_name) ], +); + +sub new { + my ($class, $file_name, $mode) = @_; + + my $self = $class->SUPER::new; + + my $path = $self->prepare_path; + $file_name =~ s:.*/::g; + $file_name = "${path}/${file_name}"; + + $self->fh(IO::File->new($file_name, $mode)) if $mode; + $self->file_name($file_name); + + return $self; +} + +sub exists { + my ($self) = @_; + return -f $self->file_name; +} + +sub size { + my ($self) = @_; + return -s $self->file_name; +} + +sub displayable_mtime { + my ($self) = @_; + return '' unless $self->exists; + + my @mtime = localtime((stat $self->file_name)[9]); + return $::locale->format_date(\%::myconfig, $mtime[5] + 1900, $mtime[4] + 1, $mtime[3]) . ' ' . strftime('%H:%M:%S', @mtime); +} + +sub get_path { + die "No session ID" unless $::auth->get_session_id; + return "users/session_files/" . $::auth->get_session_id; +} + +sub prepare_path { + my $path = get_path(); + return $path if -d $path; + make_path $path; + die "Creating ${path} failed" unless -d $path; + return $path; +} + +sub destroy_session { + my ($class, $session_id) = @_; + + $session_id =~ s/[^a-z0-9]//gi; + remove_tree "users/session_files/$session_id" if $session_id; +} + +1; +__END__ + +=pod + +=encoding utf8 + +=head1 NAME + +SL::SessionFile - Create files that are removed when the session is +destroyed or expires + +=head1 SYNOPSIS + + use SL::SessionFile; + + # Create a session file named "customer.csv" (relative names only) + my $sfile = SL::SessionFile->new("customer.csv", "w"); + $sfile->fh->print("col1;col2;col3\n" . + "value1;value2;value3\n"); + $sfile->fh->close; + + # Does temporary file exist? + my $sfile = SL::SessionFile->new("customer.csv"); + if ($sfile->exists) { + print "file exists; size " . $sfile->size . " bytes; mtime " . $sfile->displayable_mtime . "\n"; + } + +A small class that wraps around files that only exist as long as the +user's session exists. The session expiration mechanism will delete +all session files when the session itself is removed due to expiry or +the user logging out. + +Files are stored in session-specific folders in +C. + +=head1 MEMBER FUNCTIONS + +=over 4 + +=item C + +Create a new instance. C<$file_name> is a relative file name (path +components are stripped) to the session-specific temporary directory. + +If C<$mode> is given then try to open the file as an instance of +C. C<$mode> is passed through to C. + +=item C + +Returns the instance of C associated with the file. + +=item C + +Returns the full relative file name associated with this instance. If +it has been created for "customer.csv" then the value returned might +be C. + +=item C + +Returns trueish if the file exists. + +=item C + +Returns the file's size in bytes. + +=item C + +Returns the modification time suitable for display (e.g. date +formatted according to the user's date format), e.g. +C<22.01.2011 14:12:22>. + +=back + +=head1 OBJECT FUNCTIONS + +=over 4 + +=item C + +Returns the name of the session-specific directory used for file +storage relative to the Lx-Office installation folder. + +=item C + +Creates all directories in C if they do not exist. Returns +the same as C. + +=item C + +Removes all files and the directory belonging to the session C<$id>. + +=back + +=head1 BUGS + +Nothing here yet. + +=head1 AUTHOR + +Moritz Bunkus Em.bunkus@linet-services.deE + +=cut -- 2.20.1