dcd1f5d48c
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>
360 lines
24 KiB
Text
360 lines
24 KiB
Text
[% USE raw %]
|
||
[% USE Asset %]
|
||
[% SET footerjs = 1 %]
|
||
[% INCLUDE 'doc-head-open.inc' %]
|
||
<title>Koha › Tools › MARC modification templates</title>
|
||
[% INCLUDE 'doc-head-close.inc' %]
|
||
<style type="text/css">
|
||
#add_action { display: none; }
|
||
</style>
|
||
</head>
|
||
|
||
<body id="tools_marc_modification_templates" class="tools">
|
||
[% INCLUDE 'header.inc' %]
|
||
[% INCLUDE 'cat-search.inc' %]
|
||
|
||
[% IF ( TemplatesLoop ) %]
|
||
[% FOREACH TemplatesLoo IN TemplatesLoop %]
|
||
[% IF ( TemplatesLoo.selected ) %]
|
||
[% SET template_name = TemplatesLoo.name %]
|
||
[% END %]
|
||
[% END %]
|
||
[% END %]
|
||
|
||
<div id="breadcrumbs">
|
||
<a href="/cgi-bin/koha/mainpage.pl">Home</a> ›
|
||
<a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> ›
|
||
[% IF ( template_name ) %]
|
||
<a href="/cgi-bin/koha/tools/marc_modification_templates.pl">MARC modification templates</a>
|
||
› [% template_name | html %]
|
||
[% ELSE %]
|
||
MARC modification templates
|
||
[% END %]
|
||
</div>
|
||
|
||
<div id="doc3" class="yui-t2">
|
||
<div id="bd">
|
||
<div id="yui-main">
|
||
<div class="yui-b">
|
||
|
||
<div id="toolbar" class="btn-toolbar">
|
||
<a href="#" data-toggle="modal" data-template_id="" data-target="#createTemplate" id="new_template" class="btn btn-default btn-sm duplicate_template"><i class="fa fa-plus"></i> New template</a>
|
||
[% IF ( template_id != '' ) %]
|
||
<a href="#" id="new_action" class="btn btn-default btn-sm"><i class="fa fa-plus"></i> New action</a>
|
||
[% END %]
|
||
</div>
|
||
|
||
[% IF error %]
|
||
[% IF error == 'no_from_field' %]
|
||
<div class="dialog message">Error: no field value specified.</div>
|
||
[% END %]
|
||
[% END %]
|
||
|
||
[% IF ( TemplatesLoop ) %]
|
||
|
||
[% IF ( template_id == '' ) %]
|
||
|
||
<h2>MARC modification templates [% template_id | html %]</h2>
|
||
|
||
<table id="templatest">
|
||
<thead>
|
||
<tr>
|
||
<th>Template</th>
|
||
<th>Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
[% FOREACH TemplatesLoo IN TemplatesLoop %]
|
||
<tr>
|
||
<td>[% TemplatesLoo.name | html %]</td>
|
||
<td class="actions">
|
||
<a class="btn btn-default btn-xs" href="/cgi-bin/koha/tools/marc_modification_templates.pl?template_id=[% TemplatesLoo.template_id | html %]&op=select_template" ><i class="fa fa-fw fa-pencil"></i> Edit actions</a>
|
||
<a class="btn btn-default btn-xs duplicate_template" href="#" data-toggle="modal" data-template_id="[% TemplatesLoo.template_id | html %]" data-target="#createTemplate"><i class="fa fa-fw fa-copy"></i> Duplicate</a>
|
||
<a class="btn btn-default btn-xs delete_template" href="/cgi-bin/koha/tools/marc_modification_templates.pl?template_id=[% TemplatesLoo.template_id | html %]&op=delete_template"><i class="fa fa-fw fa-trash"></i> Delete</a>
|
||
</td>
|
||
</tr>
|
||
[% END %]
|
||
</tbody>
|
||
</table>
|
||
|
||
[% ELSE %]
|
||
|
||
<h2>Actions for <i>[% template_name | html %]</i></h2>
|
||
|
||
[% IF ( ActionsLoop ) %]
|
||
|
||
<table id="template_actions" class="template_actions">
|
||
<thead>
|
||
<tr>
|
||
<th>Change order</th>
|
||
<th>Order</th>
|
||
<th>Action</th>
|
||
<th>Description</th>
|
||
<th> </th>
|
||
<th> </th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
[% FOREACH ActionsLoo IN ActionsLoop %]
|
||
<tr>
|
||
<td class="actions">
|
||
<a title="Move action up" href="marc_modification_templates.pl?op=move_action&where=up&template_id=[% ActionsLoo.template_id | html %]&mmta_id=[% ActionsLoo.mmta_id | html %]">
|
||
<i class="fa fa-arrow-up fa-lg order-control"></i>
|
||
</a>
|
||
|
||
<a title="Move action to top" href="marc_modification_templates.pl?op=move_action&where=top&template_id=[% ActionsLoo.template_id | html %]&mmta_id=[% ActionsLoo.mmta_id | html %]">
|
||
<i class="fa fa-arrow-up fa-lg overline order-control"></i>
|
||
</a>
|
||
|
||
<a title="Move action to bottom" href="marc_modification_templates.pl?op=move_action&where=bottom&template_id=[% ActionsLoo.template_id | html %]&mmta_id=[% ActionsLoo.mmta_id | html %]">
|
||
<i class="fa fa-arrow-down fa-lg underline order-control"></i>
|
||
</a>
|
||
|
||
<a title="Move action down" href="marc_modification_templates.pl?op=move_action&where=down&template_id=[% ActionsLoo.template_id | html %]&mmta_id=[% ActionsLoo.mmta_id | html %]">
|
||
<i class="fa fa-arrow-down fa-lg order-control"></i>
|
||
</a>
|
||
</td>
|
||
|
||
<td>[% ActionsLoo.ordering | html %]</td>
|
||
<td>
|
||
[% IF ( ActionsLoo.action_delete_field ) %] Delete [% END %]
|
||
[% IF ( ActionsLoo.action_add_field ) %] Add new [% END %]
|
||
[% IF ( ActionsLoo.action_update_field ) %] Update existing or add new [% END %]
|
||
[% IF ( ActionsLoo.action_move_field ) %] Move [% END %]
|
||
[% IF ( ActionsLoo.action_copy_field ) %] Copy [% END %]
|
||
[% IF ( ActionsLoo.action_copy_and_replace_field ) %] Copy and replace [% END %]
|
||
|
||
[% UNLESS ( ActionsLoo.action_update_field ) %]
|
||
[% IF ( ActionsLoo.field_number ) %]
|
||
1st
|
||
[% END %]
|
||
[% END %]
|
||
|
||
field
|
||
|
||
[% ActionsLoo.from_field | html %][% IF ( ActionsLoo.from_subfield ) %]$[% ActionsLoo.from_subfield | html %][% END %]
|
||
|
||
[% IF ( ActionsLoo.field_value ) %]
|
||
with value <i>[% ActionsLoo.field_value | html %]</i>
|
||
[% END %]
|
||
|
||
[% IF ( ActionsLoo.to_field ) %]
|
||
to [% ActionsLoo.to_field | html %][% IF ( ActionsLoo.to_subfield ) %]$[% ActionsLoo.to_subfield | html %][% END %]
|
||
|
||
[% IF ( ActionsLoo.to_regex_search ) %]
|
||
using RegEx s<strong>/[% ActionsLoo.to_regex_search | html %]/[% ActionsLoo.to_regex_replace | html %]/[% ActionsLoo.to_regex_modifiers | html %]</strong>
|
||
[% END %]
|
||
[% END %]
|
||
|
||
[% IF ( ActionsLoo.conditional ) %]
|
||
[% IF ( ActionsLoo.conditional_if ) %] if [% END %]
|
||
[% IF ( ActionsLoo.conditional_unless ) %] unless [% END %]
|
||
|
||
[% ActionsLoo.conditional_field | html %][% IF ( ActionsLoo.conditional_subfield ) %]$[% ActionsLoo.conditional_subfield | html %][% END %]
|
||
|
||
[% IF ( ActionsLoo.conditional_comparison_exists ) %] exists [% END %]
|
||
[% IF ( ActionsLoo.conditional_comparison_not_exists ) %] does not exist [% END %]
|
||
[% IF ( ActionsLoo.conditional_comparison_equals ) %] matches [% END %]
|
||
[% IF ( ActionsLoo.conditional_comparison_not_equals ) %] does not match [% END %]
|
||
|
||
[% IF ( ActionsLoo.conditional_regex ) %] RegEx m/[% END %]
|
||
<strong>[% ActionsLoo.conditional_value | html %]</strong>
|
||
[% IF ( ActionsLoo.conditional_regex ) %]/[% END %]
|
||
[% END %]
|
||
</td>
|
||
<td>[% ActionsLoo.description | html %]</td>
|
||
<td>
|
||
<a class="btn btn-default btn-xs" href="#modaction" onclick='editAction(
|
||
"[% ActionsLoo.mmta_id |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.ordering |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.action |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.field_number |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.from_field |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.from_subfield |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.field_value |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.to_field |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.to_subfield |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.to_regex_search |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.to_regex_replace |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.to_regex_modifiers |replace('\\\\', '\\\\') |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.conditional |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.conditional_field |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.conditional_subfield |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.conditional_comparison |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.conditional_value |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.conditional_regex |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]",
|
||
"[% ActionsLoo.description |replace('\\\\', '\\\\') |replace("'", "\'") |replace('"', '\"') |replace('\n', '\\n') |replace('\r', '\\r') | html %]"
|
||
);updateAllEvery();'><i class="fa fa-pencil"></i> Edit</a>
|
||
</td>
|
||
<td>
|
||
<a class="btn btn-default btn-xs" href="marc_modification_templates.pl?template_id=[% ActionsLoo.template_id | html %]&op=delete_action&mmta_id=[% ActionsLoo.mmta_id | html %]" onclick="return confirmDeleteAction();"><i class="fa fa-trash"></i> Delete</a>
|
||
</td>
|
||
</tr>
|
||
[% END # /FOREACH ActionsLoo %]
|
||
</tbody>
|
||
</table>
|
||
[% ELSE %]
|
||
<div class="dialog message template_actions"><p>There are no defined actions for this template.</p></div>
|
||
[% END # /IF ActionsLoop %]
|
||
|
||
<form method="post" action="/cgi-bin/koha/tools/marc_modification_templates.pl" id="add_action" >
|
||
<a name="modaction"></a>
|
||
<fieldset>
|
||
<legend id="modaction_legend">Add a new action</legend>
|
||
<div id="warning_multivalued" style="color:red; display:none;">You have chosen a condition on the same field as the original field. If your records contain multivalued fields it is highly recommended not to do that.</div>
|
||
|
||
<select name="action" id="action" onchange="onActionChange(this);">
|
||
<option value="delete_field">Delete</option>
|
||
<option value="add_field">Add new</option>
|
||
<option value="update_field">Update existing or add new</option>
|
||
<option value="move_field">Move</option>
|
||
<option value="copy_field">Copy</option>
|
||
<option value="copy_and_replace_field">Copy and replace</option>
|
||
</select>
|
||
|
||
<span id="field_number_block">
|
||
<select name="field_number" id="field_number">
|
||
<option value="0">All</option>
|
||
<option value="1">1st</option>
|
||
</select>
|
||
</span>
|
||
|
||
field(s) <input type="text" name="from_field" id="from_field" size="3" maxlength="3" /> <input type="text" name="from_subfield" id="from_subfield" size="1" maxlength="1" title="let blank for the entire field" />
|
||
|
||
<span name="with_value_block" id="with_value_block" style="display:none;">
|
||
with value <input type="text" name="field_value" id="field_value" />
|
||
</span>
|
||
|
||
<span name="to_field_block" id="to_field_block" style="display:none;">
|
||
to field <input type="text" name="to_field" id="to_field" size="3" maxlength="3" /> <input type="text" name="to_subfield" id="to_subfield" size="1" maxlength="1" title="let blank for the entire field" />
|
||
|
||
<span name="to_field_regex_block" id="to_field_regex_block">
|
||
<sup>
|
||
<label for="to_field_regex">RegEx</label>
|
||
<input type="checkbox" name="to_field_regex" id="to_field_regex" onchange="onToFieldRegexChange(this);" />
|
||
|
||
<span name="to_field_regex_value_block" id="to_field_regex_value_block" style="display:none;">
|
||
s/<input type="text" name="to_regex_search" id="to_regex_search" placeholder="regex pattern" />/<input type="text" name="to_regex_replace" id="to_regex_replace" placeholder="regex replacement" />/<input type="text" name="to_regex_modifiers" id="to_regex_modifiers" placeholder="ig" size="3" />
|
||
</span>
|
||
</sup>
|
||
</span>
|
||
</span>
|
||
|
||
<p/>
|
||
|
||
<select name="conditional" id="conditional" onchange="onConditionalChange(this);">
|
||
<option value="" selected="selected" />
|
||
<option value="if">if</option>
|
||
<option value="unless">unless</option>
|
||
</select>
|
||
|
||
<span name="conditional_block" id="conditional_block" style="display:none;">
|
||
field <input type="text" name="conditional_field" id="conditional_field" size="3" maxlength="3" /> <input type="text" name="conditional_subfield" id="conditional_subfield" size="1" maxlength="1" />
|
||
|
||
<select name="conditional_comparison" id="conditional_comparison" onchange="onConditionalComparisonChange(this);">
|
||
<option value="" />
|
||
<option value="exists">exists</option>
|
||
<option value="not_exists">doesn't exist</option>
|
||
<option value="equals">matches</option>
|
||
<option value="not_equals">doesn't match</option>
|
||
</select>
|
||
|
||
<span name="conditional_comparison_block" id="conditional_comparison_block" style="display:none;">
|
||
|
||
<span class="match_regex_prefix">m/</span><input type="text" id="conditional_value" name="conditional_value" /><span class="match_regex_suffix">/</span>
|
||
|
||
<sup>
|
||
<label for="conditional_regex">RegEx</label>
|
||
<input type="checkbox" name="conditional_regex" id="conditional_regex" onchange="onConditionalRegexChange(this);" />
|
||
</sup>
|
||
|
||
</span>
|
||
</span>
|
||
|
||
<input type="hidden" name="template_id" value="[% template_id | html %]" />
|
||
<input type="hidden" name="mmta_id" id="mmta_id" />
|
||
<input type="hidden" name="op" value="add_action" />
|
||
|
||
<br/><br/>
|
||
<label for="description">Description:</label>
|
||
<input type="text" name="description" id="description" size="60" />
|
||
|
||
<br/><br/>
|
||
<input id="action_submit" type="submit" value="Add action" /> <a href="#modaction" id="cancel_edit" onclick="cancelEditAction();">Cancel</a>
|
||
|
||
</fieldset>
|
||
</form>
|
||
|
||
[% END %]
|
||
|
||
[% ELSE %]
|
||
<div class="dialog message"><p>There are no defined templates. Please create a template first.</p></div>
|
||
[% END # /IF TemplatesLoop %]
|
||
|
||
<!-- Modal to create new template -->
|
||
<div class="modal" id="createTemplate" tabindex="-1" role="dialog" aria-labelledby="LabelcreateTemplate" 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="LabelcreateTemplate">Create a new template</h3>
|
||
</div>
|
||
<form method="post" action="/cgi-bin/koha/tools/marc_modification_templates.pl" id="add_template" class="validated">
|
||
<div class="modal-body">
|
||
<fieldset>
|
||
<p>
|
||
<label for="template_name" class="required">Name: </label>
|
||
<input name="template_name" id="template_name" type="text" size="30" required="required" class="required" />
|
||
<span class="required">Required</span>
|
||
</p>
|
||
|
||
<input type="hidden" name="op" value="create_template" />
|
||
|
||
<p>
|
||
<label for="duplicate_a_template">Duplicate a template:</label>
|
||
<select name="template_id" id="duplicate_a_template">
|
||
<option value=""> -- None --</option>
|
||
[% FOREACH TemplatesLoo IN TemplatesLoop %]
|
||
<option value="[% TemplatesLoo.template_id | html %]"> [% TemplatesLoo.name | html %]</option>
|
||
[% END %]
|
||
</select>
|
||
<input type="hidden" name="duplicate_current_template" id="duplicate_current_template" />
|
||
</p>
|
||
</fieldset>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="submit" class="btn btn-default">Submit</button>
|
||
<button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="yui-b">
|
||
[% INCLUDE 'tools-menu.inc' %]
|
||
</div>
|
||
</div>
|
||
|
||
[% MACRO jsinclude BLOCK %]
|
||
[% Asset.js("js/tools-menu.js") | $raw %]
|
||
<script type="text/javascript">
|
||
var MSG_MMT_SUBFIELDS_MATCH = _("Both subfield values should be filled or empty.");
|
||
var MSG_MMT_DESTINATION_REQUIRED = _("The destination should be filled.");
|
||
var MSG_MMT_CONTROL_FIELD_EMPTY = _("If the field is a control field, the subfield should be empty");
|
||
var MSG_MMT_CONTROL_FIELD = _("A control field cannot be used with a regular field.");
|
||
var MSG_MMT_SOURCE_SUBFIELD = _("The source subfield should be filled for update.");
|
||
var MSG_MMT_SOURCE_FIELD = _("The source field should be filled.");
|
||
var MSG_MMT_EVERY = _("Every");
|
||
var MSG_MMT_ALL = _("All");
|
||
var MSG_MMT_CONFIRM_DEL_TEMPLATE = _("Are you sure you wish to delete this template?");
|
||
var MSG_MMT_CONFIRM_DEL_TEMPLATE_ACTION = _("Are you sure you wish to delete this template action?");
|
||
var MSG_MMT_EDIT_ACTION = _("Edit action %s");
|
||
var MSG_MMT_UPDATE_ACTION = _("Update action");
|
||
</script>
|
||
[% Asset.js("js/marc_modification_templates.js") | $raw %]
|
||
[% END %]
|
||
|
||
[% INCLUDE 'intranet-bottom.inc' %]
|