Exemplo n.º 1
0
def test_google_link_no_proxy_group(
    app,
    client,
    db_session,
    encoded_creds_jwt,
    add_new_g_acnt_mock,
    google_auth_get_user_info_mock,
    add_google_email_to_proxy_group_mock,
):
    user_id = encoded_creds_jwt["user_id"]

    test_auth_code = "abc123"
    redirect = "http://localhost"
    google_account = "*****@*****.**"

    test_session_jwt = create_session_token(
        app.keypairs[0],
        config.get("SESSION_TIMEOUT"),
        context={
            "google_link": True,
            "user_id": user_id,
            "google_proxy_group_id": None,  # <- no proxy group
            "redirect": redirect,
        },
    )

    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()

    # manually set cookie for initial session
    client.set_cookie("localhost",
                      config["SESSION_COOKIE_NAME"],
                      test_session_jwt,
                      httponly=True)

    # simulate successfully authed reponse with user email
    google_auth_get_user_info_mock.return_value = {"email": google_account}

    r = client.get("/link/google/callback",
                   query_string={"code": test_auth_code})

    assert not add_new_g_acnt_mock.called

    # make sure we're redirecting with error information
    parsed_url = urlparse(r.headers["Location"])
    query_params = parse_qs(parsed_url.query)
    response_redirect = urlunparse(
        (parsed_url.scheme, parsed_url.netloc, parsed_url.path, "", "", ""))
    assert "exp" not in query_params
    assert "linked_email" not in query_params
    assert "error" in query_params
    assert "error_description" in query_params
    assert response_redirect == redirect

    assert not flask.session.get("google_link")
    assert not flask.session.get("user_id")
    assert not flask.session.get("google_proxy_group_id")

    assert not add_google_email_to_proxy_group_mock.called
Exemplo n.º 2
0
def test_linked_user(db_session, test_user):

    user_google_account = UserGoogleAccount(
        id=1, email="*****@*****.**", user_id=1)
    db_session.add(user_google_account)
    db_session.commit()

    yield user_google_account
Exemplo n.º 3
0
def load_google_specific_user_data(db_session, test_user_d):
    """Add Google-specific user data to Fence db."""

    gpg = GoogleProxyGroup(id=userd_dict["gpg_id"],
                           email=userd_dict["gpg_email"])

    gsak = GoogleServiceAccountKey(
        id=userd_dict["gsak_id"],
        key_id=userd_dict["gsak_key_id"],
        service_account_id=userd_dict["gsa_id"],
    )
    gsa = GoogleServiceAccount(
        id=userd_dict["gsa_id"],
        google_unique_id="d_gui",
        user_id=userd_dict["user_id"],
        google_project_id="d_gpid",
        email=userd_dict["gsa_email"],
    )
    bkt = Bucket(id=userd_dict["bucket_id"])
    gbag = GoogleBucketAccessGroup(
        id=userd_dict["gbag_id"],
        bucket_id=userd_dict["bucket_id"],
        email=userd_dict["gbag_email"],
    )
    gpg_gbag = GoogleProxyGroupToGoogleBucketAccessGroup(
        id=userd_dict["gpg_to_gbag_id"],
        proxy_group_id=userd_dict["gpg_id"],
        access_group_id=userd_dict["gbag_id"],
    )
    uga = UserGoogleAccount(
        id=userd_dict["uga_id"],
        email=userd_dict["uga_email"],
        user_id=userd_dict["user_id"],
    )
    uga_pg = UserGoogleAccountToProxyGroup(
        user_google_account_id=userd_dict["uga_id"],
        proxy_group_id=userd_dict["gpg_id"])
    db_session.add_all([gpg, gsak, gsa, bkt, gbag, gpg_gbag, uga, uga_pg])

    user = (db_session.query(User).filter_by(
        username=userd_dict["user_username"]).first())
    user.google_proxy_group_id = userd_dict["gpg_id"]

    db_session.commit()
Exemplo n.º 4
0
def test_userinfo_extra_claims_get(app, client, oauth_client, db_session,
                                   encoded_creds_jwt):

    encoded_credentials_jwt = encoded_creds_jwt["jwt"]
    user_id = encoded_creds_jwt["user_id"]
    db_session.add(
        UserGoogleAccount(user_id=user_id, email="*****@*****.**"))
    db_session.commit()
    extra_claims = {"claims": {"userinfo": {"linked_google_account": None}}}

    resp = client.post(
        "/user",
        data=json.dumps(extra_claims),
        headers={"Authorization": "Bearer " + encoded_credentials_jwt},
    )

    assert resp.json["sub"]
    assert resp.json["name"]
    assert resp.json["linked_google_account"]
    assert resp.status_code == 200
