def add_participation(username, contest_id, ip, delay_time, extra_time, password, team_code, hidden, unrestricted): logger.info("Creating the user's participation in the database.") delay_time = delay_time if delay_time is not None else 0 extra_time = extra_time if extra_time is not None else 0 if hidden: logger.warning("The participation will be hidden") if unrestricted: logger.warning("The participation will be unrestricted") try: with SessionGen() as session: user = \ session.query(User).filter(User.username == username).first() if user is None: logger.error("No user with username `%s' found.", username) return False contest = Contest.get_from_id(contest_id, session) if contest is None: logger.error("No contest with id `%s' found.", contest_id) return False team = None if team_code is not None: team = \ session.query(Team).filter(Team.code == team_code).first() if team is None: logger.error("No team with code `%s' found.", team_code) return False participation = Participation( user=user, contest=contest, ip=ip, delay_time=datetime.timedelta(seconds=delay_time), extra_time=datetime.timedelta(seconds=extra_time), password=password, team=team, hidden=hidden, unrestricted=unrestricted) session.add(participation) session.commit() except IntegrityError: logger.error("A participation for this user in this contest " "already exists.") return False logger.info("Participation added.") return True
def _makeparticipation(self, username, cdb, udb, gdb, teamdb): user = self.users[username] pdb = Participation(user=udb, contest=cdb) pdb.password = build_password(user.password) pdb.group = gdb pdb.ip = user.ip pdb.hidden = user.hidden pdb.unrestricted = user.unrestricted pdb.team = teamdb return pdb
def do_import(self): """Get the user from the UserLoader and store it.""" # Get the user user = self.loader.get_user() if user is None: return False # Store logger.info("Creating user %s on the database.", user.username) with SessionGen() as session: if self.contest_id is not None: contest = session.query(Contest)\ .filter(Contest.id == self.contest_id)\ .first() if contest is None: logger.critical( "The specified contest (id %s) does not exist. " "Aborting.", self.contest_id) return False # Check whether the user already exists old_user = session.query(User) \ .filter(User.username == user.username) \ .first() if old_user is not None: logger.critical("The user already exists.") return False session.add(user) if self.contest_id is not None: logger.info("Creating participation of user %s in contest %s.", user.username, contest.name) participation = Participation(user=user, contest=contest) session.add(participation) session.commit() user_id = user.id logger.info("Import finished (new user id: %s).", user_id) return True
def add_participation(username, contest_id): try: with SessionGen() as session: user = session.query(User).filter(User.username == username).first() if user is None: return False contest = Contest.get_from_id(contest_id, session) if contest is None: return False participation = Participation( user=user, contest=contest, hidden=False, unrestricted=False ) session.add(participation) session.commit() except IntegrityError: return False logger.info("Added participation for user {}".format(username)) return True
def post(self, user_id): fallback_page = self.url("user", user_id) user = self.safe_get_item(User, user_id) try: group_id = self.get_argument("group_id") assert group_id != "null", "Please select a valid group" except Exception as error: self.service.add_notification( make_datetime(), "Invalid field(s)", repr(error)) self.redirect(fallback_page) return group = self.safe_get_item(Group, group_id) self.contest = group.contest attrs = {} self.get_bool(attrs, "hidden") self.get_bool(attrs, "unofficial") self.get_bool(attrs, "unrestricted") # Create the participation. participation = Participation(contest=self.contest, user=user, group=group, hidden=attrs["hidden"], unofficial=attrs["unofficial"], unrestricted=attrs["unrestricted"]) self.sql_session.add(participation) if self.try_commit(): # Create the user on RWS. self.service.proxy_service.reinitialize() # Maybe they'll want to do this again (for another contest). self.redirect(fallback_page)
def _participation_to_db(session, contest, new_p): """Add the new participation to the DB and attach it to the contest session (Session): session to use. contest (Contest): the contest in the DB. new_p (dict): dictionary with the participation data, including at least "username"; may contain "team", "hidden", "ip", "password". return (Participation): the participation in the DB. raise (ImportDataError): in case of one of these errors: - the user for this participation does not already exist in the DB; - the team for this participation does not already exist in the DB. """ user = session.query(User)\ .filter(User.username == new_p["username"]).first() if user is None: # FIXME: it would be nice to automatically try to import. raise ImportDataError("User \"%s\" not found in database. " "Use cmsImportUser to import it." % new_p["username"]) team = session.query(Team)\ .filter(Team.code == new_p.get("team")).first() if team is None and new_p.get("team") is not None: # FIXME: it would be nice to automatically try to import. raise ImportDataError("Team \"%s\" not found in database. " "Use cmsImportTeam to import it." % new_p.get("team")) # Check that the participation is not already defined. p = session.query(Participation)\ .filter(Participation.user_id == user.id)\ .filter(Participation.contest_id == contest.id)\ .first() # FIXME: detect if some details of the participation have been updated # and thus the existing participation needs to be changed. if p is not None: logger.warning( "Participation of user %s in this contest already " "exists, not updating it.", new_p["username"]) return p # Prepare new participation args = { "user": user, "contest": contest, } if "team" in new_p: args["team"] = team if "hidden" in new_p: args["hidden"] = new_p["hidden"] if "ip" in new_p and new_p["ip"] is not None: args["ip"] = [ipaddress.ip_network(new_p["ip"])] if "password" in new_p: args["password"] = new_p["password"] new_p = Participation(**args) session.add(new_p) return new_p
def user_handler(self): if local.data['action'] == 'new': try: username = local.data['username'] password = local.data['password'] email = local.data['email'].lower() firstname = local.data['firstname'] lastname = local.data['lastname'] recaptcha_response = local.data['recaptcha_response'] except KeyError: logger.warning('Missing parameters') return 'Bad request' # Check captcha r = requests.post( "https://www.google.com/recaptcha/api/siteverify", data={'secret': config.get("core", "recaptcha_secret_key"), 'response': recaptcha_response}, #, 'remoteip': ''}, verify=False) try: assert r.json()["success"] == True except: return "Bad request" token = self.hashpw(password) err = self.check_user(username) if err is not None: return err err = self.check_email(email) if err is not None: return err user = User( first_name=firstname, last_name=lastname, username=username, password=token, email=email ) social_user = SocialUser( access_level=6, registration_time=make_datetime() ) contest = local.session.query(Contest)\ .filter(Contest.id == self.CONTEST_ID)\ .first() participation = Participation( user=user, contest=contest ) social_user.user = user if 'institute' in local.data: social_user.institute_id = int(local.data['institute']) try: local.session.add(user) local.session.add(social_user) local.session.add(participation) local.session.commit() except IntegrityError: return 'User already exists' elif local.data['action'] == 'login': try: username = local.data['username'] password = local.data['password'] except KeyError: logger.warning('Missing parameter') return 'Bad request' token = self.hashpw(password) participation = self.get_participation(username, token) if participation is None: return 'login.error' else: user = participation.user local.resp['token'] = token local.resp['user'] = self.get_user_info(user) elif local.data['action'] == 'get': user = local.session.query(User)\ .filter(User.username == local.data['username']).first() if user is None: return 'Not found' local.resp = self.get_user_info(user) # Append scores of tried tasks local.resp['scores'] = [] for ts in user.social_user.taskscores: taskinfo = dict() taskinfo['name'] = ts.task.name taskinfo['score'] = ts.score taskinfo['title'] = ts.task.title local.resp['scores'].append(taskinfo) elif local.data['action'] == 'list': query = local.session.query(User)\ .join(SocialUser)\ .order_by(desc(SocialUser.score))\ .order_by(desc(SocialUser.id)) if 'institute' in local.data: query = query\ .filter(SocialUser.institute_id == local.data['institute']) users, local.resp['num'] = self.sliced_query(query) local.resp['users'] = map(self.get_user_info, users) elif local.data['action'] == 'update': if local.user is None: return 'Unauthorized' if 'institute' in local.data and \ local.data['institute'] is not None: local.user.institute_id = int(local.data['institute']) if 'email' in local.data and \ local.data['email'] != '' and \ local.user.email != local.data['email']: err = self.check_email(local.data['email']) if err is not None: return err local.user.email = local.data['email'] if 'old_password' in local.data and \ local.data['old_password'] != '': old_token = self.hashpw(local.data['old_password']) if local.user.password != old_token: return 'Wrong password' if len(local.data['password']) < 5: return 'Password\'s too short' new_token = self.hashpw(local.data['password']) local.user.password = new_token local.resp['token'] = new_token local.session.commit() else: return 'Bad request'
def validate_login(sql_session, contest, timestamp, username, password, ip_address): """Authenticate a user logging in, with username and password. Given the information the user provided (the username and the password) and some context information (contest, to determine which users are allowed to log in, how and with which restrictions; timestamp for cookie creation; IP address to check against) try to authenticate the user and return its participation and the cookie to set to help authenticate future visits. After finding the participation, IP login and hidden users restrictions are checked. sql_session (Session): the SQLAlchemy database session used to execute queries. contest (Contest): the contest the user is trying to access. timestamp (datetime): the date and the time of the request. username (str): the username the user provided. password (str): the password the user provided. ip_address (IPv4Address|IPv6Address): the IP address the request came from. return ((Participation, bytes)|(None, None)): if the user couldn't be authenticated then return None, otherwise return the participation that they wanted to authenticate as; if a cookie has to be set return it as well, otherwise return None. """ def log_failed_attempt(msg, *args): logger.info( "Unsuccessful login attempt from IP address %s, as user " "%r, on contest %s, at %s: " + msg, ip_address, username, contest.name, timestamp, *args) if not contest.allow_password_authentication: log_failed_attempt("password authentication not allowed") return None, None participation = sql_session.query(Participation) \ .join(Participation.user) \ .options(contains_eager(Participation.user)) \ .filter(Participation.contest == contest)\ .filter(User.username == username)\ .first() user = sql_session.query(User).filter(User.username == username).first() if participation is None: if user is None: log_failed_attemp("user not found") return None, None else: participation = Participation(user=user, contest=contest, team=None) sql_session.add(participation) sql_session.commit() if not safe_validate_password(participation, password): log_failed_attempt("wrong password") return None, None if contest.ip_restriction and participation.ip is not None \ and not any(ip_address in network for network in participation.ip): log_failed_attempt("unauthorized IP address") return None, None if contest.block_hidden_participations and participation.hidden: log_failed_attempt("participation is hidden and unauthorized") return None, None logger.info( "Successful login attempt from IP address %s, as user %r, on " "contest %s, at %s", ip_address, username, contest.name, timestamp) return (participation, json.dumps([username, password, make_timestamp(timestamp)]).encode("utf-8"))
def do_import(self): """Get the contest from the Loader and store it.""" # We need to check whether the contest has changed *before* calling # get_contest() as that method might reset the "has_changed" bit. if self.update_contest: contest_has_changed = self.loader.contest_has_changed() # Get the contest contest, tasks, participations = self.loader.get_contest() # Apply the modification flags if self.zero_time: contest.start = datetime.datetime(1970, 1, 1) contest.stop = datetime.datetime(1970, 1, 1) elif self.test: contest.start = datetime.datetime(1970, 1, 1) contest.stop = datetime.datetime(2100, 1, 1) with SessionGen() as session: # Check whether the contest already exists old_contest = session.query(Contest) \ .filter(Contest.name == contest.name).first() if old_contest is not None: if self.update_contest: if contest_has_changed: # Participations are handled later, so we ignore them # at this point (note that contest does not even have # participations). Tasks can be ignored or not, since # they can live even detached from a contest. self._update_object(old_contest, contest, ignore={"participations"}) contest = old_contest elif self.update_tasks: contest = old_contest else: logger.critical( "Contest \"%s\" already exists in database.", contest.name) return False # Check needed tasks for tasknum, taskname in enumerate(tasks): task = session.query(Task) \ .filter(Task.name == taskname).first() if task is None: if self.import_tasks: task = self.loader.get_task_loader(taskname).get_task( get_statement=not self.no_statements) if task: session.add(task) else: logger.critical("Could not import task \"%s\".", taskname) return False else: logger.critical("Task \"%s\" not found in database.", taskname) return False elif self.update_tasks: task_loader = self.loader.get_task_loader(taskname) if task_loader.task_has_changed(): new_task = task_loader.get_task( get_statement=not self.no_statements) if new_task: ignore = set(("num", )) if self.no_statements: ignore.update( ("primary_statements", "statements")) self._update_object(task, new_task, ignore=ignore) else: logger.critical("Could not reimport task \"%s\".", taskname) return False if task.contest is not None \ and task.contest.name != contest.name: logger.critical( "Task \"%s\" is already tied to a " "contest.", taskname) return False else: # We should tie this task to the contest task.num = tasknum task.contest = contest # Check needed participations if participations is None: participations = [] for p in participations: user = session.query(User) \ .filter(User.username == p["username"]).first() team = session.query(Team) \ .filter(Team.code == p.get("team")).first() if user is None: # FIXME: it would be nice to automatically try to # import. logger.critical("User \"%s\" not found in database.", p["username"]) return False if team is None and p.get("team") is not None: # FIXME: it would be nice to automatically try to # import. logger.critical("Team \"%s\" not found in database.", p.get("team")) return False # Check that the participation is not already defined. participation = session.query(Participation) \ .filter(Participation.user_id == user.id) \ .filter(Participation.contest_id == contest.id) \ .first() # FIXME: detect if some details of the participation have been # updated and thus the existing participation needs to be # changed. if participation is None: # Prepare new participation args = { "user": user, "team": team, "contest": contest, } if "hidden" in p: args["hidden"] = p["hidden"] if "ip" in p: args["ip"] = p["ip"] if "password" in p: args["password"] = p["password"] session.add(Participation(**args)) else: logger.warning( "Participation of user %s in this contest " "already exists, not going to update it.", p["username"]) # Here we could check if there are actually some tasks or # users to add: if there are not, then don't create the # contest. However, I would like to be able to create it # anyway (and later tie to it some tasks and users). if old_contest is None: logger.info("Creating contest on the database.") session.add(contest) # Final commit session.commit() logger.info("Import finished (new contest id: %s).", contest.id) return True
def post(self): try: first_name = self.get_argument("first_name") last_name = self.get_argument("last_name") grade = int(self.get_argument("grade")) city_region = self.get_argument("city_region") school_name = self.get_argument("school_name") username = self.get_argument("username") password = self.get_argument("password") email = self.get_argument("email") if len(email) == 0: email = None if not 1 <= len(first_name) <= self.MAX_INPUT_LENGTH: raise ValueError() if not 1 <= len(last_name) <= self.MAX_INPUT_LENGTH: raise ValueError() if not 1 <= len(username) <= self.MAX_INPUT_LENGTH: raise ValueError() if not re.match(r"^[A-Za-z0-9_-]+$", username): raise ValueError() if not self.MIN_PASSWORD_LENGTH <= len(password) \ <= self.MAX_INPUT_LENGTH: raise ValueError() except (tornado_web.MissingArgumentError, ValueError): raise tornado_web.HTTPError(400) # 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 user = User(first_name=first_name, last_name=last_name, username=username, password=password, email=email, grade=grade,school_name=school_name,city_region=city_region) self.sql_session.add(user) participation = Participation(user=user, contest=self.contest, team=team) self.sql_session.add(participation) self.sql_session.commit() self.finish(username)
def load_participations(path): logger.info("Loading...") with open(path, 'r') as io: data = json.load(io) participations = data['participations'] with SessionGen() as session: for entry in participations: logger.info('Loading: %s' % (entry)) contest = Contest.get_from_id(entry['contest_id'], session) if contest is None: logger.error(" Contest ID %d not found" % (entry['contest_id'])) session.rollback() return False userdata = entry['user'] user = session.query(User).filter( User.username == userdata['username']).first() if user is None: user = User(username=userdata['username'], first_name=userdata['first_name'], last_name=userdata['last_name'], password=build_password( generate_random_password())) logger.info(' Creating new user: %s' % (user.username)) session.add(user) else: logger.info(' Using existing user: %s (id=%d)' % (user.username, user.id)) if 'plaintext_password' in userdata: logger.info(' * password') user.password = build_password(userdata['plaintext_password'], 'plaintext') if 'first_name' in userdata: logger.info(' * first_name: %s' % (userdata['first_name'])) user.first_name = userdata['first_name'] if 'last_name' in userdata: logger.info(' * last_name: %s' % (userdata['last_name'])) user.last_name = userdata['last_name'] participation = session.query(Participation).join( Participation.user).filter( Participation.contest == contest).filter( User.username == user.username).first() if participation is None: participation = Participation(user=user, contest=contest) logger.info( ' Creating new participation for contest_id=%d user=%s' % (contest.id, user.username)) session.add(participation) else: logger.info( ' Updating participation: id=%d contest_id=%d user=%s' % (participation.id, participation.contest_id, participation.user.username)) if 'plaintext_password' in entry: logger.info(' * plaintext_password') participation.password = build_password( entry['plaintext_password'], 'plaintext') if 'ip' in entry: logger.info(' * ip: %s' % (entry['ip'])) participation.ip = [ipaddress.ip_network(entry['ip'])] if 'delay_time' in entry: logger.info(' * delay_time: %d' % (entry['delay_time'])) participation.delay_time = datetime.timedelta( seconds=entry['delay_time']) if 'extra_time' in entry: logger.info(' * extra_time: %d' % (entry['extra_time'])) participation.extra_time = datetime.timedelta( seconds=entry['extra_time']) if 'hidden' in entry: logger.info(' * hidden: %s' % (entry['hidden'])) participation.hidden = entry['hidden'] if 'unrestricted' in entry: logger.info(' * unrestricted: %s' % (entry['unrestricted'])) participation.unrestricted = entry['unrestricted'] if 'team' in userdata: team = session.query(Team).filter( Team.code == userdata['team']['code']).first() if team is None: team = Team(code=userdata['team']['code'], name=userdata['team']['name']) logger.info(' Creating new team: %s' % (team.code)) session.add(team) else: logger.info(' Using existing team: %s' % (team.code)) if 'name' in userdata['team']: logger.info(' * name: %s' % (userdata['team']['name'])) team.name = userdata['team']['name'] participation.team = team session.commit() logger.info("Done.") return True
def post(self): if not self.contest.allow_registration: raise tornado.web.HTTPError(404) try: first_name = self.get_argument("first_name") last_name = self.get_argument("last_name") username = self.get_argument("username") password = self.get_argument("password") email = self.get_argument("email") if len(email) == 0: email = None if not 1 <= len(first_name) <= self.MAX_INPUT_LENGTH: raise ValueError() if not 1 <= len(last_name) <= self.MAX_INPUT_LENGTH: raise ValueError() if not 1 <= len(username) <= self.MAX_INPUT_LENGTH: raise ValueError() if not re.match(r"^[A-Za-z0-9_-]+$", username): raise ValueError() if not self.MIN_PASSWORD_LENGTH <= len(password) \ <= self.MAX_INPUT_LENGTH: raise ValueError() except (tornado.web.MissingArgumentError, ValueError): raise tornado.web.HTTPError(400) # 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") school = self.get_argument("school") 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 school = 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 user = User(first_name, last_name, username, password, email=email) self.sql_session.add(user) # # Get contest IDs of all contests which are public # f = open('/home/ubuntu/public_contests') # public_contests = set() # for line in f: # digit_contain = False # if (line[0] == '#'): # continue # for c in line: # if (48 <= ord(c)) and (ord(c) <= 57): # digit_contain = True # break # if digit_contain: # public_contests.add(int(line.strip())) # f.close() # Add participation to all public contests for contest in self.sql_session.query(Contest): # if (contest.id in public_contests): if (contest.allow_registration): self.sql_session.add(Participation(user=user, contest=contest, team=team)) # Make log to add additional school if (school != None) and (len(school) > 0): f = open('/home/ubuntu/logs/TODO_logs', 'a') l = str(datetime.datetime.now()) l += " ADD SCHOOL REQUEST " l += " Username: "******" School: " + school f.write(l+'\n') f.close() self.sql_session.commit() self.finish(username)
def post(self, contest_id): fallback_page = self.url("contest", contest_id, "users", "import") self.contest = self.safe_get_item(Contest, contest_id) r_params = self.render_params() action = self.get_body_argument('action', 'upload') if action == 'upload': ignore_existing = self.get_body_argument('ignore_existing', False) load_passwords = self.get_body_argument('load_passwords', False) try: user_csv = self.request.files["users_csv"][0] users = CsvUserLoader(None, None, user_csv['body']).read_users() processed_users = [] some_participants_exist = False for user in users: username = user['username'] result = { 'participant': False, 'username': username } db_user = self.sql_session.query(User).filter_by( username=username).first() if not db_user: self.application.service.add_notification( make_datetime(), 'User missing', '"%s" doesn\'t exist. Import users first.' % username) self.redirect(fallback_page) return result['user_id'] = db_user.id result['team'] = user.get('team') participation = self.sql_session.query(Participation) \ .filter(Participation.user == db_user) \ .filter(Participation.contest == self.contest) \ .first() if participation: result['participant'] = True if not ignore_existing and not some_participants_exist: some_participants_exist = True self.application.service.add_notification( make_datetime(), 'User exists', 'Some participants already exist') if load_passwords: result['password'] = \ cmscommon.crypto.hash_password(user.get('password'), method='plaintext') else: result['password'] = None processed_users.append(result) r_params['users'] = processed_users r_params['has_errors'] = \ (some_participants_exist and not ignore_existing) r_params['load_passwords'] = load_passwords self.render('participation_preview.html', **r_params) return except Exception as error: self.application.service.add_notification( make_datetime(), "Bad CSV file", repr(error)) self.redirect(fallback_page) return elif action == 'save': user_id = self.get_body_arguments('user_id', False) teams = self.get_body_arguments('team', False) passwords = self.get_body_arguments('password', False) for i in range(len(user_id)): user = self.safe_get_item(User, user_id[i]) team = None if teams[i]: team_code = ImportParticipantsHandler \ .prepare_team_code(teams[i]) team = self.sql_session.query(Team) \ .filter_by(code=team_code).first() if not team: team = Team(code=team_code, name=teams[i]) self.sql_session.add(team) password = passwords[i] if passwords else None participation = Participation(user=user, contest=self.contest, team=team, password=password) self.sql_session.add(participation) if self.try_commit(): # Create the user on RWS. self.application.service.proxy_service.reinitialize() self.redirect(self.url("contest", contest_id, "users")) return self.redirect(fallback_page)
def add_participation(username, contest_id, ip, delay_time, extra_time, password, method, is_hashed, team_code, hidden, unrestricted, groupname): logger.info("Creating the user's participation in the database.") delay_time = delay_time if delay_time is not None else 0 extra_time = extra_time if extra_time is not None else 0 if hidden: logger.warning("The participation will be hidden") if unofficial: logger.warning("The participation will be unofficial") if unrestricted: logger.warning("The participation will be unrestricted") try: with SessionGen() as session: user = \ session.query(User).filter(User.username == username).first() if user is None: logger.error("No user with username `%s' found.", username) return False contest = Contest.get_from_id(contest_id, session) if contest is None: logger.error("No contest with id `%s' found.", contest_id) return False if groupname is None: group = contest.main_group else: group = \ session.query(Group) \ .filter(Group.contest_id == contest_id, Group.name == groupname).first() if group is None: logger.error("No group with name `%s' found.", groupname) return False team = None if team_code is not None: team = \ session.query(Team).filter(Team.code == team_code).first() if team is None: logger.error("No team with code `%s' found.", team_code) return False if password is not None: if is_hashed: password = build_password(password, method) else: password = hash_password(password, method) participation = Participation( user=user, contest=contest, group=group, ip=[ipaddress.ip_network(ip)] if ip is not None else None, delay_time=datetime.timedelta(seconds=delay_time), extra_time=datetime.timedelta(seconds=extra_time), password=password, team=team, hidden=hidden, unofficial=unofficial, unrestricted=unrestricted) session.add(participation) session.commit() except IntegrityError: logger.error("A participation for this user in this contest " "already exists.") return False logger.info("Participation added.") return True
def post(self, contest_id): contest = self.safe_get_item(Contest, contest_id) reg_allowed = True try: attrs = contest.get_attrs() reg_allowed = attrs.get("allow_registration") self.get_string(attrs, "name", empty=None) self.get_string(attrs, "description") assert attrs.get("name") is not None, "No contest name specified." allowed_localizations = \ self.get_argument("allowed_localizations", "") if allowed_localizations: attrs["allowed_localizations"] = \ [x.strip() for x in allowed_localizations.split(",") if len(x) > 0 and not x.isspace()] else: attrs["allowed_localizations"] = [] attrs["languages"] = self.get_arguments("languages") self.get_bool(attrs, "submissions_download_allowed") self.get_bool(attrs, "allow_questions") self.get_bool(attrs, "allow_user_tests") self.get_bool(attrs, "block_hidden_participations") self.get_bool(attrs, "allow_password_authentication") self.get_bool(attrs, "allow_registration") self.get_bool(attrs, "ip_restriction") self.get_bool(attrs, "ip_autologin") self.get_string(attrs, "token_mode") self.get_int(attrs, "token_max_number") self.get_timedelta_sec(attrs, "token_min_interval") self.get_int(attrs, "token_gen_initial") self.get_int(attrs, "token_gen_number") self.get_timedelta_min(attrs, "token_gen_interval") self.get_int(attrs, "token_gen_max") self.get_int(attrs, "max_submission_number") self.get_int(attrs, "max_user_test_number") self.get_timedelta_sec(attrs, "min_submission_interval") self.get_timedelta_sec(attrs, "min_user_test_interval") self.get_datetime(attrs, "start") self.get_datetime(attrs, "stop") self.get_string(attrs, "timezone", empty=None) self.get_timedelta_sec(attrs, "per_user_time") self.get_int(attrs, "score_precision") self.get_bool(attrs, "analysis_enabled") self.get_datetime(attrs, "analysis_start") self.get_datetime(attrs, "analysis_stop") # Update the contest. contest.set_attrs(attrs) except Exception as error: self.service.add_notification(make_datetime(), "Invalid field(s).", repr(error)) self.redirect(self.url("contest", contest_id)) return # TODO update participations if attrs.get("allow_registration") and not reg_allowed: for unreg_user in self.sql_session.query(User).filter( User.id.notin_( self.sql_session.query(Participation.user_id).filter( Participation.contest == contest).all())).all(): self.sql_session.add( Participation(contest=contest, user=unreg_user)) if self.try_commit(): # Update the contest on RWS. self.service.proxy_service.reinitialize() self.redirect(self.url("contest", contest_id))