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/checkouts.js") | $raw %]
|
||||||
[% Asset.js("js/tables/bookings.js") | $raw %]
|
[% Asset.js("js/tables/bookings.js") | $raw %]
|
||||||
[% Asset.js("js/recalls.js") | $raw %]
|
[% Asset.js("js/recalls.js") | $raw %]
|
||||||
|
[% Asset.js("js/form-submit.js") | $raw %]
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% INCLUDE 'intranet-bottom.inc' %]
|
[% INCLUDE 'intranet-bottom.inc' %]
|
||||||
|
|
|
@ -786,6 +786,7 @@
|
||||||
[% INCLUDE 'str/members-menu.inc' %]
|
[% INCLUDE 'str/members-menu.inc' %]
|
||||||
[% Asset.js("js/members-menu.js") | $raw %]
|
[% Asset.js("js/members-menu.js") | $raw %]
|
||||||
[% Asset.js("js/recalls.js") | $raw %]
|
[% Asset.js("js/recalls.js") | $raw %]
|
||||||
|
[% Asset.js("js/form-submit.js") | $raw %]
|
||||||
<script>
|
<script>
|
||||||
const LoadCheckoutsTableDelay = 0;
|
const LoadCheckoutsTableDelay = 0;
|
||||||
const AlwaysLoadCheckoutsTable = [% Koha.Preference('AlwaysLoadCheckoutsTable') | html %];
|
const AlwaysLoadCheckoutsTable = [% Koha.Preference('AlwaysLoadCheckoutsTable') | html %];
|
||||||
|
|
|
@ -40,11 +40,20 @@
|
||||||
<h1>Patron lists</h1>
|
<h1>Patron lists</h1>
|
||||||
|
|
||||||
[% IF ( lists ) %]
|
[% 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">
|
<div class="page-section">
|
||||||
<table id="patron-lists-table">
|
<table id="patron-lists-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<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>Name</th>
|
||||||
<th>Patrons in list</th>
|
<th>Patrons in list</th>
|
||||||
<th>Shared</th>
|
<th>Shared</th>
|
||||||
|
@ -57,7 +66,9 @@
|
||||||
[% SET shared_by_other = l.owner.id != logged_in_user.id %]
|
[% SET shared_by_other = l.owner.id != logged_in_user.id %]
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<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>
|
<a href="/cgi-bin/koha/patron_lists/list.pl?patron_list_id=[% l.patron_list_id | uri %]">[% l.name | html %]</a>
|
||||||
</td>
|
</td>
|
||||||
<td>[% l.patron_list_patrons_rs.count || 0 | html %]</td>
|
<td>[% l.patron_list_patrons_rs.count || 0 | html %]</td>
|
||||||
|
@ -79,13 +90,22 @@
|
||||||
>
|
>
|
||||||
[% UNLESS shared_by_other %]
|
[% UNLESS shared_by_other %]
|
||||||
<li
|
<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
|
><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
|
|
||||||
><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
|
|
||||||
></li
|
></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 %]
|
[% END %]
|
||||||
[% IF ( l.patron_list_patrons_rs.count ) %]
|
[% IF ( l.patron_list_patrons_rs.count ) %]
|
||||||
<li><hr class="dropdown-divider" /></li>
|
<li><hr class="dropdown-divider" /></li>
|
||||||
|
@ -118,6 +138,8 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.page-section -->
|
<!-- /.page-section -->
|
||||||
|
</form>
|
||||||
|
<!-- /#patron_lists_form -->
|
||||||
|
|
||||||
<!-- Modal to print patron cards -->
|
<!-- Modal to print patron cards -->
|
||||||
<div class="modal" id="patronExportModal" tabindex="-1" role="dialog" aria-labelledby="patronExportModal_label" aria-hidden="true">
|
<div class="modal" id="patronExportModal" tabindex="-1" role="dialog" aria-labelledby="patronExportModal_label" aria-hidden="true">
|
||||||
|
@ -140,6 +162,7 @@
|
||||||
|
|
||||||
[% MACRO jsinclude BLOCK %]
|
[% MACRO jsinclude BLOCK %]
|
||||||
[% Asset.js("js/tools-menu.js") | $raw %]
|
[% Asset.js("js/tools-menu.js") | $raw %]
|
||||||
|
[% Asset.js("js/form-submit.js") | $raw %]
|
||||||
[% INCLUDE 'datatables.inc' %]
|
[% INCLUDE 'datatables.inc' %]
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
@ -152,32 +175,34 @@
|
||||||
autoWidth: false,
|
autoWidth: false,
|
||||||
columnDefs: [{ orderable: false, searchable: false, targets: ["NoSort"] }],
|
columnDefs: [{ orderable: false, searchable: false, targets: ["NoSort"] }],
|
||||||
pagingType: "full",
|
pagingType: "full",
|
||||||
|
"sorting": [[ 1, "asc" ]]
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".delete_patron").on("click", function(){
|
$(".delete_patron").on("click", function(){
|
||||||
$(".dropdown").removeClass("open");
|
$(".dropdown").removeClass("open");
|
||||||
var list = $(this).data("list-name");
|
var list = $(this).data("list-name");
|
||||||
return confirmDelete( _("Are you sure you want to delete the list %s?").format(list));
|
return confirmDelete( _("Are you sure you want to delete the list %s?").format(list));
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#delete_selected_lists").on("click", function() {
|
$("#patrons_lists_form").submit(function(){
|
||||||
if (selectedPatronLists.length != 0) {
|
var checkedItems = $("input[name=patron_lists_ids]:checked");
|
||||||
if (confirm(_("Are you sure you want to delete the selected lists ?"))) {
|
if ( checkedItems.size() == 0) {
|
||||||
var delete_lists_url = '/cgi-bin/koha/patron_lists/delete.pl?patron_lists_ids=' + selectedPatronLists.join("&patron_lists_ids=");
|
alert(_("You must select one or more lists to delete"));
|
||||||
window.location.href = delete_lists_url;
|
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() {
|
$(document).on("click", ".select_list", function() {
|
||||||
if($(this).is(':checked')){
|
var checkedItems = $("input[name=patron_lists_ids]:checked");
|
||||||
$("#delete_selected_lists").attr("class","btn btn-default btn-sm");
|
if ( checkedItems.size() == 0 ) {
|
||||||
selectedPatronLists.push($(this).data("patron-list-id"));
|
$("#delete_selected_lists").addClass("disabled").prop("disabled", true);
|
||||||
}
|
} else {
|
||||||
else {
|
$("#delete_selected_lists").removeClass("disabled").prop("disabled", false);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
[% USE raw %]
|
||||||
|
[% USE Koha %]
|
||||||
|
[% USE Asset %]
|
||||||
[% USE KohaDates %]
|
[% USE KohaDates %]
|
||||||
|
|
||||||
[% IF no_access_to_patron %]
|
[% IF no_access_to_patron %]
|
||||||
|
@ -57,11 +60,18 @@
|
||||||
<li
|
<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
|
><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
|
<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 %]"
|
<a
|
||||||
><i class="fa fa-trash"></i> Delete list</a
|
class="dropdown-item submit-form-link"
|
||||||
></li
|
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 %]
|
[% END %]
|
||||||
[% IF ( l.patron_list_patrons_rs.count ) %]
|
[% IF ( l.patron_list_patrons_rs.count ) %]
|
||||||
<li><hr class="dropdown-divider" /></li>
|
<li><hr class="dropdown-divider" /></li>
|
||||||
|
|
|
@ -26,6 +26,7 @@ use C4::Output;
|
||||||
use Koha::List::Patron qw( DelPatronList );
|
use Koha::List::Patron qw( DelPatronList );
|
||||||
|
|
||||||
my $cgi = CGI->new;
|
my $cgi = CGI->new;
|
||||||
|
my $op = $cgi->param('op') // q{};
|
||||||
|
|
||||||
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
|
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 $id = $cgi->param('patron_list_id');
|
||||||
my @lists_ids = $cgi->multi_param('patron_lists_ids');
|
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 } );
|
DelPatronList( { patron_list_id => $id } );
|
||||||
}
|
}
|
||||||
if (@lists_ids) {
|
if (@lists_ids) {
|
||||||
foreach my $list_id (@lists_ids) {
|
foreach my $list_id (@lists_ids) {
|
||||||
DelPatronList( { patron_list_id => $list_id } );
|
DelPatronList( { patron_list_id => $list_id } );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print $cgi->redirect('lists.pl');
|
print $cgi->redirect('lists.pl');
|
||||||
|
|
Loading…
Reference in a new issue