Skip to content

Commit

Permalink
oidc: adds group handler
Browse files Browse the repository at this point in the history
  • Loading branch information
jrcastro2 authored and kpsherva committed Jun 20, 2023
1 parent f6d2436 commit 1e792d5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 7 deletions.
32 changes: 27 additions & 5 deletions invenio.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,26 @@ SECURITY_SEND_REGISTER_EMAIL = False
# -------------------
# See https://github.com/inveniosoftware/invenio-oauthclient/blob/master/invenio_oauthclient/config.py
from invenio_oauthclient.contrib.keycloak import KeycloakSettingsHelper
from cds_rdm.oidc import cern_info_serializer, confirm_registration_form
from cds_rdm.oidc import (
cern_info_serializer,
confirm_registration_form,
cern_group_serializer,
cern_group_handler,
)
from urllib.parse import quote

_base_url = os.environ.get("CERN_KEYCLOAK_BASE_URL", "https://keycloak-qa.cern.ch/")

_keycloak_helper = KeycloakSettingsHelper(
title="CERN",
description="CERN SSO authentication",
base_url=os.environ.get("CERN_KEYCLOAK_BASE_URL", "https://keycloak-qa.cern.ch/"),
base_url=_base_url,
realm="cern",
app_key="CERN_APP_CREDENTIALS",
logout_url="{}auth/realms/cern/protocol/openid-connect/logout?redirect_uri={}".format(
_base_url,
quote(os.environ.get("INVENIO_SITE_UI_URL", SITE_UI_URL))
),
)
OAUTHCLIENT_CERN_REALM_URL = _keycloak_helper.realm_url
OAUTHCLIENT_CERN_USER_INFO_URL = _keycloak_helper.user_info_url
Expand All @@ -210,9 +222,19 @@ OAUTHCLIENT_CERN_VERIFY_AUD = False
OAUTHCLIENT_CERN_USER_INFO_FROM_ENDPOINT = False

handlers = _keycloak_helper.get_handlers()
handlers["signup_handler"]["info_serializer"] = cern_info_serializer
rest_handlers = _keycloak_helper.get_handlers()
rest_handlers["signup_handler"]["info_serializer"] = cern_info_serializer
handlers["signup_handler"] = {
**handlers["signup_handler"],
"info_serializer": cern_info_serializer,
"groups_serializer": cern_group_serializer,
"groups": cern_group_handler,
}
rest_handlers = _keycloak_helper.get_rest_handlers()
rest_handlers["signup_handler"] = {
**rest_handlers["signup_handler"],
"info_serializer": cern_info_serializer,
"groups_serializer": cern_group_serializer,
"groups": cern_group_handler,
}

OAUTHCLIENT_SIGNUP_FORM = confirm_registration_form

Expand Down
25 changes: 23 additions & 2 deletions site/cds_rdm/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,43 @@
from invenio_userprofiles.forms import confirm_register_form_preferences_factory
from flask import current_app
from werkzeug.local import LocalProxy
from invenio_oauthclient import current_oauthclient
from invenio_oauthclient.contrib.keycloak.handlers import get_user_info

_security = LocalProxy(lambda: current_app.extensions["security"])


def confirm_registration_form(*args, **kwargs):
Form = confirm_register_form_preferences_factory(_security.confirm_register_form)

class _Form(Form):
password = None
recaptcha = None
submit = None # defined in the template

return _Form(*args, **kwargs)


def cern_info_serializer(remote, resp, token_user_info, user_info):
def cern_group_serializer(remote, groups, **kwargs):
"""Serialize the groups response object."""
serialized_groups = []
# E-groups do have unique names and this name cannot be updated, therefore the name can act as an ID for invenio
for group_name in groups:
serialized_groups.append({"id": group_name, "name": group_name})

return serialized_groups


def cern_group_handler(remote, resp):
"""Retrieves groups from remote account."""
token_user_info, user_info = get_user_info(remote, resp)
groups = token_user_info.get("groups", [])
handlers = current_oauthclient.signup_handlers[remote.name]
# `remote` param automatically injected via `make_handler` helper
return handlers["groups_serializer"](groups)


def cern_info_serializer(remote, resp, token_user_info, user_info):
user_info = user_info or {} # prevent errors when accessing None.get(...)

email = token_user_info.get("email") or user_info["email"]
Expand All @@ -43,4 +65,3 @@ def cern_info_serializer(remote, resp, token_user_info, user_info):
"external_id": cern_upn,
"external_method": remote.name,
}

0 comments on commit 1e792d5

Please sign in to comment.