View | Details | Raw Unified | Return to bug 14296
Collapse All | Expand All

(-)a/C4/UploadedFiles.pm (-3 / +34 lines)
Lines 59-64 use File::Basename; Link Here
59
59
60
use C4::Context;
60
use C4::Context;
61
61
62
use constant MAX_DEFAULT_UPLOAD => 10000000;  # relatively large fallback;
63
62
sub _get_file_path {
64
sub _get_file_path {
63
    my ($id, $dirname, $filename) = @_;
65
    my ($id, $dirname, $filename) = @_;
64
66
Lines 142-153 sub UploadFile { Link Here
142
        return;
144
        return;
143
    }
145
    }
144
146
147
    my $ue = C4::Context->userenv;
148
    my $owner = $ue? $ue->{number}: undef;
149
    my $max = C4::UploadedFiles::MaxUploadSize( $owner );
150
145
    my $buffer;
151
    my $buffer;
146
    my $data = '';
152
    my $data = '';
147
    while($handle->read($buffer, 1024)) {
153
    while( $handle->read($buffer, 1024) && length($data) <= $max ) {
148
        $data .= $buffer;
154
        $data .= $buffer;
149
    }
155
    }
150
    $handle->close;
156
    $handle->close;
157
    if( length($data) > $max ) {
158
        # double check actually (see js); normally not possible, so we just
159
        # rely on a general error message and a warn
160
        warn "UploadFile: upload size exceeded after submit!";
161
        return;
162
    }
151
163
152
    my $sha = new Digest::SHA;
164
    my $sha = new Digest::SHA;
153
    $sha->add($data);
165
    $sha->add($data);
Lines 180-187 sub UploadFile { Link Here
180
        VALUES (?,?, ?, ?, ?);
192
        VALUES (?,?, ?, ?, ?);
181
    };
193
    };
182
    my $sth = $dbh->prepare($query);
194
    my $sth = $dbh->prepare($query);
183
    my $ue = C4::Context->userenv;
184
    my $owner = $ue? $ue->{number}: undef;
185
    if( $sth->execute($id, $filename, $dir, length($data), $owner ) ) {
195
    if( $sth->execute($id, $filename, $dir, length($data), $owner ) ) {
186
        return $id;
196
        return $id;
187
    }
197
    }
Lines 335-338 sub httpheaders { Link Here
335
          '-attachment' => $file, );
345
          '-attachment' => $file, );
336
}
346
}
337
347
348
=head2 MaxUploadSize
349
350
    Returns max upload size for borrower or if the borrower has no explicit
351
    user limit, the default max. If no records are found, falls back to a
352
    constant.
