コード例 #1
0
ファイル: test_journalist.py プロジェクト: tmc/securedrop
 def test_login_with_invalid_password_doesnt_call_scrypt(
         self, mock_scrypt_hash):
     invalid_pw = 'a' * (Journalist.MAX_PASSWORD_LEN + 1)
     with self.assertRaises(InvalidPasswordLength):
         Journalist.login(self.user.username, invalid_pw, 'mocked')
     self.assertFalse(mock_scrypt_hash.called,
                      "Called _scrypt_hash for password w/ invalid length")
コード例 #2
0
ファイル: test_2fa.py プロジェクト: tmc/securedrop
 def test_totp_reuse_protections2(self):
     """More granular than the preceeding test, we want to make sure
     the right exception is being raised in the right place."""
     valid_token = self.user.totp.now()
     Journalist.login(self.user.username, self.user_pw, valid_token)
     with self.assertRaises(BadTokenException):
         Journalist.login(self.user.username, self.user_pw, valid_token)
コード例 #3
0
 def test_valid_login_calls_scrypt(self,
                                   mock_scrypt_hash,
                                   mock_valid_password):
     Journalist.login(self.user.username, self.user_pw, 'mocked')
     self.assertTrue(
         mock_scrypt_hash.called,
         "Failed to call _scrypt_hash for password w/ valid length")
コード例 #4
0
ファイル: test_2fa.py プロジェクト: freedomofpress/securedrop
 def test_totp_reuse_protections2(self):
     """More granular than the preceeding test, we want to make sure
     the right exception is being raised in the right place.
     """
     valid_token = self.user.totp.now()
     Journalist.login(self.user.username, self.user_pw, valid_token)
     with self.assertRaises(BadTokenException):
         Journalist.login(self.user.username, self.user_pw, valid_token)
コード例 #5
0
ファイル: journalist.py プロジェクト: fowlslegs/securedrop
def login():
    if request.method == "POST":
        try:
            user = Journalist.login(request.form["username"], request.form["password"], request.form["token"])
        except Exception as e:
            app.logger.error("Login for '{}' failed: {}".format(request.form["username"], e))
            login_flashed_msg = "Login failed."

            if isinstance(e, LoginThrottledException):
                login_flashed_msg += " Please wait at least 60 seconds before logging in again."
            else:
                try:
                    user = Journalist.query.filter_by(username=request.form["username"]).one()
                    if user.is_totp:
                        login_flashed_msg += " Please wait for a new two-factor token before logging in again."
                except:
                    pass

            flash(login_flashed_msg, "error")
        else:
            app.logger.info(
                "Successful login for '{}' with token {}".format(request.form["username"], request.form["token"])
            )

            # Update access metadata
            user.last_access = datetime.utcnow()
            db_session.add(user)
            db_session.commit()

            session["uid"] = user.id
            return redirect(url_for("index"))

    return render_template("login.html")
コード例 #6
0
ファイル: journalist.py プロジェクト: pep8er/securedrop
def login():
    if request.method == 'POST':
        try:
            user = Journalist.login(request.form['username'],
                                    request.form['password'],
                                    request.form['token'])
        except Exception as e:
            app.logger.error("Login for '{}' failed: {}".format(
                request.form['username'], e))
            login_flashed_msg = "Login failed."

            if isinstance(e, LoginThrottledException):
                login_flashed_msg += " Please wait at least 60 seconds before logging in again."
            else:
                try:
                    user = Journalist.query.filter_by(username=request.form['username']).one()
                    if user.is_totp:
                        login_flashed_msg += " Please wait for a new two-factor token before logging in again."
                except:
                    pass

            flash(login_flashed_msg, "error")
        else:
            app.logger.info("Successful login for '{}' with token {}".format(
                request.form['username'], request.form['token']))

            # Update access metadata
            user.last_access = datetime.utcnow()
            db_session.add(user)
            db_session.commit()

            session['uid'] = user.id
            return redirect(url_for('index'))

    return render_template("login.html")
