If a patron is deleted and there's a checkout associated with them, an api call to {url}/api/v1/checkouts?checked_in=true
will result in an error. This patch updates the api to allow for a null value to be returned for patron_id
To test:
Before applying the patch:
1. In Administration->System preference enable the RESTBasicAuth system preference.
2. Checkout an item to a patron (I used item barcode: 39999000000252 and patron barcode 23529000121682)
3. Check the item back in
4. In your brower go to {sandbox/ktdurl}/api/v1/checkouts?checked_in=1
5. Observe there is a patron ID in the JSON response
6. Delete the patron
7. Repeat step 4
8. Observe an error because a "null" value was returned
9. Apply patch
Sandbox:
In sandbox management Actions->Apply patches
Once complete Actions->Build CSS and JS
Actions->Restart services
KTD:
ktd --shell
git bz apply 41889
yarn build
restart_all
10. Repeat step 4
11. Observe the checkout loads, but now has a null patron id.
12. Sign off
On KTD can also run the script: qa
to run tests.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This is a quite ugly solution, but that may answer end-user needs.
It add the option the group items by status on the bibliographic record
detail page.
However it will have VERY bad impact on performances for record with a
lot of items, as we are going to determine the status of each items of
the record.
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Signed-off-by: Bob Bennhoff <bbennhoff@clicweb.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Build on the new ActionLog DBIC relations to expose them as opt-in
embeds, and shore up gaps in the test coverage that QA flagged.
Swagger
* paths/action_logs.yaml declares an x-koha-embed header parameter
constrained to the supported relations (librarian, patron).
* definitions/action_log.yaml adds the corresponding optional
`librarian` and `patron` object fields.
Tests
* Convert the single 24-test subtest into focused subtests:
- authorization (403 vs 200)
- simple typed filters
- q-DSL: multi-value module, info LIKE, combined filter
- embeds: librarian and patron, with and without x-koha-embed
- pagination + X-Total-Count and order_by
* Mock AuthSuccessLog/AuthFailureLog/BorrowersLog to 0 to remove the
flakiness where the API GET itself appended an AUTH log row between
delete and assertion.
* Build the test librarian with both `tools` and `borrowers` flags so
embedded patron fields are not redacted by Koha::Patron->is_accessible.
* Use a small build_fixtures() helper to avoid copy-pasting setup
across subtests.
Test plan:
1. yarn build && restart_all (refresh swagger bundle)
2. prove t/db_dependent/api/v1/action_logs.t (all subtests green)
3. curl -H 'x-koha-embed: librarian,patron' \
/api/v1/action_logs?module=MEMBERS -- patron and librarian
objects appear in the response.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The cash register transaction history page (pos/register.pl) allows
access with either cashup OR anonymous_refund permission, but the
API endpoints for fetching cashups only checked for cashup permission.
This caused a 403 error when users with only anonymous_refund permission
tried to view the transaction history page, as the cashups table failed
to load.
This patch updates the API permissions for:
- GET /cash_registers/{id}/cashups
- GET /cashups/{id}
to accept either cashup or anonymous_refund permission, matching the
page access logic.
Test plan:
1. Create a staff user with only cash_management > anonymous_refund
permission (not cashup)
2. Navigate to Point of Sale > Transaction history for any cash register
3. Verify the cashups table loads successfully (previously returned 403)
4. Run: prove t/db_dependent/api/v1/cashups.t
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Rename /libraries/{id}/holidays to /libraries/{id}/closed_dates
for consistency with existing sub-resource naming (desks,
cash_registers).
Efficiency: instead of calling $calendar->is_holiday() per day
(which re-checks all three data sources each time), access the
pre-loaded data structures directly: weekly_closed_days array,
day_month_closed_days hash, and _holidays hash. The logic properly
handles exceptions (dates marked open despite a weekly/annual
closure).
Additional fixes:
- Add 365-day max range guard
- Add missing 401/403 responses in swagger spec
- Add request_id_header parameter
- Test exception handling (open on normally-closed day)
- Remove fragile 'empty defaults' assertion
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
- Add list_holidays controller to Koha::REST::V1::Libraries
- Returns closed days for a library within a configurable date range
- Uses Koha::Calendar to determine holidays
- Defaults to today + 3 months if no range specified
- Add OpenAPI spec for the new endpoint
- Register route in swagger.yaml
- Add unit tests in t/db_dependent/api/v1/libraries.t
To test:
1. Apply patch
2. prove t/db_dependent/api/v1/libraries.t
3. Verify all tests pass, including the new list_holidays subtest
which covers:
- Holidays returned within a specified date range
- Empty list when no holidays exist in range
- 400 response when 'to' date precedes 'from' date
- 404 response for non-existent library
- Default range (no params) returns successfully
Sponsored-by: Büchereizentrale Schleswig-Holstein <https://www.bz-sh.de/>
Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Christopher Brannon <cbrannon@cdalibrary.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
POST /api/v1/authorities currently offers only the heading-based
C4::AuthoritiesMarc::FindDuplicateAuthority check, and the only
escape hatch is the `x-koha-override` header.
Koha already ships configurable record matching rules (see
Administration > Record matching rules) and C4::Matcher already
supports `record_type = authority`. This patch lets an API caller
opt into one of those rules when creating an authority by sending
its numeric id in a new `x-koha-matchrule` header.
Behaviour:
* If no `x-koha-matchrule` header is sent the existing heading-based
duplicate check is used. Existing clients are unaffected.
* If `x-koha-matchrule: <id>` is sent:
* non-existent id -> 400 `matching_rule_not_found`
* matcher not record_type=authority
-> 400 `invalid_matching_rule_type`
* matcher returns matches -> 409 `duplicate`; the response
body additionally contains a
`matches: [{authid, score}, ...]`
array listing every hit returned
by the matcher
* matcher returns nothing -> record is created (201)
* `x-koha-override: any|duplicate` continues to bypass all duplicate
checks, including the matcher.
A non-integer header value is rejected by the OpenAPI schema
validator before the controller runs.
Test plan:
1) Apply the patch series.
2) Run `prove t/db_dependent/api/v1/authorities.t`
=> all subtests pass.
3) Log in to the staff interface as a user with the
'manage_matching_rules' subpermission and go to
Administration > Record matching rules > New record matching
rule:
a) Set Matching rule code e.g. `AUTH_HEADING`
b) Set Description e.g. `Authority heading match`
c) Set Record type to `authority`
d) Set Threshold to e.g. `1000`
e) Add a match point:
* Search index: `Heading-Main` (or your authorities index)
* Score: `1000`
* Tag: `110` (or the heading tag used by your
authority type)
* Subfields: `a`
f) Save. Note the numeric matching rule id in the edit URL
(`admin/matching-rules.pl?op=edit_matching_rule&matcher_id=N`).
4) Export an existing authority record as MARCXML (for example
from the authority details page). Save it as `duplicate.xml`.
5) From the command line, POST the record back to Koha using the
new header (replace <N>, credentials and host):
curl -u <user>:<pass> -X POST \
-H 'Content-Type: application/marcxml+xml' \
-H 'x-authority-type: CORPO_NAME' \
-H 'x-koha-matchrule: <N>' \
--data-binary @duplicate.xml \
http://<your-koha>/api/v1/authorities
=> Expect HTTP 409. The JSON response body contains
`error_code: "duplicate"` and a `matches` array listing the
authid(s) that were found along with their score.
6) Edit `duplicate.xml` so the main heading is something that is
not already in the catalogue. POST it again with the same
header.
=> Expect HTTP 201 and a `Location` header pointing to the new
authority.
7) Re-run the POST from step 5 but additionally send
`-H 'x-koha-override: duplicate'`.
=> Expect HTTP 201 (override bypasses the matcher).
8) Send a POST with `x-koha-matchrule: 999999`.
=> Expect HTTP 400 with `error_code: "matching_rule_not_found"`.
9) Create a second matching rule with Record type `biblio` and
note its id. POST with `x-koha-matchrule` set to that id.
=> Expect HTTP 400 with
`error_code: "invalid_matching_rule_type"`.
10) POST with `x-koha-matchrule: abc`.
=> Expect HTTP 400 from the OpenAPI schema validator.
11) POST without `x-koha-matchrule`.
=> Expect the existing heading-based duplicate check to run
exactly as before (409 for a known duplicate, 201 otherwise).
12) Sign off.
Signed-off-by: Brian J. Barr <brian.barr@churchofjesuschrist.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Add x-koha-embed parameter to GET /deleted/biblios/{biblio_id} and use
$c->objects->to_api() to properly handle embedding items.
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
The restore functionality is a cataloguing operation and should live
under the editcatalogue permission module (bit 9) rather than tools
(bit 13), consistent with where it appears in the UI.
Update all references:
- userpermissions.sql and atomicupdate: module_bit 13 → 9
- Swagger x-koha-authorization: tools → editcatalogue
- CGI flagsrequired: tools → editcatalogue
- Templates: CAN_user_tools_records_restore → CAN_user_editcatalogue_records_restore
- C4::Auth::get_cataloguing_page_permissions: remove from tools
sub-perms list (editcatalogue '*' already covers it)
- Tests: module_bit 13 → 9
Signed-off-by: Michaela <michaela.sieber@kit.edu>
Sponsored-by: ByWater Solutions
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds a new API endpoint to retrieve the search field
mappings configuration (search fields and their MARC mappings, grouped
by index).
The endpoint supports content negotiation:
- application/json (default)
- application/yaml (for export/import compatibility)
An optional 'type' query parameter allows filtering mappings by MARC
type (marc21 or unimarc).
Implementation notes:
- New controller: Koha::REST::V1::Config::SearchMappings
- Reuses Koha::SearchEngine::Elasticsearch::raw_elasticsearch_mappings
- Registers 'application/yaml' MIME type in Koha::REST::V1
- Permission: manage_search_engine_config
To test:
1. Apply this patch
2. Rebuild the API bundle:
$ yarn api:bundle
3. Restart Plack
4. Run:
$ prove t/db_dependent/api/v1/config_search_mappings.t
=> SUCCESS: Tests pass
5. Test manually:
$ curl -u user:pass /api/v1/config/search_mappings
=> SUCCESS: Returns JSON with search field mappings
$ curl -u user:pass -H 'Accept: application/yaml' \
/api/v1/config/search_mappings
=> SUCCESS: Returns YAML output
$ curl -u user:pass /api/v1/config/search_mappings?type=marc21
=> SUCCESS: Only marc21 mappings are returned
6. Sign off :-D
Signed-off-by: Laurence <laurence.rault@biblibre.com>
Signed-off-by: Thomas Klausner <domm@plix.at>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This patch adds new overrides opac_reg_yes and opac_reg_no to the patrons api
and will send a notice to the library when a patron is registered via the API if the pref is
active and the NO override is not sent, or the YES override is sent
To test:
1 - Apply patches
2 - yarn build
3 - restart_all
4 - run unit tests
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This new route will be used in a follow-up bug to auto-complete
sysprefs when using the header to search for sysprefs.
Note that this is based on top of bug 41834 that NULL options,
explanation and type in DB, but a future enhancement will populate the
response to return the values present in the yaml files.
Test plan:
1. Bundle the swagger specs and reload plack:
yarn api:bundle && koha-plack --reload kohadev
2. Fetch the sysprefs using the new route:
curl -u koha:koha --request GET 'http://${INSTANCE}-intra.localhost/api/v1/sysprefs' --header "Content-Type: application/json" | jq
3. Confirm that the tests pass
prove t/db_dependent/api/v1/sysprefs.t
Signed-off-by: Owen Leonard <oleonard@myacpl.org>
Signed-off-by: Jan Kissig <bibliothek@th-wildau.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
* Add Cypress tests to cover the 404 redirect if the pref is disabled
* Add "invoices" as possible embed option for
/acquisitions/vendors/:vendor_id
Seems relevant as the api def for invoice if expecting for it
api/v1/swagger/definitions/invoice.yaml
* Tell insertObject how to generate an invoice and return it.
Unfortunately we don't have a direct route for that, hence the embed
on /vendors/:vendor_id
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Bob Bennhoff <bbennhoff@clicweb.org>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
This also includes a 'manager' accessor which returns the Koha::Patron
object
Signed-off-by: Jeremy Evans <Jeremy.Evans@ukhsa.gov.uk>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Required to get users filtered by 'ill' permission for patron search modal
prove t/db_dependent/api/v1/ill_users.t
Signed-off-by: Jeremy Evans <Jeremy.Evans@ukhsa.gov.uk>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
This patch moves hardcoded source filter from 'MARC overlay rules' (batchmod, intranet, z3950, staged import, bulk import, import_lexile) to 'Record Sources' and makes them untouchable. They cannot be renamed or modified.
New record sources can be added and modified though.
All default and newly created record sources are available as filter for the module "Source" in 'MARC overlay rules'.
The API route for PUT /biblios/:biblio_id now checks for a given header x-record-source-id.
If an id is given the name of the rule is retrieved and forwarded as an overlay_context to ModBiblio.
If no id is given the fallback '*' is added as overlay_context.
Also the record source id is getting saved.
Test plan:
pre) run perl installer/data/mysql/updatedatabase.pl to add new is_system column
pre) run dbic to build Koha::Schema::Result::RecordSource as it gets a new columns is_system
pre) run 'redocly bundle --ext json api/v1/swagger/swagger.yaml --output api/v1/swagger/swagger_bundle.json' or 'yarn build'
a) enable system preference MARCOverlayRules and RESTBasicAuth
b) create new record source in /cgi-bin/koha/admin/record_sources and recognize its <NAME> and <ID>
c) create overlay rules in /cgi-bin/koha/admin/marc-overlay-rules.pl
f.e.
+----+-----+--------+----------+-----------+
| id | tag | module | filter | preset |
+----+-----+--------+----------+-----------+
| 1 | 245 | source | * | protect |
+----+-----+--------+----------+-----------+
This will make the 245 field protected from change, unless the record source matches
d) go to /cgi-bin/koha/catalogue/detail.pl?biblionumber=262 and change 245 (title) via edit -> edit record
e) save and take a look the title is still the same
f) run the updateBiblio-Request from below with a API-testing client like REST Client
g) check that title gets overwritten even though it is protected. This is due the fact the updateBiblio is not setting an overlay context.
h) apply patch
redo d) and e)
i) add another overlay rule allowing your record source to change 245:
+----+-----+--------+----------+-----------+
| id | tag | module | filter | preset |
+----+-----+--------+----------+-----------+
| 1 | 245 | source | * | protect |
| 2 | 245 | source | <NAME> | overwrite |
+----+-----+--------+----------+-----------+
j) run the updateBiblio-Request from below, be sure to fill out x-record-source-id:with your ID from step b)
k) check that title gets overwritten
l) run the updateBiblio-Request from below, but omit x-record-source-id or set it to another value than <ID>
m) check that title is not overwritten
PUT http://main-intra.localhost/api/v1/biblios/262
Authorization: Basic koha:koha
Authorization: Basic koha:koha
Content-Type: application/marcxml+xml
x-record-source-id: <ID>
<?xml version="1.0" encoding="UTF-8"?>
<record
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.loc.gov/MARC21/slimhttp://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
xmlns="http://www.loc.gov/MARC21/slim">
<leader>01075cam a2200313 a 4500</leader>
<controlfield tag="001">foo</controlfield>
<controlfield tag="005">20200421093825.0</controlfield>
<controlfield tag="008">120417s2012 ch a b 001 0 eng </controlfield>
<datafield tag="040" ind1=" " ind2=" ">
<subfield code="c">482</subfield>
</datafield>
<datafield tag="100" ind1="1" ind2=" ">
<subfield code="a">Christiansen, Tom.</subfield>
<subfield code="9">482</subfield>
</datafield>
<datafield tag="245" ind1="1" ind2="0">
<subfield code="a">New Title</subfield>
<subfield code="c">Tom Christiansen, Brian D. Foy & Larry Wall.</subfield>
</datafield>
<datafield tag="260" ind1=" " ind2=" ">
<subfield code="a">City</subfield>
</datafield>
<datafield tag="300" ind1=" " ind2=" ">
<subfield code="a">Pages and more</subfield>
</datafield>
<datafield tag="942" ind1=" " ind2=" ">
<subfield code="c">BKS</subfield>
</datafield>
</record>
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
This changes the structure of record source with an is_system column which controls whether this value can be deleted.
Also predefined values are inserted to reflect the default hard coded values from 'Record overlay rules' sources
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
Adds a new REST API endpoint to retrieve Koha version information.
This implementation includes:
- Koha::Status class for instance status information
- /status/version endpoint returning structured version data
- OpenAPI specification with koha_version definition
- REST controller for handling the endpoint
The returned version object includes:
- version: full version string (e.g., '25.06.00.029')
- major: major version number
- minor: minor version number
- release: major.minor version
- maintenance: major.minor.maintenance version
- development: development version (if applicable)
This prepares the foundation for a future /status endpoint that will
include all information displayed in the about page.
To test:
1. Apply the patch
2. Run:
$ ktd --shell
k$ yarn api:bundle
3. Run the tests:
k$ prove t/Koha/Status.t \
t/db_dependent/api/v1/status.t
=> SUCCESS: Tests pass!
4. Sign off :-D
Signed-off-by: David Nind <david@davidnind.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
This commit adds support for the AllowFineOverrideRenewing functionality
to the REST API renewal endpoints using the standard x-koha-override pattern.
Changes:
1. Added x-koha-override header parameter to both renewal endpoints:
- POST /checkouts/{checkout_id}/renewal
- POST /checkouts/{checkout_id}/renewals
2. Updated Koha::REST::V1::Checkouts::renew() to:
- Check for 'debt_limit' in the overrides stash
- Check AllowFineOverrideRenewing preference when override is requested
- Allow renewal override only when both:
* x-koha-override header contains 'debt_limit' AND
* AllowFineOverrideRenewing preference is enabled
- Follows the established x-koha-override pattern used by other endpoints
3. Updated OpenAPI specification (swagger) to document the new header
using the standard pattern with enum values
Usage:
curl -X POST /api/v1/checkouts/123/renewal \
-H "x-koha-override: debt_limit"
The override only works for too_much_owing errors and requires
the AllowFineOverrideRenewing system preference to be enabled.
This implementation follows the same pattern as holds and other
endpoints that support overrides, maintaining consistency across
the REST API.
Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
This patch uses the REST API to populate the holds table
Test plan:
1) Apply the patch
2) Go to a record with holds
3) Check that the holds table is populated correctly
4) Check that hold tables functions work correctly
5) Change HoldsSplitQueue and HoldsSplitQueueNumbering system preference, try all variations
6) Repeat steps 3 and 4
7) Search for records and place holds to multiple records
8) Repeat steps 3 and 4
9) Try with lesser permissions
Sponsored-by: Koha-Suomi Oy
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
Schema type [array,object] is not valid in OpenAPI version 2.
There are two different CSP reporting directives.
One is the now deprecated "report-uri" directive. Browsers typically send a single
JSON object following the CSP2 specification.
"report-uri" is deprecated in CSP3 in favor of the newer "report-to" directive. It
is expected to contain an array of report objects.
There are browser that do not yet support the "report-to" directive, so both
directives should be supported.
There are also variations among the "report-uri" format. See
https://www.tollmanz.com/content-security-policy-report-samples/
Because of these variations, it becomes quite complex to handle the most common
cases in a single API endpoint.
We could build two separate endpoints for both directives.
Or we can accept any type of input and handle the variations in a single endpoint.
This patch attempts to do that.
Before this patch input parameters were validated by JSON::Validator. That is the
normal and recommended way to build OpenAPI endpoints in Koha. After this patch we
remove all input parameter restrictions from the OpenAPI spec, and simply accept
any type of body.
This means the controller will now always return a HTTP 204 regardless of the type
of data passed to the controller. It instead truncates too long input before
writing them into log files.
As this is not an endpoint that developers will build new Koha clients for, we
do not have to offer a very in-depth input parameter spec for this endpoint.
To test:
1. t/db_dependent/api/v1/public/csp_reports.t
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
[FAIL] api/v1/swagger/definitions/csp_report.yaml
FAIL new_line_at_the_end_of_file
Missing new line at the end of file, make sure your editor correctly reads .editorconfig ('insert_final_newline = true'). See bug 40541.
Signed-off-by: Lari Taskula <lari.taskula@hypernova.fi>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
This patch attempts to set some sane input limits to the CSP violation report.
To test:
1. Rebuild API
redocly bundle --ext json api/v1/swagger/swagger.yaml --output api/v1/swagger/swagger_bundle.json
2. t/db_dependent/api/v1/public/csp_reports.t
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Add /api/v1/public/csp-reports endpoint to receive and log
Content-Security-Policy violation reports from browsers.
When CSP is configured with a report-uri directive pointing to this
endpoint, browsers will POST violation reports whenever a CSP rule
is violated. These reports are logged using Koha's logging system
for administrator review.
Features:
- Public endpoint (no authentication required, as browsers send
these reports automatically)
- Logs violations at WARN level with key details (violated directive,
blocked URI, document URI, source location)
- Logs full report at DEBUG level for detailed analysis
- Accepts both application/csp-report and application/json content types
Configuration example (in koha-conf.xml csp_header_value):
...; report-uri /api/v1/public/csp-reports
Log4perl configuration to capture CSP violations:
log4perl.logger.api.csp = WARN, CSP
log4perl.appender.CSP = Log::Log4perl::Appender::File
log4perl.appender.CSP.filename = /var/log/koha/csp-violations.log
log4perl.appender.CSP.layout = PatternLayout
log4perl.appender.CSP.layout.ConversionPattern = [%d] %m%n
Also updates koha-conf.xml documentation with CSP configuration guidance.
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Lari Taskula <lari.taskula@hypernova.fi>
Signed-off-by: David Cook <dcook@prosentient.com.au>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>