diff --git a/poetry.lock b/poetry.lock
index 0669f7469c19382063dbbca5c8d3731a11e8d2d8..7215f4f35bd70d49f65cbc2f04edb63e6e804d9a 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -502,7 +502,7 @@ dev = ["black (==19.10b0)", "flake8 (==3.8.4)", "mypy (==0.812)", "pytest (==6.2
 
 [[package]]
 name = "decorator"
-version = "5.0.8"
+version = "5.0.9"
 description = "Decorators for Humans"
 category = "main"
 optional = false
@@ -1991,7 +1991,7 @@ testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist",
 
 [[package]]
 name = "pytest-django"
-version = "4.2.0"
+version = "4.3.0"
 description = "A Django plugin for pytest."
 category = "dev"
 optional = false
@@ -2580,6 +2580,26 @@ category = "main"
 optional = false
 python-versions = "*"
 
+[[package]]
+name = "whoosh"
+version = "2.7.4"
+description = "Fast, pure-Python full text indexing, search, and spell checking library."
+category = "main"
+optional = true
+python-versions = "*"
+
+[[package]]
+name = "xapian-haystack"
+version = "2.1.1"
+description = "A Xapian backend for Haystack"
+category = "main"
+optional = true
+python-versions = "*"
+
+[package.dependencies]
+django = ">=1.8"
+django-haystack = ">=2.5.1"
+
 [[package]]
 name = "yubiotp"
 version = "1.0.0.post1"
@@ -2606,11 +2626,13 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pyt
 [extras]
 ldap = ["django-auth-ldap"]
 s3 = ["boto3", "django-storages"]
+whoosh = ["Whoosh"]
+xapian = ["xapian-haystack"]
 
 [metadata]
 lock-version = "1.1"
 python-versions = "^3.7"
-content-hash = "d535d52d247e075ff7d5c71710f6824e85019c13139ee394bc0b95e5fcd8abd6"
+content-hash = "ed6f13c7b98173d7a2f25e8ab76d870e94c446c9fdc638a562e5594445e50c37"
 
 [metadata.files]
 alabaster = [
@@ -2853,8 +2875,8 @@ curlylint = [
     {file = "curlylint-0.12.2.tar.gz", hash = "sha256:76b557cf8d007bd92df2dae61a02e65f8aa2ff3e05c6398b1314d92692fbb0d8"},
 ]
 decorator = [
-    {file = "decorator-5.0.8-py3-none-any.whl", hash = "sha256:77a3141f7f5837b5de43569c35508ca4570022ba501db8c8a2a8b292bd35772a"},
-    {file = "decorator-5.0.8.tar.gz", hash = "sha256:bff00cfb18698f9a19fa6400451fd7ea894f3845cedd7b8b7b0ce9c53171fefb"},
+    {file = "decorator-5.0.9-py3-none-any.whl", hash = "sha256:6e5c199c16f7a9f0e3a61a4a54b3d27e7dad0dbdde92b944426cb20914376323"},
+    {file = "decorator-5.0.9.tar.gz", hash = "sha256:72ecfba4320a893c53f9706bebb2d55c270c1e51a28789361aa93e4a21319ed5"},
 ]
 dj-database-url = [
     {file = "dj-database-url-0.5.0.tar.gz", hash = "sha256:4aeaeb1f573c74835b0686a2b46b85990571159ffc21aa57ecd4d1e1cb334163"},
@@ -3106,6 +3128,7 @@ flake8-bandit = [
 ]
 flake8-black = [
     {file = "flake8-black-0.2.1.tar.gz", hash = "sha256:f26651bc10db786c03f4093414f7c9ea982ed8a244cec323c984feeffdf4c118"},
+    {file = "flake8_black-0.2.1-py3-none-any.whl", hash = "sha256:941514149cb8b489cb17a4bb1cf18d84375db3b34381bb018de83509437931a0"},
 ]
 flake8-builtins = [
     {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"},
@@ -3538,8 +3561,8 @@ pytest-cov = [
     {file = "pytest_cov-2.12.0-py2.py3-none-any.whl", hash = "sha256:95d4933dcbbacfa377bb60b29801daa30d90c33981ab2a79e9ab4452c165066e"},
 ]
 pytest-django = [
-    {file = "pytest-django-4.2.0.tar.gz", hash = "sha256:80f8875226ec4dc0b205f0578072034563879d98d9b1bec143a80b9045716cb0"},
-    {file = "pytest_django-4.2.0-py3-none-any.whl", hash = "sha256:a51150d8962200250e850c6adcab670779b9c2aa07271471059d1fb92a843fa9"},
+    {file = "pytest-django-4.3.0.tar.gz", hash = "sha256:d1c6758a592fb0ef8abaa2fe12dd28858c1dcfc3d466102ffe52aa8934733dca"},
+    {file = "pytest_django-4.3.0-py3-none-any.whl", hash = "sha256:f96c4556f4e7b15d987dd1dcc1d1526df81d40c1548d31ce840d597ed2be8c46"},
 ]
 pytest-django-testing-postgresql = [
     {file = "pytest-django-testing-postgresql-0.1.post0.tar.gz", hash = "sha256:78b0c58930084cb4393407b2e5a2a3b8734c627b841ecef7d62d39bbfb8e8a45"},
@@ -3861,6 +3884,14 @@ webencodings = [
     {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
     {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
 ]
+whoosh = [
+    {file = "Whoosh-2.7.4-py2.py3-none-any.whl", hash = "sha256:aa39c3c3426e3fd107dcb4bde64ca1e276a65a889d9085a6e4b54ba82420a852"},
+    {file = "Whoosh-2.7.4.tar.gz", hash = "sha256:7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83"},
+    {file = "Whoosh-2.7.4.zip", hash = "sha256:e0857375f63e9041e03fedd5b7541f97cf78917ac1b6b06c1fcc9b45375dda69"},
+]
+xapian-haystack = [
+    {file = "xapian-haystack-2.1.1.tar.gz", hash = "sha256:1e2fc4d84dc32f132e5b143266e4d4a32e6abac1d363742d0ebc212fac8ade70"},
+]
 yubiotp = [
     {file = "YubiOTP-1.0.0.post1-py2.py3-none-any.whl", hash = "sha256:7ad57011866e0bc6c6d179ffbc3926fcc0e82d410178a6d01ba4da0f88332878"},
     {file = "YubiOTP-1.0.0.post1.tar.gz", hash = "sha256:c13825f7b76a69afb92f19521f4dea9f5031d70f45123b505dc2e0ac03132065"},
diff --git a/pyproject.toml b/pyproject.toml
index def1cc21003e3b1d453399919b584819c29f9274..51c242e9edadb6f8cbd89fd686a5de1cdf08065c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -98,10 +98,14 @@ django-storages = {version = "^1.11.1", optional = true}
 boto3 = {version = "^1.17.33", optional = true}
 django-cleanup = "^5.1.0"
 djangorestframework = "^3.12.4"
+Whoosh = {version = "^2.7.4", optional = true}
+xapian-haystack = {version = "^2.1.1", optional = true}
 
 [tool.poetry.extras]
 ldap = ["django-auth-ldap"]
 s3 = ["boto3", "django-storages"]
+whoosh = ["whoosh"]
+xapian = ["xapian-haystack"]
 
 [tool.poetry.dev-dependencies]
 aleksis-builddeps = "*"