Bug 11317: Add a way to access files from the intranet
authorRoch D'Amour <roch.damour@inlibro.com>
Tue, 17 Apr 2018 18:24:07 +0000 (14:24 -0400)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Thu, 3 May 2018 16:26:49 +0000 (13:26 -0300)
This squash contains all of these commits:
- Adds a page to access log files on the server from the intranet
- Update ID to allow for permalinking
- Rename config to "'accessdir' and fix qa
- Allows for multiple directories to be accessible
- Update the link under reports
- (Follow-up) Fixing merge error and cosmetic changes
- (Follow-up) Fix tab chars and move javascript to the footer
- (QA Follow-up) Fix datatable
- Make filename unicode-proof, renamed accessdir to access_dir and fix update

Test plans:
- Apply patch, update database
- Add to koha-conf:
<access_dir>/tmp/koha-public/one</access_dir>
<access_dir>/tmp/koha-public/two</access_dir>
<access_dir>/tmp/koha-public</access_dir>
- Create these directories ( mkdir /tmp/koha-public , etc...)
- Create these files:
echo "hello world!" > /tmp/koha-public/❤
echo "test" > /tmp/koha-public/one/samename.txt
echo "this is not the same" > /tmp/koha-public/two/samename.txt
- Login as Superadmin, go to tools > reports files
    - Click on ❤, make sure it's downloadable and readable
    - Click on both samename.txt, look inside and make sure the file is different
- Login as NON-superadmin. Go under tools, see no Report/Log under the third column
    - Go to add tools/access_file permission to user
    - See new entry under tools third column.
    - validate link is ok.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>

Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

debian/templates/koha-conf-site.xml.in
etc/koha-conf.xml
installer/data/mysql/atomicupdate/bz11317-add-permission-for-tools-access-file.sql [new file with mode: 0644]
installer/data/mysql/userpermissions.sql
koha-tmpl/intranet-tmpl/prog/en/includes/permissions.inc
koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc
koha-tmpl/intranet-tmpl/prog/en/modules/reports/reports-home.tt
koha-tmpl/intranet-tmpl/prog/en/modules/tools/access_files.tt [new file with mode: 0644]
koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt
tools/access_files.pl [new file with mode: 0755]

index d6f515f..3c2aa46 100644 (file)
@@ -296,7 +296,10 @@ __END_SRU_PUBLICSERVER__
  <!-- Secret passphrase used by Mojolicious for signed cookies -->
  <api_secret_passphrase>__API_SECRET__</api_secret_passphrase>
 
- <!-- true type font mapping accoding to type from $font_types in C4/Creators/Lib.pm -->
+ <!-- Accessible directory from the staff client, uncomment the following line and define a valid path to let the intranet user access it-->
+ <!-- <access_dir></access_dir> -->
+
+ <!-- true type font mapping according to type from $font_types in C4/Creators/Lib.pm -->
  <ttf>
     <font type="TR" >/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf</font>
     <font type="TB" >/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf</font>
index 092a26c..37b304c 100644 (file)
@@ -127,6 +127,9 @@ __PAZPAR2_TOGGLE_XML_POST__
  <!-- Secret passphrase used by Mojolicious for signed cookies -->
  <api_secret_passphrase>CHANGEME</api_secret_passphrase>
 
+ <!-- Accessible directory from the staff client, uncomment the following line and define a valid path to let the intranet user access it-->
+ <!-- <access_dir></access_dir> -->
+
  <!-- true type font mapping accoding to type from $font_types in C4/Creators/Lib.pm -->
  <ttf>
     <font type="TR" >__FONT_DIR__/DejaVuSerif.ttf</font>
diff --git a/installer/data/mysql/atomicupdate/bz11317-add-permission-for-tools-access-file.sql b/installer/data/mysql/atomicupdate/bz11317-add-permission-for-tools-access-file.sql
new file mode 100644 (file)
index 0000000..8861378
--- /dev/null
@@ -0,0 +1 @@
+INSERT IGNORE INTO permissions (module_bit, code, description) VALUES (13, 'access_files', 'Access to the files stored on the server');
index 2ea387e..047ec42 100644 (file)
@@ -58,6 +58,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES
    (13, 'records_batchmod', 'Perform batch modification of records (biblios or authorities)'),
    (13, 'marc_modification_templates', 'Manage marc modification templates'),
    (13, 'records_batchdel', 'Perform batch deletion of records (bibliographic or authority)'),
+   (13, 'access_files', 'Access to the files stored on the server'),
    (13, 'upload_general_files', 'Upload any file'),
    (13, 'upload_manage', 'Manage uploaded files'),
    (15, 'check_expiration', 'Check the expiration of a serial'),
index 78f4995..017ffb9 100644 (file)
     [%- CASE 'delete_public_lists' -%]<span>Delete public lists</span>
     [%- CASE 'upload_general_files' -%]<span>Upload any file</span>
     [%- CASE 'upload_manage' -%]<span>Manage uploaded files (<i>Useless without upload_general_files</i>)</span>
