Bug 20638: Add APIKEYS support to log viewer

Add comprehensive support for viewing API key logs in the log viewer:

tools/viewlog.pl:
- Add APIKEYS to patron lookup logic alongside MEMBERS, CIRCULATION, FINES
- Enable patron name display for API key log entries

koha-tmpl/.../viewlog.tt:
- Add APIKEYS to the modules list for filtering
- Add ACTIVATE and REVOKE to the actions list for filtering
- Include APIKEYS in patron display logic for object column

koha-tmpl/.../action-logs.inc:
- Add APIKEYS module translation: 'API keys'
- Include ApiKeyLog system preference check with warning icon
- Add ACTIVATE and REVOKE action translations
- Maintain alphabetical order in translation blocks

This enables librarians to view and filter API key creation, activation,
revocation, and deletion activities in the standard log viewer interface,
with proper patron name resolution and preference-based logging status
indicators.

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This commit is contained in:
Tomás Cohen Arazi 2025-09-17 14:18:37 -03:00 committed by Lucas Gass
parent bc6110ae10
commit ddb282013f
No known key found for this signature in database
GPG Key ID: 60B447398B0D36CA
3 changed files with 35 additions and 15 deletions

View File

@ -1,5 +1,7 @@
[% BLOCK translate_log_module %]
[% SWITCH module %]
[% CASE 'APIKEYS' %]
<span>API keys</span>[% UNLESS Koha.Preference('ApiKeyLog') %]<i class="log-disabled fa-solid fa-triangle-exclamation" title="Log not enabled" data-log="ApiKeyLog"></i>[% END %]
[% CASE 'AUTH' %]
<span>Authentication</span>[% UNLESS Koha.Preference('AuthFailureLog') && Koha.Preference('AuthSuccessLog') %]
<i class="log-disabled fa-solid fa-triangle-exclamation" title="Log not enabled" data-log="AuthFailureLog|AuthSuccessLog"></i>
@ -49,12 +51,16 @@
[% BLOCK translate_log_action %]
[% SWITCH action %]
[% CASE 'ACTIVATE' %]
<span>Activate</span>
[% CASE 'ADD' %]
<span>Add</span>
[% CASE 'DELETE' %]
<span>Delete</span>
[% CASE 'MODIFY' %]
<span>Modify</span>
[% CASE 'REVOKE' %]
<span>Revoke</span>
[% CASE 'ISSUE' %]
<span>Checkout</span>
[% CASE 'RETURN' %]

View File

