Exemple #1
0
def test_get_userinfo_from_endpoint(app,
                                    example_keycloak_token,
                                    example_keycloak_userinfo,
                                    example_keycloak_realm_info):
    """Test the "/userinfo" mechanism when the "id_token" mechanism fails."""
    mock_keycloak(app.config,
                  example_keycloak_token,
                  example_keycloak_userinfo.data,
                  example_keycloak_realm_info)

    with app.test_client() as c:
        # ensure that remote apps have been loaded (before first request)
        c.get(url_for("invenio_oauthclient.login", remote_app="keycloak"))

        remote = app.extensions["oauthlib.client"].remote_apps["keycloak"]

        # the OAuthClient has to get its token from this call
        c.get(
            url_for(
                "invenio_oauthclient.authorized", remote_app="keycloak",
                code="test", state=get_state("keycloak")
            )
        )

        # force the endpoint mechanism by not providing a token
        user_info = get_user_info(remote, None)

        assert user_info is not None
        assert user_info == example_keycloak_userinfo.data
Exemple #2
0
def test_get_userinfo_from_token(app,
                                 example_keycloak_token,
                                 example_keycloak_userinfo,
                                 example_keycloak_realm_info):
    """Test the "id_token" extraction mechanism from Keycloak's response."""
    mock_keycloak(app.config,
                  example_keycloak_token,
                  dict(),
                  example_keycloak_realm_info)

    token = example_keycloak_token["id_token"]
    options = {"verify_signature": False}
    expected_result = jwt.decode(token, verify=False, options=options)

    with app.test_client() as c:
        # ensure that remote apps have been loaded (before first request)
        c.get(url_for("invenio_oauthclient.login", remote_app="keycloak"))
        remote = app.extensions["oauthlib.client"].remote_apps["keycloak"]

        # the OAuthClient has to get its token from this call
        c.get(
            url_for(
                "invenio_oauthclient.authorized", remote_app="keycloak",
                code="test", state=get_state("keycloak")
            )
        )

        user_info = get_user_info(remote, example_keycloak_token,
                                  fallback_to_endpoint=False,
                                  options={"verify_exp": False})

        assert user_info is not None
        assert user_info == expected_result
Exemple #3
0
def test_get_realm_key(app,
                       example_keycloak_token,
                       example_keycloak_userinfo,
                       example_keycloak_realm_info):
    """Test the mechanism for fetching the realm's public key."""
    mock_keycloak(app.config,
                  example_keycloak_token,
                  example_keycloak_userinfo.data,
                  example_keycloak_realm_info)
Exemple #4
0
def test_authorized_signup_valid_user(app_with_userprofiles,
                                      example_keycloak_token,
                                      example_keycloak_userinfo,
                                      example_keycloak_realm_info):
    """Test authorized callback with sign-up."""
    app = app_with_userprofiles
    example_keycloak = example_keycloak_userinfo.data

    with app.test_client() as c:
        # ensure that remote_apps have been initialized (before first request)
        resp = c.get(
            url_for("invenio_oauthclient.login", remote_app="keycloak")
        )
        assert resp.status_code == 302

        # mock a running keycloak instance
        mock_keycloak(app.config,
                      example_keycloak_token,
                      example_keycloak,
                      example_keycloak_realm_info)

        # user authorized the request and is redirected back
        resp = c.get(
            url_for(
                "invenio_oauthclient.authorized", remote_app="keycloak",
                code="test", state=get_state("keycloak")
            )
        )

        # note: because we provided an e-mail address in 'info_handler',
        #       the user does not need to sign up
        assert resp.status_code == 302
        assert resp.location == ("http://localhost/"
                                 "account/settings/linkedaccounts/")

        # check that the user exists
        user = User.query.filter_by(email=example_keycloak["email"]).one()
        assert user is not None
        assert user.email == example_keycloak["email"]
        assert user.profile.full_name == "Max Moser"
        assert user.active

        # check that the user has a linked Keycloak account
        uid = UserIdentity.query.filter_by(
            method="keycloak",
            id_user=user.id,
            id=example_keycloak["sub"]
        ).one()
        assert uid.user is user

        # disconnect the Keycloak account again
        resp = c.get(
            url_for("invenio_oauthclient.disconnect", remote_app="keycloak")
        )

        assert resp.status_code == 302

        # check that the user still exists
        user = User.query.filter_by(email=example_keycloak["email"]).one()
        assert user is not None

        # check that the Keycloak account has been unlinked
        count = UserIdentity.query.filter_by(
            method="keycloak",
            id_user=user.id,
            id=example_keycloak["sub"]
        ).count()
        assert count == 0
Exemple #5
0
def test_authorized_already_authenticated(app,
                                          models_fixture,
                                          example_keycloak_token,
                                          example_keycloak_userinfo,
                                          example_keycloak_realm_info):
    """Test authorized callback with sign-in."""
    datastore = app.extensions["invenio-accounts"].datastore
    login_manager = app.login_manager

    example_keycloak = example_keycloak_userinfo.data
    existing_mail = "*****@*****.**"
    user = datastore.find_user(email=existing_mail)

    @login_manager.user_loader
    def load_user(user_id):
        return user

    @app.route("/logmein")
    def login():
        login_user(user)
        return "Logged in"

    with app.test_client() as c:
        c.get("/logmein", follow_redirects=True)

        # ensure that remote apps have been loaded (before first request)
        c.get(url_for("invenio_oauthclient.login", remote_app="keycloak"))

        # mock a running keycloak instance
        mock_keycloak(app.config,
                      example_keycloak_token,
                      example_keycloak,
                      example_keycloak_realm_info)

        # user goes to 'linked accounts' and clicks 'connect' with Keycloak
        resp = c.get(
            url_for("invenio_oauthclient.login", remote_app="keycloak",
                    next="/someurl/")
        )

        assert resp.status_code == 302

        # the user logged in to Keycloak and authorized the request
        resp = c.get(
            url_for(
                "invenio_oauthclient.authorized", remote_app="keycloak",
                code="test", state=get_state("keycloak")
            )
        )

        # check if the Keycloak account has been linked to the user
        u = User.query.filter_by(email=existing_mail).one()
        UserIdentity.query.filter_by(
            method="keycloak",
            id_user=u.id,
            id=example_keycloak["sub"]
        ).one()

        # let the user hit the 'disconnect' button
        resp = c.get(
            url_for("invenio_oauthclient.disconnect", remote_app="keycloak")
        )
        assert resp.status_code == 302

        # check that the user still exists,
        # but the Keycloak account has been unlinked
        u = User.query.filter_by(email=existing_mail).one()
        count = UserIdentity.query.filter_by(
            method="keycloak",
            id_user=u.id,
            id=example_keycloak["sub"]
        ).count()
        assert count == 0