Remove opt-in fields
This commit is contained in:
parent
f0157a36fb
commit
96546af95f
16
docs/api.md
16
docs/api.md
@ -319,22 +319,6 @@ including `gt` (>), `gte` (>=), `lt` (<), `lte` (<=), and `range`.
|
|||||||
Lastly, document link fields support a `contains` operator that behaves
|
Lastly, document link fields support a `contains` operator that behaves
|
||||||
like a "is superset of" check.
|
like a "is superset of" check.
|
||||||
|
|
||||||
!!! warning
|
|
||||||
|
|
||||||
It is possible to do case-insensitive exact match (i.e., `iexact`) and
|
|
||||||
case-sensitive substring match (i.e., `contains`, `startswith`,
|
|
||||||
`endswith`) for string, URL, and monetary fields, but
|
|
||||||
[they may not work as expected on some database backends](https://docs.djangoproject.com/en/5.1/ref/databases/#substring-matching-and-case-sensitivity).
|
|
||||||
|
|
||||||
It is also possible to use regular expressions to match string, URL, and
|
|
||||||
monetary fields, but the syntax is database-dependent, and accepting
|
|
||||||
regular expressions from untrusted sources could make your instance
|
|
||||||
vulnerable to regular expression denial of service attacks.
|
|
||||||
|
|
||||||
For these reasons the above expressions are disabled by default.
|
|
||||||
If you understand the implications, you may enable them by uncommenting
|
|
||||||
`PAPERLESS_CUSTOM_FIELD_LOOKUP_OPT_IN` in your configuration file.
|
|
||||||
|
|
||||||
### `/api/search/autocomplete/`
|
### `/api/search/autocomplete/`
|
||||||
|
|
||||||
Get auto completions for a partial search term.
|
Get auto completions for a partial search term.
|
||||||
|
@ -152,7 +152,7 @@ export class CustomFieldsLookupDropdownComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getOperatorsForField(field: CustomField): string[] {
|
getOperatorsForField(field: CustomField): string[] {
|
||||||
return ['exact', 'in', 'isnull', 'exists']
|
return ['exact', 'in', 'icontains', 'isnull', 'exists']
|
||||||
// TODO: implement this
|
// TODO: implement this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,15 +239,9 @@ class CustomFieldLookupParser:
|
|||||||
EXPR_BY_CATEGORY = {
|
EXPR_BY_CATEGORY = {
|
||||||
"basic": ["exact", "in", "isnull", "exists"],
|
"basic": ["exact", "in", "isnull", "exists"],
|
||||||
"string": [
|
"string": [
|
||||||
"iexact",
|
|
||||||
"contains",
|
|
||||||
"icontains",
|
"icontains",
|
||||||
"startswith",
|
|
||||||
"istartswith",
|
"istartswith",
|
||||||
"endswith",
|
|
||||||
"iendswith",
|
"iendswith",
|
||||||
"regex",
|
|
||||||
"iregex",
|
|
||||||
],
|
],
|
||||||
"arithmetic": [
|
"arithmetic": [
|
||||||
"gt",
|
"gt",
|
||||||
@ -259,23 +253,6 @@ class CustomFieldLookupParser:
|
|||||||
"containment": ["contains"],
|
"containment": ["contains"],
|
||||||
}
|
}
|
||||||
|
|
||||||
# These string lookup expressions are problematic. We shall disable
|
|
||||||
# them by default unless the user explicitly opts in.
|
|
||||||
STR_EXPR_DISABLED_BY_DEFAULT = [
|
|
||||||
# SQLite: is case-sensitive outside the ASCII range
|
|
||||||
"iexact",
|
|
||||||
# SQLite: behaves the same as icontains
|
|
||||||
"contains",
|
|
||||||
# SQLite: behaves the same as istartswith
|
|
||||||
"startswith",
|
|
||||||
# SQLite: behaves the same as iendswith
|
|
||||||
"endswith",
|
|
||||||
# Syntax depends on database backends, can be exploited for ReDoS
|
|
||||||
"regex",
|
|
||||||
# Syntax depends on database backends, can be exploited for ReDoS
|
|
||||||
"iregex",
|
|
||||||
]
|
|
||||||
|
|
||||||
SUPPORTED_EXPR_CATEGORIES = {
|
SUPPORTED_EXPR_CATEGORIES = {
|
||||||
CustomField.FieldDataType.STRING: ("basic", "string"),
|
CustomField.FieldDataType.STRING: ("basic", "string"),
|
||||||
CustomField.FieldDataType.URL: ("basic", "string"),
|
CustomField.FieldDataType.URL: ("basic", "string"),
|
||||||
@ -495,22 +472,6 @@ class CustomFieldLookupParser:
|
|||||||
# Check if the operator is supported for the current data_type.
|
# Check if the operator is supported for the current data_type.
|
||||||
supported = False
|
supported = False
|
||||||
for category in self.SUPPORTED_EXPR_CATEGORIES[custom_field.data_type]:
|
for category in self.SUPPORTED_EXPR_CATEGORIES[custom_field.data_type]:
|
||||||
if (
|
|
||||||
category == "string"
|
|
||||||
and op in self.STR_EXPR_DISABLED_BY_DEFAULT
|
|
||||||
and op not in settings.CUSTOM_FIELD_LOOKUP_OPT_IN
|
|
||||||
):
|
|
||||||
raise serializers.ValidationError(
|
|
||||||
[
|
|
||||||
_(
|
|
||||||
"{expr!r} is disabled by default because it does not "
|
|
||||||
"behave consistently across database backends, or can "
|
|
||||||
"cause security risks. If you understand the implications "
|
|
||||||
"you may enabled it by adding it to "
|
|
||||||
"`PAPERLESS_CUSTOM_FIELD_LOOKUP_OPT_IN`.",
|
|
||||||
).format(expr=op),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
if op in self.EXPR_BY_CATEGORY[category]:
|
if op in self.EXPR_BY_CATEGORY[category]:
|
||||||
supported = True
|
supported = True
|
||||||
break
|
break
|
||||||
|
@ -1200,10 +1200,6 @@ EMPTY_TRASH_DELAY = max(__get_int("PAPERLESS_EMPTY_TRASH_DELAY", 30), 1)
|
|||||||
# custom_field_lookup Filter Settings #
|
# custom_field_lookup Filter Settings #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
CUSTOM_FIELD_LOOKUP_OPT_IN = __get_list(
|
|
||||||
"PAPERLESS_CUSTOM_FIELD_LOOKUP_OPT_IN",
|
|
||||||
default=[],
|
|
||||||
)
|
|
||||||
CUSTOM_FIELD_LOOKUP_MAX_DEPTH = __get_int(
|
CUSTOM_FIELD_LOOKUP_MAX_DEPTH = __get_int(
|
||||||
"PAPERLESS_CUSTOM_FIELD_LOOKUP_MAX_DEPTH",
|
"PAPERLESS_CUSTOM_FIELD_LOOKUP_MAX_DEPTH",
|
||||||
default=10,
|
default=10,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user