コード例 #1
0
    def test_login_with_email_password_inactive_user(self):
        """Inactive user logging in with username and password."""

        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        full_name = 'Test user login'

        # Inactive user
        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name=full_name,
                has_consented=True,
                notes='Test test test',
                role_ids=[1],
                active=False,
                password=password,
                password_repeat=password,
                activation_url='https://activate.com/activate',
            ),
        )

        with pytest.raises(McAuthLoginException) as ex:
            login_with_email_password(db=db, email=email, password=password)

        # Make sure the error message explicitly states that login failed due to user not being active
        assert 'not active' in str(ex)
コード例 #2
0
    def test_send_password_reset_token(self):
        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        password_reset_link = 'http://password-reset.com/'

        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name='Test user login',
                has_consented=True,
                notes='Test test test',
                role_ids=[1],
                active=True,
                password=password,
                password_repeat=password,
                activation_url='',  # user is active, no need for activation URL
            ),
        )

        # Existing user
        send_password_reset_token(db=db,
                                  email=email,
                                  password_reset_link=password_reset_link)

        # Nonexisting user (call shouldn't fail because we don't want to reveal which users are in the system so we
        # pretend that we've sent the email)
        send_password_reset_token(db=db,
                                  email='*****@*****.**',
                                  password_reset_link=password_reset_link)
コード例 #3
0
    def test_login_with_api_key_inactive_user(self):
        """Inactive user logging in with API key."""

        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        full_name = 'Test user login'
        ip_address = '1.2.3.4'

        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name=full_name,
                notes='Test test test',
                role_ids=[1],
                active=False,
                password=password,
                password_repeat=password,
                activation_url='https://activate.com/activate',
            ),
        )

        user = user_info(db=db, email=email)
        assert user
        global_api_key = user.global_api_key()

        with pytest.raises(McAuthLoginException) as ex:
            login_with_api_key(db=db,
                               api_key=global_api_key,
                               ip_address=ip_address)

        # Make sure the error message explicitly states that login failed due to user not being active
        assert 'not active' in str(ex)
コード例 #4
0
    def test_regenerate_api_key(self):
        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        full_name = 'Test user login'
        ip_address = '1.2.3.4'

        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name=full_name,
                has_consented=True,
                notes='Test test test',
                role_ids=[1],
                active=True,
                password=password,
                password_repeat=password,
                activation_url='',  # user is active, no need for activation URL
            ),
        )

        # Get sample API keys
        user = login_with_email_password(db=db,
                                         email=email,
                                         password=password,
                                         ip_address=ip_address)
        assert user

        before_global_api_key = user.global_api_key()
        assert before_global_api_key

        before_per_ip_api_key = user.api_key_for_ip_address(
            ip_address=ip_address)
        assert before_per_ip_api_key

        assert before_global_api_key != before_per_ip_api_key

        # Regenerate API key, purge per-IP API keys
        regenerate_api_key(db=db, email=email)

        # Get sample API keys again
        user = login_with_email_password(db=db,
                                         email=email,
                                         password=password,
                                         ip_address=ip_address)
        assert user

        after_global_api_key = user.global_api_key()
        assert after_global_api_key

        after_per_ip_api_key = user.api_key_for_ip_address(
            ip_address=ip_address)
        assert after_per_ip_api_key

        # Make sure API keys are different
        assert before_global_api_key != after_global_api_key
        assert before_per_ip_api_key != after_per_ip_api_key