Exemplo n.º 5
0
def test_google_id_token_linked(db_session, encoded_creds_jwt,
                                oauth_test_client):
    """
    Test google email and link expiration are in id_token for a linked account
    """
    user_id = encoded_creds_jwt["user_id"]
    proxy_group_id = encoded_creds_jwt["proxy_group_id"]

    original_expiration = 1000
    google_account = "*****@*****.**"

    # add google account and link
    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()
    g_account_access = UserGoogleAccountToProxyGroup(
        user_google_account_id=existing_account.id,
        proxy_group_id=proxy_group_id,
        expires=original_expiration,
    )
    db_session.add(g_account_access)
    db_session.commit()

    # get google account info with utility function
    assert get_linked_google_account_email(user_id) == google_account
    assert get_linked_google_account_exp(user_id) == original_expiration

    # get the id token through endpoint
    data = {"confirm": "yes"}
    oauth_test_client.authorize(data=data)
    tokens = oauth_test_client.token()
    id_token = jwt.decode(tokens.id_token, verify=False)

    assert "google" in id_token["context"]["user"]
    assert (id_token["context"]["user"]["google"].get("linked_google_account")
            == google_account)
    assert (id_token["context"]["user"]["google"].get(
        "linked_google_account_exp") == original_expiration)
Exemplo n.º 6
0
def add_new_user_google_account(user_id, google_email, session):
    user_google_account = UserGoogleAccount(email=google_email,
                                            user_id=user_id)
    session.add(user_google_account)
    session.commit()
    return user_google_account
Exemplo n.º 7
0
def test_google_link_g_account_exists_linked_to_different_user(
    app,
    client,
    db_session,
    encoded_creds_jwt,
    add_new_g_acnt_mock,
    google_auth_get_user_info_mock,
    add_google_email_to_proxy_group_mock,
):
    """
    Test the link endpoint that gets hit after authN when the provided Google
    account is already linked to a different user. We should not attempt to
    create a new user google account and just redirect with
    an error.
    """
    user_id = encoded_creds_jwt["user_id"]
    proxy_group_id = encoded_creds_jwt["proxy_group_id"]

    test_auth_code = "abc123"
    redirect = "http://localhost"
    google_account = "*****@*****.**"

    test_session_jwt = create_session_token(
        app.keypairs[0],
        config.get("SESSION_TIMEOUT"),
        context={
            "google_link": True,
            "user_id": user_id + 5,  # <- NOT the user whose g acnt exists
            "google_proxy_group_id": proxy_group_id,
            "redirect": redirect,
        },
    )

    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()

    # manually set cookie for initial session
    client.set_cookie("localhost", config["SESSION_COOKIE_NAME"],
                      test_session_jwt)

    # simulate successfully authed reponse with user email
    google_auth_get_user_info_mock.return_value = {"email": google_account}

    r = client.get("/link/google/callback",
                   query_string={"code": test_auth_code})

    assert not add_new_g_acnt_mock.called

    # make sure we're redirecting with error information
    parsed_url = urlparse(r.headers["Location"])
    query_params = parse_qs(parsed_url.query)
    response_redirect = urlunparse(
        (parsed_url.scheme, parsed_url.netloc, parsed_url.path, "", "", ""))
    response_redirect = urlunparse(
        (parsed_url.scheme, parsed_url.netloc, parsed_url.path, "", "", ""))
    assert "exp" not in query_params
    assert "linked_email" not in query_params
    assert "error" in query_params
    assert "error_description" in query_params
    assert response_redirect == redirect

    assert not flask.session.get("google_link")
    assert not flask.session.get("user_id")
    assert not flask.session.get("google_proxy_group_id")

    assert not add_google_email_to_proxy_group_mock.called
