Example #1
0
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
Example #2
0
    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
Example #3
0
    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
Example #4
0
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
Example #5
0
    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)
Example #6
0
    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
Example #7
0
    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'
Example #8
0
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"))
Example #9
0
    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
Example #10
0
    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)
Example #11
0
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
Example #12
0
File: main.py Project: rvisser7/cms
    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)
Example #13
0
    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)
Example #14
0
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
Example #15
0
    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))