コード例 #5
0
def test_login_with_api_key():
    db = connect_to_db()

    email = '*****@*****.**'
    password = '******'
    full_name = 'Test user login'
    ip_address = '1.2.3.4'

    add_user(
        db=db,
        new_user=NewUser(
            email=email,
            full_name=full_name,
            notes='Test test test',
            role_ids=[1],
            active=True,
            password=password,
            password_repeat=password,
            activation_url='',  # user is active, no need for activation URL
        ),
    )

    # Get sample API keys
    user = login_with_email_password(db=db,
                                     email=email,
                                     password=password,
                                     ip_address=ip_address)
    assert user

    global_api_key = user.global_api_key()
    assert global_api_key

    per_ip_api_key = user.api_key_for_ip_address(ip_address=ip_address)
    assert per_ip_api_key

    assert global_api_key != per_ip_api_key

    # Non-existent API key
    with pytest.raises(McAuthLoginException):
        login_with_api_key(db=db,
                           api_key='Non-existent API key',
                           ip_address=ip_address)

    # Global API key
    user = login_with_api_key(db=db,
                              api_key=global_api_key,
                              ip_address=ip_address)
    assert user
    assert user.email() == email
    assert user.global_api_key() == global_api_key

    # Per-IP API key
    user = login_with_api_key(db=db,
                              api_key=per_ip_api_key,
                              ip_address=ip_address)
    assert user
    assert user.email() == email
コード例 #6
0
def test_all_users():
    db = connect_to_db()

    email = '*****@*****.**'
    full_name = 'Test user info'
    notes = 'Test test test'
    weekly_requests_limit = 123
    weekly_requested_items_limit = 456
    max_topic_stories = 789

    add_user(
        db=db,
        new_user=NewUser(
            email=email,
            full_name=full_name,
            has_consented=True,
            notes=notes,
            role_ids=[1],
            active=True,
            password='******',
            password_repeat='user_info',
            activation_url='',  # user is active, no need for activation URL
            resource_limits=Resources(
                weekly_requests=weekly_requests_limit,
                weekly_requested_items=weekly_requested_items_limit,
                max_topic_stories=max_topic_stories,
            ),
        ),
    )

    users = all_users(db=db)
    assert len(users) == 1

    user = users[0]
    assert isinstance(user, CurrentUser)
    assert user.user_id()
    assert user.email() == email
    assert user.full_name() == full_name
    assert user.notes() == notes
    assert user.resource_limits()
    assert user.resource_limits().weekly_requests() == weekly_requests_limit
    assert user.resource_limits().weekly_requested_items(
    ) == weekly_requested_items_limit
    assert user.resource_limits().max_topic_stories() == max_topic_stories
    assert user.active()
    assert user.has_consented()
    assert user.global_api_key()
    assert user.password_hash()
    assert user.has_role('admin')
コード例 #7
0
def test_login_with_email_password():
    db = connect_to_db()

    email = '*****@*****.**'
    password = '******'
    full_name = 'Test user login'

    add_user(
        db=db,
        new_user=NewUser(
            email=email,
            full_name=full_name,
            has_consented=True,
            notes='Test test test',
            role_ids=[1],
            active=True,
            password=password,
            password_repeat=password,
            activation_url='',  # user is active, no need for activation URL
        ),
    )

    # Successful login
    user = login_with_email_password(db=db, email=email, password=password)
    assert user
    assert isinstance(user, CurrentUser)
    assert user.email() == email
    assert user.full_name() == full_name

    # Unsuccessful login
    with pytest.raises(McAuthLoginException):
        login_with_email_password(db=db,
                                  email=email,
                                  password='******')

    # Subsequent login attempt after a failed one should be delayed by 1 second
    with pytest.raises(McAuthLoginException):
        login_with_email_password(db=db, email=email, password=password)

    # Successful login after waiting out the delay
    time.sleep(2)
    user = login_with_email_password(db=db, email=email, password=password)
    assert user
    assert isinstance(user, CurrentUser)
    assert user.email() == email
    assert user.full_name() == full_name
コード例 #8
0
    def test_send_user_activation_token(self):

        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        activation_url = 'http://activate.com/'
        subscribe_to_newsletter = True

        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name='Test user login',
                notes='Test test test',
                role_ids=[1],
                active=True,
                password=password,
                password_repeat=password,
                activation_url='',  # user is active, no need for activation URL
                subscribe_to_newsletter=subscribe_to_newsletter,
            ),
        )

        # Existing user
        send_user_activation_token(
            db=db,
            email=email,
            activation_link=activation_url,
            subscribe_to_newsletter=subscribe_to_newsletter,
        )

        # Nonexistent user (call shouldn't fail because we don't want to reveal which users are in the system so we
        # pretend that we've sent the email)
        send_user_activation_token(
            db=db,
            email='*****@*****.**',
            activation_link=activation_url,
            subscribe_to_newsletter=subscribe_to_newsletter,
        )
