prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Submission search
  Search submissions akin to how users are searched
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `CTFd/admin/submissions.py`
  Content:
  ```
  1 from flask import render_template, request
  2 
  3 from CTFd.admin import admin
  4 from CTFd.models import Challenges, Submissions
  5 from CTFd.utils.decorators import admins_only
  6 from CTFd.utils.modes import get_model
  7 
  8 
  9 @admin.route("/admin/submissions", defaults={"submission_type": None})
  10 @admin.route("/admin/submissions/<submission_type>")
  11 @admins_only
  12 def submissions_listing(submission_type):
  13     filters = {}
  14     if submission_type:
  15         filters["type"] = submission_type
  16 
  17     curr_page = abs(int(request.args.get("page", 1, type=int)))
  18     results_per_page = 50
  19     page_start = results_per_page * (curr_page - 1)
  20     page_end = results_per_page * (curr_page - 1) + results_per_page
  21     sub_count = Submissions.query.filter_by(**filters).count()
  22     page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)
  23 
  24     Model = get_model()
  25 
  26     submissions = (
  27         Submissions.query.add_columns(
  28             Submissions.id,
  29             Submissions.type,
  30             Submissions.challenge_id,
  31             Submissions.provided,
  32             Submissions.account_id,
  33             Submissions.date,
  34             Challenges.name.label("challenge_name"),
  35             Model.name.label("team_name"),
  36         )
  37         .filter_by(**filters)
  38         .join(Challenges)
  39         .join(Model)
  40         .order_by(Submissions.date.desc())
  41         .slice(page_start, page_end)
  42         .all()
  43     )
  44 
  45     return render_template(
  46         "admin/submissions.html",
  47         submissions=submissions,
  48         page_count=page_count,
  49         curr_page=curr_page,
  50         type=submission_type,
  51     )
  52
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/CTFd/admin/submissions.py b/CTFd/admin/submissions.py
  --- a/CTFd/admin/submissions.py
  +++ b/CTFd/admin/submissions.py
  @@ -1,4 +1,4 @@
  -from flask import render_template, request
  +from flask import render_template, request, url_for
   
   from CTFd.admin import admin
   from CTFd.models import Challenges, Submissions
  @@ -10,16 +10,21 @@
   @admin.route("/admin/submissions/<submission_type>")
   @admins_only
   def submissions_listing(submission_type):
  -    filters = {}
  +    filters_by = {}
       if submission_type:
  -        filters["type"] = submission_type
  +        filters_by["type"] = submission_type
  +    filters = []
   
  -    curr_page = abs(int(request.args.get("page", 1, type=int)))
  -    results_per_page = 50
  -    page_start = results_per_page * (curr_page - 1)
  -    page_end = results_per_page * (curr_page - 1) + results_per_page
  -    sub_count = Submissions.query.filter_by(**filters).count()
  -    page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)
  +    q = request.args.get("q")
  +    field = request.args.get("field")
  +    page = abs(request.args.get("page", 1, type=int))
  +
  +    if q:
  +        submissions = []
  +        if Submissions.__mapper__.has_property(
  +            field
  +        ):  # The field exists as an exposed column
  +            filters.append(getattr(Submissions, field).like("%{}%".format(q)))
   
       Model = get_model()
   
  @@ -34,18 +39,27 @@
               Challenges.name.label("challenge_name"),
               Model.name.label("team_name"),
           )
  -        .filter_by(**filters)
  +        .filter_by(**filters_by)
  +        .filter(*filters)
           .join(Challenges)
           .join(Model)
           .order_by(Submissions.date.desc())
  -        .slice(page_start, page_end)
  -        .all()
  +        .paginate(page=page, per_page=50)
       )
   
  +    args = dict(request.args)
  +    args.pop("page", 1)
  +
       return render_template(
           "admin/submissions.html",
           submissions=submissions,
  -        page_count=page_count,
  -        curr_page=curr_page,
  +        prev_page=url_for(
  +            request.endpoint, type=submission_type, page=submissions.prev_num, **args
  +        ),
  +        next_page=url_for(
  +            request.endpoint, type=submission_type, page=submissions.next_num, **args
  +        ),
           type=submission_type,
  +        q=q,
  +        field=field,
       )
  
verification_info: {"golden_diff": "diff --git a/CTFd/admin/submissions.py b/CTFd/admin/submissions.py\n--- a/CTFd/admin/submissions.py\n+++ b/CTFd/admin/submissions.py\n@@ -1,4 +1,4 @@\n-from flask import render_template, request\n+from flask import render_template, request, url_for\n \n from CTFd.admin import admin\n from CTFd.models import Challenges, Submissions\n@@ -10,16 +10,21 @@\n @admin.route(\"/admin/submissions/<submission_type>\")\n @admins_only\n def submissions_listing(submission_type):\n-    filters = {}\n+    filters_by = {}\n     if submission_type:\n-        filters[\"type\"] = submission_type\n+        filters_by[\"type\"] = submission_type\n+    filters = []\n \n-    curr_page = abs(int(request.args.get(\"page\", 1, type=int)))\n-    results_per_page = 50\n-    page_start = results_per_page * (curr_page - 1)\n-    page_end = results_per_page * (curr_page - 1) + results_per_page\n-    sub_count = Submissions.query.filter_by(**filters).count()\n-    page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)\n+    q = request.args.get(\"q\")\n+    field = request.args.get(\"field\")\n+    page = abs(request.args.get(\"page\", 1, type=int))\n+\n+    if q:\n+        submissions = []\n+        if Submissions.__mapper__.has_property(\n+            field\n+        ):  # The field exists as an exposed column\n+            filters.append(getattr(Submissions, field).like(\"%{}%\".format(q)))\n \n     Model = get_model()\n \n@@ -34,18 +39,27 @@\n             Challenges.name.label(\"challenge_name\"),\n             Model.name.label(\"team_name\"),\n         )\n-        .filter_by(**filters)\n+        .filter_by(**filters_by)\n+        .filter(*filters)\n         .join(Challenges)\n         .join(Model)\n         .order_by(Submissions.date.desc())\n-        .slice(page_start, page_end)\n-        .all()\n+        .paginate(page=page, per_page=50)\n     )\n \n+    args = dict(request.args)\n+    args.pop(\"page\", 1)\n+\n     return render_template(\n         \"admin/submissions.html\",\n         submissions=submissions,\n-        page_count=page_count,\n-        curr_page=curr_page,\n+        prev_page=url_for(\n+            request.endpoint, type=submission_type, page=submissions.prev_num, **args\n+        ),\n+        next_page=url_for(\n+            request.endpoint, type=submission_type, page=submissions.next_num, **args\n+        ),\n         type=submission_type,\n+        q=q,\n+        field=field,\n     )\n", "issue": "Submission search\nSearch submissions akin to how users are searched\n", "before_files": [{"content": "from flask import render_template, request\n\nfrom CTFd.admin import admin\nfrom CTFd.models import Challenges, Submissions\nfrom CTFd.utils.decorators import admins_only\nfrom CTFd.utils.modes import get_model\n\n\n@admin.route(\"/admin/submissions\", defaults={\"submission_type\": None})\n@admin.route(\"/admin/submissions/<submission_type>\")\n@admins_only\ndef submissions_listing(submission_type):\n    filters = {}\n    if submission_type:\n        filters[\"type\"] = submission_type\n\n    curr_page = abs(int(request.args.get(\"page\", 1, type=int)))\n    results_per_page = 50\n    page_start = results_per_page * (curr_page - 1)\n    page_end = results_per_page * (curr_page - 1) + results_per_page\n    sub_count = Submissions.query.filter_by(**filters).count()\n    page_count = int(sub_count / results_per_page) + (sub_count % results_per_page > 0)\n\n    Model = get_model()\n\n    submissions = (\n        Submissions.query.add_columns(\n            Submissions.id,\n            Submissions.type,\n            Submissions.challenge_id,\n            Submissions.provided,\n            Submissions.account_id,\n            Submissions.date,\n            Challenges.name.label(\"challenge_name\"),\n            Model.name.label(\"team_name\"),\n        )\n        .filter_by(**filters)\n        .join(Challenges)\n        .join(Model)\n        .order_by(Submissions.date.desc())\n        .slice(page_start, page_end)\n        .all()\n    )\n\n    return render_template(\n        \"admin/submissions.html\",\n        submissions=submissions,\n        page_count=page_count,\n        curr_page=curr_page,\n        type=submission_type,\n    )\n", "path": "CTFd/admin/submissions.py"}], "after_files": [{"content": "from flask import render_template, request, url_for\n\nfrom CTFd.admin import admin\nfrom CTFd.models import Challenges, Submissions\nfrom CTFd.utils.decorators import admins_only\nfrom CTFd.utils.modes import get_model\n\n\n@admin.route(\"/admin/submissions\", defaults={\"submission_type\": None})\n@admin.route(\"/admin/submissions/<submission_type>\")\n@admins_only\ndef submissions_listing(submission_type):\n    filters_by = {}\n    if submission_type:\n        filters_by[\"type\"] = submission_type\n    filters = []\n\n    q = request.args.get(\"q\")\n    field = request.args.get(\"field\")\n    page = abs(request.args.get(\"page\", 1, type=int))\n\n    if q:\n        submissions = []\n        if Submissions.__mapper__.has_property(\n            field\n        ):  # The field exists as an exposed column\n            filters.append(getattr(Submissions, field).like(\"%{}%\".format(q)))\n\n    Model = get_model()\n\n    submissions = (\n        Submissions.query.add_columns(\n            Submissions.id,\n            Submissions.type,\n            Submissions.challenge_id,\n            Submissions.provided,\n            Submissions.account_id,\n            Submissions.date,\n            Challenges.name.label(\"challenge_name\"),\n            Model.name.label(\"team_name\"),\n        )\n        .filter_by(**filters_by)\n        .filter(*filters)\n        .join(Challenges)\n        .join(Model)\n        .order_by(Submissions.date.desc())\n        .paginate(page=page, per_page=50)\n    )\n\n    args = dict(request.args)\n    args.pop(\"page\", 1)\n\n    return render_template(\n        \"admin/submissions.html\",\n        submissions=submissions,\n        prev_page=url_for(\n            request.endpoint, type=submission_type, page=submissions.prev_num, **args\n        ),\n        next_page=url_for(\n            request.endpoint, type=submission_type, page=submissions.next_num, **args\n        ),\n        type=submission_type,\n        q=q,\n        field=field,\n    )\n", "path": "CTFd/admin/submissions.py"}]}