Пример #1
0
    def test_cookie_contains_password(self):
        self.contest.ip_autologin = False

        # Cookies are of no use if one cannot login by password.
        self.contest.allow_password_authentication = False
        self.assertFailure()

        # The cookie works with all methods as it holds the plaintext password.
        self.contest.allow_password_authentication = True
        self.user.password = hash_password("mypass", method="bcrypt")
        self.assertSuccessAndCookieRefreshed()

        self.user.password = hash_password("mypass", method="plaintext")
        self.assertSuccessAndCookieRefreshed()

        # Cookies contain the password, which is validated every time.
        self.user.password = build_password("newpass")
        self.assertFailure()

        # Contest-specific passwords take precedence over global ones.
        self.participation.password = build_password("mypass")
        self.assertSuccessAndCookieRefreshed()

        # And they do so in the negative case too.
        self.user.password = build_password("mypass")
        self.participation.password = build_password("newpass")
        self.assertFailure()
Пример #2
0
    def test_cookie_contains_password(self):
        self.contest.ip_autologin = False

        # Cookies are of no use if one cannot login by password.
        self.contest.allow_password_authentication = False
        self.assertFailure()

        # The cookie works with all methods as it holds the plaintext password.
        self.contest.allow_password_authentication = True
        self.user.password = hash_password("mypass", method="bcrypt")
        self.assertSuccessAndCookieRefreshed()

        self.user.password = hash_password("mypass", method="plaintext")
        self.assertSuccessAndCookieRefreshed()

        # Cookies contain the password, which is validated every time.
        self.user.password = build_password("newpass")
        self.assertFailure()

        # Contest-specific passwords take precedence over global ones.
        self.participation.password = build_password("mypass")
        self.assertSuccessAndCookieRefreshed()

        # And they do so in the negative case too.
        self.user.password = build_password("mypass")
        self.participation.password = build_password("newpass")
        self.assertFailure()
Пример #3
0
    def get_password(self, dest, old_password, allow_unset):
        """Parse a (possibly hashed) password.

        Parse the value of the password and the method that should be
        used to hash it (if any) and fill it into the given destination
        making sure that a hashed password can be left unchanged and,
        if allowed, unset.

        dest (dict): a place to store the result in.
        old_password (string|None): the current password for the object
            if any, with a "<method>:" prefix.
        allow_unset (bool): whether the password is allowed to be left
            unset, which is represented as a value of None in dest.

        """
        # The admin leaving the password field empty could mean one of
        # two things: they want the password to be unset (this applies
        # to participations only and it means they inherit the user's
        # password) or, if a password was set and it was hashed, they
        # want to keep using that old password. We distinguish between
        # the two essentially by looking at the method: an empty
        # plaintext means "unset", an empty hashed means "keep".

        # Find out whether a password was set and whether it was
        # plaintext or hashed.
        if old_password is not None:
            try:
                old_method, _ = parse_authentication(old_password)
            except ValueError:
                # Treated as if no password was set.
                old_method = None
        else:
            old_method = None

        password = self.get_argument("password")
        method = self.get_argument("method")

        # If a password is given, we use that.
        if len(password) > 0:
            dest["password"] = hash_password(password, method)
        # If the password was set and was hashed, and the admin kept
        # the method unchanged and didn't specify anything, they must
        # have meant to keep the old password unchanged.
        elif old_method is not None and old_method != "plaintext" \
                and method == old_method:
            # Since the content of dest overwrites the current values
            # of the participation, by not adding anything to dest we
            # cause the current values to be kept.
            pass
        # Otherwise the fact that the password is empty means that the
        # admin wants the password to be unset.
        elif allow_unset:
            dest["password"] = None
        # Or that they really mean the password to be the empty string.
        else:
            dest["password"] = hash_password("", method)
