def test_default_scope2claims(): assert scope2claims(["openid"]) == {"sub": None} assert set(scope2claims(["profile"]).keys()) == { "name", "given_name", "family_name", "middle_name", "nickname", "profile", "picture", "website", "gender", "birthdate", "zoneinfo", "locale", "updated_at", "preferred_username", } assert set(scope2claims(["email"]).keys()) == {"email", "email_verified"} assert set(scope2claims(["address"]).keys()) == {"address"} assert set(scope2claims(["phone"]).keys()) == { "phone_number", "phone_number_verified", } assert scope2claims(["offline_access"]) == {} assert scope2claims(["openid", "email", "phone"]) == { "sub": None, "email": None, "email_verified": None, "phone_number": None, "phone_number_verified": None, }
def test_custom_scopes(): custom_scopes = { "research_and_scholarship": [ "name", "given_name", "family_name", "email", "email_verified", "sub", "iss", "eduperson_scoped_affiliation", ] } _scopes = SCOPE2CLAIMS.copy() _scopes.update(custom_scopes) assert set(scope2claims(["email"], map=_scopes).keys()) == { "email", "email_verified", } assert set(scope2claims(["address"], map=_scopes).keys()) == {"address"} assert set(scope2claims(["phone"], map=_scopes).keys()) == { "phone_number", "phone_number_verified", } assert set(scope2claims(["research_and_scholarship"], map=_scopes).keys()) == { "name", "given_name", "family_name", "email", "email_verified", "sub", "iss", "eduperson_scoped_affiliation", }
def __call__(self, sid: str, uinfo: Dict, sinfo: Dict, *args, aud: Optional[Any], client_id: Optional[str], **kwargs): """ Return a token. :param sid: Session id :param uinfo: User information :param sinfo: Session information :param aud: The default audience == client_id :return: """ payload = {"sid": sid, "ttype": self.type, "sub": sinfo["sub"]} if self.add_claims: self.do_add_claims(payload, uinfo, self.add_claims) if self.add_claims_by_scope: self.do_add_claims( payload, uinfo, scope2claims(sinfo["authn_req"]["scope"], map=self.scope_claims_map).keys(), ) # Add claims if is access token if self.type == 'T' and self.enable_claims_per_client: client = self.cdb.get(client_id, {}) client_claims = client.get("access_token_claims") if client_claims: self.do_add_claims(payload, uinfo, client_claims) payload.update(kwargs) signer = JWT( key_jar=self.key_jar, iss=self.issuer, lifetime=self.lifetime, sign_alg=self.alg, ) if aud is None: _aud = self.def_aud else: _aud = aud if isinstance(aud, list) else [aud] _aud.extend(self.def_aud) return signer.pack(payload, aud=_aud)
def __call__(self, sid: str, uinfo: Dict, sinfo: Dict, *args, aud: Optional[Any], **kwargs): """ Return a token. :param sid: Session id :param uinfo: User information :param sinfo: Session information :param aud: The default audience == client_id :return: """ payload = {"sid": sid, "ttype": self.type, "sub": sinfo["sub"]} if "add_claims" in self.args: self.add_claims(payload, uinfo, self.args["add_claims"]) if self.args.get("add_claims_by_scope", False): self.add_claims( payload, uinfo, scope2claims(sinfo["authn_req"]["scope"], map=self.scope_claims_map).keys(), ) payload.update(kwargs) signer = JWT( key_jar=self.key_jar, iss=self.issuer, lifetime=self.lifetime, sign_alg=self.alg, ) if aud is None: _aud = self.def_aud else: _aud = aud if isinstance(aud, list) else [aud] _aud.extend(self.def_aud) return signer.pack(payload, aud=_aud)
def collect_user_info(endpoint_context, session, userinfo_claims=None, scope_to_claims=None): """ Collect information about a user. This can happen in two cases, either when constructing an IdToken or when returning user info through the UserInfo endpoint :param session: Session information :param userinfo_claims: user info claims :return: User info """ authn_req = session["authn_req"] if scope_to_claims is None: scope_to_claims = endpoint_context.scope2claims supported_scopes = [ s for s in authn_req["scope"] if s in endpoint_context.provider_info["scopes_supported"] ] if userinfo_claims is None: uic = scope2claims(supported_scopes, map=scope_to_claims) # Get only keys allowed by user and update the dict if such info # is stored in session perm_set = session.get("permission") if perm_set: uic = {key: uic[key] for key in uic if key in perm_set} uic = update_claims(session, "userinfo", provider_info=endpoint_context.provider_info, old_claims=uic) if uic: userinfo_claims = Claims(**uic) else: userinfo_claims = None logger.debug("userinfo_claim: %s" % sanitize(userinfo_claims.to_dict())) logger.debug("Session info: %s" % sanitize(session)) authn_event = session["authn_event"] if authn_event: uid = authn_event["uid"] else: uid = session["uid"] info = endpoint_context.userinfo(uid, authn_req["client_id"], userinfo_claims) if "sub" in userinfo_claims: if not claims_match(session["sub"], userinfo_claims["sub"]): raise FailedAuthentication("Unmatched sub claim") info["sub"] = session["sub"] try: logger.debug("user_info_response: {}".format(info)) except UnicodeEncodeError: logger.debug("user_info_response: {}".format(info.encode("utf-8"))) return info