MARC import: part 2 of large file support
authorGalen Charlton <galen.charlton@liblime.com>
Fri, 23 Nov 2007 20:44:54 +0000 (14:44 -0600)
committerJoshua Ferraro <jmf@liblime.com>
Sun, 25 Nov 2007 22:45:49 +0000 (16:45 -0600)
* Added check_cookie_auth to C4::Auth
* Added permissions checks to the file upload scripts
* Added more error handling

Signed-off-by: Joshua Ferraro <jmf@liblime.com>
C4/Auth.pm
koha-tmpl/intranet-tmpl/prog/en/includes/file-upload.inc
koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tmpl
tools/upload-file-progress.pl
tools/upload-file.pl

index f35dbb8..300a9ed 100755 (executable)
@@ -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<check_cookie_auth> 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;
index d81c649..f8f72fb 100644 (file)
                 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);
index e6f0163..aae7aa3 100644 (file)
@@ -65,6 +65,7 @@ function CheckForm(f) {
         <button clase="input" onclick="return ajaxFileUpload();">Upload file</button>
                </form>
         <div id="fileuploadstatus" style="display:none">Upload progress: <span id="fileuploadprogress">0<span>%</div>
+        <div id="fileuploadfailed" style="display:none"></div>
         </div>
        </li>
     <form method="post" action="<!-- TMPL_VAR name="SCRIPT_NAME" -->" enctype="multipart/form-data">
index 74ddc2b..c7b1f3e 100755 (executable)
@@ -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');
 
index 4b58114..ad9efc8 100755 (executable)
@@ -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