コード例 #7
0
ファイル: utils.py プロジェクト: freedomofpress/securedrop
def validate_user(username, password, token, error_message=None):
    """
    Validates the user by calling the login and handling exceptions
    :param username: Username
    :param password: Password
    :param token: Two-factor authentication token
    :param error_message: Localized error message string to use on failure
    :return: Journalist user object if successful, None otherwise.
    """
    try:
        return Journalist.login(username, password, token)
    except (InvalidUsernameException,
            BadTokenException,
            WrongPasswordException,
            LoginThrottledException) as e:
        current_app.logger.error("Login for '{}' failed: {}".format(
            username, e))
        if not error_message:
            error_message = gettext('Login failed.')
        login_flashed_msg = error_message

        if isinstance(e, LoginThrottledException):
            login_flashed_msg += " "
            period = Journalist._LOGIN_ATTEMPT_PERIOD
            # ngettext is needed although we always have period > 1
            # see https://github.com/freedomofpress/securedrop/issues/2422
            login_flashed_msg += ngettext(
                "Please wait at least {seconds} second "
                "before logging in again.",
                "Please wait at least {seconds} seconds "
                "before logging in again.", period).format(seconds=period)
        else:
            try:
                user = Journalist.query.filter_by(
                    username=username).one()
                if user.is_totp:
                    login_flashed_msg += " "
                    login_flashed_msg += gettext(
                        "Please wait for a new two-factor token"
                        " before trying again.")
            except:
                pass

        flash(login_flashed_msg, "error")
        return None
コード例 #8
0
    def setUp(self):
        common.shared_setup()

        # Patch the two-factor verification so it always succeeds
        patcher = patch('db.Journalist.verify_token')
        self.addCleanup(patcher.stop)
        self.mock_journalist_verify_token = patcher.start()
        self.mock_journalist_verify_token.return_value = True

        self.username = "******"
        self.password = "******"
        self.user = Journalist(username=self.username, password=self.password)
        db_session.add(self.user)
        db_session.commit()

        # Use a patched login function to avoid dealing with two-factor tokens
        # (which are being ignored here anyway)
        self.login = lambda username, password: \
                Journalist.login(username, password, "")
コード例 #9
0
ファイル: utils.py プロジェクト: zyphlar/securedrop
def validate_user(username, password, token, error_message=None):
    """
    Validates the user by calling the login and handling exceptions
    :param username: Username
    :param password: Password
    :param token: Two-factor authentication token
    :param error_message: Localized error message string to use on failure
    :return: Journalist user object if successful, None otherwise.
    """
    try:
        return Journalist.login(username, password, token)
    except (InvalidUsernameException, BadTokenException,
            WrongPasswordException, LoginThrottledException) as e:
        current_app.logger.error("Login for '{}' failed: {}".format(
            username, e))
        if not error_message:
            error_message = gettext('Login failed.')
        login_flashed_msg = error_message

        if isinstance(e, LoginThrottledException):
            login_flashed_msg += " "
            period = Journalist._LOGIN_ATTEMPT_PERIOD
            # ngettext is needed although we always have period > 1
            # see https://github.com/freedomofpress/securedrop/issues/2422
            login_flashed_msg += ngettext(
                "Please wait at least {seconds} second "
                "before logging in again.",
                "Please wait at least {seconds} seconds "
                "before logging in again.", period).format(seconds=period)
        else:
            try:
                user = Journalist.query.filter_by(username=username).one()
                if user.is_totp:
                    login_flashed_msg += " "
                    login_flashed_msg += gettext(
                        "Please wait for a new two-factor token"
                        " before trying again.")
            except:
                pass

        flash(login_flashed_msg, "error")
        return None
コード例 #10
0
    def setUp(self):
        common.shared_setup()

        # Patch the two-factor verification so it always succeeds
        patcher = patch('db.Journalist.verify_token')
        self.addCleanup(patcher.stop)
        self.mock_journalist_verify_token = patcher.start()
        self.mock_journalist_verify_token.return_value = True

        self.username = "******"
        self.password = "******"
        self.user = Journalist(
                username=self.username,
                password=self.password)
        db_session.add(self.user)
        db_session.commit()

        # Use a patched login function to avoid dealing with two-factor tokens
        # (which are being ignored here anyway)
        self.login = lambda username, password: \
                Journalist.login(username, password, "")