def process_request(self, request=None, **kwargs): _sdb = self.endpoint_context.sdb # should be an access token if not _sdb.is_token_valid(request["access_token"]): return self.error_cls(error="invalid_token", error_description="Invalid Token") session = _sdb.read(request["access_token"]) allowed = True # if the authenticate is still active or offline_access is granted. if session["authn_event"]["valid_until"] > time_sans_frac(): pass else: if "offline_access" in session["authn_req"]["scope"]: pass else: allowed = False if allowed: # Scope can translate to userinfo_claims info = collect_user_info(self.endpoint_context, session) else: info = { "error": "invalid_request", "error_description": "Offline access not granted", } return { "response_args": info, "client_id": session["authn_req"]["client_id"] }
def make(self, req, sess_info, authn_req=None, user_claims=False, **kwargs): _context = self.endpoint_context _sdb = _context.sdb if authn_req: _client_id = authn_req["client_id"] else: _client_id = req["client_id"] _cinfo = _context.cdb[_client_id] try: default_idtoken_claims = self.kwargs["default_claims"] except KeyError: default_idtoken_claims = None lifetime = self.kwargs.get("lifetime") userinfo = userinfo_in_id_token_claims(_context, sess_info, default_idtoken_claims) if user_claims: info = collect_user_info(_context, sess_info) if userinfo is None: userinfo = info else: userinfo.update(info) try: req_sid = _cinfo["frontchannel_logout_session_required"] except KeyError: try: req_sid = _cinfo["backchannel_logout_session_required"] except KeyError: req_sid = False if req_sid: xargs = { "sid": _context.sdb.get_sid_by_sub_and_client_id( sess_info["sub"], _client_id) } else: xargs = {} return self.sign_encrypt(sess_info, _client_id, sign=True, user_info=userinfo, lifetime=lifetime, extra_claims=xargs, **kwargs)
def make(self, req, sess_info, authn_req=None, user_claims=False, **kwargs): _context = self.endpoint_context _sdb = _context.sdb if authn_req: _client_id = authn_req["client_id"] else: _client_id = req["client_id"] _cinfo = _context.cdb[_client_id] default_idtoken_claims = dict(self.kwargs.get("default_claims", {})) lifetime = self.kwargs.get("lifetime") userinfo = userinfo_in_id_token_claims(_context, sess_info, default_idtoken_claims) if user_claims: info = collect_user_info(_context, sess_info) if userinfo is None: userinfo = info else: userinfo.update(info) # Should I add session ID req_sid = include_session_id(_context, _client_id, "back") or include_session_id( _context, _client_id, "front") if req_sid: xargs = { "sid": _context.sdb.get_sid_by_sub_and_client_id( sess_info["sub"], _client_id) } else: xargs = {} return self.sign_encrypt(sess_info, _client_id, sign=True, user_info=userinfo, lifetime=lifetime, extra_claims=xargs, **kwargs)
def process_request(self, request=None, **kwargs): _sdb = self.endpoint_context.sdb # should be an access token if not _sdb.is_token_valid(request['access_token']): return self.error_cls(error="invalid_token", error_description="Invalid Token") session = _sdb.read(request['access_token']) # Scope can translate to userinfo_claims info = collect_user_info(self.endpoint_context, session) return {'response_args': info, 'client_id': session['authn_req']['client_id']}
def test_collect_user_info(self): _session_info = {"authn_req": OIDR} session = _session_info.copy() session["sub"] = "doe" session["uid"] = "diana" session["authn_event"] = create_authn_event("diana", "salt") res = collect_user_info(self.endpoint_context, session) assert res == { 'email': '*****@*****.**', 'email_verified': False, 'nickname': 'Dina', 'given_name': 'Diana', 'sub': 'doe' }
def test_collect_user_info(): _session_info = {'authn_req': OIDR} session = _session_info.copy() session['sub'] = 'doe' session['uid'] = 'diana' session['authn_event'] = create_authn_event('diana', 'salt') endpoint_context = EndpointContext({ 'userinfo': { 'class': UserInfo, 'kwargs': { 'db': USERINFO_DB } }, 'password': "******", 'issuer': 'https://example.com/op', 'token_expires_in': 900, 'grant_expires_in': 600, 'refresh_token_expires_in': 86400, "endpoint": {}, "authentication": [{ 'acr': INTERNETPROTOCOLPASSWORD, 'name': 'NoAuthn', 'kwargs': { 'user': '******' } }], 'template_dir': 'template' }) res = collect_user_info(endpoint_context, session) assert res == { 'given_name': 'Diana', 'nickname': 'Dina', 'sub': 'doe', 'email': '*****@*****.**', 'email_verified': False }
def test_collect_user_info(self): _req = OIDR.copy() _req["claims"] = CLAIMS_2 _session_info = {"authn_req": _req} session = _session_info.copy() session["sub"] = "doe" session["uid"] = "diana" session["authn_event"] = create_authn_event("diana", "salt") res = collect_user_info(self.endpoint_context, session) assert res == { "nickname": "Dina", "sub": "doe", "email": "*****@*****.**", "email_verified": False, }
def test_collect_user_info(): _session_info = {"authn_req": OIDR} session = _session_info.copy() session["sub"] = "doe" session["uid"] = "diana" session["authn_event"] = create_authn_event("diana", "salt") endpoint_context = EndpointContext( { "userinfo": {"class": UserInfo, "kwargs": {"db": USERINFO_DB}}, "password": "******", "issuer": "https://example.com/op", "token_expires_in": 900, "grant_expires_in": 600, "refresh_token_expires_in": 86400, "endpoint": {}, "jwks": { "public_path": "jwks.json", "key_defs": KEYDEFS, "uri_path": "static/jwks.json", }, "authentication": { "anon": { "acr": INTERNETPROTOCOLPASSWORD, "class": "oidcendpoint.user_authn.user.NoAuthn", "kwargs": {"user": "******"}, } }, "template_dir": "template", } ) res = collect_user_info(endpoint_context, session) assert res == { "given_name": "Diana", "nickname": "Dina", "sub": "doe", "email": "*****@*****.**", "email_verified": False, }
def test_collect_user_info_2(self): _req = OIDR.copy() _req["scope"] = "openid email" del _req["claims"] _session_info = {"authn_req": _req} session = _session_info.copy() session["sub"] = "doe" session["uid"] = "diana" session["authn_event"] = create_authn_event("diana", "salt") self.endpoint_context.provider_info["scopes_supported"] = [ "openid", "email", "offline_access" ] res = collect_user_info(self.endpoint_context, session) assert res == { "sub": "doe", "email": "*****@*****.**", "email_verified": False, }
def create_authn_response(endpoint_context, request, sid): # create the response aresp = AuthorizationResponse() try: aresp["state"] = request["state"] except KeyError: pass if "response_type" in request and request["response_type"] == ["none"]: fragment_enc = False else: _sinfo = endpoint_context.sdb[sid] try: aresp["scope"] = request["scope"] except KeyError: pass rtype = set(request["response_type"][:]) handled_response_type = [] if len(rtype) == 1 and "code" in rtype: fragment_enc = False else: fragment_enc = True if "code" in request["response_type"]: _code = aresp["code"] = endpoint_context.sdb[sid]["code"] handled_response_type.append("code") else: endpoint_context.sdb.update(sid, code=None) _code = None if "token" in rtype: _dic = endpoint_context.sdb.upgrade_to_token(issue_refresh=False, key=sid) logger.debug("_dic: %s" % sanitize(_dic)) for key, val in _dic.items(): if key in aresp.parameters() and val is not None: aresp[key] = val handled_response_type.append("token") try: _access_token = aresp["access_token"] except KeyError: _access_token = None if "id_token" in request["response_type"]: user_info = userinfo_in_id_token_claims(endpoint_context, _sinfo) if request["response_type"] == ["id_token"]: # scopes should be returned here info = collect_user_info(endpoint_context, _sinfo) if user_info is None: user_info = info else: user_info.update(info) # client_info = endpoint_context.cdb[str(request["client_id"])] hargs = {} if {'code', 'id_token', 'token'}.issubset(rtype): hargs = {"code": _code, "access_token": _access_token} elif {'code', 'id_token'}.issubset(rtype): hargs = {"code": _code} elif {'id_token', 'token'}.issubset(rtype): hargs = {"access_token": _access_token} # or 'code id_token' try: id_token = sign_encrypt_id_token(endpoint_context, _sinfo, str(request["client_id"]), user_info=user_info, sign=True, **hargs) except (JWEException, NoSuitableSigningKeys) as err: logger.warning(str(err)) return AuthorizationErrorResponse( error="invalid_request", error_description="Could not sign/encrypt id_token") aresp["id_token"] = id_token _sinfo["id_token"] = id_token handled_response_type.append("id_token") not_handled = rtype.difference(handled_response_type) if not_handled: raise UnSupported("unsupported_response_type", list(not_handled)) return {'response_args': aresp, 'fragment_enc': fragment_enc}