Koha/koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt
Jonathan Druart dcd1f5d48c Bug 13618: Add html filters to all the variables
Here we go, next step then.
As we did not fix the performance issue when autofiltering
the variables (see bug 20975), the only solution we have is to add the
filters explicitely.

This patch has been autogenerated (using add_html_filters.pl, see next
pathces) and add the html filter to all the variables displayed in the
template.
Exceptions are made (using the new 'raw' TT filter) to the variable we
already listed in the previous versions of this patch.

To test:
- Use t/db_dependent/Koha/Patrons.t to populate your DB with autogenerated
data which contain <script> tags

- Remove them from borrower_debarments.comments (there are allowed here)
update  borrower_debarments set comment="html tags possible here";

- From the interface hit page and try to catch alert box.
If you find one it means you find a possible XSS.
To know where it comes from:
* note the exact URL where you found it
* note the alert box content
* Dump your DB and search for the string in the dump to identify its
location (for instance table.field)

Next:
* Ideally we would like to use the raw filter when it is not necessary
to HTML escape the variables (in big loop for instance)
* Provide a QA script to catch missing filters (we want html, uri, url
or raw, certainly others that I am forgetting now)
* Replace the html filters with uri when needed (!)

Signed-off-by: Owen Leonard <oleonard@myacpl.org>

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
2018-08-17 15:55:05 +00:00

