(backend) add indexed search feature flag

Add setting FEATURES_INDEXED_SEARCH that allows to disable the
search of indexed files while using the indexation tools.

Signed-off-by: Fabre Florian <ffabre@hybird.org>
This commit is contained in:
Fabre Florian
2025-11-28 06:39:23 +01:00
committed by Quentin BEY
parent 8c232f85d6
commit 03124f4bf1
7 changed files with 55 additions and 4 deletions

View File

@@ -42,6 +42,7 @@ This document lists all configurable environment variables for the Drive applica
| `EMAIL_USE_SSL` | Use SSL for SMTP connection | `False` |
| `EMAIL_USE_TLS` | Use TLS for SMTP connection | `False` |
| `FEATURES_ALPHA` | Enable alpha features | `False` |
| `FEATURES_INDEXED_SEARCH` | Enable the search of indexed files through the API | `True` |
| `FRONTEND_THEME` | Frontend theme configuration | `None` |
| `FRONTEND_FEEDBACK_BUTTON_SHOW` | Show feedback button | `False` |
| `FRONTEND_FEEDBACK_BUTTON_IDLE` | Make feedback button idle (e.g. to bind to external library) | `False` |

View File

@@ -15,7 +15,7 @@ See [how-to-use-indexer.md](how-to-use-indexer.md) for details.
## Configure settings of Drive
Add those Django settings the Drive application to enable the feature.
Add those Django settings the Drive application to enable the indexation feature.
```python
SEARCH_INDEXER_CLASS="core.services.search_indexers.SearchIndexer"
@@ -43,3 +43,9 @@ OIDC_STORE_ACCESS_TOKEN = True # Store the access token in the session
OIDC_STORE_REFRESH_TOKEN = True # Store the encrypted refresh token in the session
OIDC_STORE_REFRESH_TOKEN_KEY = "your-32-byte-encryption-key==" # Must be a valid Fernet key (32 url-safe base64-encoded bytes)
```
And to enable the search of indexed files through the API, add this feature flag (default=True)
```python
FEATURES_INDEXED_SEARCH=True
```

View File

@@ -80,6 +80,9 @@ SEARCH_INDEXER_SECRET=find-api-key-for-driv-with-exactly-50-chars-length # Key
SEARCH_INDEXER_URL="http://find:8000/api/v1.0/documents/index/"
SEARCH_INDEXER_QUERY_URL="http://find:8000/api/v1.0/documents/search/"
# Enables the search of indexed files through the API
FEATURES_INDEXED_SEARCH=True
# Store OIDC tokens in the session
# OIDC_STORE_ACCESS_TOKEN = True
# OIDC_STORE_REFRESH_TOKEN = True # Store the encrypted refresh token in the session.

View File

@@ -1097,7 +1097,7 @@ class ItemViewSet(
Applies filtering based on request parameter 'q' from `SearchItemFilter`.
Depending of the configuration it can be:
- A fulltext search through the opensearch indexation app "find" if the backend is
enabled (see SEARCH_INDEXER_CLASS)
enabled (see SEARCH_INDEXER_CLASS) and the feature flag INDEXED_SEARCH_ENABLED is True
- A filtering by the model fields 'title' & 'type'.
"""
queryset = self.queryset
@@ -1136,7 +1136,8 @@ class ItemViewSet(
queryset = queryset.filter(path_list)
if indexer:
# use indexed search ONLY when the feature flag is enabled
if indexer and settings.FEATURES_INDEXED_SEARCH is True:
# When the indexer is configured pop "title" from queryset search and use
# fulltext results instead.
return self._indexed_search(

View File

@@ -278,7 +278,8 @@ class SearchIndexer(BaseItemIndexer):
mimetype = item.mimetype or ""
if mimetype.startswith("text/"):
return default_storage.open(item.file_key, "rb").read().decode()
with default_storage.open(item.file_key, "rb") as fd:
return fd.read().decode()
raise SuspiciousFileOperation(f"Unrecognized mimetype {mimetype}")

View File

@@ -437,3 +437,36 @@ def test_api_items_search_pagination_endpoint_is_none(
assert content["count"] == expected["count"]
assert content["previous"] == previous_url
assert content["next"] == next_url
def test_api_items_search_feature_disabled(indexer_settings):
"""Should not use indexed search if the feature is disabled"""
indexer_settings.FEATURES_INDEXED_SEARCH = False
assert get_file_indexer() is not None
user = factories.UserFactory()
client = APIClient()
client.force_login(user)
docs = factories.ItemFactory.create_batch(
5,
title="alpha",
users=[user],
parent=user.get_main_workspace(),
)
response = client.get(
"/api/v1.0/items/search/",
data={
"title": "alpha",
},
)
assert response.status_code == 200
content = response.json()
results = content.pop("results")
assert [r["id"] for r in results] == [str(d.pk) for d in docs]

View File

@@ -159,6 +159,10 @@ class Base(Configuration):
},
}
FEATURES_INDEXED_SEARCH = values.BooleanValue(
default=True, environ_name="FEATURES_INDEXED_SEARCH", environ_prefix=None
)
# Posthog
POSTHOG_KEY = SecretFileValue(None, environ_name="POSTHOG_KEY", environ_prefix=None)
POSTHOG_HOST = values.Value(
@@ -1052,6 +1056,8 @@ class Test(Base):
CELERY_TASK_ALWAYS_EAGER = values.BooleanValue(True)
FEATURES_INDEXED_SEARCH = True
SEARCH_INDEXER_CLASS = None
OIDC_STORE_ACCESS_TOKEN = False
OIDC_STORE_REFRESH_TOKEN = False