Merge pull request #1352 from CTFd/1339-submission-searching

* Add Admin Panel UI for submission searching
* Closes #1339
remove-get-config-from-models
Kevin Chung 2020-04-27 20:21:46 -04:00 committed by GitHub
commit e4a0f99f7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 23 deletions

View File

@ -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 @@ from CTFd.utils.modes import get_model
@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 @@ def submissions_listing(submission_type):
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,
)

View File

@ -12,6 +12,36 @@
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
{% if q and field %}
<h5 class="text-muted text-center">Searching for submissions with <strong>{{ field }}</strong> matching <strong>{{ q }}</strong></h5>
<h6 class="text-muted text-center pb-3">Page {{ submissions.page }} of {{ submissions.total }} results</h6>
{% endif %}
<form method="GET" class="form-inline">
<div class="form-group col-md-2">
<label for="sel1" class="sr-only" >Search Field</label>
<select class="form-control custom-select w-100" id="sel1" name="field">
<option value="provided" {% if field == 'provided' %}selected{% endif %}>Provided</option>
<option value="id" {% if field == 'id' %}selected{% endif %}>ID</option>
</select>
</div>
<div class="form-group col-md-8">
<label for="team-name-search" class="sr-only">Parameter</label>
<input type="text" class="form-control w-100" id="team-name-search" name="q" placeholder="Search for matching submission" {% if q %}value="{{q}}"{% endif %}>
</div>
<div class="form-group col-md-2">
<label for="team-name-search" class="sr-only">Search</label>
<button type="submit" class="btn btn-primary w-100"><i class="fas fa-search" aria-hidden="true"></i></button>
</div>
</form>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-12">
<div class="float-right pb-3">
@ -37,12 +67,12 @@
<th class="sort-col"><b>Team</b></th>
<th class="sort-col"><b>Challenge</b></th>
<th class="sort-col"><b>Type</b></th>
<th class="sort-col"><b>Submission</b></th>
<th class="sort-col"><b>Provided</b></th>
<th class="text-center sort-col"><b>Date</b></th>
</tr>
</thead>
<tbody>
{% for sub in submissions %}
{% for sub in submissions.items %}
<tr>
<td class="border-right" data-checkbox>
<div class="form-check text-center">
@ -73,19 +103,19 @@
{% endfor %}
</tbody>
</table>
{% if page_count > 1 %}
{% if submissions.pages > 1 %}
<div class="text-center">Page
<br>
{% if curr_page != 1 %}
<a href="?page={{ curr_page - 1 }}">&lt;&lt;&lt;</a>
{% if submissions.page != 1 %}
<a href="{{ prev_page }}">&lt;&lt;&lt;</a>
{% endif %}
<select class="page-select">
{% for page in range(1, page_count + 1) %}
<option {% if curr_page == page %}selected{% endif %}>{{ page }}</option>
{% for page in range(1, submissions.pages + 1) %}
<option {% if submissions.page == page %}selected{% endif %}>{{ page }}</option>
{% endfor %}
</select>
{% if curr_page != page_count %}
<a href="?page={{ curr_page + 1 }}">&gt;&gt;&gt;</a>
{% if submissions.next_num %}
<a href="{{ next_page }}">&gt;&gt;&gt;</a>
{% endif %}
</div>
{% endif %}