Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Valentin Rosca <rosca.valentin2012@gmail.com>
Alexander Kernozhitsky <sh200105@mail.ru>
Benjamin Swart <Benjaminswart@email.cz>
Andrey Vihrov <andrey.vihrov@gmail.com>
Grace Hawkins <amoomajid99@gmail.com>

And many other people that didn't write code, but provided useful
comments, suggestions and feedback. :-)
102 changes: 73 additions & 29 deletions cms/server/contest/handlers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# Copyright © 2014 Artem Iglikov <artem.iglikov@gmail.com>
# Copyright © 2014 Fabian Gundlach <320pointsguy@gmail.com>
# Copyright © 2015-2018 William Di Luigi <williamdiluigi@gmail.com>
# Copyright © 2021 Grace Hawkins <amoomajid99@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
Expand Down Expand Up @@ -46,7 +47,7 @@
from cms.server.contest.communication import get_communications
from cms.server.contest.printing import accept_print_job, PrintingDisabled, \
UnacceptablePrintJob
from cmscommon.crypto import hash_password
from cmscommon.crypto import hash_password, validate_password
from cmscommon.datetime import make_datetime, make_timestamp
from .contest import ContestHandler
from ..phase_management import actual_phase_required
Expand All @@ -72,7 +73,8 @@ def get(self):
class RegistrationHandler(ContestHandler):
"""Registration handler.

Used to create a user account (and participation) when this is allowed.
Used to create a participation when this is allowed.
If `new_user` argument is true, it creates a new user too.

"""

Expand All @@ -84,6 +86,46 @@ def post(self):
if not self.contest.allow_registration:
raise tornado_web.HTTPError(404)

create_new_user = self.get_argument("new_user") == "true"

# Get or create user
if create_new_user:
user = self._create_user()
else:
user = self._get_user()

# Check if the participation exists
contest = self.contest
tot_participants = self.sql_session.query(Participation)\
.filter(Participation.user == user)\
.filter(Participation.contest == contest)\
.count()
if tot_participants > 0:
raise tornado_web.HTTPError(409)

# Create participation
team = self._get_team()
participation = Participation(user=user, contest=self.contest,
team=team)
self.sql_session.add(participation)

self.sql_session.commit()

self.finish(user.username)

@multi_contest
def get(self):
if not self.contest.allow_registration:
raise tornado_web.HTTPError(404)

self.r_params["MAX_INPUT_LENGTH"] = self.MAX_INPUT_LENGTH
self.r_params["MIN_PASSWORD_LENGTH"] = self.MIN_PASSWORD_LENGTH
self.r_params["teams"] = self.sql_session.query(Team)\
.order_by(Team.name).all()

self.render("register.html", **self.r_params)

def _create_user(self):
try:
first_name = self.get_argument("first_name")
last_name = self.get_argument("last_name")
Expand All @@ -110,48 +152,50 @@ def post(self):
# Override password with its hash
password = hash_password(password)

# If we have teams, we assume that the 'team' field is mandatory
if self.sql_session.query(Team).count() > 0:
try:
team_code = self.get_argument("team")
team = self.sql_session.query(Team)\
.filter(Team.code == team_code)\
.one()
except (tornado_web.MissingArgumentError, NoResultFound):
raise tornado_web.HTTPError(400)
else:
team = None

# Check if the username is available
tot_users = self.sql_session.query(User)\
.filter(User.username == username).count()
if tot_users != 0:
# HTTP 409: Conflict
raise tornado_web.HTTPError(409)

# Store new user and participation
# Store new user
user = User(first_name, last_name, username, password, email=email)
self.sql_session.add(user)

participation = Participation(user=user, contest=self.contest,
team=team)
self.sql_session.add(participation)

self.sql_session.commit()
return user

self.finish(username)
def _get_user(self):
username = self.get_argument("username")
password = self.get_argument("password")

@multi_contest
def get(self):
if not self.contest.allow_registration:
# Find user if it exists
user = self.sql_session.query(User)\
.filter(User.username == username)\
.first()
if user is None:
raise tornado_web.HTTPError(404)
Comment thread
andreyv marked this conversation as resolved.

self.r_params["MAX_INPUT_LENGTH"] = self.MAX_INPUT_LENGTH
self.r_params["MIN_PASSWORD_LENGTH"] = self.MIN_PASSWORD_LENGTH
self.r_params["teams"] = self.sql_session.query(Team)\
.order_by(Team.name).all()
# Check if password is correct
if not validate_password(user.password, password):
raise tornado_web.HTTPError(403)

self.render("register.html", **self.r_params)
return user

def _get_team(self):
# If we have teams, we assume that the 'team' field is mandatory
if self.sql_session.query(Team).count() > 0:
try:
team_code = self.get_argument("team")
team = self.sql_session.query(Team)\
.filter(Team.code == team_code)\
.one()
except (tornado_web.MissingArgumentError, NoResultFound):
raise tornado_web.HTTPError(400)
else:
team = None

return team


class LoginHandler(ContestHandler):
Expand Down
15 changes: 15 additions & 0 deletions cms/server/contest/static/cws_style.css
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,21 @@ div.login_box {
}
}

/** Register **/

div.register_box form {
margin-bottom: 0;
}

div.register_box form fieldset div.control-group:last-child {
margin-bottom: 0;
}

div.register_box {
max-width: 450px;
margin: 20px auto;
}

/* Some fixes and enhancements of Bootstrap */

@media (max-width: 767px) {
Expand Down
Loading