Пример #4
0
    def get_password(self, dest, old_password, allow_unset):
        """Parse a (possibly hashed) password.

        Parse the value of the password and the method that should be
        used to hash it (if any) and fill it into the given destination
        making sure that a hashed password can be left unchanged and,
        if allowed, unset.

        dest (dict): a place to store the result in.
        old_password (string|None): the current password for the object
            if any, with a "<method>:" prefix.
        allow_unset (bool): whether the password is allowed to be left
            unset, which is represented as a value of None in dest.

        """
        # The admin leaving the password field empty could mean one of
        # two things: they want the password to be unset (this applies
        # to participations only and it means they inherit the user's
        # password) or, if a password was set and it was hashed, they
        # want to keep using that old password. We distinguish between
        # the two essentially by looking at the method: an empty
        # plaintext means "unset", an empty hashed means "keep".

        # Find out whether a password was set and whether it was
        # plaintext or hashed.
        if old_password is not None:
            try:
                old_method, _ = parse_authentication(old_password)
            except ValueError:
                # Treated as if no password was set.
                old_method = None
        else:
            old_method = None

        password = self.get_argument("password")
        method = self.get_argument("method")

        # If a password is given, we use that.
        if len(password) > 0:
            dest["password"] = hash_password(password, method)
        # If the password was set and was hashed, and the admin kept
        # the method unchanged and didn't specify anything, they must
        # have meant to keep the old password unchanged.
        elif old_method is not None and old_method != "plaintext" \
                and method == old_method:
            # Since the content of dest overwrites the current values
            # of the participation, by not adding anything to dest we
            # cause the current values to be kept.
            pass
        # Otherwise the fact that the password is empty means that the
        # admin wants the password to be unset.
        elif allow_unset:
            dest["password"] = None
        # Or that they really mean the password to be the empty string.
        else:
            dest["password"] = hash_password("", method)
Пример #5
0
Файл: admin.py Проект: Nyrio/cms
def _admin_attrs(handler):
    """Return a dictionary with the arguments to define an admin

    handler (BaseHandler): the handler receiving the arguments.

    return (dict): a dictionary with the arguments to define an admin,
        based on those passed to handler.

    """
    attrs = {}

    handler.get_string(attrs, "username", empty=None)
    handler.get_string(attrs, "name", empty=None)

    assert attrs.get("username") is not None, "No username specified."
    assert attrs.get("name") is not None, "No admin name specified."

    # Get the password and translate it to an authentication, if present.
    handler.get_string(attrs, "password", empty=None)
    if attrs['password'] is not None:
        attrs["authentication"] = hash_password(attrs["password"])
    del attrs["password"]

    handler.get_bool(attrs, "permission_all")
    handler.get_bool(attrs, "permission_messaging")

    handler.get_bool(attrs, "enabled")

    return attrs
Пример #6
0
def add_admin(username, password=None):
    logger.info("Creating the admin on the database.")

    generated = False
    if password == EmptyPassword.GENERATE or password is None:
        password = generate_random_password()
        generated = True
    elif password == EmptyPassword.PROMPT:
        password = getpass.getpass()

    admin = Admin(username=username,
                  authentication=hash_password(password),
                  name=username,
                  permission_all=True)
    try:
        with SessionGen() as session:
            session.add(admin)
            session.commit()
    except IntegrityError:
        logger.error("An admin with the given username already exists.")
        return False

    if generated:
        logger.info("Admin with complete access added. "
                    "Login with username %s and password %s",
                username, password)
    else:
         logger.info("Admin with complete access added. "
                    "Login with username %s and supplied password", username)
    return True
Пример #7
0
def update_password(username, password, method, is_hashed):
    logger.info("Updating user password in the database.")

    if password is None:
        return False
    # shell will interfere with special characters, so a hashed string must be protected by
    # single quotes. We must remove them
    if password[0] == "'":
        password[0] = ' '
        if password[-1] == "'":
            password[-1] = ' '
        password = password.strip()

    if is_hashed:
        stored_password = build_password(password, method)
    else:
        stored_password = hash_password(password, method)

    with SessionGen() as session:
        user = session.query(User)\
            .filter(User.username == username).first()
        if user is None:
            logger.error("User %s does not exist.", username)
            return False

        session.query(User).filter(User.username == username).\
            update({"password": stored_password}, synchronize_session="fetch")
        session.commit()

    logger.info("User %s password updated, method=%s. " % (username, method))
    return True