コード例 #9
0
def test_user_info():
    db = connect_to_db()

    email = '*****@*****.**'
    full_name = 'Test user info'
    notes = 'Test test test'
    weekly_requests_limit = 123
    weekly_requested_items_limit = 456

    add_user(
        db=db,
        new_user=NewUser(
            email=email,
            full_name=full_name,
            notes=notes,
            role_ids=[1],
            active=True,
            password='******',
            password_repeat='user_info',
            activation_url='',  # user is active, no need for activation URL
            weekly_requests_limit=weekly_requests_limit,
            weekly_requested_items_limit=weekly_requested_items_limit,
        ),
    )

    user = user_info(db=db, email=email)

    assert isinstance(user, CurrentUser)
    assert user.email() == email
    assert user.full_name() == full_name
    assert user.notes() == notes
    assert user.weekly_requests_limit() == weekly_requests_limit
    assert user.weekly_requested_items_limit() == weekly_requested_items_limit
    assert user.active()
    assert user.created_date()
    assert __looks_like_iso8601_date(user.created_date())
    assert user.global_api_key()
    assert user.password_hash()
    assert user.has_role('admin')
コード例 #10
0
    def test_add_user(self):
        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        full_name = 'Test user login'

        new_user = NewUser(
            email=email,
            full_name=full_name,
            has_consented=True,
            notes='Test test test',
            role_ids=[1],
            active=True,
            password=password,
            password_repeat=password,
            activation_url='',  # user is active, no need for activation URL
        )

        # Add user
        add_user(db=db, new_user=new_user)

        # Test logging in
        user = login_with_email_password(db=db, email=email, password=password)
        assert user
        assert isinstance(user, CurrentUser)
        assert user.email() == email
        assert user.full_name() == full_name

        # Faulty input
        with pytest.raises(McAuthRegisterException):
            # noinspection PyTypeChecker
            add_user(db=db, new_user=None)

        # Existing user
        with pytest.raises(McAuthRegisterException):
            add_user(db=db, new_user=new_user)

        # Existing user with uppercase email
        with pytest.raises(McAuthRegisterException):
            add_user(
                db=db,
                new_user=NewUser(
                    email=email.upper(),
                    full_name=full_name,
                    has_consented=True,
                    notes='Test test test',
                    role_ids=[1],
                    active=True,
                    password=password,
                    password_repeat=password,
                    activation_url=
                    '',  # user is active, no need for activation URL
                ),
            )

        # Invalid password
        with pytest.raises(McAuthUserException):
            add_user(
                db=db,
                new_user=NewUser(
                    email='*****@*****.**',
                    full_name=full_name,
                    has_consented=True,
                    notes='Test test test',
                    role_ids=[1],
                    active=True,
                    password='******',
                    password_repeat='def',
                    activation_url=
                    '',  # user is active, no need for activation URL
                ),
            )

        # Nonexistent roles
        with pytest.raises(McAuthRegisterException):
            add_user(
                db=db,
                new_user=NewUser(
                    email='*****@*****.**',
                    full_name=full_name,
                    has_consented=True,
                    notes='Test test test',
                    role_ids=[42],
                    active=True,
                    password=password,
                    password_repeat=password,
                    activation_url=
                    '',  # user is active, no need for activation URL
                ),
            )

        # Both the user is set as active and the activation URL is set
        with pytest.raises(McAuthUserException):
            add_user(
                db=db,
                new_user=NewUser(
                    email='*****@*****.**',
                    full_name=full_name,
                    has_consented=True,
                    notes='Test test test',
                    role_ids=[1],
                    active=True,
                    password=password,
                    password_repeat=password,
                    activation_url='https://activate-user.com/activate',
                ),
            )

        # User is neither active not the activation URL is set
        with pytest.raises(McAuthUserException):
            add_user(
                db=db,
                new_user=NewUser(
                    email='*****@*****.**',
                    full_name=full_name,
                    has_consented=True,
                    notes='Test test test',
                    role_ids=[1],
                    active=False,
                    password=password,
                    password_repeat=password,
                    activation_url='',
                ),
            )