304 lines
12 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[% USE raw %]
[% USE Asset %]
[% SET footerjs = 1 %]
[% PROCESS 'merge-record.inc' %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha &rsaquo; Cataloging &rsaquo; Merging records</title>
[% INCLUDE 'doc-head-close.inc' %]
<style type="text/css">
div.record ul, div.record li { float:none; display:block; }
div#result { margin-top: 1em; }
/* We use this style "against" the li ui-tabs-nav style automatically applied */
#dataPreview { width : 80%; } @media (max-width: 767px) { #dataPreview { margin: 0; width : auto; } }
</style>
</head>
<body id="cat_merge" class="cat">
[% INCLUDE 'header.inc' %]
[% INCLUDE 'cataloging-search.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/cataloguing/addbooks.pl">Cataloging</a> &rsaquo; Merging records</div>
<div id="doc" class="yui-t7">
<div id="bd">
<div id="yui-main">
<h1>Merging records</h1>
[% IF ( result ) %]
[% IF ( errors.size ) %]
[% FOREACH error IN errors %]
<div class="dialog alert">
[% IF error.code == 'CANNOT_MOVE' %]
The following items could not be moved from the old record to the new one: [% error.value | html %]
[% ELSE %]
[% error | html %]
[% END %]
<br />
Therefore, the record to be merged has not been deleted.
</div>
[% END %]
[% ELSE %]
<p>The merge was successful. <a href="/cgi-bin/koha/catalogue/MARCdetail.pl?biblionumber=[% ref_biblionumber | html %]">Click here to see the merged record.</a></p>
<h3>Report</h3>
<table>
<thead>
<tr>
<th>Biblionumber</th>
[% FOREACH key IN report_header.keys.sort %]
[% tag = key.substr(0, 3) | html %]
[% code = key.substr(3, 1) | html %]
[% IF code == '@' %]
[% header = tag | html %]
[% ELSE %]
[% header = tag _ '$' _ code | html %]
[% END %]
<th>[% header | html %]</th>
[% END %]
</tr>
</thead>
<tbody>
[% FOREACH record IN report_records %]
<tr>
<td>
[% record.biblionumber | html %]
[% IF loop.first %]
(record kept)
[% END %]
</td>
[% FOREACH key IN report_header.keys.sort %]
<td>
[% values = record.fields.$key | html %]
[% IF values %]
[% FOREACH value IN record.fields.$key %]
[% value | html %]
[% UNLESS loop.last %]<br />[% END %]
[% END %]
[% END %]
</td>
[% END %]
</tr>
[% END %]
</tbody>
</table>
[% END %]
[% ELSE %]
[% IF ( choosereference ) %]
<p>Please choose which record will be the reference for the merge. The record chosen as reference will be kept, and the other will be deleted.</p>
<form id="mergeform" action="/cgi-bin/koha/cataloguing/merge.pl" method="post">
<fieldset class="rows">
<legend>Merge reference</legend>
<ol>
[% FOREACH record IN records %]
<li class="radio">
[% IF loop.first %]
<input type="radio" value="[% record.biblionumber | html %]" checked="checked" id="ref_biblionumber[% record.biblionumber | html %]" name="ref_biblionumber" onclick="changeFramework('[% record.frameworkcode | html %]')" />
[% ELSE %]
<input type="radio" value="[% record.biblionumber | html %]" id="ref_biblionumber[% record.biblionumber | html %]" name="ref_biblionumber" onclick="changeFramework('[% record.frameworkcode | html %]')" />
[% END %]
<label for="ref_biblionumber[% record.biblionumber | html %]">
[% record.data.title | html %]
[% FOREACH subtitle IN record.subtitles %]
[% subtitle.subfield | html %]
[% END %]
([% record.biblionumber | html %]) <a href="/cgi-bin/koha/catalogue/showmarc.pl?id=[% record.biblionumber | html %]" class="previewData">View MARC</a>
</label>
</li>
[% END %]
<li>
<label for="frameworkcode">Using framework:</label>
<select name="frameworkcode" id="frameworkcode">
<option value="">Default</option>
[% FOREACH framework IN frameworks %]
<option value="[% framework.frameworkcode | html %]">[% framework.frameworktext | html %]</option>
[% END %]
</select>
</li>
</ol>
[% FOREACH record IN records %]
<input type="hidden" name="biblionumber" value="[% record.biblionumber | html %]" />
[% END %]
<fieldset class="action">
<input type="submit" value="Next" />
</fieldset>
</fieldset>
</form>
<div id="dataPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="dataPreviewLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="dataPreviewLabel">Preview</h3>
</div>
<div class="modal-body">
<div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
</div>
<div class="modal-footer">
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
</div>
</div>
</div>
</div>
[% ELSE %]
[% IF ( errors.size ) %]
<div class="dialog alert">
[% FOREACH error IN errors %]
<p>[% error | html %]</p>
[% END %]
</div>
[% ELSE %]
<form id="mergeform" action="/cgi-bin/koha/cataloguing/merge.pl" method="post" onsubmit="return mergeformsubmit()">
<div class="yui-g">
<div class="yui-u first">
[% PROCESS mergesource sourcerecords=records %]
</div>
<div class="yui-u">
[% PROCESS mergetarget %]
</div> <!-- .yui-u -->
<input type="hidden" name="ref_biblionumber" value="[% ref_biblionumber | html %]" />
[% FOREACH record IN records %]
<input type="hidden" name="biblionumber" value="[% record.recordid | html %]" />
[% END %]
<input type="hidden" name="frameworkcode" value="[% framework | html %]" />
<fieldset class="action">
<input type="submit" name="merge" value="Merge" />
<label for="report_fields">Fields to display in report:</label>
<input type="text" name="report_fields" id="report_fields" value="[% MergeReportFields | html %]" />
<span class="hint">(Example: "001,245ab,600")
</fieldset>
</div>
</form>
[% END %]
[% END %]
[% END %]
</div>
</div>
</div>
[% MACRO jsinclude BLOCK %]
[% Asset.js("js/merge-record.js") | $raw %]
[% INCLUDE 'merge-record-strings.inc' %]
<script type="text/javascript">
[% UNLESS (result) %]
[% IF (choosereference) %]
function changeFramework(fw) {
$("#frameworkcode").val(fw);
}
$(document).ready(function(){
$(".previewData").on("click", function(e){
e.preventDefault();
var ltitle = $(this).text();
var page = $(this).attr("href");
$("#dataPreviewLabel").text(ltitle);
$("#dataPreview .modal-body").load(page + " div");
$('#dataPreview').modal({show:true});
});
$("#dataPreview").on("hidden", function(){
$("#dataPreviewLabel").html("");
$("#dataPreview .modal-body").html("<div id=\"loading\"><img src=\"[% interface | html %]/[% theme | html %]/img/spinner-small.gif\" alt=\"\" /> "+_("Loading")+"</div>");
});
});
[% ELSE %]
function check_mandatory () {
var missing = {
'fields': [],
'subfields': []
};
for (tag in tagslib) {
if (tag == '000' || tag == '001')
continue;
if (tagslib[tag].mandatory == 1) {
if ($("#resultul span.field:contains("+ tag +")").length == 0) {
missing.fields.push(tag);
}
}
for (subfieldcode in tagslib[tag]) {
if (subfieldcode == 'lib' || subfieldcode == 'mandatory'
|| subfieldcode == 'repeatable' || subfieldcode == 'tab'
|| subfieldcode == '@') {
continue;
}
if (tagslib[tag][subfieldcode].mandatory == 1 && tagslib[tag][subfieldcode].tab >= 0) {
var fields = $("#resultul span.field:contains("+ tag +")");
$(fields).each(function() {
var subfields = $(this).parents('li').find("span.subfield:contains("+ subfieldcode +")");
if (subfields.length == 0) {
missing.subfields.push( {
'tag': tag,
'subfieldcode': subfieldcode
} );
}
});
}
}
}
return missing;
}
// When submiting the form
function mergeformsubmit() {
var missing = check_mandatory();
var alert_msg = '';
var error = 0;
if (missing.fields.length > 0) {
alert_msg += _("Following required fields are missing:") + "\n";
for (var i in missing.fields) {
alert_msg += "\t- " + missing.fields[i] + "\n";
error ++;
}
alert_msg += "\n";
}
if (missing.subfields.length > 0) {
alert_msg += _("Following required subfields are missing:") + "\n";
for (var i in missing.subfields) {
var subfield = missing.subfields[i];
alert_msg += "\t- " + subfield.tag + "$" + subfield.subfieldcode + "\n";
error ++;
}
}
if (error != 0) {
alert(alert_msg);
return false;
} else {
$("#tabs").remove();
}
}
$(document).ready(function(){
tagslib = [];
$.getJSON("/cgi-bin/koha/cataloguing/merge_ajax.pl", {frameworkcode : "[% framework | html %]" }, function(json) {
tagslib = json;
rebuild_target($("#tabs"), $("#resultul"));
});
// Creating tabs
$("#tabs").tabs();
// Check all checkboxes in first tab, and uncheck all others to avoid
// inconsistencies from a page refresh.
$('#tabs div#tabrecord[% ref_biblionumber | html %]').find('input[type="checkbox"]').prop('checked', true);
$('#tabs > div:not("#tabrecord[% ref_biblionumber | html %]")').find('input[type="checkbox"]').prop('checked', false);
//Set focus to cataloging search
$("input[name=q]:eq(0)").focus();
});
[% END %]
[% END %]
</script>
[% END %]
[% INCLUDE 'intranet-bottom.inc' %]