Skip to content

Commit 917b5c6

Browse files
committed
fix(search-api): set max page size to 100 for auth, 25 for guest
1 parent 9cab3b1 commit 917b5c6

File tree

2 files changed

+78
-6
lines changed

2 files changed

+78
-6
lines changed

site/tests/test_search.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2025 CERN.
4+
#
5+
# ZenodoRDM is free software; you can redistribute it and/or modify it
6+
# under the terms of the MIT License; see LICENSE file for more details.
7+
8+
"""Test search API page size validation."""
9+
10+
import pytest
11+
12+
13+
@pytest.fixture
14+
def search_url(test_app):
15+
"""Search API URL."""
16+
host = test_app.config["SITE_API_URL"]
17+
return f"{host}/records"
18+
19+
20+
def test_guest_page_size_validation(client, search_url):
21+
"""Guest users limited to 25 results per page."""
22+
# Guest: size=25 works
23+
res = client.get(f"{search_url}?size=25")
24+
assert res.status_code == 200
25+
26+
# Guest: size=26 exceeds limit
27+
res = client.get(f"{search_url}?size=26")
28+
assert res.status_code == 400
29+
assert res.json == {
30+
"status": 400,
31+
"message": "A validation error occurred.",
32+
"errors": [
33+
{
34+
"field": "size",
35+
"messages": [
36+
"Page size cannot be greater than 25. Please use authenticated requests to increase the limit to 100."
37+
],
38+
}
39+
],
40+
}
41+
42+
43+
def test_authenticated_page_size_validation(client_with_login, search_url):
44+
"""Authenticated users limited to 100 results per page."""
45+
# Auth: size=100 works
46+
res = client_with_login.get(f"{search_url}?size=100")
47+
assert res.status_code == 200
48+
49+
# Auth: size=101 exceeds limit
50+
res = client_with_login.get(f"{search_url}?size=101")
51+
assert res.status_code == 400
52+
assert res.json == {
53+
"status": 400,
54+
"message": "A validation error occurred.",
55+
"errors": [
56+
{
57+
"field": "size",
58+
"messages": ["Page size cannot be greater than 100."],
59+
}
60+
],
61+
}

site/zenodo_rdm/params.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from invenio_rdm_records.resources.config import RDMSearchRequestArgsSchema
1515
from invenio_rdm_records.services.config import RDMSearchOptions
1616
from invenio_records_resources.services.records.params.base import ParamInterpreter
17-
from marshmallow import fields, pre_load
17+
from marshmallow import ValidationError, fields, pre_load, validates
1818

1919

2020
class LegacyAllVersionsParam(ParamInterpreter):
@@ -101,12 +101,23 @@ class ZenodoArgsSchema(RDMSearchRequestArgsSchema):
101101
type = fields.String()
102102
subtype = fields.String()
103103

104-
@property
105-
def max_page_size(self):
106-
"""Max page size depending on user authentication."""
104+
MAX_PAGE_SIZE_AUTHENTICATED = 100
105+
MAX_PAGE_SIZE_GUEST = 25
106+
107+
@validates("size")
108+
def validate_max_page_size(self, value):
109+
"""Validate maximum page size based on user authentication."""
107110
if request and current_user.is_authenticated:
108-
return 200
109-
return 100
111+
if value > self.MAX_PAGE_SIZE_AUTHENTICATED:
112+
raise ValidationError(
113+
f"Page size cannot be greater than {self.MAX_PAGE_SIZE_AUTHENTICATED}."
114+
)
115+
else:
116+
if value > self.MAX_PAGE_SIZE_GUEST:
117+
raise ValidationError(
118+
f"Page size cannot be greater than {self.MAX_PAGE_SIZE_GUEST}. "
119+
f"Please use authenticated requests to increase the limit to {self.MAX_PAGE_SIZE_AUTHENTICATED}."
120+
)
110121

111122
@pre_load
112123
def load_all_versions(self, data, **kwargs):

0 commit comments

Comments
 (0)