コード例 #11
0
    def test_change_password_with_reset_token(self):
        # FIXME test changing password for user A using reset token from user B

        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        full_name = 'Test user login'

        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name=full_name,
                notes='Test test test',
                role_ids=[1],
                active=True,
                password=password,
                password_repeat=password,
                activation_url='',  # user is active, no need for activation URL
            ),
        )

        # Successful login
        user = login_with_email_password(db=db, email=email, password=password)
        assert user
        assert isinstance(user, CurrentUser)
        assert user.email() == email
        assert user.full_name() == full_name

        # Make sure password reset token is not set
        password_reset_token_hash = db.query("""
            SELECT password_reset_token_hash
            FROM auth_users
            WHERE email = %(email)s
        """, {'email': email}).flat()
        assert password_reset_token_hash[0] is None

        # Send password reset link
        password_reset_url = 'https://reset-password.com/reset'
        final_password_reset_url = _generate_password_reset_token(
            db=db,
            email=email,
            password_reset_link=password_reset_url,
        )
        assert final_password_reset_url
        assert password_reset_url in final_password_reset_url

        final_password_reset_uri = furl(final_password_reset_url)
        assert final_password_reset_uri.args['email']
        assert final_password_reset_uri.args['password_reset_token']

        # Make sure password reset token is set
        password_reset_token_hash = db.query("""
            SELECT password_reset_token_hash
            FROM auth_users
            WHERE email = %(email)s
        """, {'email': email}).flat()
        assert password_reset_token_hash[0] is not None

        # Change password
        new_password = '******'
        change_password_with_reset_token(
            db=db,
            email=email,
            password_reset_token=final_password_reset_uri.args['password_reset_token'],
            new_password=new_password,
            new_password_repeat=new_password,
        )

        # Make sure password reset token has been reset after changing password
        password_reset_token_hash = db.query("""
            SELECT password_reset_token_hash
            FROM auth_users
            WHERE email = %(email)s
        """, {'email': email}).flat()
        assert password_reset_token_hash[0] is None

        # Unsuccessful login with old password
        with pytest.raises(McAuthLoginException):
            login_with_email_password(db=db, email=email, password=password)

        # Imposed delay after unsuccessful login
        time.sleep(2)

        # Successful login with new password
        user = login_with_email_password(db=db, email=email, password=new_password)
        assert user
        assert isinstance(user, CurrentUser)
        assert user.email() == email
        assert user.full_name() == full_name

        # Incorrect password reset token
        _generate_password_reset_token(
            db=db,
            email=email,
            password_reset_link=password_reset_url,
        )
        with pytest.raises(McAuthChangePasswordException):
            change_password_with_reset_token(
                db=db,
                email=email,
                password_reset_token='incorrect password reset token',
                new_password=new_password,
                new_password_repeat=new_password,
            )

        # Changing for nonexistent user
        final_password_reset_url = _generate_password_reset_token(
            db=db,
            email=email,
            password_reset_link=password_reset_url,
        )
        with pytest.raises(McAuthChangePasswordException):
            change_password_with_reset_token(
                db=db,
                email='*****@*****.**',
                password_reset_token=furl(final_password_reset_url).args['password_reset_token'],
                new_password=new_password,
                new_password_repeat=new_password,
            )

        # Passwords don't match
        final_password_reset_url = _generate_password_reset_token(
            db=db,
            email=email,
            password_reset_link=password_reset_url,
        )
        with pytest.raises(McAuthChangePasswordException):
            change_password_with_reset_token(
                db=db,
                email=email,
                password_reset_token=furl(final_password_reset_url).args['password_reset_token'],
                new_password='******',
                new_password_repeat='not match',
            )