Exemplo n.º 8
0
def test_google_link_g_account_access_extension(
    app,
    client,
    db_session,
    encoded_creds_jwt,
    add_new_g_acnt_mock,
    google_auth_get_user_info_mock,
    add_google_email_to_proxy_group_mock,
):
    """
    Test the link endpoint that gets hit after authN when the provided Google
    account is already linked. This time test if we correctly extend the
    google accounts access.
    """
    user_id = encoded_creds_jwt["user_id"]
    proxy_group_id = encoded_creds_jwt["proxy_group_id"]

    original_expiration = 1000
    test_auth_code = "abc123"
    redirect = "http://localhost"
    google_account = "*****@*****.**"

    test_session_jwt = create_session_token(
        app.keypairs[0],
        config.get("SESSION_TIMEOUT"),
        context={
            "google_link": True,
            "user_id": user_id,
            "google_proxy_group_id": proxy_group_id,
            "redirect": redirect,
        },
    )

    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()
    g_account_access = UserGoogleAccountToProxyGroup(
        user_google_account_id=existing_account.id,
        proxy_group_id=proxy_group_id,
        expires=original_expiration,
    )
    db_session.add(g_account_access)
    db_session.commit()

    # manually set cookie for initial session
    client.set_cookie("localhost", config["SESSION_COOKIE_NAME"],
                      test_session_jwt)

    # simulate successfully authed reponse with user email
    google_auth_get_user_info_mock.return_value = {"email": google_account}

    r = client.get("/link/google/callback",
                   query_string={"code": test_auth_code})

    account_in_proxy_group = (
        db_session.query(UserGoogleAccountToProxyGroup).filter(
            UserGoogleAccountToProxyGroup.user_google_account_id ==
            existing_account.id).first())
    assert account_in_proxy_group.proxy_group_id == proxy_group_id

    # check that expiration changed and that it's less than the cfg
    # expires in (since this check will happen a few seconds after
    # it gets set)
    assert account_in_proxy_group.expires != original_expiration
    assert account_in_proxy_group.expires <= (
        int(time.time()) + config["GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN"])

    assert not add_new_g_acnt_mock.called
    assert r.status_code == 302

    parsed_url = urlparse(r.headers["Location"])
    query_params = parse_qs(parsed_url.query)
    response_redirect = urlunparse(
        (parsed_url.scheme, parsed_url.netloc, parsed_url.path, "", "", ""))
    assert "exp" in query_params
    assert query_params["linked_email"][0] == google_account
    assert response_redirect == redirect

    assert not flask.session.get("google_link")
    assert not flask.session.get("user_id")
    assert not flask.session.get("google_proxy_group_id")

    assert not add_google_email_to_proxy_group_mock.called
Exemplo n.º 9
0
def test_patch_google_link_account_not_in_token(
    app,
    client,
    db_session,
    encoded_creds_jwt,
    google_auth_get_user_info_mock,
    add_google_email_to_proxy_group_mock,
):
    """
    Test extending expiration for previously linked G account access via PATCH.

    This will test the case where the linking happened during the life
    of an access token and the same access token is used here (e.g.
    account exists but a new token hasn't been generated with the linkage
    info yet)
    """
    encoded_credentials_jwt = encoded_creds_jwt["jwt"]
    user_id = encoded_creds_jwt["user_id"]
    proxy_group_id = encoded_creds_jwt["proxy_group_id"]

    original_expiration = 1000
    google_account = "*****@*****.**"

    test_session_jwt = create_session_token(
        app.keypairs[0],
        config.get("SESSION_TIMEOUT"),
        context={"google_proxy_group_id": proxy_group_id},
    )

    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()
    g_account_access = UserGoogleAccountToProxyGroup(
        user_google_account_id=existing_account.id,
        proxy_group_id=proxy_group_id,
        expires=original_expiration,
    )
    db_session.add(g_account_access)
    db_session.commit()

    # manually set cookie for initial session
    client.set_cookie("localhost", config["SESSION_COOKIE_NAME"],
                      test_session_jwt)

    r = client.patch(
        "/link/google",
        headers={"Authorization": "Bearer " + encoded_credentials_jwt})

    assert r.status_code == 200

    account_in_proxy_group = (
        db_session.query(UserGoogleAccountToProxyGroup).filter(
            UserGoogleAccountToProxyGroup.user_google_account_id ==
            existing_account.id).first())
    assert account_in_proxy_group.proxy_group_id == proxy_group_id

    # check that expiration changed and that it's less than the cfg
    # expires in (since this check will happen a few seconds after
    # it gets set)
    assert account_in_proxy_group.expires != original_expiration
    assert account_in_proxy_group.expires <= (
        int(time.time()) + config["GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN"])

    assert not add_google_email_to_proxy_group_mock.called
Exemplo n.º 10
0
def test_patch_google_link(
    app,
    client,
    db_session,
    encoded_creds_jwt,
    google_auth_get_user_info_mock,
    add_google_email_to_proxy_group_mock,
):
    """
    Test extending expiration for previously linked G account access via PATCH.
    Test valid and invalid expires_in parameters.
    """
    encoded_credentials_jwt = encoded_creds_jwt["jwt"]
    user_id = encoded_creds_jwt["user_id"]
    proxy_group_id = encoded_creds_jwt["proxy_group_id"]

    original_expiration = 1000
    google_account = "*****@*****.**"

    test_session_jwt = create_session_token(
        app.keypairs[0],
        config.get("SESSION_TIMEOUT"),
        context={
            "google_proxy_group_id": proxy_group_id,
            "linked_google_email": google_account,
        },
    )

    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()
    g_account_access = UserGoogleAccountToProxyGroup(
        user_google_account_id=existing_account.id,
        proxy_group_id=proxy_group_id,
        expires=original_expiration,
    )
    db_session.add(g_account_access)
    db_session.commit()

    # manually set cookie for initial session
    client.set_cookie("localhost", config["SESSION_COOKIE_NAME"],
                      test_session_jwt)

    r = client.patch(
        "/link/google",
        headers={"Authorization": "Bearer " + encoded_credentials_jwt})

    assert r.status_code == 200

    account_in_proxy_group = (
        db_session.query(UserGoogleAccountToProxyGroup).filter(
            UserGoogleAccountToProxyGroup.user_google_account_id ==
            existing_account.id).first())
    assert account_in_proxy_group.proxy_group_id == proxy_group_id

    # check that expiration changed and that it's less than the cfg
    # expires in (since this check will happen a few seconds after
    # it gets set)
    updated_expiration = account_in_proxy_group.expires
    assert updated_expiration != original_expiration
    assert updated_expiration <= (int(time.time()) +
                                  config["GOOGLE_ACCOUNT_ACCESS_EXPIRES_IN"])

    assert not add_google_email_to_proxy_group_mock.called

    # invalid expires_in: should fail
    requested_exp = "abc"  # expires_in must be int >0
    r = client.patch(
        "/link/google?expires_in={}".format(requested_exp),
        headers={"Authorization": "Bearer " + encoded_credentials_jwt},
    )
    assert r.status_code == 400

    # valid expires_in: should succeed
    requested_exp = 60
    r = client.patch(
        "/link/google?expires_in={}".format(requested_exp),
        headers={"Authorization": "Bearer " + encoded_credentials_jwt},
    )
    assert r.status_code == 200

    account_in_proxy_group = (
        db_session.query(UserGoogleAccountToProxyGroup).filter(
            UserGoogleAccountToProxyGroup.user_google_account_id ==
            existing_account.id).first())
    # make sure the link is valid for the requested time
    # (allow up to 15 sec for runtime)
    diff = account_in_proxy_group.expires - int(time.time())
    assert requested_exp <= diff <= requested_exp + 15
Exemplo n.º 11
0
def test_google_link_g_account_exists(
    app,
    client,
    db_session,
    encoded_creds_jwt,
    add_new_g_acnt_mock,
    google_auth_get_user_info_mock,
    add_google_email_to_proxy_group_mock,
):
    """
    Test the link endpoint that gets hit after authN when the provided Google
    account is already linked. Make sure we don't attempt to create a new one
    and that we redirect with no errors
    """
    user_id = encoded_creds_jwt["user_id"]
    proxy_group_id = encoded_creds_jwt["proxy_group_id"]

    test_auth_code = "abc123"
    redirect = "http://localhost"
    google_account = "*****@*****.**"

    test_session_jwt = create_session_token(
        app.keypairs[0],
        config.get("SESSION_TIMEOUT"),
        context={
            "google_link": True,
            "user_id": user_id,
            "google_proxy_group_id": proxy_group_id,
            "redirect": redirect,
        },
    )

    existing_account = UserGoogleAccount(email=google_account, user_id=user_id)
    db_session.add(existing_account)
    db_session.commit()

    # manually set cookie for initial session
    client.set_cookie(
        "localhost",
        config["SESSION_COOKIE_NAME"],
        test_session_jwt,
        httponly=True,
        samesite="Lax",
    )

    # simulate successfully authed reponse with user email
    google_auth_get_user_info_mock.return_value = {"email": google_account}

    r = client.get("/link/google/callback", query_string={"code": test_auth_code})

    assert not add_new_g_acnt_mock.called
    assert r.status_code == 302

    parsed_url = urlparse(r.headers["Location"])
    query_params = parse_qs(parsed_url.query)
    response_redirect = urlunparse(
        (parsed_url.scheme, parsed_url.netloc, parsed_url.path, "", "", "")
    )
    assert "exp" in query_params
    assert query_params["linked_email"][0] == google_account
    assert response_redirect == redirect

    assert not flask.session.get("google_link")
    assert not flask.session.get("user_id")
    assert not flask.session.get("google_proxy_group_id")

    # check that we're adding the G account to the proxy group
    assert add_google_email_to_proxy_group_mock.called