def auth(self): # Start with an authentication request # The client ID appears in the request AUTH_REQ = AuthorizationRequest( client_id="client_1", redirect_uri="https://example.com/cb", scope=["openid", "mail", "address", "offline_access"], state="STATE", response_type="code", ) # The authentication returns a user ID user_id = "diana" # User info is stored in the Session DB authn_event = create_authn_event( user_id, authn_info=INTERNETPROTOCOLPASSWORD, authn_time=time_sans_frac(), ) user_info = UserSessionInfo(user_id=user_id) self.session_manager.set([user_id], user_info) # Now for client session information client_id = AUTH_REQ["client_id"] client_info = ClientSessionInfo(client_id=client_id) self.session_manager.set([user_id, client_id], client_info) # The user consent module produces a Grant instance grant = Grant( scope=AUTH_REQ["scope"], resources=[client_id], authorization_request=AUTH_REQ, authentication_event=authn_event, ) # the grant is assigned to a session (user_id, client_id) self.session_manager.set([user_id, client_id, grant.id], grant) session_id = self.session_manager.encrypted_session_id( user_id, client_id, grant.id) # Constructing an authorization code is now done by code = grant.mint_token( session_id=session_id, endpoint_context=self.endpoint_context, token_class="authorization_code", token_handler=self.session_manager. token_handler["authorization_code"], expires_at=time_sans_frac() + 300, # 5 minutes from now ) # get user info user_info = self.session_manager.get_user_info(uid=user_id, ) return grant.id, code
def test_grant(self): grant = Grant() assert grant.issued_token == [] assert grant.is_active() is True code = self._mint_token("authorization_code", grant, self.dummy_session_id) assert isinstance(code, AuthorizationCode) assert code.is_active() assert len(grant.issued_token) == 1 assert code.max_usage_reached() is False
def test_mint_token_exp_at(self, exp_in): grant = Grant() grant.usage_rules = {"authorization_code": {"expires_in": exp_in}} DUMMY_SESSION_ID = self.session_manager.encrypted_session_id( "user_id", "client_id", "grant.id" ) code = self.endpoint.mint_token("authorization_code", grant, DUMMY_SESSION_ID) if exp_in in [360, "360"]: assert code.expires_at else: assert code.expires_at == 0
def test_client_info_add2(self): user_info = UserSessionInfo(foo="bar") self.db.set(["diana"], user_info) client_info = ClientSessionInfo(sid="abcdef") self.db.set(["diana", "client_1"], client_info) # The reference is there but not the value del self.db.db[self.db.session_key("diana", "client_1")] authn_event = create_authn_event(uid="diana", expires_in=10, authn_info="authn_class_ref") grant = Grant(authentication_event=authn_event, authorization_request=AUTHZ_REQ) access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) stored_client_info = self.db.get(["diana", "client_1"]) assert set(stored_client_info.keys()) == { "subordinate", "revoked", "type", "client_id", "extra_args", } stored_grant_info = self.db.get(["diana", "client_1", "G1"]) assert stored_grant_info.issued_at
def test_json_conversion(self): session_id = self._create_session(AREQ) session_info = self.endpoint_context.session_manager.get_session_info( session_id=session_id, grant=True ) grant = session_info["grant"] code = grant.mint_token( session_id, endpoint_context=self.endpoint_context, token_class="authorization_code", token_handler=TOKEN_HANDLER["authorization_code"], ) grant.mint_token( session_id, endpoint_context=self.endpoint_context, token_class="access_token", token_handler=TOKEN_HANDLER["access_token"], based_on=code, ) _item = grant.dump() _grant_copy = Grant().load(_item) assert len(_grant_copy.issued_token) == 2 tt = {"code": 0, "access_token": 0} for token in _grant_copy.issued_token: if token.token_class == "authorization_code": tt["code"] += 1 if token.token_class == "access_token": tt["access_token"] += 1 assert tt == {"code": 1, "access_token": 1}
def test_removed(self): grant = Grant() access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) self.db.delete(["diana", "client_1"]) with pytest.raises(KeyError): self.db.get(["diana", "client_1", "G1"])
def test_replace_grant_info_not_there(self): grant = Grant() access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) # The reference is there but not the value del self.db.db[self.db.session_key("diana", "client_1", "G1")] grant = Grant() access_code = SessionToken("access_code", value="aaaaaaaaa") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) stored_grant_info = self.db.get(["diana", "client_1", "G1"]) assert stored_grant_info.issued_at assert len(stored_grant_info.issued_token) == 1 token = stored_grant_info.issued_token[0] assert token.value == "aaaaaaaaa"
def test_json_custom_token_map(self): session_id = self._create_session(AREQ) session_info = self.endpoint_context.session_manager.get_session_info( session_id=session_id, grant=True ) grant = session_info["grant"] token_map = TOKEN_MAP.copy() token_map["my_token"] = MyToken grant.token_map = token_map code = grant.mint_token( session_id, endpoint_context=self.endpoint_context, token_class="authorization_code", token_handler=TOKEN_HANDLER["authorization_code"], ) grant.mint_token( session_id, endpoint_context=self.endpoint_context, token_class="access_token", token_handler=TOKEN_HANDLER["access_token"], based_on=code, ) grant.mint_token( session_id, endpoint_context=self.endpoint_context, token_class="my_token", token_handler=DefaultToken("my_token", typ="M"), ) _jstr = grant.dump() _grant_copy = Grant(token_map=token_map).load(_jstr) assert len(_grant_copy.issued_token) == 3 tt = {k: 0 for k, v in grant.token_map.items()} for token in _grant_copy.issued_token: for _type in tt.keys(): if token.token_class == _type: tt[_type] += 1 assert tt == { "access_token": 1, "authorization_code": 1, "my_token": 1, "refresh_token": 0, "id_token": 0, }
def test_step_wise(self): salt = "natriumklorid" # store user info self.db.set(["diana"], UserSessionInfo(user_id="diana")) # Client specific information self.db.set(["diana", "client_1"], ClientSessionInfo(sub=public_id("diana", salt))) # Grant grant = Grant() access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant)
def test_half_way(self): # store user info self.db.set(["diana"], UserSessionInfo(user_id="diana")) grant = Grant() access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) stored_grant_info = self.db.get(["diana", "client_1", "G1"]) assert stored_grant_info.issued_at assert len(stored_grant_info.issued_token) == 1
def _mint_token( self, token_class: str, grant: Grant, session_id: str, client_id: str, based_on: Optional[SessionToken] = None, scope: Optional[list] = None, token_args: Optional[dict] = None, token_type: Optional[str] = "" ) -> SessionToken: _context = self.endpoint.server_get("endpoint_context") _mngr = _context.session_manager usage_rules = grant.usage_rules.get(token_class) if usage_rules: _exp_in = usage_rules.get("expires_in") else: _exp_in = 0 token_args = token_args or {} for meth in _context.token_args_methods: token_args = meth(_context, client_id, token_args) if token_args: _args = {"token_args": token_args} else: _args = {} token = grant.mint_token( session_id, endpoint_context=_context, token_class=token_class, token_handler=_mngr.token_handler[token_class], based_on=based_on, usage_rules=usage_rules, scope=scope, token_type=token_type, **_args, ) if _exp_in: if isinstance(_exp_in, str): _exp_in = int(_exp_in) if _exp_in: token.expires_at = time_sans_frac() + _exp_in _context.session_manager.set(_context.session_manager.unpack_session_key(session_id), grant) return token
def test_jump_ahead(self): grant = Grant() access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) user_info = self.db.get(["diana"]) assert user_info.subordinate == ["client_1"] client_info = self.db.get(["diana", "client_1"]) assert client_info.subordinate == ["G1"] grant_info = self.db.get(["diana", "client_1", "G1"]) assert grant_info.issued_at assert len(grant_info.issued_token) == 1 token = grant_info.issued_token[0] assert token.value == "1234567890" assert token.token_class == "access_code"
def test_grant_info(self): user_info = UserSessionInfo(foo="bar") self.db.set(["diana"], user_info) client_info = ClientSessionInfo(sid="abcdef") self.db.set(["diana", "client_1"], client_info) with pytest.raises(ValueError): self.db.get(["diana", "client_1", "G1"]) grant = Grant() access_code = SessionToken("access_code", value="1234567890") grant.issued_token.append(access_code) self.db.set(["diana", "client_1", "G1"], grant) # removed value del self.db.db[self.db.session_key("diana", "client_1", "G1")] with pytest.raises(NoSuchGrant): self.db.get(["diana", "client_1", "G1"])