Пример #8
0
def add_user(first_name, last_name, username, password, use_bcrypt, is_raw,
             email, timezone, preferred_languages):
    logger.info("Creating the user in the database.")
    if password is None:
        password = generate_random_password_with_method()
    elif not is_raw:
        method = "bcrypt" if use_bcrypt else "text"
        password = hash_password(password, method)

    if preferred_languages is None or preferred_languages == "":
        preferred_languages = "[]"
    else:
        preferred_languages = \
            "[" + ",".join("\"" + lang + "\""
                           for lang in preferred_languages.split(",")) + "]"
    user = User(first_name=first_name,
                last_name=last_name,
                username=username,
                password=password,
                email=email,
                timezone=timezone,
                preferred_languages=preferred_languages)
    try:
        with SessionGen() as session:
            session.add(user)
            session.commit()
    except IntegrityError:
        logger.error("A user with the given username already exists.")
        return False

    logger.info("User added. "
                "Use AddParticipation to add this user to a contest.")
    return True
Пример #9
0
    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")
                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, 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()

        self.finish(username)
Пример #10
0
def _admin_attrs(handler):
    """Return a dictionary with the arguments to define an admin

    handler (BaseHandler): the handler receiving the arguments.

    return (dict): a dictionary with the arguments to define an admin,
        based on those passed to handler.

    """
    attrs = {}

    handler.get_string(attrs, "username", empty=None)
    handler.get_string(attrs, "name", empty=None)

    assert attrs.get("username") is not None, "No username specified."
    assert attrs.get("name") is not None, "No admin name specified."

    # Get the password and translate it to an authentication, if present.
    handler.get_string(attrs, "password", empty=None)
    if attrs['password'] is not None:
        attrs["authentication"] = hash_password(attrs["password"])
    del attrs["password"]

    handler.get_bool(attrs, "permission_all")
    handler.get_bool(attrs, "permission_messaging")

    handler.get_bool(attrs, "enabled")

    return attrs
Пример #11
0
    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")

            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, last_name, username, password)
        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)