353
354
=cut
355
356
sub MaxUploadSize {
357
    my ( $user ) = @_;
358
    my $dbh = C4::Context->dbh;
359
    my $query = qq|
360
SELECT count1 FROM upload_settings
361
WHERE (borrowernumber=? OR borrowernumber IS NULL) AND
362
    type='filesize'
363
ORDER BY IFNULL(borrowernumber, 0) DESC;
364
    |;
365
    my ( $max ) = $dbh->selectrow_array( $query, undef, ( $user ) );
366
    return $max // MAX_DEFAULT_UPLOAD;
367
}
368
338
1;
369
1;
(-)a/cataloguing/value_builder/upload.pl (-10 / +4 lines)
Lines 90-99 my $launcher = sub { Link Here
90
        $id = C4::UploadedFiles::UploadFile($uploaded_file, $dir, $fh->handle);
90
        $id = C4::UploadedFiles::UploadFile($uploaded_file, $dir, $fh->handle);
91
        my $OPACBaseURL = C4::Context->preference('OPACBaseURL') // '';
91
        my $OPACBaseURL = C4::Context->preference('OPACBaseURL') // '';
92
        $OPACBaseURL =~ s#/$##;
92
        $OPACBaseURL =~ s#/$##;
93
        if (!$OPACBaseURL) {
93
        if( !$OPACBaseURL ) {
94
            $template->param(MissingURL => 1);
94
            $template->param( MissingURL => 1 );
95
        }
95
        } elsif( $id ) {
96
        if($id && $OPACBaseURL) {
97
            my $return = "$OPACBaseURL/cgi-bin/koha/opac-retrieve-file.pl?id=$id";
96
            my $return = "$OPACBaseURL/cgi-bin/koha/opac-retrieve-file.pl?id=$id";
98
            $template->param(
97
            $template->param(
99
                success => 1,
98
                success => 1,
Lines 116-126 my $launcher = sub { Link Here
116
    } else {
115
    } else {
117
        my $upload_path = C4::Context->config('upload_path');
116
        my $upload_path = C4::Context->config('upload_path');
118
        if ($upload_path) {
117
        if ($upload_path) {
119
            my $filefield = CGI::filefield(
120
                -name => 'uploaded_file',
121
                -size => 50,
122
            );
123
124
            my $dirs_tree = [ {
118
            my $dirs_tree = [ {
125
                name => '/',
119
                name => '/',
126
                value => '/',
120
                value => '/',
Lines 129-135 my $launcher = sub { Link Here
129
123
130
            $template->param(
124
            $template->param(
131
                dirs_tree => $dirs_tree,
125
                dirs_tree => $dirs_tree,
132
                filefield => $filefield,
126
                maxfilesize => C4::UploadedFiles::MaxUploadSize($loggedinuser),
133
            );
127
            );
134
        } else {
128
        } else {
135
            $template->param( error_upload_path_not_configured => 1 );
129
            $template->param( error_upload_path_not_configured => 1 );
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/value_builder/upload.tt (-25 / +26 lines)
Lines 7-38 Link Here
7
    <script type="text/javascript" src="[% interface %]/lib/jquery/jquery.js"></script>
7
    <script type="text/javascript" src="[% interface %]/lib/jquery/jquery.js"></script>
8
    <link rel="stylesheet" type="text/css" href="[% themelang %]/css/staff-global.css" />
8
    <link rel="stylesheet" type="text/css" href="[% themelang %]/css/staff-global.css" />
9
    <script type="text/javascript">
9
    <script type="text/javascript">
10
      function ValidateForm() {
10
//<![CDATA[
11
        var filename = document.forms["UploadForm"]["uploaded_file"].value;
11
    function _(s) { return s; } // dummy for translation
12
13
    function ValidateForm() {
14
        var filename = $('#uploaded_file').val();
15
        var files = $('#uploaded_file').prop('files');
12
        var selected = 0;
16
        var selected = 0;
13
        var value;
17
        if( $('#UploadForm').find('input[type="radio"][name="dir"]:checked').length > 0 ) {
14
        $('form').each(function() {
15
          value = $(this).find('input[type="radio"][name="dir"]:checked').val();
16
          if (value) {
17
            selected = 1;
18
            selected = 1;
18
          }
19
        });
20
        if (!filename && !selected) {
21
          alert("Please select a file and its destination.");
22
          return false;
23
        }
24
        else if (!filename) {
25
          alert("Please select a file to upload.");
26
          return false;
27
        }
19
        }
28
        else if (!selected) {
20
29
          alert("Please select a file destination.");
21
        if (!filename && !selected) {
30
          return false;
22
            alert( _("Please select a file and its destination.") );
31
        }
23
        } else if (!filename || files.length<1 ) {
32
        else {
24
            alert( _("Please select a file to upload.") );
33
          return true;
25
        } else if (!selected) {
26
            alert( _("Please select a file destination.") );
27
        } else if( files[0].size > [% maxfilesize %] ) {
28
            // check file size in advance; server will do repeated check later
29
            alert( _("The file size exceeds the maximum.") );
30
return true;
31
        } else {
32
            return true;
34
        }
33
        }
35
      }
34
        return false;
35
    }
36
//]]>
36
    </script>
37
    </script>
37
38
38
</head>
39
</head>
Lines 102-110 Link Here
102
          [% IF (dangling) %]
103
          [% IF (dangling) %]
103
              <p class="error">Error: The URL has no file to retrieve.</p>
104
              <p class="error">Error: The URL has no file to retrieve.</p>
104
          [% END %]
105
          [% END %]
105
          <h2>Please select the file to upload : </h2>
106
          <h2>Please select the file to upload:</h2>
106
          <form name="UploadForm" method="post" enctype="multipart/form-data" action="/cgi-bin/koha/cataloguing/plugin_launcher.pl" onsubmit="return ValidateForm()">
107
          <form id="UploadForm" method="post" enctype="multipart/form-data" action="/cgi-bin/koha/cataloguing/plugin_launcher.pl" onsubmit="return ValidateForm()">
107
              [% filefield %]
108
              <input type="file" name="uploaded_file" id="uploaded_file" />
108
              <h3>Choose where to upload the file</h3>
109
              <h3>Choose where to upload the file</h3>
109
              [% INCLUDE list_dirs dirs = dirs_tree %]
110
              [% INCLUDE list_dirs dirs = dirs_tree %]
110
              <input type="hidden" name="from_popup" value="1" />
111
              <input type="hidden" name="from_popup" value="1" />
(-)a/t/db_dependent/UploadedFiles.t (-2 / +41 lines)
Lines 3-9 Link Here
3
use Modern::Perl;
3
use Modern::Perl;
4
use File::Temp qw/tempdir/;
4
use File::Temp qw/tempdir/;
5
use Test::CGI::Multipart;
5
use Test::CGI::Multipart;
6
use Test::More tests => 20;
6
use Test::More tests => 21;
7
use Test::Warn;
7
use Test::Warn;
8
8
9
use t::lib::Mocks;
9
use t::lib::Mocks;
Lines 11-16 use t::lib::Mocks; Link Here
11
use C4::Context;
11
use C4::Context;
12
use C4::UploadedFiles;
12
use C4::UploadedFiles;
13
13
14
my $dbh = C4::Context->dbh;
15
$dbh->{AutoCommit} = 0;
16
$dbh->{RaiseError} = 1;
17
14
# This simulates a multipart POST request with a file upload.
18
# This simulates a multipart POST request with a file upload.
15
my $tcm = new Test::CGI::Multipart;
19
my $tcm = new Test::CGI::Multipart;
16
$tcm->upload_file(
20
$tcm->upload_file(
Lines 70-72 mkdir $temp2.'/A/AA'; Link Here
70
mkdir $temp2.'/A/BB';
74
mkdir $temp2.'/A/BB';
71
$a= C4::UploadedFiles::finddirs( $temp2 );
75
$a= C4::UploadedFiles::finddirs( $temp2 );
72
is( @{$a->[0]->{dirs}} == 2, 1, 'Finddir returns subdirectories' );
76
is( @{$a->[0]->{dirs}} == 2, 1, 'Finddir returns subdirectories' );
73
- 
77
78
#tests for MaxUploadSize
79
subtest 'Tests for MaxUploadSize' => sub {
80
    test_max();
81
};
82
83
#end of game
84
$dbh->rollback;
85
86
sub test_max {
87
    $dbh->do("DELETE FROM upload_settings");
88
    my $max = C4::UploadedFiles::MaxUploadSize();
89
    is( $max, 10000000, 'MaxUploadSize is equal to fallback' );
90
91
    $dbh->do("INSERT INTO upload_settings (type, count1) VALUES (?, ?)",
92
        undef, ( 'filesize', 500 ));
93
    $max = C4::UploadedFiles::MaxUploadSize();
94
    is( $max, 500, 'MaxUploadSize is equal to default' );
95
96
    my $borr = $dbh->selectall_arrayref(
97
        'SELECT borrowernumber FROM borrowers LIMIT 2' );
98
    if( @$borr < 2 ) {
99
        done_testing(2);
100
        return;
101
    }
102
    my $b1 = $borr->[0]->[0];
103
    $dbh->do("INSERT INTO upload_settings (borrowernumber, type, count1)
104
        VALUES (?, ?, ?)", undef, ( $b1, 'filesize', 1500 ));
105
    $max = C4::UploadedFiles::MaxUploadSize($b1);
106
    is( $max, 1500, 'MaxUploadSize is equal to user limit' );
107
108
    my $b2 = $borr->[1]->[0];
109
    $max = C4::UploadedFiles::MaxUploadSize($b2);
110
    is( $max, 500, 'MaxUploadSize is still equal to default for user 2' );
111
    done_testing(4);
112
}

Return to bug 14296