@ -123,7 +123,7 @@
[% ELSE %]
<label for="moduleALL" class="viewlog"><input type="checkbox" id="moduleALL" name="modules" value="" /> All</label>
[% END %]
[% FOREACH modx IN [ 'AUTH' 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'CLAIMS' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS', 'SEARCHENGINE', 'NOTICES', 'NEWS', 'RECALLS', 'SUGGESTION', 'TRANSFERS' ] %]
[% FOREACH modx IN [ 'APIKEYS' 'AUTH' 'CATALOGUING' 'AUTHORITIES' 'MEMBERS' 'ACQUISITIONS' 'SERIAL' 'HOLDS' 'ILL' 'CIRCULATION' 'CLAIMS' 'FINES' 'SYSTEMPREFERENCE' 'CRONJOBS', 'REPORTS', 'SEARCHENGINE', 'NOTICES', 'NEWS', 'RECALLS', 'SUGGESTION', 'TRANSFERS' ] %]
[% IF modules.grep(modx).size %]
<label for="module[% modx | html %]" class="viewlog"
><input type="checkbox" id="module[% modx | html %]" name="modules" value="[% modx | html %]" checked="checked" /> [% PROCESS translate_log_module module=modx %]</label
@ -147,7 +147,7 @@
<label for="actionALL" class="viewlog"><input type="checkbox" id="actionALL" name="actions" value="" /> All</label>
[% END %]
[% FOREACH actx IN [ 'ADD' 'DELETE' 'MODIFY' 'ISSUE' 'RETURN' 'RENEW' 'CREATE' 'CANCEL' 'FILL' 'SUSPEND' 'RESUME' 'ADDCIRCMESSAGE' 'MODCIRCMESSAGE' 'DELCIRCMESSAGE' 'STATUS_CHANGE' 'PATRON_NOTICE' 'CHANGE PASS' 'RESET PASS' 'Run' 'End' 'PATRON_MERGE' 'EDIT_MAPPINGS' 'RESET_MAPPINGS' 'ADD_BASKET' 'MODIFY_BASKET' 'MODIFY_BASKET_HEADER' 'MODIFY_BASKET_USERS' 'CLOSE_BASKET' 'APPROVE_BASKET' 'REOPEN_BASKET' 'CANCEL_ORDER' 'CREATE_ORDER' 'MODIFY_ORDER' 'CREATE_INVOICE_ADJUSTMENT' 'UPDATE_INVOICE_ADJUSTMENT' 'DELETE_INVOICE_ADJUSTMENT' 'RECEIVE_ORDER' 'MODIFY_BUDGET' 'MODIFY_FUND' 'CREATE_FUND' 'DELETE_FUND' 'ACQUISITION CLAIM' 'ACQUISITION ORDER' 'OVERDUE' 'EXPIRE' 'CREATE_RESTRICTION' 'MODIFY_RESTRICTION' 'DELETE_RESTRICTION' 'MODIFY_CARDNUMBER' 'RESET 2FA' ] %]
[% FOREACH actx IN [ 'ACTIVATE' 'ADD' 'DELETE' 'MODIFY' 'REVOKE' 'ISSUE' 'RETURN' 'RENEW' 'CREATE' 'CANCEL' 'FILL' 'SUSPEND' 'RESUME' 'ADDCIRCMESSAGE' 'MODCIRCMESSAGE' 'DELCIRCMESSAGE' 'STATUS_CHANGE' 'PATRON_NOTICE' 'CHANGE PASS' 'RESET PASS' 'Run' 'End' 'PATRON_MERGE' 'EDIT_MAPPINGS' 'RESET_MAPPINGS' 'ADD_BASKET' 'MODIFY_BASKET' 'MODIFY_BASKET_HEADER' 'MODIFY_BASKET_USERS' 'CLOSE_BASKET' 'APPROVE_BASKET' 'REOPEN_BASKET' 'CANCEL_ORDER' 'CREATE_ORDER' 'MODIFY_ORDER' 'CREATE_INVOICE_ADJUSTMENT' 'UPDATE_INVOICE_ADJUSTMENT' 'DELETE_INVOICE_ADJUSTMENT' 'RECEIVE_ORDER' 'MODIFY_BUDGET' 'MODIFY_FUND' 'CREATE_FUND' 'DELETE_FUND' 'ACQUISITION CLAIM' 'ACQUISITION ORDER' 'OVERDUE' 'EXPIRE' 'CREATE_RESTRICTION' 'MODIFY_RESTRICTION' 'DELETE_RESTRICTION' 'MODIFY_CARDNUMBER' 'RESET 2FA' ] %]
[% IF actions.grep(actx).size %]
<label for="action[% actx| replace('\s+', '_') | html %]" class="viewlog"
><input type="checkbox" id="action[% actx | replace('\s+', '_') | html %]" name="actions" value="[% actx | html %]" checked="checked" /> [% PROCESS translate_log_action action=actx %]</label
@ -263,19 +263,29 @@
<td>[% PROCESS translate_log_module module=loopro.module %]</td>
<td>[% PROCESS translate_log_action action=loopro.action %]</td>
<td>
[% IF ( loopro.module == 'MEMBERS' ) || ( loopro.module == 'CIRCULATION' ) || ( loopro.module == 'FINES' ) %]
[% IF ( loopro.module == 'MEMBERS' ) || ( loopro.module == 'CIRCULATION' ) || ( loopro.module == 'FINES' ) || ( loopro.module == 'APIKEYS' ) %]
[% IF loopro.patron %]
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% loopro.object | uri %]" title="Display member details.">
[% IF ( loopro.object ) %][% IF ( loopro.patron.firstname ) || ( loopro.patron.surname ) %]
[% loopro.patron.firstname | html %]
[% loopro.patron.surname | html %]
([% loopro.object | html %])
[% ELSE %]
<span>Member</span> [% loopro.object | html %]
[% END %][% END %]
</a>
[% IF ( loopro.module == 'APIKEYS' ) %]
<a href="/cgi-bin/koha/members/apikeys.pl?patron_id=[% loopro.object | uri %]" title="View API keys for this patron">
API keys for [% loopro.patron.firstname | html %] [% loopro.patron.surname | html %] ([% loopro.object | html %])
</a>
[% ELSE %]
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% loopro.object | uri %]" title="Display member details.">
[% IF ( loopro.object ) %][% IF ( loopro.patron.firstname ) || ( loopro.patron.surname ) %]
[% loopro.patron.firstname | html %]
[% loopro.patron.surname | html %]
([% loopro.object | html %])
[% ELSE %]
<span>Member</span> [% loopro.object | html %]
[% END %][% END %]
</a>
[% END %]
[% ELSE %]
[% loopro.object | html %]
[% IF ( loopro.module == 'APIKEYS' ) %]
API keys for patron [% loopro.object | html %]
[% ELSE %]
[% loopro.object | html %]
[% END %]
[% END %]
[% ELSIF ( loopro.module == 'CATALOGUING' ) %]
[% IF ( loopro.info.substr(0, 4) == 'item' ) %]

View File

@ -203,8 +203,12 @@ if ($do_it) {
}
}
#add firstname and surname for borrower, when using the CIRCULATION, MEMBERS, FINES
if ( $log->module eq "CIRCULATION" || $log->module eq "MEMBERS" || $log->module eq "FINES" ) {
#add firstname and surname for borrower, when using the CIRCULATION, MEMBERS, FINES, APIKEYS
if ( $log->module eq "CIRCULATION"
|| $log->module eq "MEMBERS"
|| $log->module eq "FINES"
|| $log->module eq "APIKEYS" )
{
if ( $log->object ) {
my $patron = Koha::Patrons->find( $log->object );
if ( $patron && $output eq 'screen' ) {