|
21 | 21 | from abc import ABC, abstractmethod |
22 | 22 | from contextlib import asynccontextmanager, contextmanager |
23 | 23 | from dataclasses import dataclass |
| 24 | +from datetime import datetime as dt |
24 | 25 | from functools import lru_cache |
25 | 26 | from pathlib import Path |
26 | 27 | from typing import ( |
@@ -491,8 +492,10 @@ def read_query(query_arg: str | None): |
491 | 492 | status.HTTP_422_UNPROCESSABLE_ENTITY, |
492 | 493 | f"Invalid query filter property: {prop!r}, allowed properties are: {allowed_properties}", |
493 | 494 | ) |
| 495 | + value = str(query_arg.split(op)[1]).strip("'\"") |
| 496 | + check_input_type(self.get_queryables(), prop, value) |
494 | 497 | # Update stac params |
495 | | - stac_params[prop] = str(query_arg.split(op)[1]).strip("'\"") # type: ignore |
| 498 | + stac_params[prop] = value # type: ignore |
496 | 499 |
|
497 | 500 | read_cql(params.pop("filter", {})) |
498 | 501 | read_query(self.request.query_params.get("filter")) |
@@ -930,3 +933,33 @@ def get_sort_key(item): |
930 | 933 | detail=f"Invalid attribute '{attribute}' for sorting: {str(e)},", |
931 | 934 | ) from e |
932 | 935 | return ItemCollection(features=sorted_items, type=item_collection.type) |
| 936 | + |
| 937 | + |
| 938 | +def check_input_type(field_info, key, input_value): |
| 939 | + """Function to check query parameters types agains default queryables.""" |
| 940 | + expected_type = field_info[key].type # Get the expected type as a string |
| 941 | + |
| 942 | + # Map expected type to actual Python types |
| 943 | + type_mapping = { |
| 944 | + "string": lambda input: isinstance(input, str), |
| 945 | + "integer": lambda input: input.isdigit(), |
| 946 | + "bool": lambda input_value: input_value.lower() in [True, False, 1, 0, "true", "false", "1", "0"], |
| 947 | + "datetime": check_datetime_input, # Adding support for datetime |
| 948 | + } |
| 949 | + |
| 950 | + if not type_mapping.get(expected_type)(input_value): # type: ignore |
| 951 | + raise log_http_exception( |
| 952 | + status.HTTP_422_UNPROCESSABLE_ENTITY, |
| 953 | + "Invalid CQL2 filter value", |
| 954 | + ) |
| 955 | + |
| 956 | + |
| 957 | +def check_datetime_input(input_value: Any) -> bool: |
| 958 | + """Used to check if a parameter is a datetime-like string""" |
| 959 | + if isinstance(input_value, str): # If input is a string, try parsing it |
| 960 | + try: |
| 961 | + dt.fromisoformat(input_value) # ISO 8601 format check |
| 962 | + return True |
| 963 | + except ValueError: |
| 964 | + return False |
| 965 | + return False # Not a string, so it can't be a valid datetime |
0 commit comments