-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added option to validate incoming URL query parameters #1122
Changes from 2 commits
bb5e65a
7934450
44b7955
22cf3cf
425d489
b732778
641ac7b
1bcff25
5523405
b7022ac
9989f72
7d80fab
59933df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
# pylint: disable=import-outside-toplevel,too-many-locals | ||
import re | ||
from warnings import warn | ||
import urllib.parse | ||
from datetime import datetime | ||
from typing import Any, Dict, List, Set, Union | ||
|
@@ -22,6 +23,8 @@ | |
from optimade.server.exceptions import BadRequest, InternalServerError | ||
from optimade.server.query_params import EntryListingQueryParams, SingleEntryQueryParams | ||
from optimade.utils import mongo_id_for_database, get_providers, PROVIDER_LIST_URLS | ||
from optimade.server.mappers import BaseResourceMapper | ||
from optimade.server.warnings import UnknownProviderQueryParameter | ||
|
||
__all__ = ( | ||
"BASE_URL_PREFIXES", | ||
|
@@ -235,6 +238,7 @@ def get_entries( | |
"""Generalized /{entry} endpoint getter""" | ||
from optimade.server.routers import ENTRY_COLLECTIONS | ||
|
||
check_params(request, params) | ||
( | ||
results, | ||
data_returned, | ||
|
@@ -284,6 +288,7 @@ def get_single_entry( | |
) -> EntryResponseOne: | ||
from optimade.server.routers import ENTRY_COLLECTIONS | ||
|
||
check_params(request, params) | ||
params.filter = f'id="{entry_id}"' | ||
( | ||
results, | ||
|
@@ -319,3 +324,25 @@ def get_single_entry( | |
), | ||
included=included, | ||
) | ||
|
||
|
||
def check_params( | ||
request: Request, params: Union[EntryListingQueryParams, SingleEntryQueryParams] | ||
): | ||
for param in request.query_params.keys(): | ||
if not hasattr(params, param): | ||
split_param = param.split("_") | ||
if param.startswith("_") and len(split_param) > 2: | ||
if split_param[1] not in BaseResourceMapper.KNOWN_PROVIDER_PREFIXES: | ||
warn( | ||
f"The Query parameter '{param}' has an unknown provider prefix: '{split_param[1]}'. This query parameter has been ignored.", | ||
UnknownProviderQueryParameter, | ||
) | ||
elif split_param[1] in BaseResourceMapper.SUPPORTED_PREFIXES: | ||
raise BadRequest( | ||
detail=f"The query parameter '{param}' has a prefix that is supported by this server, yet the parameter is not known." | ||
) | ||
else: | ||
raise BadRequest( | ||
detail=f"The query parameter '{param}' is not known by this entry point." | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would unify the error messages for the second and third cases (I'm not sure telling the client that the prefix is supported is that much more useful). This should allow the code to be simplified quite a bit (especially wrt. my other comment). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only issue I can foresee is if an implementation is already using a custom query parameter without registering it in the query param model. Maybe this param check should be toggle-able and off by default (for now)? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I would suggest looping over all the parameters and accumulating all the errors and warnings before emitting them.
It would probably be fine to just raise one error for all unrecognised fields, e.g.
"The query parameter(s) ['fitler', '_exmpl_test'] are not recognised by this entrypoint."
Something like: