def test_should_return_404_when_email_address_does_not_exist(app_, mock_get_user_by_email_not_found):
    with app_.test_request_context():
        with app_.test_client() as client:
            data = json.dumps({'email': '*****@*****.**', 'created_at': str(datetime.utcnow())})
            token = generate_token(data, app_.config['SECRET_KEY'], app_.config['DANGEROUS_SALT'])
        response = client.get(url_for('.new_password', token=token))
        assert response.status_code == 404
def test_should_throw_exception_when_token_is_tampered_with():
    import uuid
    token = generate_token(str(uuid.uuid4()), 'secret-key', 'dangerous-salt')
    try:
        check_token(token + 'qerqwer', 'secret-key', 'dangerous-salt', 30)
        fail()
    except BadSignature:
        pass
def test_return_none_when_token_is_expired():
    max_age = -1000
    payload = 'some_payload'
    token = generate_token(payload, 'secret-key', 'dangerous-salt')
    try:
        assert check_token(token, 'secret-key', 'dangerous-salt', max_age) is None
        fail('Expected a SignatureExpired exception')
    except SignatureExpired:
        pass
def test_should_redirect_to_forgot_password_with_flash_message_when_token_is_expired(
        app_, mock_get_user_by_email_request_password_reset, mock_login
):
    with app_.test_request_context():
        with app_.test_client() as client:
            app_.config['TOKEN_MAX_AGE_SECONDS'] = -1000
            user = mock_get_user_by_email_request_password_reset.return_value
            token = generate_token(user.email_address, app_.config['SECRET_KEY'], app_.config['DANGEROUS_SALT'])
        response = client.post(url_for('.new_password', token=token), data={'new_password': '******'})
        assert response.status_code == 302
        assert response.location == url_for('.forgot_password', _external=True)
        app_.config['TOKEN_MAX_AGE_SECONDS'] = 3600
def test_should_render_new_password_template(app_,
                                             api_user_active,
                                             mock_login,
                                             mock_send_verify_code,
                                             mock_get_user_by_email_request_password_reset):
    with app_.test_request_context():
        with app_.test_client() as client:
            data = json.dumps({'email': api_user_active.email_address, 'created_at': str(datetime.utcnow())})
            token = generate_token(data, app_.config['SECRET_KEY'],
                                   app_.config['DANGEROUS_SALT'])
        response = client.get(url_for('.new_password', token=token))
        assert response.status_code == 200
        assert 'You can now create a new password for your account.' in response.get_data(as_text=True)
def test_should_redirect_index_if_user_has_already_changed_password(app_,
                                                                    mock_get_user_by_email_user_changed_password,
                                                                    mock_login,
                                                                    mock_send_verify_code):
    with app_.test_request_context():
        with app_.test_client() as client:
            user = mock_get_user_by_email_user_changed_password.return_value
            data = json.dumps({'email': user.email_address, 'created_at': str(datetime.utcnow())})
            token = generate_token(data, app_.config['SECRET_KEY'], app_.config['DANGEROUS_SALT'])
        response = client.post(url_for('.new_password', token=token), data={'new_password': '******'})
        assert response.status_code == 302
        assert response.location == url_for('.index', _external=True)
        mock_get_user_by_email_user_changed_password.assert_called_once_with(user.email_address)
def test_accept_invite_returns_400_when_invited_user_does_not_exist(notify_api):
    with notify_api.test_request_context():
        with notify_api.test_client() as client:
            token = generate_token(str(uuid.uuid4()), notify_api.config['SECRET_KEY'],
                                   notify_api.config['DANGEROUS_SALT'])
            url = '/invite/{}'.format(token)
            auth_header = create_authorization_header()
            response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])

            assert response.status_code == 404
            json_resp = json.loads(response.get_data(as_text=True))
            assert json_resp['result'] == 'error'
            assert json_resp['message'] == 'No result found'
def test_should_redirect_to_user_profile_when_user_confirms_email_link(app_,
                                                                       api_user_active,
                                                                       mock_login,
                                                                       mock_update_user_attribute
                                                                       ):
    with app_.test_request_context():
        with app_.test_client() as client:
            client.login(api_user_active)

        token = generate_token(payload=json.dumps({'user_id': api_user_active.id, 'email': '*****@*****.**'}),
                               secret=app_.config['SECRET_KEY'], salt=app_.config['DANGEROUS_SALT'])
        response = client.get(url_for('main.user_profile_email_confirm', token=token))

        assert response.status_code == 302
        assert response.location == url_for('main.user_profile', _external=True)
def test_accept_invite_for_expired_token_returns_400(notify_api, sample_invited_user):
    with notify_api.test_request_context():
        with notify_api.test_client() as client:
            with freeze_time('2016-01-01T12:00:00'):
                token = generate_token(str(sample_invited_user.id), notify_api.config['SECRET_KEY'],
                                       notify_api.config['DANGEROUS_SALT'])
        url = '/invite/{}'.format(token)
        auth_header = create_authorization_header()
        response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])

        assert response.status_code == 400
        json_resp = json.loads(response.get_data(as_text=True))
        assert json_resp['result'] == 'error'
        assert json_resp['message'] == {'invitation': [
            'Your invitation to GOV.UK Notify has expired. '
            'Please ask the person that invited you to send you another one']}
def test_accept_invite_returns_200_when_token_valid(notify_api, sample_invited_user):
    with notify_api.test_request_context():
        with notify_api.test_client() as client:
            token = generate_token(str(sample_invited_user.id), notify_api.config['SECRET_KEY'],
                                   notify_api.config['DANGEROUS_SALT'])
            url = '/invite/{}'.format(token)
            auth_header = create_authorization_header()
            response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])

            assert response.status_code == 200
            json_resp = json.loads(response.get_data(as_text=True))
            assert json_resp['data']['id'] == str(sample_invited_user.id)
            assert json_resp['data']['email_address'] == sample_invited_user.email_address
            assert json_resp['data']['from_user'] == str(sample_invited_user.user_id)
            assert json_resp['data']['service'] == str(sample_invited_user.service_id)
            assert json_resp['data']['status'] == sample_invited_user.status
            assert json_resp['data']['permissions'] == sample_invited_user.permissions
Example #11
0
def test_should_redirect_to_two_factor_when_password_reset_is_successful(
        app_, client, mock_get_user_by_email_request_password_reset,
        mock_login, mock_send_verify_code, mock_reset_failed_login_count):
    user = mock_get_user_by_email_request_password_reset.return_value
    data = json.dumps({
        'email': user.email_address,
        'created_at': str(datetime.utcnow())
    })
    token = generate_token(data, app_.config['SECRET_KEY'],
                           app_.config['DANGEROUS_SALT'])
    response = client.post(url_for_endpoint_with_token('.new_password',
                                                       token=token),
                           data={'new_password': '******'})
    assert response.status_code == 302
    assert response.location == url_for('.two_factor', _external=True)
    mock_get_user_by_email_request_password_reset.assert_called_once_with(
        user.email_address)
def test_validate_invitation_token_returns_400_when_token_is_malformed(client, invitation_type):
    token = generate_token(
        str(uuid.uuid4()),
        current_app.config['SECRET_KEY'],
        current_app.config['DANGEROUS_SALT']
    )[:-2]

    url = '/invite/{}/{}'.format(invitation_type, token)
    auth_header = create_authorization_header()
    response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])

    assert response.status_code == 400
    json_resp = json.loads(response.get_data(as_text=True))
    assert json_resp['result'] == 'error'
    assert json_resp['message'] == {
        'invitation': 'Something’s wrong with this link. Make sure you’ve copied the whole thing.'
    }
def test_should_redirect_index_if_user_has_already_changed_password(
        app_, client, mock_get_user_by_email_user_changed_password, mock_login,
        mock_send_verify_code, mock_reset_failed_login_count):
    user = mock_get_user_by_email_user_changed_password.return_value
    data = json.dumps({
        'email': user['email_address'],
        'created_at': str(datetime.utcnow())
    })
    token = generate_token(data, app_.config['SECRET_KEY'],
                           app_.config['DANGEROUS_SALT'])
    response = client.post(url_for_endpoint_with_token('.new_password',
                                                       token=token),
                           data={'new_password': '******'})
    assert response.status_code == 302
    assert response.location == url_for('.index', _external=True)
    mock_get_user_by_email_user_changed_password.assert_called_once_with(
        user['email_address'])
def test_validate_invitation_token_returns_400_when_token_is_malformed(
        client, invitation_type):
    token = generate_token(
        str(uuid.uuid4()),
        current_app.config["SECRET_KEY"],
        current_app.config["DANGEROUS_SALT"],
    )[:-2]

    url = "/invite/{}/{}".format(invitation_type, token)
    auth_header = create_authorization_header()
    response = client.get(url,
                          headers=[("Content-Type", "application/json"),
                                   auth_header])

    assert response.status_code == 400
    json_resp = json.loads(response.get_data(as_text=True))
    assert json_resp["result"] == "error"
    assert json_resp["message"] == {"invitation": "bad invitation link"}
Example #15
0
def test_should_render_new_password_template(
    app_,
    client,
    api_user_active,
    mock_login,
    mock_send_verify_code,
    mock_get_user_by_email_request_password_reset,
):
    data = json.dumps({
        'email': api_user_active.email_address,
        'created_at': str(datetime.utcnow())
    })
    token = generate_token(data, app_.config['SECRET_KEY'],
                           app_.config['DANGEROUS_SALT'])
    response = client.get(url_for('.new_password', token=token))
    assert response.status_code == 200
    assert 'You can now create a new password for your account.' in response.get_data(
        as_text=True)
def test_validate_invitation_token_for_expired_token_returns_400(
        client, invitation_type):
    with freeze_time("2016-01-01T12:00:00"):
        token = generate_token(
            str(uuid.uuid4()),
            current_app.config["SECRET_KEY"],
            current_app.config["DANGEROUS_SALT"],
        )
    url = "/invite/{}/{}".format(invitation_type, token)
    auth_header = create_authorization_header()
    response = client.get(url,
                          headers=[("Content-Type", "application/json"),
                                   auth_header])

    assert response.status_code == 400
    json_resp = json.loads(response.get_data(as_text=True))
    assert json_resp["result"] == "error"
    assert json_resp["message"] == {"invitation": "invitation expired"}
Example #17
0
def test_should_redirect_to_user_profile_when_user_confirms_email_link(
    app_,
    logged_in_client,
    api_user_active,
    mock_update_user_attribute,
):

    token = generate_token(payload=json.dumps({
        'user_id': api_user_active.id,
        'email': '*****@*****.**'
    }),
                           secret=app_.config['SECRET_KEY'],
                           salt=app_.config['DANGEROUS_SALT'])
    response = logged_in_client.get(
        url_for('main.user_profile_email_confirm', token=token))

    assert response.status_code == 302
    assert response.location == url_for('main.user_profile', _external=True)
Example #18
0
def test_validate_invitation_token_for_expired_token_returns_400(client):
    with freeze_time('2016-01-01T12:00:00'):
        token = generate_token(str(uuid.uuid4()),
                               current_app.config['SECRET_KEY'],
                               current_app.config['DANGEROUS_SALT'])
    url = '/invite/service/{}'.format(token)
    auth_header = create_authorization_header()
    response = client.get(url,
                          headers=[('Content-Type', 'application/json'),
                                   auth_header])

    assert response.status_code == 400
    json_resp = json.loads(response.get_data(as_text=True))
    assert json_resp['result'] == 'error'
    assert json_resp['message'] == {
        'invitation':
        'Your invitation to GOV.UK Notify has expired. '
        'Please ask the person that invited you to send you another one'
    }
Example #19
0
def test_should_render_new_password_template(
    app_,
    client,
    api_user_active,
    mock_login,
    mock_send_verify_code,
    mock_get_user_by_email_request_password_reset,
):
    data = json.dumps({
        "email": api_user_active["email_address"],
        "created_at": str(datetime.utcnow()),
    })
    token = generate_token(data, app_.config["SECRET_KEY"],
                           app_.config["DANGEROUS_SALT"])

    response = client.get(
        url_for_endpoint_with_token(".new_password", token=token))
    assert response.status_code == 200
    assert "You can now create a new password for your account." in response.get_data(
        as_text=True)
def test_should_redirect_to_user_profile_when_user_confirms_email_link(
    app_,
    logged_in_client,
    api_user_active,
    mock_update_user_attribute,
):

    token = generate_token(
        payload=json.dumps({
            "user_id": api_user_active["id"],
            "email": "*****@*****.**"
        }),
        secret=app_.config["SECRET_KEY"],
        salt=app_.config["DANGEROUS_SALT"],
    )
    response = logged_in_client.get(
        url_for_endpoint_with_token("main.user_profile_email_confirm",
                                    token=token))

    assert response.status_code == 302
    assert response.location == url_for("main.user_profile", _external=True)
def test_validate_invitation_token_returns_200_when_token_valid(
        client, invitation_type, sample_invited_user, sample_invited_org_user
):
    invited_user = sample_invited_user if invitation_type == 'service' else sample_invited_org_user

    token = generate_token(str(invited_user.id), current_app.config['SECRET_KEY'],
                           current_app.config['DANGEROUS_SALT'])
    url = '/invite/{}/{}'.format(invitation_type, token)
    auth_header = create_authorization_header()
    response = client.get(url, headers=[('Content-Type', 'application/json'), auth_header])

    assert response.status_code == 200
    json_resp = json.loads(response.get_data(as_text=True))
    if invitation_type == 'service':
        assert json_resp['data']['id'] == str(sample_invited_user.id)
        assert json_resp['data']['email_address'] == sample_invited_user.email_address
        assert json_resp['data']['from_user'] == str(sample_invited_user.user_id)
        assert json_resp['data']['service'] == str(sample_invited_user.service_id)
        assert json_resp['data']['status'] == sample_invited_user.status
        assert json_resp['data']['permissions'] == sample_invited_user.permissions
    if invitation_type == 'organisation':
        assert json_resp['data'] == sample_invited_org_user.serialize()
Example #22
0
def test_validate_invitation_token_returns_200_when_token_valid(
        client, sample_invited_user, endpoint_format_str):
    token = generate_token(str(sample_invited_user.id),
                           current_app.config['SECRET_KEY'],
                           current_app.config['DANGEROUS_SALT'])
    url = endpoint_format_str.format(token)
    auth_header = create_authorization_header()
    response = client.get(url,
                          headers=[('Content-Type', 'application/json'),
                                   auth_header])

    assert response.status_code == 200
    json_resp = json.loads(response.get_data(as_text=True))
    assert json_resp['data']['id'] == str(sample_invited_user.id)
    assert json_resp['data'][
        'email_address'] == sample_invited_user.email_address
    assert json_resp['data']['from_user'] == str(sample_invited_user.user_id)
    assert json_resp['data']['service'] == str(sample_invited_user.service_id)
    assert json_resp['data']['status'] == sample_invited_user.status
    assert json_resp['data']['permissions'] == sample_invited_user.permissions
    assert json_resp['data'][
        'folder_permissions'] == sample_invited_user.folder_permissions
Example #23
0
def test_should_redirect_index_if_user_has_already_changed_password(
    app_,
    client,
    mock_get_user_by_email_user_changed_password,
    mock_login,
    mock_send_verify_code,
    mock_reset_failed_login_count,
):
    user = mock_get_user_by_email_user_changed_password.return_value
    data = json.dumps({
        "email": user["email_address"],
        "created_at": str(datetime.utcnow())
    })
    token = generate_token(data, app_.config["SECRET_KEY"],
                           app_.config["DANGEROUS_SALT"])
    response = client.post(
        url_for_endpoint_with_token(".new_password", token=token),
        data={"new_password": "******"},
    )
    assert response.status_code == 302
    assert response.location == url_for(".index", _external=True)
    mock_get_user_by_email_user_changed_password.assert_called_once_with(
        user["email_address"])
Example #24
0
def test_should_sign_in_when_password_reset_is_successful_for_email_auth(
    app_,
    client,
    mock_get_user,
    mock_get_user_by_email_request_password_reset,
    mock_login,
    mock_send_verify_code,
    mock_reset_failed_login_count,
    mock_update_user_password,
    mock_get_login_events,
):
    user = mock_get_user_by_email_request_password_reset.return_value
    user["auth_type"] = "email_auth"
    data = json.dumps({
        "email": user["email_address"],
        "created_at": str(datetime.utcnow())
    })
    token = generate_token(data, app_.config["SECRET_KEY"],
                           app_.config["DANGEROUS_SALT"])

    response = client.post(
        url_for_endpoint_with_token(".new_password", token=token),
        data={"new_password": "******"},
    )

    assert response.status_code == 302
    assert response.location == url_for(".show_accounts_or_dashboard",
                                        _external=True)
    assert mock_get_user_by_email_request_password_reset.called
    assert mock_reset_failed_login_count.called

    # the log-in flow makes a couple of calls
    mock_get_user.assert_called_once_with(user["id"])
    mock_update_user_password.assert_called_once_with(user["id"],
                                                      "a-new_password")

    assert not mock_send_verify_code.called
Example #25
0
def url_with_token(data, url, config, base_url=None):
    from notifications_utils.url_safe_token import generate_token
    token = generate_token(data, config['SECRET_KEY'],
                           config['DANGEROUS_SALT'])
    base_url = (base_url or config['ADMIN_BASE_URL']) + url
    return base_url + token
def test_should_return_payload_from_signed_token():
    payload = '*****@*****.**'
    token = generate_token(payload, 'secret-key', 'dangerous-salt')
    assert payload == check_token(token, 'secret-key', 'dangerous-salt', 30)
Example #27
0
def url_with_token(data, url, config):
    from notifications_utils.url_safe_token import generate_token
    token = generate_token(data, config['SECRET_KEY'], config['DANGEROUS_SALT'])
    base_url = config['ADMIN_BASE_URL'] + url
    return base_url + token
Example #28
0
def test_should_return_payload_from_signed_token():
    payload = '*****@*****.**'
    token = generate_token(payload, 'secret-key', 'dangerous-salt')
    token = urllib.parse.unquote(token)
    assert payload == check_token(token, 'secret-key', 'dangerous-salt', 30)