Skip to content

Commit

Permalink
Merge pull request #635 from SUNET/lundberg_orcid_fix
Browse files Browse the repository at this point in the history
validate userinfo and handle missing "name"
  • Loading branch information
helylle authored May 28, 2024
2 parents e245444 + b803016 commit 833165f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/eduid/webapp/orcid/helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from enum import unique
from typing import Optional

from pydantic import BaseModel, Field

from eduid.common.models.generic import HttpUrlStr
from eduid.webapp.common.api.messages import TranslatableMsg


Expand All @@ -22,3 +26,11 @@ class OrcidMsg(TranslatableMsg):
sub_mismatch = "orc.sub_mismatch"
# ORCID proofing data saved for user
authz_success = "orc.authorization_success"


class OrcidUserinfo(BaseModel):
orcid: HttpUrlStr = Field(alias="id")
sub: str
name: Optional[str] = None
family_name: str
given_name: str
26 changes: 17 additions & 9 deletions src/eduid/webapp/orcid/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from flask import Blueprint, redirect, request, url_for
from oic.oic.message import AuthorizationResponse, Claims, ClaimsRequest
from pydantic import ValidationError
from werkzeug.wrappers import Response as WerkzeugResponse

from eduid.userdb.logs import OrcidProofing
Expand All @@ -13,7 +14,7 @@
from eduid.webapp.common.api.schemas.csrf import EmptyRequest
from eduid.webapp.common.api.utils import get_unique_hash, save_and_sync_user
from eduid.webapp.orcid.app import current_orcid_app as current_app
from eduid.webapp.orcid.helpers import OrcidMsg
from eduid.webapp.orcid.helpers import OrcidMsg, OrcidUserinfo
from eduid.webapp.orcid.schemas import OrcidResponseSchema

__author__ = "lundberg"
Expand Down Expand Up @@ -100,13 +101,20 @@ def authorization_response(user: User) -> WerkzeugResponse:

# do userinfo request
current_app.logger.debug("Trying to do userinfo request:")
userinfo = current_app.oidc_client.do_user_info_request(
userinfo_result = current_app.oidc_client.do_user_info_request(
method=current_app.conf.userinfo_endpoint_method, state=authn_resp["state"]
)
current_app.logger.debug(f"userinfo received: {userinfo!s}")
if userinfo["sub"] != id_token["sub"]:
current_app.logger.debug(f"userinfo received: {userinfo_result}")

try:
userinfo = OrcidUserinfo(**userinfo_result)
except ValidationError as e:
current_app.logger.error(f"Failed to parse userinfo: {e}")
return redirect_with_msg(redirect_url, OrcidMsg.authz_error)

if userinfo.sub != id_token["sub"]:
current_app.logger.error(
f"The 'sub' of userinfo does not match 'sub' of ID Token for user {proofing_state.eppn!s}."
f"The 'sub' of userinfo does not match 'sub' of ID Token for user {proofing_state.eppn}."
)
return redirect_with_msg(redirect_url, OrcidMsg.sub_mismatch)

Expand All @@ -132,10 +140,10 @@ def authorization_response(user: User) -> WerkzeugResponse:
created_by="orcid",
)
orcid_element = Orcid(
id=userinfo["id"],
name=userinfo["name"],
given_name=userinfo["given_name"],
family_name=userinfo["family_name"],
id=userinfo.orcid,
name=userinfo.name,
given_name=userinfo.given_name,
family_name=userinfo.family_name,
is_verified=True,
oidc_authz=oidc_authz,
created_by="orcid",
Expand Down

0 comments on commit 833165f

Please sign in to comment.