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
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
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)
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
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