コード例 #12
0
def test_change_password():
    db = connect_to_db()

    email = '*****@*****.**'
    password = '******'
    full_name = 'Test user login'

    add_user(
        db=db,
        new_user=NewUser(
            email=email,
            full_name=full_name,
            has_consented=True,
            notes='Test test test',
            role_ids=[1],
            active=True,
            password=password,
            password_repeat=password,
            activation_url='',  # user is active, no need for activation URL
        ),
    )

    # Successful login
    user = login_with_email_password(db=db, email=email, password=password)
    assert user
    assert isinstance(user, CurrentUser)
    assert user.email() == email
    assert user.full_name() == full_name

    # Change password
    new_password = '******'
    change_password(
        db=db,
        email=email,
        new_password=new_password,
        new_password_repeat=new_password,
        do_not_inform_via_email=True,
    )

    # Unsuccessful login with old password
    with pytest.raises(McAuthLoginException):
        login_with_email_password(db=db, email=email, password=password)

    # Imposed delay after unsuccessful login
    time.sleep(2)

    # Successful login with new password
    user = login_with_email_password(db=db, email=email, password=new_password)
    assert user
    assert isinstance(user, CurrentUser)
    assert user.email() == email
    assert user.full_name() == full_name

    # Changing for nonexistent user
    with pytest.raises(McAuthChangePasswordException):
        change_password(
            db=db,
            email='*****@*****.**',
            new_password=new_password,
            new_password_repeat=new_password,
            do_not_inform_via_email=True,
        )

    # Passwords don't match
    with pytest.raises(McAuthChangePasswordException):
        change_password(
            db=db,
            email=email,
            new_password='******',
            new_password_repeat='not match',
            do_not_inform_via_email=True,
        )
コード例 #13
0
    def test_activate_user_via_token(self):
        db = connect_to_db()

        email = '*****@*****.**'
        password = '******'
        full_name = 'Test user login'
        activation_url = 'https://activate.com/activate'

        # Add inactive user
        add_user(
            db=db,
            new_user=NewUser(
                email=email,
                full_name=full_name,
                notes='Test test test',
                role_ids=[1],
                active=False,  # not active, needs to be activated
                password=password,
                password_repeat=password,
                activation_url=activation_url,
            ),
        )

        # Test logging in
        with pytest.raises(McAuthLoginException) as ex:
            login_with_email_password(db=db, email=email, password=password)

        # Make sure the error message explicitly states that login failed due to user not being active
        assert 'not active' in str(ex)

        # Make sure activation token is set
        activation_token_hash = db.query(
            """
            SELECT password_reset_token_hash
            FROM auth_users
            WHERE email = %(email)s
        """, {
                'email': email
            }).flat()
        assert activation_token_hash
        assert len(activation_token_hash) == 1
        assert len(activation_token_hash[0]) > 0

        # Send password reset link
        final_activation_url = _generate_user_activation_token(
            db=db,
            email=email,
            activation_link=activation_url,
        )
        final_activation_uri = furl(final_activation_url)
        assert final_activation_uri.args['email']

        activation_token = final_activation_uri.args['activation_token']
        assert activation_token

        # Make sure activation token is (still) set
        activation_token_hash = db.query(
            """
            SELECT password_reset_token_hash
            FROM auth_users
            WHERE email = %(email)s
        """, {
                'email': email
            }).flat()
        assert activation_token_hash
        assert len(activation_token_hash) == 1
        assert len(activation_token_hash[0]) > 0

        # Activate user
        activate_user_via_token(db=db,
                                email=email,
                                activation_token=activation_token)

        # Imposed delay after unsuccessful login
        time.sleep(2)

        # Test logging in
        user = login_with_email_password(db=db, email=email, password=password)
        assert user
        assert isinstance(user, CurrentUser)
        assert user.email() == email
        assert user.full_name() == full_name

        # Make sure activation token is not set anymore
        activation_token_hash = db.query(
            """
            SELECT password_reset_token_hash
            FROM auth_users
            WHERE email = %(email)s
        """, {
                'email': email
            }).flat()
        assert activation_token_hash
        assert len(activation_token_hash) == 1
        assert activation_token_hash[0] is None

        # Incorrect activation token
        _generate_user_activation_token(db=db,
                                        email=email,
                                        activation_link=activation_url)
        with pytest.raises(McAuthRegisterException):
            activate_user_via_token(
                db=db,
                email=email,
                activation_token='incorrect activation token')

        # Activating nonexistent user
        final_activation_url = _generate_user_activation_token(
            db=db,
            email=email,
            activation_link=activation_url,
        )
        final_activation_uri = furl(final_activation_url)
        activation_token = final_activation_uri.args['activation_token']
        with pytest.raises(McAuthRegisterException):
            activate_user_via_token(db=db,
                                    email='*****@*****.**',
                                    activation_token=activation_token)
