Bug 37266: patron_lists/delete.pl should have CSRF protection
This patch adds CSRF protection to patron list deletions. Also changed: The "Delete selected lists" button is now in a floating toolbar. To test, apply the patch and go to Tools -> Patron lists. - If necessary, create a few patron lists. - Test the two methods for list deletion available on the page: - Check one or more checkboxes and then click the "Delete selected lists" at the top of the page. - Click the "Actions" button for an individual list and choose "Delete list." - Open the checkout page for a patron. - Under the "Patron lists" tab, add the patron to a list. - Click the "Actions" button for an that list and choose "Delete list." - When you are taken to the patron lists page the list should have been deleted. - Perform the same test on the patron details page. Sponsored-by: Athens County Public Libraries Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org> Signed-off-by: Julian Maurice <julian.maurice@biblibre.com> Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
parent
b504d8c5e9
commit
08a9ded6b0
5 changed files with 142 additions and 102 deletions
|
@ -1199,6 +1199,7 @@
|
|||
[% Asset.js("js/checkouts.js") | $raw %]
|
||||
[% Asset.js("js/tables/bookings.js") | $raw %]
|
||||
[% Asset.js("js/recalls.js") | $raw %]
|
||||
[% Asset.js("js/form-submit.js") | $raw %]
|
||||
[% END %]
|
||||
|
||||
[% INCLUDE 'intranet-bottom.inc' %]
|
||||
|
|
|
@ -786,6 +786,7 @@
|
|||
[% INCLUDE 'str/members-menu.inc' %]
|
||||
[% Asset.js("js/members-menu.js") | $raw %]
|
||||
[% Asset.js("js/recalls.js") | $raw %]
|
||||
[% Asset.js("js/form-submit.js") | $raw %]
|
||||
<script>
|
||||
const LoadCheckoutsTableDelay = 0;
|
||||
const AlwaysLoadCheckoutsTable = [% Koha.Preference('AlwaysLoadCheckoutsTable') | html %];
|
||||
|
|
|
@ -40,11 +40,20 @@
|
|||
<h1>Patron lists</h1>
|
||||
|
||||
[% IF ( lists ) %]
|
||||
<form action="/cgi-bin/koha/patron_lists/delete.pl" method="post" id="patrons_lists_form">
|
||||
[% INCLUDE 'csrf-token.inc' %]
|
||||
<input type="hidden" name="op" value="cud-delete" />
|
||||
<div id="searchheader" class="searchheader noprint sticky">
|
||||
<div class="btn-group">
|
||||
<button type="submit" class="btn btn-default btn-sm disabled" id="delete_selected_lists"><i class="fa fa-trash" aria-hidden="true"></i> Delete selected lists</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-section">
|
||||
<table id="patron-lists-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<input type="button" type="submit" class="btn btn-default btn-sm disabled" value="Delete selected lists" id="delete_selected_lists" />
|
||||
<th class="NoSort"></th>
|
||||
<th>Name</th>
|
||||
<th>Patrons in list</th>
|
||||
<th>Shared</th>
|
||||
|
@ -57,7 +66,9 @@
|
|||
[% SET shared_by_other = l.owner.id != logged_in_user.id %]
|
||||
<tr>
|
||||
<td>
|
||||
<input class="select_patron" type="checkbox" autocomplete="off" data-patron-list-id="[% l.patron_list_id | html %]" />
|
||||
<input class="select_list" name="patron_lists_ids" value="[% l.patron_list_id | html %]" type="checkbox" autocomplete="off" data-patron-list-id="[% l.patron_list_id | html %]" />
|
||||
</td>
|
||||
<td>
|
||||
<a href="/cgi-bin/koha/patron_lists/list.pl?patron_list_id=[% l.patron_list_id | uri %]">[% l.name | html %]</a>
|
||||
</td>
|
||||
<td>[% l.patron_list_patrons_rs.count || 0 | html %]</td>
|
||||
|
@ -79,13 +90,22 @@
|
|||
>
|
||||
[% UNLESS shared_by_other %]
|
||||
<li
|
||||
><a class="dropdown-item" href="/cgi-bin/koha/patron_lists/add-modify.pl?patron_list_id=[% l.patron_list_id | uri %]"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit list</a></li
|
||||
>
|
||||
<li
|
||||
><a class="delete_patron dropdown-item" href="/cgi-bin/koha/patron_lists/delete.pl?patron_list_id=[% l.patron_list_id | html %]" data-list-name="[% l.name | html %]"
|
||||
><i class="fa fa-trash-can"></i> Delete list</a
|
||||
><a class="dropdown-item" href="/cgi-bin/koha/patron_lists/add-modify.pl?patron_list_id=[% l.patron_list_id | uri %]"
|
||||
><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit list</a
|
||||
></li
|
||||
>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item submit-form-link"
|
||||
href="#"
|
||||
data-patron_list_id="[% l.patron_list_id | html %]"
|
||||
data-action="delete.pl"
|
||||
data-method="post"
|
||||
data-op="cud-delete"
|
||||
data-confirmation-msg="Are you sure you want to delete this list?"
|
||||
><i class="fa fa-trash-can"></i> Delete list</a
|
||||
>
|
||||
</li>
|
||||
[% END %]
|
||||
[% IF ( l.patron_list_patrons_rs.count ) %]
|
||||
<li><hr class="dropdown-divider" /></li>
|
||||
|
@ -118,6 +138,8 @@
|
|||
</table>
|
||||
</div>
|
||||
<!-- /.page-section -->
|
||||
</form>
|
||||
<!-- /#patron_lists_form -->
|
||||
|
||||
<!-- Modal to print patron cards -->
|
||||
<div class="modal" id="patronExportModal" tabindex="-1" role="dialog" aria-labelledby="patronExportModal_label" aria-hidden="true">
|
||||
|
@ -140,6 +162,7 @@
|
|||
|
||||
[% MACRO jsinclude BLOCK %]
|
||||
[% Asset.js("js/tools-menu.js") | $raw %]
|
||||
[% Asset.js("js/form-submit.js") | $raw %]
|
||||
[% INCLUDE 'datatables.inc' %]
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
@ -152,32 +175,34 @@
|
|||
autoWidth: false,
|
||||
columnDefs: [{ orderable: false, searchable: false, targets: ["NoSort"] }],
|
||||
pagingType: "full",
|
||||
"sorting": [[ 1, "asc" ]]
|
||||
});
|
||||
|
||||
$(".delete_patron").on("click", function(){
|
||||
$(".dropdown").removeClass("open");
|
||||
var list = $(this).data("list-name");
|
||||
return confirmDelete( _("Are you sure you want to delete the list %s?").format(list));
|
||||
});
|
||||
|
||||
$("#delete_selected_lists").on("click", function() {
|
||||
if (selectedPatronLists.length != 0) {
|
||||
if (confirm(_("Are you sure you want to delete the selected lists ?"))) {
|
||||
var delete_lists_url = '/cgi-bin/koha/patron_lists/delete.pl?patron_lists_ids=' + selectedPatronLists.join("&patron_lists_ids=");
|
||||
window.location.href = delete_lists_url;
|
||||
$("#patrons_lists_form").submit(function(){
|
||||
var checkedItems = $("input[name=patron_lists_ids]:checked");
|
||||
if ( checkedItems.size() == 0) {
|
||||
alert(_("You must select one or more lists to delete"));
|
||||
return false;
|
||||
}
|
||||
if( confirm(_("Are you sure you want to delete the selected lists?")) ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("click", ".select_patron", function() {
|
||||
if($(this).is(':checked')){
|
||||
$("#delete_selected_lists").attr("class","btn btn-default btn-sm");
|
||||
selectedPatronLists.push($(this).data("patron-list-id"));
|
||||
}
|
||||
else {
|
||||
selectedPatronLists = selectedPatronLists.filter(item => item !== $(this).data("patron-list-id"));
|
||||
if(selectedPatronLists.length === 0){
|
||||
$("#delete_selected_lists").attr("class","btn btn-default btn-sm disabled");
|
||||
}
|
||||
$(document).on("click", ".select_list", function() {
|
||||
var checkedItems = $("input[name=patron_lists_ids]:checked");
|
||||
if ( checkedItems.size() == 0 ) {
|
||||
$("#delete_selected_lists").addClass("disabled").prop("disabled", true);
|
||||
} else {
|
||||
$("#delete_selected_lists").removeClass("disabled").prop("disabled", false);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
[% USE raw %]
|
||||
[% USE Koha %]
|
||||
[% USE Asset %]
|
||||
[% USE KohaDates %]
|
||||
|
||||
[% IF no_access_to_patron %]
|
||||
|
@ -57,11 +60,18 @@
|
|||
<li
|
||||
><a class="dropdown-item" href="/cgi-bin/koha/patron_lists/add-modify.pl?patron_list_id=[% l.patron_list_id | uri %]"><i class="fa fa-pencil"></i> Edit list</a></li
|
||||
>
|
||||
<li
|
||||
><a class="delete_patron dropdown-item" href="/cgi-bin/koha/patron_lists/delete.pl?patron_list_id=[% l.patron_list_id | html %]" data-list-name="[% l.name | html %]"
|
||||
><i class="fa fa-trash"></i> Delete list</a
|
||||
></li
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item submit-form-link"
|
||||
href="#"
|
||||
data-patron_list_id="[% l.patron_list_id | html %]"
|
||||
data-action="/cgi-bin/koha/patron_lists/delete.pl"
|
||||
data-method="post"
|
||||
data-op="cud-delete"
|
||||
data-confirmation-msg="Are you sure you want to delete this list?"
|
||||
><i class="fa fa-trash-can"></i> Delete list</a
|
||||
>
|
||||
</li>
|
||||
[% END %]
|
||||
[% IF ( l.patron_list_patrons_rs.count ) %]
|
||||
<li><hr class="dropdown-divider" /></li>
|
||||
|
|
|
@ -26,6 +26,7 @@ use C4::Output;
|
|||
use Koha::List::Patron qw( DelPatronList );
|
||||
|
||||
my $cgi = CGI->new;
|
||||
my $op = $cgi->param('op') // q{};
|
||||
|
||||
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
|
||||
{
|
||||
|
@ -39,13 +40,15 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
|
|||
my $id = $cgi->param('patron_list_id');
|
||||
my @lists_ids = $cgi->multi_param('patron_lists_ids');
|
||||
|
||||
if ( defined $id && $id ne '' ) {
|
||||
if ( $op eq 'cud-delete' ) {
|
||||
if ( defined $id && $id ne '' ) {
|
||||
DelPatronList( { patron_list_id => $id } );
|
||||
}
|
||||
if (@lists_ids) {
|
||||
}
|
||||
if (@lists_ids) {
|
||||
foreach my $list_id (@lists_ids) {
|
||||
DelPatronList( { patron_list_id => $list_id } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print $cgi->redirect('lists.pl');
|
||||
|
|
Loading…
Reference in a new issue