Exemple #1
0
def test_delete_all_failed_login_attempts_by_user(db, user):
    """Delete all failed login attempts for a specific user."""
    failed_login_attempt = FailedLoginAttempt(user.email, '127.0.0.1')
    failed_login_attempt.save()
    other_failed_login_attempt = FailedLoginAttempt('foo', '127.0.0.1')
    other_failed_login_attempt.save()

    FailedLoginAttempt.delete_all_by_user(user)
    db.session.commit()
    attempts = FailedLoginAttempt.query.all()
    assert failed_login_attempt not in attempts
    assert [other_failed_login_attempt] == attempts
Exemple #2
0
def test_get_all_failed_login_attempts_by_user(db, user):
    """Get all failed login attempts for a specific user."""
    failed_login_attempt = FailedLoginAttempt(user.email, '127.0.0.1')
    failed_login_attempt.save()
    other_failed_login_attempt = FailedLoginAttempt('foo', '127.0.0.1')
    other_failed_login_attempt.save()

    attempts = FailedLoginAttempt.get_all_by_user(user)
    assert other_failed_login_attempt not in attempts
    assert [failed_login_attempt] == attempts
Exemple #3
0
def test_login_attempt_purge():
    """Test purging login attempts for username/IP combo."""
    foo_login_attempt = FailedLoginAttempt('foo', '127.0.0.1')
    foo_login_attempt.save()
    bar_login_attempt = FailedLoginAttempt('bar', '127.0.0.1')
    bar_login_attempt.save()

    attempts = FailedLoginAttempt.query.all()
    assert len(attempts) == 2

    FailedLoginAttempt.purge_failed_for_username_and_ip('foo', '127.0.0.1')

    attempts = FailedLoginAttempt.query.all()
    assert len(attempts) == 1
    assert bar_login_attempt in attempts
Exemple #4
0
def test_login_attempt_repr():
    """Check repr output."""
    FailedLoginAttempt('foo', '127.0.0.1').save()

    attempt = FailedLoginAttempt.query.first()
    repr = '<FailedLoginAttempt({id}:{username!r})>'
    assert attempt.__repr__() == repr.format(id=attempt.id, username=attempt.username)
Exemple #5
0
def forget_user(email, dry_run):
    """Remove all traces of a user from the system."""
    user = User.get_by_email(email)
    if user:
        if user.is_admin:
            click.echo('User "{}" is a sysadmin, refusing to delete.'.format(user))
            sys.exit(1)

        if len(User.get_modified_and_created_by_user(user)) > 0:
            click.echo('User "{}" has created or modified users, refusing to delete.'.format(user))
            sys.exit(1)

        if len(Collection.get_modified_and_created_by_user(user)) > 0:
            click.echo('User "{}" has created or modified collections, '
                       'refusing to delete.'.format(user))
            sys.exit(1)

        if len(Permission.get_modified_and_created_by_user(user)) > 0:
            click.echo('User "{}" has created or modified permissions, '
                       'refusing to delete.'.format(user))
            sys.exit(1)

        if dry_run:
            tokens = Token.get_all_by_user(user)
            grants = Grant.get_all_by_user(user)
            failed_login_attempts = FailedLoginAttempt.get_all_by_user(user)
            permissions = user.permissions
            password_resets = user.password_resets
            click.echo('These tokens would be deleted: {}'.format(tokens))
            click.echo('These grants would be deleted: {}'.format(grants))
            click.echo('These failed login attempts would be deleted: {}'.format(
                failed_login_attempts))
            click.echo('These permissions would be deleted: {}'.format(permissions))
            click.echo('These password_resets would be deleted: {}'.format(password_resets))
        else:
            if click.confirm('Are you sure you want to delete all information '
                             'related to user "{}"?'.format(user)):
                Token.delete_all_by_user(user)
                Grant.delete_all_by_user(user)
                Permission.delete_all_by_user(user)
                PasswordReset.delete_all_by_user(user)
                FailedLoginAttempt.delete_all_by_user(user)
                user.delete()

    else:
        click.echo('User "{}" not found. Aborting...'.format(email))
        sys.exit(1)
Exemple #6
0
def test_login_attempt_too_many_recent_failures(app):
    """Ensure login attempt is not allowed after too many failed attempts."""
    username = '******'
    remote_addr = '127.0.0.1'
    app.config['XL_AUTH_FAILED_LOGIN_MAX_ATTEMPTS'] = 1
    app.config['XL_AUTH_FAILED_LOGIN_TIMEFRAME'] = 5 * 60

    assert FailedLoginAttempt.too_many_recent_failures_for(username) is False

    login_attempt = FailedLoginAttempt(username, remote_addr)
    login_attempt.save()

    assert FailedLoginAttempt.too_many_recent_failures_for(username) is True

    login_attempt.created_at = datetime.utcnow() - timedelta(seconds=10 * 60)
    login_attempt.save()

    assert FailedLoginAttempt.too_many_recent_failures_for(username) is False
def test_block_login_on_too_many_failed_attempts(user, testapp):
    """Temporarily block login if too many failed attempts."""
    current_app.config['XL_AUTH_FAILED_LOGIN_MAX_ATTEMPTS'] = 1
    # Goes to homepage.
    res = testapp.get('/')
    # Fills out login form, password incorrect.
    form = res.forms['loginForm']
    form['username'] = user.email
    form['password'] = '******'
    # Submits.
    res = form.submit()
    # Sees error.
    assert _('Invalid password') in res

    # Goes to homepage a second time.
    res = testapp.get('/')
    # Fills out login form, password incorrect.
    form = res.forms['loginForm']
    form['username'] = user.email
    form['password'] = '******'
    # Submits and sees error.
    res = form.submit(expect_errors=True)
    assert res.status_code == 429

    # Also traceable in Nginx logs:
    assert res.headers['X-Username'] == user.email

    FailedLoginAttempt.purge_failed_for_username_and_ip(
        user.email, '127.0.0.1')

    # Goes to homepage a third time.
    res = testapp.get('/')
    # Fills out login form, password incorrect.
    form = res.forms['loginForm']
    form['username'] = user.email
    form['password'] = '******'
    # Submits.
    res = form.submit().follow()
    assert res.status_code == 200
Exemple #8
0
def test_login_attempt_purge(superuser):
    """Test purging login attempts for username/IP combo."""
    user = User('*****@*****.**', 'Foo fooson')
    user.save_as(superuser)

    foo_login_attempt = FailedLoginAttempt('*****@*****.**', '127.0.0.1')
    foo_login_attempt.save()
    bar_login_attempt = FailedLoginAttempt('bar', '127.0.0.1')
    bar_login_attempt.save()

    attempts = FailedLoginAttempt.query.all()
    assert len(attempts) == 2
    user.update_last_login_internal(commit=True, remote_address='127.0.0.1')

    attempts = FailedLoginAttempt.query.all()
    assert len(attempts) == 1
    assert bar_login_attempt in attempts