From 296e4909e0dfaae245389fd994b4838cd9dff8b8 Mon Sep 17 00:00:00 2001 From: Galen Charlton Date: Fri, 23 Nov 2007 14:44:54 -0600 Subject: [PATCH] MARC import: part 2 of large file support * Added check_cookie_auth to C4::Auth * Added permissions checks to the file upload scripts * Added more error handling Signed-off-by: Joshua Ferraro --- C4/Auth.pm | 110 ++++++++++++++++++ .../prog/en/includes/file-upload.inc | 16 ++- .../en/modules/tools/stage-marc-import.tmpl | 1 + tools/upload-file-progress.pl | 15 ++- tools/upload-file.pl | 13 ++- 5 files changed, 144 insertions(+), 11 deletions(-) diff --git a/C4/Auth.pm b/C4/Auth.pm index f35dbb87e2..300a9ed01b 100755 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -90,6 +90,7 @@ C4::Auth - Authenticates Koha users @EXPORT_OK = qw( &check_api_auth &get_session + &check_cookie_auth ); =item get_template_and_user @@ -963,6 +964,115 @@ sub check_api_auth { } } +=item check_cookie_auth + + ($status, $sessionId) = check_api_auth($cookie, $userflags); + +Given a CGISESSID cookie set during a previous login to Koha, determine +if the user has the privileges specified by C<$userflags>. + +C is meant for authenticating special services +such as tools/upload-file.pl that are invoked by other pages that +have been authenticated in the usual way. + +Possible return values in C<$status> are: + +=over 4 + +=item "ok" -- user authenticated; C<$sessionID> have valid values. + +=item "failed" -- credentials are not correct; C<$sessionid> are undef + +=item "maintenance" -- DB is in maintenance mode; no login possible at the moment + +=item "expired -- session cookie has expired; API user should resubmit userid and password + +=back + +=cut + +sub check_cookie_auth { + my $cookie = shift; + my $flagsrequired = shift; + + my $dbh = C4::Context->dbh; + my $timeout = C4::Context->preference('timeout'); + $timeout = 600 unless $timeout; + + unless (C4::Context->preference('Version')) { + # database has not been installed yet + return ("maintenance", undef); + } + my $kohaversion=C4::Context::KOHAVERSION; + $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; + if (C4::Context->preference('Version') < $kohaversion) { + # database in need of version update; assume that + # no API should be called while databsae is in + # this condition. + return ("maintenance", undef); + } + + # FIXME -- most of what follows is a copy-and-paste + # of code from checkauth. There is an obvious need + # for refactoring to separate the various parts of + # the authentication code, but as of 2007-11-23 this + # is deferred so as to not introduce bugs into the + # regular authentication code for Koha 3.0. + + # see if we have a valid session cookie already + # however, if a userid parameter is present (i.e., from + # a form submission, assume that any current cookie + # is to be ignored + unless (defined $cookie and $cookie) { + return ("failed", undef); + } + my $sessionID = $cookie; + my $session = get_session($sessionID); + C4::Context->_new_userenv($sessionID); + if ($session) { + C4::Context::set_userenv( + $session->param('number'), $session->param('id'), + $session->param('cardnumber'), $session->param('firstname'), + $session->param('surname'), $session->param('branch'), + $session->param('branchname'), $session->param('flags'), + $session->param('emailaddress'), $session->param('branchprinter') + ); + + my $ip = $session->param('ip'); + my $lasttime = $session->param('lasttime'); + my $userid = $session->param('id'); + if ( $lasttime < time() - $timeout ) { + # time out + $session->delete(); + C4::Context->_unset_userenv($sessionID); + $userid = undef; + $sessionID = undef; + return ("expired", undef); + } elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) { + # IP address changed + $session->delete(); + C4::Context->_unset_userenv($sessionID); + $userid = undef; + $sessionID = undef; + return ("expired", undef); + } else { + $session->param('lasttime',time()); + my $flags = haspermission( $dbh, $userid, $flagsrequired ); + if ($flags) { + return ("ok", $sessionID); + } else { + $session->delete(); + C4::Context->_unset_userenv($sessionID); + $userid = undef; + $sessionID = undef; + return ("failed", undef); + } + } + } else { + return ("expired", undef); + } +} + =item get_session use CGI::Session; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc index d81c649212..f8f72fb991 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc @@ -24,7 +24,21 @@ fileElementId:'fileToUpload', dataType: 'json', success: function (data, status) { - $("#uploadedfileid").val(data.fileid); + if (data.status == 'denied') { + $("#fileuploadstatus").hide(); + $("#fileuploadfailed").show(); + $("#fileuploadfailed").text("Upload failed -- no permission to upload files"); + } else if (data.status == 'failed') { + $("#fileuploadstatus").hide(); + $("#fileuploadfailed").show(); + $("#fileuploadfailed").text("Upload failed -- unable to store file on server"); + } else if (data.status == 'maintenance') { + $("#fileuploadstatus").hide(); + $("#fileuploadfailed").show(); + $("#fileuploadfailed").text("Upload failed -- database in maintenance state"); + } else { + $("#uploadedfileid").val(data.fileid); + } }, error: function (data, status, e) { alert(e); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl index e6f0163465..aae7aa3618 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl @@ -65,6 +65,7 @@ function CheckForm(f) { +
" enctype="multipart/form-data"> diff --git a/tools/upload-file-progress.pl b/tools/upload-file-progress.pl index 74ddc2bfa5..c7b1f3ec27 100755 --- a/tools/upload-file-progress.pl +++ b/tools/upload-file-progress.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # Copyright (C) 2007 LibLime # @@ -24,18 +24,23 @@ use IO::File; use CGI; use CGI::Session; use C4::Context; -use C4::Auth qw/get_session/; +use C4::Auth qw/get_session check_cookie_auth/; use CGI::Cookie; # need to check cookies before # having CGI parse the POST request use Digest::MD5; my %cookies = fetch CGI::Cookie; -my $sessionID = $cookies{'CGISESSID'}->value; +my %cookies = fetch CGI::Cookie; +my ($auth_status, $sessionID) = check_cookie_auth($cookies{'CGISESSID'}->value, { tools => 1 }); +if ($auth_status ne "ok") { + my $reply = CGI->new(""); + print $reply->header(-type => 'text/html'); + print "{ progress: 0 }"; + exit 0; +} my $session = get_session($sessionID); -# FIXME - add authentication based on cookie - my $query = CGI->new; my $fileid = $session->param('current_upload'); diff --git a/tools/upload-file.pl b/tools/upload-file.pl index 4b581146a2..ad9efc899f 100755 --- a/tools/upload-file.pl +++ b/tools/upload-file.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl # Copyright (C) 2007 LibLime # @@ -24,13 +24,18 @@ use IO::File; use CGI; use CGI::Session; use C4::Context; -use C4::Auth qw/get_session/; +use C4::Auth qw/get_session check_cookie_auth/; use CGI::Cookie; # need to check cookies before # having CGI parse the POST request use Digest::MD5; my %cookies = fetch CGI::Cookie; -my $sessionID = $cookies{'CGISESSID'}->value; +my ($auth_status, $sessionID) = check_cookie_auth($cookies{'CGISESSID'}->value, { tools => 1 }); +if ($auth_status ne "ok") { + $auth_status = 'denied' if $auth_status eq 'failed'; + send_reply($auth_status, "", ""); + exit 0; +} my $session = get_session($sessionID); @@ -42,8 +47,6 @@ my $session = get_session($sessionID); # requires that the session cookie already # have been created., $fileid, $tmp_file_name -# FIXME - add authentication based on cookie - my $fileid = Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().{}.$$)); # FIXME - make staging area configurable -- 2.39.5