Пример #12
0
def add_participation(username, contest_id, ip, delay_time, extra_time,
                      password, method, is_hashed, 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
            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,
                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,
                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
Пример #13
0
def add_participation(username, contest_id, ip, delay_time, extra_time,
                      password, method, is_hashed, 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
            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,
                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,
                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
Пример #14
0
def add_user(first_name, last_name, username, password, method, is_hashed,
             email, timezone, preferred_languages, overwrite=False):
    logger.info("Creating the user in the database.")
    pwd_generated = False
    if password is None:
        assert not is_hashed
        password = generate_random_password()
        pwd_generated = True
    if is_hashed:
        stored_password = build_password(password, method)
    else:
        stored_password = hash_password(password, method)

    if preferred_languages is None or preferred_languages == "":
        preferred_languages = "[]"
    else:
        preferred_languages = \
            "[" + ",".join("\"" + lang + "\""
                           for lang in preferred_languages.split(",")) + "]"
    user = User(first_name=first_name,
                last_name=last_name,
                username=username,
                password=stored_password,
                email=email,
                timezone=timezone,
                preferred_languages=preferred_languages)

    with SessionGen() as session:
        if overwrite:
            existing_user = session.query(User) \
                .filter(User.username == username).first()
            if existing_user is not None:
                user = existing_user
                user.first_name = first_name
                user.last_name = last_name
                user.username = username
                if not pwd_generated:
                    user.password = stored_password
                else:
                    pwd_generated = False
                user.email = email or user.email
                user.timezone = timezone or user.timezone
                user.preferred_languages = preferred_languages or \
                    user.preferred_languages
        try:
            session.add(user)
            session.commit()
        except IntegrityError:
            logger.error("A user with the given username already exists.")
            return False

    logger.info("User added%s. "
                "Use AddParticipation to add this user to a contest."
                % (" with password %s" % password if pwd_generated else ""))
    return True
Пример #15
0
    def post(self, contest_id, user_id):
        fallback_page = "/contest/%s/user/%s/edit" % (contest_id, user_id)

        participation = self.get_participation(contest_id, user_id)

        # Check that the participation is valid.
        if participation is None:
            raise tornado.web.HTTPError(404)

        try:
            attrs = participation.get_attrs()

            self.get_string(attrs, "password", empty=None)
            self.get_string(attrs, "method", empty="text")
            if "method" not in attrs:
                attrs["method"] = "text"
            method = attrs["method"]
            password = attrs["password"]
            if password is not None:
                attrs["password"] = hash_password(password, method)
            elif method != "text":
                # Preserve old password if password is empty
                # and method is not text
                attrs["password"] = participation.password

            del attrs["method"]

            self.get_ip_address_or_subnet(attrs, "ip")
            self.get_datetime(attrs, "starting_time")
            self.get_timedelta_sec(attrs, "delay_time")
            self.get_timedelta_sec(attrs, "extra_time")
            self.get_bool(attrs, "hidden")
            self.get_bool(attrs, "unrestricted")

            # Update the participation.
            participation.set_attrs(attrs)

            # Update the team
            self.get_string(attrs, "team")
            team = self.sql_session.query(Team)\
                       .filter(Team.code == attrs["team"])\
                       .first()
            participation.team = team

        except Exception as error:
            self.application.service.add_notification(
                make_datetime(), "Invalid field(s)", repr(error))
            self.redirect(fallback_page)
            return

        if self.try_commit():
            # Update the user on RWS.
            self.application.service.proxy_service.reinitialize()
        self.redirect(fallback_page)
Пример #16
0
    def _create_user(self):
        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 self.contest.registration_requires_captcha:
                captcha_input = self.get_argument("captcha")
                captcha_input_signature = self.signature(captcha_input)
                captcha_cookie = self.get_secure_cookie("captcha").decode(
                    'utf-8')
                captcha_clear_signature, captcha_username = captcha_cookie.split(
                    '_', 1)

            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()
            if self.contest.registration_requires_captcha:
                if not re.match(r"^[0-9]+$", captcha_input):
                    raise ValueError()
                if not captcha_input_signature == captcha_clear_signature:
                    raise ValueError()
                if not username == captcha_username:
                    raise ValueError()
        except (tornado_web.MissingArgumentError, ValueError):
            raise tornado_web.HTTPError(400)

        # Override password with its hash
        password = hash_password(password)

        # 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
        user = User(first_name, last_name, username, password, email=email)
        self.sql_session.add(user)

        return user
Пример #17
0
    def post(self, user_id):
        fallback_page = "/user/%s" % user_id

        user = self.safe_get_item(User, user_id)

        try:
            attrs = user.get_attrs()

            self.get_string(attrs, "first_name")
            self.get_string(attrs, "last_name")
            self.get_string(attrs, "username", empty=None)
            self.get_string(attrs, "password")
            self.get_string(attrs, "method", empty="text")
            if "method" not in attrs:
                attrs["method"] = "text"

            password = attrs["password"]
            method = attrs["method"]
            if method != "text" and password == "":
                # Preserve old password if password is empty
                # and method is not text
                attrs["password"] = user.password
            else:
                attrs["password"] = hash_password(password, method)

            del attrs["method"]
            self.get_string(attrs, "email")
            self.get_string(attrs, "preferred_languages")
            self.get_string(attrs, "timezone", empty=None)

            assert attrs.get("username") is not None, \
                "No username specified."

            # Update the user.
            user.set_attrs(attrs)

        except Exception as error:
            self.application.service.add_notification(
                make_datetime(), "Invalid field(s)", repr(error))
            self.redirect(fallback_page)
            return

        if self.try_commit():
            # Update the user on RWS.
            self.application.service.proxy_service.reinitialize()
        self.redirect(fallback_page)
Пример #18
0
def add_admin(username, password=None, real_name=None):
    logger.info("Creating the admin on the database.")
    if password is None:
        password = generate_random_password()
    admin = Admin(username=username,
                  authentication=hash_password(password),
                  name=real_name or username,
                  permission_all=True)
    try:
        with SessionGen() as session:
            session.add(admin)
            session.commit()
    except IntegrityError:
        logger.error("An admin with the given username already exists.")
        return False

    logger.info("Admin '%s' with complete access added. ", username)
    return True
Пример #19
0
def add_admin(username, password=None, real_name=None):
    logger.info("Creating the admin on the database.")
    if password is None:
        password = generate_random_password()
    admin = Admin(username=username,
                  authentication=hash_password(password),
                  name=real_name or username,
                  permission_all=True)
    try:
        with SessionGen() as session:
            session.add(admin)
            session.commit()
    except IntegrityError:
        logger.error("An admin with the given username already exists.")
        return False

    logger.info("Admin '%s' with complete access added. ", username)
    return True
Пример #20
0
    def post(self):
        fallback_page = "/users/add"

        try:
            attrs = dict()

            self.get_string(attrs, "first_name")
            self.get_string(attrs, "last_name")
            self.get_string(attrs, "username", empty=None)
            self.get_string(attrs, "password")
            self.get_string(attrs, "method", empty="text")
            if "method" not in attrs:
                attrs["method"] = "text"
            attrs["password"] = hash_password(attrs["password"],
                                              method=attrs["method"])
            del attrs["method"]
            self.get_string(attrs, "email")

            assert attrs.get("username") is not None, \
                "No username specified."

            self.get_string(attrs, "timezone", empty=None)

            self.get_string(attrs, "preferred_languages")

            # Create the user.
            user = User(**attrs)
            self.sql_session.add(user)

        except Exception as error:
            self.application.service.add_notification(
                make_datetime(), "Invalid field(s)", repr(error))
            self.redirect(fallback_page)
            return

        if self.try_commit():
            # Create the user on RWS.
            self.application.service.proxy_service.reinitialize()
            self.redirect("/user/%s" % user.id)
        else:
            self.redirect(fallback_page)
Пример #21
0
    def _create_user(self):
        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)

        # 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
        user = User(first_name, last_name, username, password, email=email)
        self.sql_session.add(user)

        return user
Пример #22
0
def add_user(first_name, last_name, username, password, method, is_hashed,
             email, timezone, preferred_languages):
    logger.info("Creating the user in the database.")
    pwd_generated = False
    if password is None:
        assert not is_hashed
        password = generate_random_password()
        pwd_generated = True
    if is_hashed:
        stored_password = build_password(password, method)
    else:
        stored_password = hash_password(password, method)

    if preferred_languages is None:
        preferred_languages = []
    else:
        preferred_languages = list(lang.strip()
                                   for lang in preferred_languages.split(",")
                                   if lang.strip())
    user = User(first_name=first_name,
                last_name=last_name,
                username=username,
                password=stored_password,
                email=email,
                timezone=timezone,
                preferred_languages=preferred_languages)
    try:
        with SessionGen() as session:
            session.add(user)
            session.commit()
    except IntegrityError:
        logger.error("A user with the given username already exists.")
        return False

    logger.info("User added%s. "
                "Use AddParticipation to add this user to a contest." %
                (" with password %s" % password if pwd_generated else ""))
    return True
Пример #23
0
def add_user(first_name, last_name, username, password, method, is_hashed,
             email, timezone, preferred_languages):
    logger.info("Creating the user in the database.")
    pwd_generated = False
    if password is None:
        assert not is_hashed
        password = generate_random_password()
        pwd_generated = True
    if is_hashed:
        stored_password = build_password(password, method)
    else:
        stored_password = hash_password(password, method)

    if preferred_languages is None:
        preferred_languages = []
    else:
        preferred_languages = list(
            lang.strip() for lang in preferred_languages.split(",") if
            lang.strip())
    user = User(first_name=first_name,
                last_name=last_name,
                username=username,
                password=stored_password,
                email=email,
                timezone=timezone,
                preferred_languages=preferred_languages)
    try:
        with SessionGen() as session:
            session.add(user)
            session.commit()
    except IntegrityError:
        logger.error("A user with the given username already exists.")
        return False

    logger.info("User added%s. "
                "Use AddParticipation to add this user to a contest."
                % (" with password %s" % password if pwd_generated else ""))
    return True
Пример #24
0
 def test_plaintext(self):
     self.assertTrue(
         validate_password(hash_password("p你好", method="plaintext"), "p你好"))
     self.assertFalse(
         validate_password(hash_password("p你好", method="plaintext"), "你好"))
Пример #25
0
 def test_bcrypt(self):
     self.assertTrue(validate_password(
         hash_password("p你好", method="bcrypt"), "p你好"))
     self.assertFalse(validate_password(
         hash_password("p你好", method="bcrypt"), "你好"))
Пример #26
0
 def test_invalid_method(self):
     with self.assertRaises(ValueError):
         hash_password("test", "pwd")
     with self.assertRaises(ValueError):
         validate_password("test:pwd", "pwd")
Пример #27
0
    def post(self):
        fallback_page = self.url("users", "import")

        r_params = self.render_params()
        action = self.get_body_argument('action', 'upload')

        if action == 'upload':
            ignore_existing = self.get_body_argument('ignore_existing', False)
            generate_passwords = self.get_body_argument(
                'generate_passwords', False)
            ignored = 0
            try:
                user_csv = self.request.files["users_csv"][0]
                users = CsvUserLoader(None, None, user_csv['body']).get_users()
                processed_users = []
                for user in users:
                    if generate_passwords or callable(user.password):
                        user.password = None
                    db_user = self.sql_session.query(User).filter_by(
                        username=user.username).first()
                    if db_user:
                        if ignore_existing:
                            if db_user.password:
                                db_user.password = '******'
                            processed_users.append((False, db_user))
                            ignored += 1
                        else:
                            self.application.service.add_notification(
                                make_datetime(), 'Import failed',
                                'User "%s" already exists' % user.username)
                            self.redirect(fallback_page)
                            return
                    else:
                        processed_users.append((True, user))

                if ignored:
                    self.application.service.add_notification(
                        make_datetime(), "User exists",
                        '%d users already exist, ignored' % ignored)
                r_params['users'] = processed_users
                self.render("users_import_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':
            usernames = self.get_body_arguments('username', False)
            first_names = self.get_body_arguments('first_name', False)
            last_names = self.get_body_arguments('last_name', False)
            passwords = self.get_body_arguments('password', False)
            emails = self.get_body_arguments('email', False)
            for i in range(len(usernames)):
                args = {
                    'username': usernames[i],
                    'first_name': first_names[i],
                    'last_name': last_names[i],
                    'email': emails[i],
                }
                if passwords[i]:
                    args['password'] = passwords[i]
                else:
                    args['password'] = crypto.generate_random_password()
                args['password'] = crypto.hash_password(args['password'],
                                                        method='plaintext')
                user = User(**args)
                self.sql_session.add(user)
            if self.try_commit():
                # Create the user on RWS.
                self.application.service.proxy_service.reinitialize()
                self.redirect(self.url("users"))
                return
            else:
                self.redirect(fallback_page)
                return
        self.redirect(fallback_page)
Пример #28
0
    def post(self):
        username = self.get_argument("username", "")
        first_name = self.get_argument("first_name", "")
        last_name = self.get_argument("last_name", "")
        email = self.get_argument("email", "")
        password = self.get_argument("password", "")
        confirm_password = self.get_argument("confirm_password", "")

        if not self.contest.allow_signup:
            return tornado.web.HTTPError(404)

        if password != confirm_password:
            self.redirect("/signup?password_no_match=true")
            return

        user = self.sql_session.query(User).filter(User.username == username).first()
        participation = self.sql_session.query(Participation).filter(Participation.contest == self.contest).filter(Participation.user == user).first()

        if user is not None and participation is not None:
            self.redirect("/signup?user_exist=true")
            return

        if user is None:
            add_user(first_name=first_name, last_name=last_name, username=username, password=hash_password(password), email=email)
        add_participation(username=username, contest_id=self.contest.id)
        self.redirect("/?signup_successful=true")
        return
Пример #29
0
    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)
Пример #30
0
 def test_invalid_method(self):
     with self.assertRaises(ValueError):
         hash_password("test", "pwd")
     with self.assertRaises(ValueError):
         validate_password("test:pwd", "pwd")
Пример #31
0
 def test_bcrypt(self):
     self.assertTrue(
         validate_password(hash_password("p你好", method="bcrypt"), "p你好"))
     self.assertFalse(
         validate_password(hash_password("p你好", method="bcrypt"), "你好"))
Пример #32
0
 def test_plaintext(self):
     self.assertTrue(validate_password(
         hash_password("p你好", method="plaintext"), "p你好"))
     self.assertFalse(validate_password(
         hash_password("p你好", method="plaintext"), "你好"))