def test_construct_OpenIDRequest(): cli = Client() cli.client_id = CLIENT_ID cli.client_secret = CLIENT_SECRET cli.scope = ["openid", "profile"] cli.redirect_uris = ["https://client.example.com/cb"] request_args = {"response_type": "code id_token", "state": "af0ifjsldkj"} oidr = cli.construct_OpenIDRequest(request_args=request_args) print oidr.keys() assert _eq(oidr.keys(), ["nonce", "state", "redirect_uri", "response_type", "client_id", "scope"])
class TestOICClient: def setup_class(self): self.client = Client(CLIENT_ID) self.client.redirect_uris = ["http://example.com/redirect"] self.client.client_secret = CLIENT_SECRET self.client.keystore.set_sign_key(rsapub, "rsa") self.client.keystore.set_verify_key(rsapub, "rsa") def test_areq_1(self): ar = self.client.construct_AuthorizationRequest(request_args={"response_type": ["code"]}) print ar.to_dict() assert ar["redirect_uri"] == "http://example.com/redirect" assert ar["response_type"] == ["code"] assert "state" not in ar assert "scope" not in ar def test_areq_2(self): self.client.state = "abc" req_args = {"response_type": ["code"], "scope": ["foo", "bar"]} ar = self.client.construct_AuthorizationRequest(request_args=req_args) assert ar["redirect_uri"] == "http://example.com/redirect" assert ar["response_type"] == ["code"] assert ar["client_id"] == CLIENT_ID assert ar["state"] == "abc" assert ar["scope"] == ["foo", "bar"] def test_areq_replace_default_state(self): self.client.state = "efg" req_args = {"response_type": ["code"], "scope": ["foo", "bar"]} ar = self.client.construct_AuthorizationRequest(request_args=req_args) assert ar["redirect_uri"] == "http://example.com/redirect" assert ar["response_type"] == ["code"] assert ar["client_id"] == CLIENT_ID assert ar["state"] == "efg" assert ar["scope"] == ["foo", "bar"] def test_parse_authz_resp_url(self): url = "https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=ghi" aresp = self.client.parse_response(AuthorizationResponse, info=url, format="urlencoded") assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA" assert aresp["state"] == "ghi" assert self.client.grant["ghi"] assert self.client.grant["ghi"].code == aresp["code"] assert self.client.grant["ghi"].grant_expiration_time def test_parse_authz_resp_query(self): query = "code=SplxlOBeZQQYbYS6WxSbIA&state=hij" aresp = self.client.parse_response(AuthorizationResponse, info=query, format="urlencoded") assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA" assert aresp["state"] == "hij" print self.client.grant.keys() assert self.client.grant["hij"] assert self.client.grant["hij"].code == aresp["code"] assert self.client.grant["hij"].grant_expiration_time def test_parse_authz_resp_query_multi_scope(self): query = "code=SplxlOBeZQQYbYS6WxAAAA&state=klm" aresp = self.client.parse_response(AuthorizationResponse, info=query, format="urlencoded") assert aresp["code"] == "SplxlOBeZQQYbYS6WxAAAA" assert aresp["state"] == "klm" assert self.client.grant["klm"] assert self.client.grant["klm"].code == aresp["code"] assert self.client.grant["klm"].grant_expiration_time assert _eq(self.client.grant.keys(), ["ghi", "hij", "klm"]) def test_parse_authz_resp_query_unknown_parameter(self): query = "code=SplxlOBeZQQYbYS6WxSbIA&state=xyz&foo=bar" aresp = self.client.parse_response(AuthorizationResponse, info=query, format="urlencoded") assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA" assert aresp["state"] == "xyz" print aresp.__dict__.keys() assert "foo" not in aresp.__dict__ assert self.client.grant["xyz"] assert self.client.grant["xyz"].code == aresp["code"] assert self.client.grant["xyz"].grant_expiration_time def test_get_access_token_request_1(self): self.client.reset() self.client.redirect_uris = ["http://client.example.com/authz"] grant = Grant() grant.code = "AbCdEf" grant.grant_expiration_time = time_util.time_sans_frac() + 30 self.client.grant = {"stat": grant} # scope is default="" atr = self.client.construct_AccessTokenRequest(state="stat") assert atr["grant_type"] == "authorization_code" assert atr["code"] == "AbCdEf" assert atr["redirect_uri"] == "http://client.example.com/authz" def test_construct_access_token_request_fail(self): raises(Exception, 'self.client.construct_AccessTokenRequest(state="unknown")') def test_get_access_token_request_override(self): self.client.reset() self.client.redirect_uris = ["http://client.example.com/authz"] grant = Grant() grant.code = "AbCdEf" grant.grant_expiration_time = time_util.time_sans_frac() + 30 self.client.grant = {"xyz": grant} atr = self.client.construct_AccessTokenRequest(state="xyz") assert atr["grant_type"] == "authorization_code" assert atr["code"] == "AbCdEf" assert atr["redirect_uri"] == "http://client.example.com/authz" def test_construct_request_no_input(self): self.client.response_type = ["code"] atr = self.client.construct_AuthorizationRequest() print atr assert atr["redirect_uri"] == "http://client.example.com/authz" assert atr["response_type"] == ["code"] assert atr["client_id"] == CLIENT_ID def test_parse_access_token_response(self): jso = """{ "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }""" self.client.parse_response(AccessTokenResponse, info="".join([x.strip() for x in jso.split("\n")])) assert self.client.grant _grant = self.client.grant[""] assert len(_grant.tokens) == 1 token = _grant.tokens[0] assert token.access_token == "2YotnFZFEjr1zCsicMWpAA" assert token.token_type == "example" assert token.expires_in == 3600 assert token.refresh_token == "tGzv3JOkF0XG5Qx2TlKWIA" # I'm dropping parameters I don't recognize assert "example_parameter" not in self.client.__dict__ # assert self.client.access_token_is_valid() def test_get_access_token_refresh_1(self): print self.client.grant self.client.grant[""].grant_expiration_time = time.time() + 60 self.client.grant[""].code = "access_code" token = self.client.grant[""].tokens[0] print token # Uses refresh_token from previous response atr = self.client.construct_RefreshAccessTokenRequest(token=token) assert atr.type() == "RefreshAccessTokenRequest" assert atr["grant_type"] == "refresh_token" assert atr["refresh_token"] == "tGzv3JOkF0XG5Qx2TlKWIA" def test_get_access_token_refresh_2(self): self.client.grant["foo"] = Grant() self.client.grant["foo"].grant_expiration_time = time.time() + 60 self.client.grant["foo"].code = "access_code" print self.client.grant["foo"] resp = AccessTokenResponse() resp["refresh_token"] = "refresh_with_me" resp["access_token"] = "access" self.client.grant["foo"].tokens.append(Token(resp)) # Uses refresh_token from previous response atr = self.client.construct_RefreshAccessTokenRequest(state="foo") assert atr.type() == "RefreshAccessTokenRequest" assert atr["grant_type"] == "refresh_token" assert atr["refresh_token"] == "refresh_with_me" def test_parse_authz_err_response(self): ruri = "https://client.example.com/cb?error=access_denied&state=xyz" resp = self.client.parse_response(AuthorizationErrorResponse, info=ruri, format="urlencoded") print type(resp), resp assert resp.type() == "AuthorizationErrorResponse" assert resp["error"] == "access_denied" assert resp["state"] == "xyz" def test_return_non_existant_grant(self): assert self.client.grant_from_state("123456abcdef") is None def test_construct_request_with_extra_args(self): req = self.client.construct_AccessTokenRequest(state="foo", extra_args={"foo": "bar"}) assert req print req.keys() assert _eq(req.keys(), ["code", "grant_type", "client_id", "client_secret", "redirect_uri", "foo"]) assert req["foo"] == "bar" def test_construct_TokenRevocationRequest(self): req = self.client.construct_TokenRevocationRequest(state="foo") assert req print req.keys() assert _eq(req.keys(), ["token"]) assert req["token"] == "access" def test_request_info_simple(self): self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info(AuthorizationRequest) # default == "POST" assert uri == "https://example.com/authz" areq = AuthorizationRequest().from_urlencoded(body) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id"]) assert h_args == {"headers": {"content-type": "application/x-www-form-urlencoded"}} assert cis.type() == "AuthorizationRequest" def test_request_info_simple_get(self): uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, method="GET") (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id"]) assert areq["redirect_uri"] == "http://client.example.com/authz" assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest" def test_request_info_simple_get_with_req_args(self): # self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info( AuthorizationRequest, method="GET", request_args={"state": "init"} ) print uri (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id", "state"]) assert areq["state"] assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest" def test_request_info_simple_get_with_extra_args(self): # self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info( AuthorizationRequest, method="GET", extra_args={"rock": "little"} ) print uri (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id", "rock"]) assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest" def test_request_info_with_req_and_extra_args(self): # self.client.authorization_endpoint = "https://example.com/authz" uri, body, h_args, cis = self.client.request_info( AuthorizationRequest, method="GET", request_args={"state": "init"}, extra_args={"rock": "little"} ) print uri (url, query) = uri.split("?") areq = AuthorizationRequest().from_urlencoded(query) assert _eq(areq.keys(), ["nonce", "redirect_uri", "response_type", "client_id", "state", "rock"]) assert body is None assert h_args == {} assert cis.type() == "AuthorizationRequest" def test_do_authorization_request(self): self.client.grant = {} self.client.redirect_uris = ["https://www.example.com/authz"] self.client.authorization_endpoint = "http://oic.example.org/authorization" self.client.client_id = "a1b2c3" self.client.state = "state0" mfos = MyFakeOICServer(KEYS) self.client.http_request = mfos.http_request args = {"response_type": ["code"], "scope": ["openid"]} result = self.client.do_authorization_request(state=self.client.state, request_args=args) assert result.status_code == 302 _loc = result.headers["location"] assert _loc.startswith(self.client.redirect_uris[0]) _, query = _loc.split("?") self.client.parse_response(AuthorizationResponse, info=query, format="urlencoded") def test_access_token_request(self): self.client.token_endpoint = "http://oic.example.org/token" print self.client.grant.keys() print self.client.state print self.client.grant[self.client.state] resp = self.client.do_access_token_request(scope="openid") print resp print resp.keys() self.client.grant[self.client.state].add_token(resp) assert resp.type() == "AccessTokenResponse" assert _eq(resp.keys(), ["token_type", "state", "access_token", "expires_in", "refresh_token", "scope"]) def test_do_user_info_request(self): self.client.userinfo_endpoint = "http://oic.example.org/userinfo" print self.client.grant.keys() print self.client.grant[self.client.state] resp = self.client.do_user_info_request(state=self.client.state) assert resp.type() == "OpenIDSchema" assert _eq(resp.keys(), ["name", "email", "verified", "nickname"]) assert resp["name"] == "Melody Gardot" def test_do_access_token_refresh(self): # token = self.client.get_token(scope="openid") resp = self.client.do_access_token_refresh(scope="openid") print resp assert resp.type() == "AccessTokenResponse" assert _eq(resp.keys(), ["token_type", "state", "access_token", "expires_in", "refresh_token", "scope"]) def test_do_check_session_request(self): self.client.redirect_uris = ["https://www.example.com/authz"] self.client.client_id = CLIENT_ID self.client.check_session_endpoint = "https://example.org/check_session" print self.client.keystore._store _sign_key = self.client.keystore.get_sign_key() print _sign_key args = {"id_token": IDTOKEN.to_jwt(key=_sign_key)} resp = self.client.do_check_session_request(request_args=args) assert resp.type() == "IdToken" assert _eq(resp.keys(), ["nonce", "user_id", "aud", "iss", "exp"]) def test_do_end_session_request(self): self.client.redirect_uris = ["https://www.example.com/authz"] self.client.client_id = "a1b2c3" self.client.end_session_endpoint = "https://example.org/end_session" _sign_key = self.client.keystore.get_sign_key() args = {"id_token": IDTOKEN.to_jwt(key=_sign_key), "redirect_url": "http://example.com/end"} resp = self.client.do_end_session_request(request_args=args, state="state1") assert resp.status_code == 302 assert resp.headers["location"].startswith("http://example.com/end") def test_do_registration_request(self): self.client.registration_endpoint = "https://example.org/registration" args = { "type": "client_associate", "application_type": "web", "application_name": "my service", "redirect_uri": "http://example.com/authz", } resp = self.client.do_registration_request(request_args=args) print resp assert _eq(resp.keys(), ["client_secret", "expires_at", "client_id"]) def test_do_user_info_request_with_access_token_refresh(self): self.client.userinfo_endpoint = "http://oic.example.org/userinfo" token = self.client.get_token(state=self.client.state, scope="openid") token.token_expiration_time = time_sans_frac() - 86400 resp = self.client.do_user_info_request(state=self.client.state) assert resp.type() == "OpenIDSchema" assert _eq(resp.keys(), ["name", "email", "verified", "nickname"]) assert resp["name"] == "Melody Gardot" def test_openid_request_with_request_1(self): claims = { "name": {"essential": True}, "nickname": None, "email": {"essential": True}, "verified": {"essential": True}, "picture": None, } areq = self.client.construct_OpenIDRequest( userinfo_claims={"claims": claims, "preferred_locale": "en"}, idtoken_claims={"claims": {"auth_time": None, "acr": {"values": ["2"]}}, "max_age": 86400}, ) print areq assert areq assert "request" in areq def test_openid_request_with_request_2(self): areq = self.client.construct_OpenIDRequest(idtoken_claims={"claims": {"user_id": {"value": "248289761001"}}}) print areq assert areq assert areq.request _keys = self.client.keystore.get_keys("ver", owner=None) jwtreq = OpenIDRequest().deserialize(areq["request"], "jwt", key=_keys) print print jwtreq print jwtreq.keys() assert _eq(jwtreq.keys(), ["id_token", "state", "redirect_uri", "response_type", "client_id"])