+    [%- CASE 'access_files' -%]<span>Access to the files stored on the server</span>
     [%- CASE 'edit_clubs' -%]<span>Create and edit clubs</span>
     [%- CASE 'edit_templates' -%]<span>Create and edit club templates</span>
     [%- CASE 'enroll' -%]<span>Enroll patrons in clubs</span>
index 50e52f7..67783e2 100644 (file)
     [% IF ( CAN_user_tools_upload_general_files ) %]
        <li><a href="/cgi-bin/koha/tools/upload.pl">Upload any file</a></li>
     [% END %]
+    [% IF ( CAN_user_tools_access_files ) %]
+    <li><a href="/cgi-bin/koha/tools/access_files.pl">Report/log files</a></li>
+    [% END %]
 </ul></div></div>
index 527f7a3..86d58ba 100644 (file)
 
     </div>
 
+<<<<<<< 3dd4c261c3d9d152edb12ead6b10b71b44418eab
     <div class="col-xs-6"><h2>Top lists</h2>
-       <ul>
-        <li><a href="/cgi-bin/koha/reports/bor_issues_top.pl">Patrons with the most checkouts</a></li>
-        <li><a href="/cgi-bin/koha/reports/cat_issues_top.pl">Most-circulated items</a></li>
-    </ul>
+        <ul>
+            <li><a href="/cgi-bin/koha/reports/bor_issues_top.pl">Patrons with the most checkouts</a></li>
+            <li><a href="/cgi-bin/koha/reports/cat_issues_top.pl">Most-circulated items</a></li>
+        </ul>
 
-    <h2>Inactive</h2>
-    <ul>
-        <li><a href="/cgi-bin/koha/reports/borrowers_out.pl">Patrons who haven't checked out</a></li>
-        <li><a href="/cgi-bin/koha/reports/catalogue_out.pl">Items with no checkouts</a></li>
-    </ul>
+        <h2>Inactive</h2>
+        <ul>
+                <li><a href="/cgi-bin/koha/reports/borrowers_out.pl">Patrons who haven't checked out</a></li>
+                <li><a href="/cgi-bin/koha/reports/catalogue_out.pl">Items with no checkouts</a></li>
+        </ul>
 
-    <h2>Other</h2>
-    <ul>
-        <li><a href="/cgi-bin/koha/reports/itemslost.pl">Items lost</a></li>
-                <li><a href="/cgi-bin/koha/reports/orders_by_fund.pl">Orders by fund</a></li>
-        <li><a href="/cgi-bin/koha/reports/manager.pl?report_name=itemtypes">Catalog by itemtype</a></li>
-        <li><a href="/cgi-bin/koha/reports/issues_avg_stats.pl">Average loan time</a></li>
-                <li><a href="http://schema.koha-community.org/" target="blank">Koha database schema</a></li>
-                <li><a href="http://wiki.koha-community.org/wiki/SQL_Reports_Library" target="blank">Koha reports library</a></li>
-</ul></div>
+        <h2>Other</h2>
+        <ul>
+            <li><a href="/cgi-bin/koha/reports/itemslost.pl">Items lost</a></li>
+            <li><a href="/cgi-bin/koha/reports/orders_by_fund.pl">Orders by fund</a></li>
+            <li><a href="/cgi-bin/koha/reports/manager.pl?report_name=itemtypes">Catalog by item type</a></li>
+            <li><a href="/cgi-bin/koha/reports/issues_avg_stats.pl">Average loan time</a></li>
+            <li><a href="http://schema.koha-community.org/" target="blank">Koha database schema</a></li>
+            <li><a href="http://wiki.koha-community.org/wiki/SQL_Reports_Library" target="blank">Koha reports library</a></li>
+            <!--<li><a href="/cgi-bin/koha/reports/stats.screen.pl">Till reconciliation</a></li> -->
+        </ul></div>
 </div>
 
 
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/access_files.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/access_files.tt
new file mode 100644 (file)
index 0000000..34e4922
--- /dev/null
@@ -0,0 +1,71 @@
+[% SET footerjs = 1 %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Report/log files</title>
+[% INCLUDE 'doc-head-close.inc' %]
+<link rel="stylesheet" type="text/css" href="[% interface %]/[% theme %]/css/datatables_[% KOHA_VERSION %].css" />
+</head>
+<body>
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'cat-search.inc' %]
+
+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; Report/log files</div>
+
+<div id="doc3" class="yui-t2">
+   <div id="bd">
+    <div id="yui-main">
+    <div class="yui-b">
+
+    <h1>Report/log files</h1>
+
+[% IF ( error_no_dir ) %]
+    <div class="dialog alert"><strong>Error : </strong>Report/log files could not be found because the "access_dir" option was not set in "koha-conf.xml". Contact your system administrator to add this option.</div>
+[% ELSE %]
+    [% IF ( files_loop ) %]
+        <table id="files">
+            <thead>
+                <tr>
+                    <th>Name</th>
+                    <th>Size (bytes)</th>
+                    <th>Date last modified</th>
+                </tr>
+            </thead>
+            <tbody>
+                [% FOREACH file IN files_loop %]
+                <tr>
+                    <td><a href="/cgi-bin/koha/tools/access_files.pl?id=[% file.id |url %]">[% file.name %]</a></td>
+                    <td align="right">[% file.size %]</td>
+                    <td>[% file.date %]</td>
+                </tr>
+                [% END %]
+            </tbody>
+        </table>
+    [% ELSE %]
+        No file found.
+    [% END %]
+[% END %]
+
+</div>
+</div>
+<div class="yui-b">
+[% INCLUDE 'tools-menu.inc' %]
+</div>
+</div>
+
+[% MACRO jsinclude BLOCK %]
+    <script type="text/javascript" src="[% interface %]/[% theme %]/js/tools-menu_[% KOHA_VERSION %].js"></script>
+    [% INCLUDE 'datatables.inc' %]
+    <script type="text/javascript">
+    //<![CDATA[
+        $(document).ready(function() {
+            $("#files").dataTable($.extend(true, {}, dataTablesDefaults, {
+                "sDom": 't',
+                "aoColumnDefs": [
+                    { "aTargets": [ -1 ], "asSorting" : [ "desc", "asc" ], "bSearchable": false }
+                ],
+                "bPaginate": false
+            }));
+    });
+    //]]>
+</script>
+[% END %]
+[% INCLUDE 'intranet-bottom.inc' %]
index 4c8cca9..da1884b 100644 (file)
     <dt><a href="/cgi-bin/koha/tools/upload.pl">Upload</a></dt>
     <dd>Upload any type of file, manage uploads</dd>
     [% END %]
