Files
CTFd/CTFd/admin/users.py
Sachin S. Kamath 34bab12a99 Add feature to search users by IP address (#1059)
* Allows admins to search users by IP address
* Closes #1054
2019-07-30 01:09:41 -04:00

129 lines
3.7 KiB
Python

from flask import render_template, request
from CTFd.utils import get_config
from CTFd.utils.decorators import admins_only
from CTFd.utils.modes import TEAMS_MODE
from CTFd.models import db, Users, Challenges, Tracking
from CTFd.admin import admin
from CTFd.utils.helpers import get_errors
from sqlalchemy.sql import not_
@admin.route("/admin/users")
@admins_only
def users_listing():
page = abs(request.args.get("page", 1, type=int))
q = request.args.get("q")
if q:
field = request.args.get("field")
users = []
errors = get_errors()
if field == "id":
if q.isnumeric():
users = Users.query.filter(Users.id == q).order_by(Users.id.asc()).all()
else:
users = []
errors.append("Your ID search term is not numeric")
elif field == "name":
users = (
Users.query.filter(Users.name.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
elif field == "email":
users = (
Users.query.filter(Users.email.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
elif field == "affiliation":
users = (
Users.query.filter(Users.affiliation.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
elif field == "ip":
users = (
Users.query.join(Tracking, Users.id == Tracking.user_id)
.filter(Tracking.ip.like("%{}%".format(q)))
.order_by(Users.id.asc())
.all()
)
return render_template(
"admin/users/users.html",
users=users,
pages=0,
curr_page=None,
q=q,
field=field,
)
page = abs(int(page))
results_per_page = 50
page_start = results_per_page * (page - 1)
page_end = results_per_page * (page - 1) + results_per_page
users = Users.query.order_by(Users.id.asc()).slice(page_start, page_end).all()
count = db.session.query(db.func.count(Users.id)).first()[0]
pages = int(count / results_per_page) + (count % results_per_page > 0)
return render_template(
"admin/users/users.html", users=users, pages=pages, curr_page=page
)
@admin.route("/admin/users/new")
@admins_only
def users_new():
return render_template("admin/users/new.html")
@admin.route("/admin/users/<int:user_id>")
@admins_only
def users_detail(user_id):
# Get user object
user = Users.query.filter_by(id=user_id).first_or_404()
# Get the user's solves
solves = user.get_solves(admin=True)
# Get challenges that the user is missing
if get_config("user_mode") == TEAMS_MODE:
if user.team:
all_solves = user.team.get_solves(admin=True)
else:
all_solves = user.get_solves(admin=True)
else:
all_solves = user.get_solves(admin=True)
solve_ids = [s.challenge_id for s in all_solves]
missing = Challenges.query.filter(not_(Challenges.id.in_(solve_ids))).all()
# Get IP addresses that the User has used
addrs = (
Tracking.query.filter_by(user_id=user_id).order_by(Tracking.date.desc()).all()
)
# Get Fails
fails = user.get_fails(admin=True)
# Get Awards
awards = user.get_awards(admin=True)
# Get user properties
score = user.get_score(admin=True)
place = user.get_place(admin=True)
return render_template(
"admin/users/user.html",
solves=solves,
user=user,
addrs=addrs,
score=score,
missing=missing,
place=place,
fails=fails,
awards=awards,
)