コード例 #14
0
ファイル: register.py プロジェクト: rleir/mediacloud
def add_user(db: DatabaseHandler, new_user: NewUser) -> None:
    """Add new user."""

    if not new_user:
        raise McAuthRegisterException("New user is undefined.")

    # Check if user already exists
    user_exists = db.query(
        """
        SELECT auth_users_id
        FROM auth_users
        WHERE email = %(email)s
        LIMIT 1
    """, {
            'email': new_user.email()
        }).hash()

    if user_exists is not None and 'auth_users_id' in user_exists:
        raise McAuthRegisterException("User with email '%s' already exists." %
                                      new_user.email())

    # Hash + validate the password
    try:
        password_hash = generate_secure_hash(password=new_user.password())
        if not password_hash:
            raise McAuthRegisterException("Password hash is empty.")
    except Exception as ex:
        log.error("Unable to hash a new password: {}".format(ex))
        raise McAuthRegisterException('Unable to hash a new password.')

    db.begin()

    # Create the user
    db.create(table='auth_users',
              insert_hash={
                  'email': new_user.email(),
                  'password_hash': password_hash,
                  'full_name': new_user.full_name(),
                  'notes': new_user.notes(),
                  'active': bool(int(new_user.active())),
              })

    # Fetch the user's ID
    try:
        user = user_info(db=db, email=new_user.email())
    except Exception as ex:
        db.rollback()
        raise McAuthRegisterException(
            "I've attempted to create the user but it doesn't exist: %s" %
            str(ex))

    # Create roles
    try:
        for auth_roles_id in new_user.role_ids():
            db.create(table='auth_users_roles_map',
                      insert_hash={
                          'auth_users_id': user.user_id(),
                          'auth_roles_id': auth_roles_id,
                      })
    except Exception as ex:
        raise McAuthRegisterException("Unable to create roles: %s" % str(ex))

    # Update limits (if they're defined)
    if new_user.weekly_requests_limit() is not None:
        db.query(
            """
            UPDATE auth_user_limits
            SET weekly_requests_limit = %(weekly_requests_limit)s
            WHERE auth_users_id = %(auth_users_id)s
        """, {
                'auth_users_id': user.user_id(),
                'weekly_requests_limit': new_user.weekly_requests_limit(),
            })

    if new_user.weekly_requested_items_limit() is not None:
        db.query(
            """
            UPDATE auth_user_limits
            SET weekly_requested_items_limit = %(weekly_requested_items_limit)s
            WHERE auth_users_id = %(auth_users_id)s
        """, {
                'auth_users_id':
                user.user_id(),
                'weekly_requested_items_limit':
                new_user.weekly_requested_items_limit(),
            })

    # Subscribe to newsletter
    if new_user.subscribe_to_newsletter():
        db.create(table='auth_users_subscribe_to_newsletter',
                  insert_hash={'auth_users_id': user.user_id()})

    if not new_user.active():
        send_user_activation_token(
            db=db,
            email=new_user.email(),
            activation_link=new_user.activation_url(),
            subscribe_to_newsletter=new_user.subscribe_to_newsletter(),
        )

    db.commit()