+
+    [% IF CAN_user_tools_access_files %]
+    <dt><a href="/cgi-bin/koha/tools/access_files.pl">Report/log files</a></dt>
+    <dd>Access report or log files</dd>
+    [% END %]
+
 </dl>
 </div>
 
diff --git a/tools/access_files.pl b/tools/access_files.pl
new file mode 100755 (executable)
index 0000000..4f58123
--- /dev/null
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+
+# Frédérick Capovilla, 2011 - Libéo
+#
+# Show a list of all the files in the directory specified by the option
+# "access_dir" in koha-conf.xml so they can be downloaded by users with the
+# "access_files" permission.
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+
+use C4::Auth;
+use CGI;
+use C4::Context;
+use C4::Output;
+use C4::Koha;
+use File::stat qw(stat);
+use Digest::MD5 qw(md5_hex);
+use Encode;
+
+my $input = new CGI;
+my $file_id = $input->param("id");
+my $access_dir = C4::Context->config('access_dir');
+my @directories = $access_dir ? (ref $access_dir ? @{$access_dir} : ($access_dir)) : ();
+
+my ($template, $borrowernumber, $cookie)
+    = get_template_and_user({template_name => "tools/access_files.tt",
+                query => $input,
+                type => "intranet",
+                authnotrequired => 0,
+                flagsrequired => { tools => 'access_files' },
+                });
+
+unless(@directories) {
+    $template->param(error_no_dir => 1);
+}
+else {
+    #Get the files list
+    my @files_list;
+    foreach my $dir(@directories){
+        opendir(DIR, $dir);
+        foreach my $filename (readdir(DIR)) {
+            my $full_path = "$dir/$filename";
+            my $id = md5_hex($full_path);
+            next if ($filename =~ /^\./ or -d $full_path);
+
+            # Make sure the filename is unicode-friendly
+            my $decoded_filename = decode('utf8', $filename);
+            my $st = stat("$dir/$decoded_filename");
+
+            my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =localtime($st->mtime);
+            my $dt=DateTime->new(year      => $year + 1900,
+                                  month    => $mon + 1,
+                                  day      => $mday,
+                                  hour     => $hour,
+                                  minute   => $min,
+                            );
+            push(@files_list, {name => $decoded_filename,
+                               access_dir => $dir,
+                               date =>Koha::DateUtils::output_pref($dt),
+                               size => $st->size,
+                               id   => $id});
+        }
+        closedir(DIR);
+    }
+
+    my %files_hash = map { $_->{id} => $_ } @files_list;
+    # If we received a file_id and it is valid, send the file to the browser
+    if(defined $file_id and exists $files_hash{$file_id} ){
+        my $filename = $files_hash{$file_id}->{name};
+        my $dir = $files_hash{$file_id}->{access_dir};
+        binmode STDOUT;
+        # Open the selected file and send it to the browser
+        print $input->header(-type => 'application/x-download',
+                             -name => "$filename",
+                             -Content_length => -s "$dir/$filename",
+                             -attachment => "$filename");
+
+        my $fh;
+        open $fh, "<:encoding(UTF-8)", "$dir/$filename";
+        binmode $fh;
+
+        my $buf;
+        while(read($fh, $buf, 65536)) {
+            print $buf;
+        }
+        close $fh;
+
+        exit(0);
+    }
+    else{
+        # Send the file list to the template
+        $template->param(files_loop => \@files_list);
+    }
+}
+
+output_html_with_http_headers $input, $cookie, $template->output;