diff --git a/aleksis/core/tasks.py b/aleksis/core/tasks.py
index f391fe05bd6dfd82eaf3e84ddb222bf322881b5f..863bf7e42839a7b79e674f7175b242228256d2d3 100644
--- a/aleksis/core/tasks.py
+++ b/aleksis/core/tasks.py
@@ -19,11 +19,13 @@ def send_notification(notification: int, resend: bool = False) -> None:
 def backup_data() -> None:
     """Backup database and media using django-dbbackup."""
     # Assemble command-line options for dbbackup management command
-    db_options = "-z " * settings.DBBACKUP_COMPRESS_DB + "-e" * settings.DBBACKUP_ENCRYPT_DB
-    media_options = (
-        "-z " * settings.DBBACKUP_COMPRESS_MEDIA + "-e" * settings.DBBACKUP_ENCRYPT_MEDIA
+    db_options = (["-z"] if settings.DBBACKUP_COMPRESS_DB else []) + (
+        ["-e"] if settings.DBBACKUP_ENCRYPT_DB else []
+    )
+    media_options = (["-z"] if settings.DBBACKUP_COMPRESS_MEDIA else []) + (
+        ["-e"] if settings.DBBACKUP_ENCRYPT_MEDIA else []
     )
 
     # Hand off to dbbackup's management commands
-    management.call_command("dbbackup", db_options)
-    management.call_command("mediabackup", media_options)
+    management.call_command("dbbackup", *db_options)
+    management.call_command("mediabackup", *media_options)
diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index d188f6cf29c6909809ec03f81a7601dbcc41c4f9..8e424174c6658feb19cf02295400c4c4946dbd38 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -9,7 +9,7 @@ from typing import Any, Callable, Optional, Sequence, Union
 from uuid import uuid4
 
 from django.conf import settings
-from django.db.models import Model
+from django.db.models import Model, QuerySet
 from django.http import HttpRequest
 from django.shortcuts import get_object_or_404
 from django.utils import timezone
@@ -17,6 +17,8 @@ from django.utils.functional import lazy
 
 from django_global_request.middleware import get_request
 
+from cache_memoize import cache_memoize
+
 from aleksis.core.util import messages
 
 
@@ -357,3 +359,20 @@ def handle_uploaded_file(f, filename: str):
     with open(filename, "wb+") as destination:
         for chunk in f.chunks():
             destination.write(chunk)
+
+
+@cache_memoize(3600)
+def queryset_rules_filter(
+    obj: Union[HttpRequest, Model], queryset: QuerySet, perm: str
+) -> QuerySet:
+    """Filter queryset by user and permission."""
+
+    wanted_objects = set()
+    if isinstance(obj, HttpRequest) and hasattr(obj, "user"):
+        obj = obj.user
+
+    for item in queryset:
+        if obj.has_perm(perm, item):
+            wanted_objects.add(item.pk)
+
+    return queryset.filter(pk__in=wanted_objects)
diff --git a/aleksis/core/util/predicates.py b/aleksis/core/util/predicates.py
index 975273d7d934ae41df8ecefb494b121ed69b2a94..7fe74e99d4a4618bd8fa0384fd6319ab588055d4 100644
--- a/aleksis/core/util/predicates.py
+++ b/aleksis/core/util/predicates.py
@@ -1,5 +1,6 @@
 from django.contrib.auth.backends import ModelBackend
 from django.contrib.auth.models import User
+from django.contrib.contenttypes.models import ContentType
 from django.db.models import Model
 from django.http import HttpRequest
 
@@ -8,7 +9,7 @@ from guardian.shortcuts import get_objects_for_user
 from rules import predicate
 
 from ..models import Group
-from .core_helpers import get_site_preferences
+from .core_helpers import get_site_preferences, queryset_rules_filter
 from .core_helpers import has_person as has_person_helper
 
 
@@ -57,15 +58,20 @@ def has_any_object(perm: str, klass):
     """Check if has any object.
 
     Build predicate which checks whether a user has access
-    to objects with the provided permission.
+    to objects with the provided permission or rule.
     """
     name = f"has_any_object:{perm}"
 
     @predicate(name)
     def fn(user: User) -> bool:
-        objs = get_objects_for_user(user, perm, klass)
-        return len(objs) > 0
-
+        try:
+            ct_perm = ContentType.objects.get(app_label=perm.split('.', 1)[0], permission__codename=perm.split('.', 1)[1])
+        except ContentType.DoesNotExist:
+            ct_perm = None
+        if ct_perm and ct_perm.model_class() == klass:
+            return get_objects_for_user(user, perm, klass).exists()
+        else:
+            return queryset_rules_filter(user, klass.objects.all(), perm).exists()
     return fn
 
 
diff --git a/aleksis/core/views.py b/aleksis/core/views.py
index 968077c9bbe1224972cdd399b72ed118591fe0f0..1ceb588ac9e4ebd984a0b2cb16a186f9d9d3adb4 100644
--- a/aleksis/core/views.py
+++ b/aleksis/core/views.py
@@ -368,6 +368,7 @@ class SystemStatus(MainView, PermissionRequiredMixin):
 
     def get(self, request, *args, **kwargs):
         status_code = 500 if self.errors else 200
+        task_results = []
 
         if "django_celery_results" in settings.INSTALLED_APPS:
             from django_celery_results.models import TaskResult  # noqa
@@ -375,11 +376,10 @@ class SystemStatus(MainView, PermissionRequiredMixin):
 
             if inspect().registered_tasks():
                 job_list = list(inspect().registered_tasks().values())[0]
-                results = []
                 for job in job_list:
-                    results.append(TaskResult.objects.filter(task_name=job).last())
+                    task_results.append(TaskResult.objects.filter(task_name=job).order_by("date_done").last())
 
-        context = {"plugins": self.plugins, "status_code": status_code}
+        context = {"plugins": self.plugins, "status_code": status_code, "tasks": task_results}
         return self.render_to_response(context, status=status_code)
 
 
diff --git a/poetry.lock b/poetry.lock
index 86a814e190cd2ab13930c35044e129b0828756c7..8d27cbbad95d95e55a3849871117ad816ea6dc6d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -690,7 +690,7 @@ description = "A pluggable framework for adding two-factor authentication to Dja
 name = "django-otp"
 optional = false
 python-versions = "*"
-version = "0.9.3"
+version = "0.9.4"
 
 [package.dependencies]
 django = ">=1.11"
@@ -2154,7 +2154,7 @@ celery = ["Celery", "django-celery-results", "django-celery-beat", "django-celer
 ldap = ["django-auth-ldap"]
 
 [metadata]
-content-hash = "a3a9d462489de57ed0d52f922959a885c5502329f81283fd5e29eecfef0c8545"
+content-hash = "c8c6c8720cf5493adfea9b718feb249d200e295d42071f7f2663a37811e707e5"
 python-versions = "^3.7"
 
 [metadata.files]
@@ -2413,8 +2413,8 @@ django-middleware-global-request = [
     {file = "django-middleware-global-request-0.1.2.tar.gz", hash = "sha256:f6490759bc9f7dbde4001709554e29ca715daf847f2222914b4e47117dca9313"},
 ]
 django-otp = [
-    {file = "django-otp-0.9.3.tar.gz", hash = "sha256:d2390e61794bc10dea2fd949cbcfb7946e9ae4fb248df5494ccc4ef9ac50427e"},
-    {file = "django_otp-0.9.3-py3-none-any.whl", hash = "sha256:97849f7bf1b50c4c36a5845ab4d2e11dd472fa8e6bcc34fe18b6d3af6e4aa449"},
+    {file = "django-otp-0.9.4.tar.gz", hash = "sha256:50e54bc09bc435e2ad88f0aa7008718079c3529c422b469b3991a97d28b147bb"},
+    {file = "django_otp-0.9.4-py3-none-any.whl", hash = "sha256:6b92c69021558765e80411479a01788977106d5696c391d2e5342074c1dd74d1"},
 ]
 django-otp-yubikey = [
     {file = "django-otp-yubikey-0.5.2.tar.gz", hash = "sha256:f0b1881562fb42ee9f12c28d284cbdb90d1f0383f2d53a595373b080a19bc261"},
diff --git a/pyproject.toml b/pyproject.toml
index f040f012a853acc82ad7f9ad53e058b7ef31edc2..47436ffe25c058ffa328ffc8a76dad96e4275483 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -72,7 +72,7 @@ django-celery-beat = {version="^2.0.0", optional=true}
 django-celery-email = {version="^3.0.0", optional=true}
 django-jsonstore = "^0.4.1"
 django-polymorphic = "^2.1.2"
-django-otp = "0.9.3"
+django-otp = "0.9.4"
 django-colorfield = "^0.3.0"
 django-bleach = "^0.6.1"
 django-guardian = "^2.2.0"