Bug 10190: Add manage_circ_triggers permission for notice trigger access

Replaces the broad manage_circ_rules permission requirement on the
circulation triggers page with a new dedicated manage_circ_triggers
sub-permission (under parameters, flag 3).

- Add manage_circ_triggers to userpermissions.sql
- Update atomicupdate to add the permission, grant it to existing
  edit_notice_status_triggers users, and remove the old permission
- Update admin/circulation_triggers.pl to require manage_circ_triggers
- Add manage_circ_triggers as an OR option on all circulation_rules
  API endpoints (GET/PUT /circulation_rules, /kinds, /config)
- Restrict manage_circ_triggers users in the API controller to
  overdue_* rule names only on write

Sponsored-by: Glasgow Colleges Library Group <https://library.cityofglasgowcollege.ac.uk>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Martin Renvoize 2026-03-24 10:47:33 +01:00 committed by Pedro Amorim
parent fabe480e52
commit e4aecaa519
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
7 changed files with 48 additions and 9 deletions

View File

@ -254,6 +254,21 @@ sub set_rules {
}
}
unless ( haspermission( $logged_in_user->userid, { parameters => 'manage_circ_rules' } )
|| haspermission( $logged_in_user->userid, { circulate => 'circulate_remaining_permissions' } ) )
{
my $rules_to_set = {%$body};
delete $rules_to_set->{context};
my @non_trigger_rules = grep { !/^overdue_/ } keys %{$rules_to_set};
if (@non_trigger_rules) {
return $c->render(
status => 403,
openapi =>
{ error => 'manage_circ_rules permission is required to manage non-trigger circulation rules' }
);
}
}
if ( $patron_category eq '*' ) {
$patron_category = undef;
} else {

View File

@ -31,7 +31,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
template_name => "admin/circulation_triggers.tt",
query => $query,
type => "intranet",
flagsrequired => { parameters => 'manage_circ_rules' },
flagsrequired => { parameters => 'manage_circ_triggers' },
}
);

View File

@ -78,6 +78,7 @@
permissions:
- circulate: circulate_remaining_permissions
- parameters: manage_circ_rules
- parameters: manage_circ_triggers
put:
x-mojo-to: CirculationRules#set_rules
operationId: setCirculationRules
@ -133,6 +134,7 @@
permissions:
- circulate: circulate_remaining_permissions
- parameters: manage_circ_rules
- parameters: manage_circ_triggers
/circulation_rules/kinds:
get:
x-mojo-to: CirculationRules#get_kinds
@ -172,3 +174,4 @@
permissions:
- circulate: circulate_remaining_permissions
- parameters: manage_circ_rules
- parameters: manage_circ_triggers

View File

@ -37,3 +37,4 @@
permissions:
- circulate: circulate_remaining_permissions
- parameters: manage_circ_rules
- parameters: manage_circ_triggers

View File

@ -3,11 +3,36 @@ use Koha::Installer::Output qw(say_warning say_failure say_success say_info);
return {
bug_number => "10190",
description => "Migrate overduerules to circulation_rules",
description => "Migrate overduerules to circulation_rules and add manage_circ_triggers permission",
up => sub {
my ($args) = @_;
my ( $dbh, $out ) = @$args{qw(dbh out)};
# Add the new dedicated permission for managing overdue notice triggers.
$dbh->do(
q{
INSERT IGNORE INTO permissions (module_bit, code, description) VALUES
(3, 'manage_circ_triggers', 'Manage overdue notice triggers')
}
);
say_success( $out, "Added new permission 'manage_circ_triggers'" );
# Grant manage_circ_triggers to any user who previously had edit_notice_status_triggers,
# so they retain access to the notice triggers page after the permission migration.
$dbh->do(
q{
INSERT IGNORE INTO user_permissions (borrowernumber, module_bit, code)
SELECT borrowernumber, 3, 'manage_circ_triggers'
FROM user_permissions
WHERE code = 'edit_notice_status_triggers'
}
);
# Remove the old tools sub-permission for notice triggers.
# user_permissions rows are cleaned up automatically via ON DELETE CASCADE.
$dbh->do(q|DELETE FROM permissions WHERE code = 'edit_notice_status_triggers'|);
say_success( $out, "Removed deprecated permission 'edit_notice_status_triggers'" );
# This script pulls data from these tables then drops them.
# Skip silently if they no longer exist (e.g. fresh install or already migrated).
if ( !TableExists('overduerules_transport_types') || !TableExists('overduerules') ) {
@ -15,12 +40,6 @@ return {
return;
}
# Remove the tools sub-permission for notice triggers; access is now
# controlled by parameters/manage_circ_rules instead.
# user_permissions rows are cleaned up automatically via ON DELETE CASCADE.
$dbh->do(q|DELETE FROM permissions WHERE code = 'edit_notice_status_triggers'|);
say_success( $out, "Removed deprecated permission 'edit_notice_status_triggers'" );
# Fetch all explicit overdue rules with their transport types.
# No phantom rows are added - only rules that were explicitly configured are migrated.
my $rules = $dbh->selectall_arrayref(

View File

@ -11,6 +11,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES
( 3, 'manage_accounts', 'Manage Account Debit and Credit Types' ),
( 3, 'manage_circ_rules', 'Manage circulation rules'),
( 3, 'manage_circ_rules_from_any_libraries', 'Manage circ rules for any libraries'),
( 3, 'manage_circ_triggers', 'Manage overdue notice triggers'),
( 3, 'manage_sysprefs', 'Manage system preferences'),
( 3, 'manage_libraries', 'Manage libraries and library groups'),
( 3, 'manage_itemtypes', 'Manage item types'),

View File

@ -243,7 +243,7 @@
:options="[
{
value: 0,
label: 'explictly set rules.',
label: 'explicitly set rules.',
},
{
value: 1,