Example #1
0
def test_bearer_header_with_http_args():
    client = Client("A")
    client.client_secret = "boarding pass"

    request_args = {"access_token": "Sesame"}

    cis = ResourceRequest()

    bh = BearerHeader(client)
    http_args = bh.construct(cis, request_args, http_args={"foo": "bar"})

    print cis
    print http_args
    assert _eq(http_args.keys(), ["foo", "headers"])
    assert http_args["headers"] == {"Authorization": "Bearer Sesame"}

    # -----------------

    request_args = {"access_token": "Sesame"}

    bh = BearerHeader(client)
    http_args = bh.construct(cis,
                             request_args,
                             http_args={"headers": {
                                 "x-foo": "bar"
                             }})

    print cis
    print http_args
    assert _eq(http_args.keys(), ["headers"])
    assert _eq(http_args["headers"].keys(), ["Authorization", "x-foo"])
    assert http_args["headers"]["Authorization"] == "Bearer Sesame"
Example #2
0
def test_client_secret_post():
    client = Client("A")
    client.client_secret = "boarding pass"

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    csp = ClientSecretPost(client)
    http_args = csp.construct(cis)

    print cis
    assert cis["client_id"] == "A"
    assert cis["client_secret"] == "boarding pass"
    print http_args
    assert http_args is None

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    request_args = {}
    http_args = csp.construct(cis,
                              request_args,
                              http_args={"client_secret": "another"})

    print cis
    assert cis["client_id"] == "A"
    assert cis["client_secret"] == "another"
    print http_args
    assert http_args == {}
Example #3
0
def test_bearer_header_with_http_args():
    client = Client("A")
    client.client_secret = "boarding pass"

    request_args = {"access_token": "Sesame"}

    cis = ResourceRequest()

    bh = BearerHeader(client)
    http_args = bh.construct(cis, request_args, http_args={"foo": "bar"})

    print cis
    print http_args
    assert _eq(http_args.keys(), ["foo", "headers"])
    assert http_args["headers"] == {"Authorization": "Bearer Sesame"}

    # -----------------

    request_args = {"access_token": "Sesame"}

    bh = BearerHeader(client)
    http_args = bh.construct(cis, request_args,
                             http_args={"headers": {"x-foo": "bar"}})

    print cis
    print http_args
    assert _eq(http_args.keys(), ["headers"])
    assert _eq(http_args["headers"].keys(), ["Authorization", "x-foo"])
    assert http_args["headers"]["Authorization"] == "Bearer Sesame"
Example #4
0
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"

        self.client = Client("1", config={"issuer": "https://example.com/as"})
        self.client.redirect_uris = [self.redirect_uri]
        self.client.authorization_endpoint = self.authorization_endpoint
Example #5
0
def test_client_secret_post():
    client = Client("A")
    client.client_secret = "boarding pass"

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    csp = ClientSecretPost(client)
    http_args = csp.construct(cis)

    print cis
    assert cis["client_id"] == "A"
    assert cis["client_secret"] == "boarding pass"
    print http_args
    assert http_args is None

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    request_args = {}
    http_args = csp.construct(cis, request_args,
                              http_args={"client_secret": "another"})

    print cis
    assert cis["client_id"] == "A"
    assert cis["client_secret"] == "another"
    print http_args
    assert http_args == {}
Example #6
0
    def test_pkce_verify_256(self, session_db_factory):
        _cli = Client(
            config={"code_challenge": {
                "method": "S256",
                "length": 64
            }})
        args, cv = _cli.add_code_challenge()

        authn_broker = AuthnBroker()
        authn_broker.add("UNDEFINED", DummyAuthn(None, "username"))
        _prov = Provider(
            "as",
            session_db_factory("https://connect-op.heroku.com"),
            {},
            authn_broker,
            Implicit(),
            verify_client,
        )

        assert _prov.verify_code_challenge(cv, args["code_challenge"]) is True
        assert _prov.verify_code_challenge(cv, args["code_challenge"],
                                           "S256") is True
        resp = _prov.verify_code_challenge("XXX", args["code_challenge"])
        assert isinstance(resp, Response)
        assert resp.info()["status_code"] == 401
Example #7
0
def test_bearer_body():
    client = Client("A")
    client.client_secret = "boarding pass"

    request_args = {"access_token": "Sesame"}

    cis = ResourceRequest()
    http_args = BearerBody(client).construct(cis, request_args)
    assert cis["access_token"] == "Sesame"
    print http_args
    assert http_args is None

    # ----------
    resp = AuthorizationResponse(code="code", state="state")
    grant = Grant()
    grant.add_code(resp)

    atr = AccessTokenResponse(access_token="2YotnFZFEjr1zCsicMWpAA",
                              token_type="example",
                              refresh_token="tGzv3JOkF0XG5Qx2TlKWIA",
                              example_parameter="example_value",
                              scope=["inner", "outer"])

    grant.add_token(atr)
    client.grant["state"] = grant

    cis = ResourceRequest()
    http_args = BearerBody(client).construct(cis, {}, state="state",
                                             scope="inner")
    assert cis["access_token"] == "2YotnFZFEjr1zCsicMWpAA"
    print http_args
    assert http_args is None
Example #8
0
def test_bearer_body():
    client = Client("A")
    client.client_secret = "boarding pass"

    request_args = {"access_token": "Sesame"}

    cis = ResourceRequest()
    http_args = BearerBody(client).construct(cis, request_args)
    assert cis["access_token"] == "Sesame"
    print http_args
    assert http_args is None

    # ----------
    resp = AuthorizationResponse(code="code", state="state")
    grant = Grant()
    grant.add_code(resp)

    atr = AccessTokenResponse(access_token="2YotnFZFEjr1zCsicMWpAA",
                              token_type="example",
                              refresh_token="tGzv3JOkF0XG5Qx2TlKWIA",
                              example_parameter="example_value",
                              scope=["inner", "outer"])

    grant.add_token(atr)
    client.grant["state"] = grant

    cis = ResourceRequest()
    http_args = BearerBody(client).construct(cis, {},
                                             state="state",
                                             scope="inner")
    assert cis["access_token"] == "2YotnFZFEjr1zCsicMWpAA"
    print http_args
    assert http_args is None
Example #9
0
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"

        self.client = Client("1", config={'issuer': 'https://example.com/as'})
        self.client.redirect_uris = [self.redirect_uri]
        self.client.response_type = "code"
        self.client.authorization_endpoint = self.authorization_endpoint
Example #10
0
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"

        self.client = Client("1")  # pylint: disable=attribute-defined-outside-init
        self.client.redirect_uris = [self.redirect_uri]
        self.client.response_type = "code"
        self.client.authorization_endpoint = self.authorization_endpoint
Example #11
0
def test_client_secret_basic():
    client = Client("A")
    client.client_secret = "boarding pass"

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    http_args = oauth2.client_secret_basic(client, cis)

    assert http_args == {"auth": ("A", "boarding pass")}
Example #12
0
    def test_construct_access_token_req_expired_grant(self):
        resp = AuthorizationResponse(code="code", state="state")
        grant = Grant(-10)  # expired grant
        grant.add_code(resp)

        client = Client()
        client.grant["openid"] = grant
        with pytest.raises(GrantExpired):
            client.construct_AccessTokenRequest(state="openid")
Example #13
0
    def test_construct_access_token_req_expired_grant(self):
        resp = AuthorizationResponse(code="code", state="state")
        grant = Grant(-10)  # expired grant
        grant.add_code(resp)

        client = Client()
        client.grant["openid"] = grant
        with pytest.raises(GrantExpired):
            client.construct_AccessTokenRequest(state="openid")
Example #14
0
 def test_pkce_create(self):
     _cli = Client(
         config={'code_challenge': {
             'method': 'S256',
             'length': 64
         }})
     args, cv = _cli.add_code_challenge()
     assert args['code_challenge_method'] == 'S256'
     assert _eq(list(args.keys()),
                ['code_challenge_method', 'code_challenge'])
Example #15
0
 def test_pkce_create(self):
     _cli = Client(
         config={"code_challenge": {
             "method": "S256",
             "length": 64
         }})
     args, cv = _cli.add_code_challenge()
     assert args["code_challenge_method"] == "S256"
     assert _eq(list(args.keys()),
                ["code_challenge_method", "code_challenge"])
Example #16
0
    def phaseN(self, environ, info, server_env, sid):
        session = server_env["CACHE"][sid]

        callback = server_env["base_url"] + self.social_endpoint

        client = Client(client_id=self.client_id,
                        client_authn_method=CLIENT_AUTHN_METHOD)
        response = client.parse_response(AuthorizationResponse, info, "dict")
        logger.info("Response: %s" % response)

        if isinstance(response, ErrorResponse):
            logger.info("%s" % response)
            session["authentication"] = "FAILED"
            return False, "Authentication failed or permission not granted"

        req_args = {
            "redirect_uri": callback,
            "client_secret": self.client_secret,
        }

        client.token_endpoint = self.extra["token_endpoint"]
        tokenresp = client.do_access_token_request(
            scope=self._scope,
            body_type=self.token_response_body_type,
            request_args=req_args,
            authn_method="client_secret_post",
            state=response["state"],
            response_cls=self.access_token_response)

        if isinstance(tokenresp, ErrorResponse):
            logger.info("%s" % tokenresp)
            session["authentication"] = "FAILED"
            return False, "Authentication failed or permission not granted"

        # Download the user profile and cache a local instance of the
        # basic profile info
        result = client.fetch_protected_resource(
            self.userinfo_endpoint(tokenresp), token=tokenresp["access_token"])

        logger.info("Userinfo: %s" % result.text)
        root = ET.fromstring(result.text)
        jsontext = json.dumps(root.attrib)
        profile = json.loads(jsontext)
        profile = self.convert(profile)
        logger.info("PROFILE: %s" % (profile, ))
        session["service"] = self.name
        session["authentication"] = "OK"
        session["status"] = "SUCCESS"
        session["authn_auth"] = self.authenticating_authority
        session["permanent_id"] = profile["uid"]

        server_env["CACHE"][sid] = session

        return True, profile, session
Example #17
0
def test_client_secret_basic():
    client = Client("A")
    client.client_secret = "boarding pass"

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    csb = ClientSecretBasic(client)
    http_args = csb.construct(cis)

    assert http_args == {"headers": {'Authorization': 'Basic %s'
                                     % base64.b64encode('A:boarding pass')}}
Example #18
0
def test_client_secret_basic():
    client = Client("A")
    client.client_secret = "boarding pass"

    cis = AccessTokenRequest(code="foo", redirect_uri="http://example.com")

    csb = ClientSecretBasic(client)
    http_args = csb.construct(cis)

    assert http_args == {"headers": {'Authorization': 'Basic %s'
                                     % base64.b64encode('A:boarding pass')}}
Example #19
0
def test_bearer_header_2():
    client = Client("A")
    client.client_secret = "boarding pass"

    cis = ResourceRequest(access_token="Sesame")

    http_args = oauth2.bearer_header(client, cis)

    print cis
    assert "access_token" not in cis
    print http_args
    assert http_args == {"headers": {"Authorization": "Bearer Sesame"}}
Example #20
0
def test_get_access_token_request():
    resp = AuthorizationResponse(code="code", state="state")
    grant = Grant(1)
    grant.add_code(resp)

    client = Client()
    client.grant["openid"] = grant
    time.sleep(2)
    try:
        client.construct_AccessTokenRequest(state="openid")
    except Exception, err:
        assert err.__class__.__name__ == "GrantExpired"
Example #21
0
def test_client_get_grant():
    cli = Client()

    resp = AuthorizationResponse(code="code", state="state")
    grant = Grant()
    grant.add_code(resp)

    cli.grant["state"] = grant

    gr1 = cli.grant_from_state("state")

    assert gr1.code == "code"
Example #22
0
def test_client_get_grant():
    cli = Client()

    resp = AuthorizationResponse(code="code", state="state")
    grant = Grant()
    grant.add_code(resp)

    cli.grant["state"] = grant

    gr1 = cli.grant_from_state("state")

    assert gr1.code == "code"
Example #23
0
def test_get_access_token_request():
    resp = AuthorizationResponse(code="code", state="state")
    grant = Grant(1)
    grant.add_code(resp)

    client = Client()
    client.grant["openid"] = grant
    time.sleep(2)
    try:
        client.construct_AccessTokenRequest(state="openid")
    except Exception, err:
        assert err.__class__.__name__ == "GrantExpired"
Example #24
0
def test_bearer_header_2():
    client = Client("A")
    client.client_secret = "boarding pass"

    bh = BearerHeader(client)
    cis = ResourceRequest(access_token="Sesame")

    http_args = bh.construct(cis)

    print cis
    assert "access_token" not in cis
    print http_args
    assert http_args == {"headers": {"Authorization": "Bearer Sesame"}}
Example #25
0
    def test_pkce_verify_512(self, session_db_factory):
        _cli = Client(config={'code_challenge': {'method': 'S512', 'length': 96}})
        args, cv = _cli.add_code_challenge()

        authn_broker = AuthnBroker()
        authn_broker.add("UNDEFINED", DummyAuthn(None, "username"))
        _prov = Provider("as",
                         session_db_factory('https://connect-op.heroku.com'), {},
                         authn_broker, Implicit(), verify_client)

        assert _prov.verify_code_challenge(cv, args['code_challenge'], 'S512') is True
        resp = _prov.verify_code_challenge('XXX', args['code_challenge'])
        assert isinstance(resp, Response)
        assert resp.info()['status_code'] == 401
Example #26
0
def test_bearer_header():
    client = Client("A")
    client.client_secret = "boarding pass"

    request_args = {"access_token": "Sesame"}

    cis = ResourceRequest()

    bh = BearerHeader(client)
    http_args = bh.construct(cis, request_args)

    print cis
    print http_args
    assert http_args == {"headers": {"Authorization": "Bearer Sesame"}}
Example #27
0
    def test_pkce_verify_512(self, session_db_factory):
        _cli = Client(config={'code_challenge': {'method': 'S512', 'length': 96}})
        args, cv = _cli.add_code_challenge()

        authn_broker = AuthnBroker()
        authn_broker.add("UNDEFINED", DummyAuthn(None, "username"))
        _prov = Provider("as",
                         session_db_factory('https://connect-op.heroku.com'), {},
                         authn_broker, Implicit(), verify_client)

        assert _prov.verify_code_challenge(cv, args['code_challenge'], 'S512') is True
        resp = _prov.verify_code_challenge('XXX', args['code_challenge'])
        assert isinstance(resp, Response)
        assert resp.info()['status_code'] == 401
Example #28
0
def test_client_parse_extra_args():
    cli = Client()

    args = {
        "response_type": "",
        "client_id": "client_id",
        "redirect_uri": "http://example.com/authz",
        "scope": "scope",
        "state": "state",
        "extra_session": "home",
    }
    ar_args = cli._parse_args(AuthorizationRequest, **args)

    assert _eq(ar_args.keys(), ["state", "redirect_uri", "response_type", "client_id", "scope", "extra_session"])
Example #29
0
def test_parse_access_token_response_missing_attribute():
    at = AccessTokenResponse(access_token="SlAV32hkKG", token_type="Bearer", refresh_token="8xLOxBtZp8", expire_in=3600)

    atdict = at.to_dict()
    del atdict["access_token"]
    atj = json.dumps(atdict)
    print atj
    client = Client()
    ATR = AccessTokenResponse

    try:
        client.parse_response(ATR, info=atj)
    except Exception, err:
        assert err.__class__.__name__ == "MissingRequiredAttribute"
Example #30
0
def test_client_parse_extra_args():
    cli = Client()

    args = {
        "response_type": "",
        "client_id": "client_id",
        "redirect_uri": "http://example.com/authz",
        "scope": "scope",
        "state": "state",
        "extra_session": "home"
    }
    ar_args = cli._parse_args(AuthorizationRequest, **args)

    assert _eq(ar_args.keys(), ['state', 'redirect_uri', 'response_type',
                                'client_id', 'scope', 'extra_session'])
Example #31
0
def test_client_parse_args():
    cli = Client()

    args = {
        "response_type": "",
        "client_id": "client_id",
        "redirect_uri": "http://example.com/authz",
        "scope": "scope",
        "state": "state",
    }

    ar_args = cli._parse_args(AuthorizationRequest, **args)

    assert _eq(ar_args.keys(), ['scope', 'state', 'redirect_uri',
                                'response_type', 'client_id'])
Example #32
0
def test_private_key_jwt():
    cli = Client("FOO")
    cli.token_endpoint = "https://example.com/token"
    cli.keyjar[""] = KC_RSA

    cis = AccessTokenRequest()
    pkj = PrivateKeyJWT(cli)
    http_args = pkj.construct(cis, algorithm="RS256")
    assert http_args == {}
    cas = cis["client_assertion"]
    header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(cas)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print header
    assert header == {'alg': 'RS256'}
Example #33
0
def test_parse_access_token_response_missing_attribute():
    at = AccessTokenResponse(access_token="SlAV32hkKG",
                             token_type="Bearer", refresh_token="8xLOxBtZp8",
                             expire_in=3600)

    atdict = at.to_dict()
    del atdict["access_token"]
    atj = json.dumps(atdict)
    print atj
    client = Client()
    ATR = AccessTokenResponse

    try:
        client.parse_response(ATR, info=atj)
    except Exception, err:
        assert err.__class__.__name__ == "MissingRequiredAttribute"
Example #34
0
    def __init__(
        self,
        session_db,
        client_config=None,
        server_info=None,
        authz_page="",
        response_type="",
        scope="",
        flow_type="",
        password=None,
    ):
        """
        Initialize a Consumer instance.

        :param session_db: Where info are kept about sessions acts like a
            dictionary
        :param client_config: Client configuration
        :param server_info: Information about the server
        :param authz_page:
        :param response_type:
        :param scope:
        :param flow_type:
        """
        if client_config is None:
            client_config = {}

        Client.__init__(self, **client_config)

        self.authz_page = authz_page
        self.response_type = response_type
        self.scope = scope
        self.flow_type = flow_type
        self.password = password

        if server_info:
            for endpoint in ENDPOINTS:
                try:
                    setattr(self, endpoint, server_info[endpoint])
                except KeyError:
                    setattr(self, endpoint, None)
        else:
            for endpoint in ENDPOINTS:
                setattr(self, endpoint, None)

        self.sdb = session_db
        self.seed = rndstr().encode("utf-8")
        self._request = None
Example #35
0
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"

        self.client = Client("1", config={'issuer': 'https://example.com/as'})
        self.client.redirect_uris = [self.redirect_uri]
        self.client.response_type = "code"
        self.client.authorization_endpoint = self.authorization_endpoint
Example #36
0
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"

        self.client = Client("1")  # pylint: disable=attribute-defined-outside-init
        self.client.redirect_uris = [self.redirect_uri]
        self.client.response_type = "code"
        self.client.authorization_endpoint = self.authorization_endpoint
Example #37
0
    def __init__(
        self,
        session_db,
        client_config=None,
        server_info=None,
        authz_page="",
        response_type="",
        scope="",
        flow_type="",
        password=None,
    ):
        """ Initializes a Consumer instance.

        :param session_db: Where info are kept about sessions acts like a
            dictionary
        :param client_config: Client configuration
        :param server_info: Information about the server
        :param authz_page:
        :param response_type:
        :param scope:
        :param flow_type:
        """
        if client_config is None:
            client_config = {}

        Client.__init__(self, **client_config)

        self.authz_page = authz_page
        self.response_type = response_type
        self.scope = scope
        self.flow_type = flow_type
        self.password = password

        if server_info:
            for endpoint in ENDPOINTS:
                try:
                    setattr(self, endpoint, server_info[endpoint])
                except KeyError:
                    setattr(self, endpoint, None)
        else:
            for endpoint in ENDPOINTS:
                setattr(self, endpoint, None)

        self.sdb = session_db
        self.seed = rndstr()
Example #38
0
def test_client_endpoint():
    cli = Client()
    cli.authorization_endpoint = "https://example.org/oauth2/as"
    cli.token_endpoint = "https://example.org/oauth2/token"
    cli.token_revocation_endpoint = "https://example.org/oauth2/token_rev"

    ae = cli._endpoint("authorization_endpoint")
    assert ae == "https://example.org/oauth2/as"
    te = cli._endpoint("token_endpoint")
    assert te == "https://example.org/oauth2/token"
    tre = cli._endpoint("token_revocation_endpoint")
    assert tre == "https://example.org/oauth2/token_rev"

    ae = cli._endpoint("authorization_endpoint",
                       **{"authorization_endpoint": "https://example.com/as"})
    assert ae == "https://example.com/as"

    cli.token_endpoint = ""
    raises(Exception, 'cli._endpoint("token_endpoint")')
    raises(Exception, 'cli._endpoint("foo_endpoint")')
Example #39
0
def test_get_authorization_request():
    client = Client()
    client.redirect_uris = ["https://www.example.com/authz"]
    client.client_id = "a1b2c3"
    args = {"response_type": ["code"]}
    ar = client.construct_AuthorizationRequest(request_args=args)
    assert ar["client_id"] == 'a1b2c3'
    assert ar["redirect_uri"] == 'https://www.example.com/authz'
    assert ar["response_type"] == ['code']

    client = Client()
    client.client_id = "a1b2c3"
    args = {"response_type": ["code"],
            "redirect_uri": "https://www.example.com/authz"}
    ar = client.construct_AuthorizationRequest(request_args=args)
    assert ar["client_id"] == 'a1b2c3'
    assert ar["redirect_uri"] == 'https://www.example.com/authz'
    assert ar["response_type"] == ['code']
Example #40
0
    def phaseN(self, environ, query, server_env, session):
        callback = server_env["base_url"] + self.opKey

        client = Client(client_id=self.client_id,
                        client_authn_method=CLIENT_AUTHN_METHOD)
        response = client.parse_response(AuthorizationResponse, query, "dict")
        logger.info("Response: %s" % response)

        if isinstance(response, ErrorResponse):
            logger.info("%s" % response)
            return (False, "Authentication failed or permission not granted")

        req_args = {
            "redirect_uri": callback,
            "client_secret": self.client_secret,
        }

        client.token_endpoint = self.extra["token_endpoint"]
        tokenresp = client.do_access_token_request(
            scope=self._scope,
            body_type=self.token_response_body_type,
            request_args=req_args,
            authn_method="client_secret_post",
            state=response["state"],
            response_cls=self.access_token_response)

        if isinstance(tokenresp, ErrorResponse):
            logger.info("%s" % tokenresp)
            return (False, "Authentication failed or permission not granted")

        # Download the user profile and cache a local instance of the
        # basic profile info
        result = client.fetch_protected_resource(
            self.userinfo_endpoint(tokenresp), token=tokenresp["access_token"])

        logger.info("Userinfo: %s" % result.text)
        profile = json.loads(result.text)

        return True, profile, tokenresp["access_token"], client
Example #41
0
def test_client_endpoint():
    cli = Client()
    cli.authorization_endpoint = "https://example.org/oauth2/as"
    cli.token_endpoint = "https://example.org/oauth2/token"
    cli.token_revocation_endpoint = "https://example.org/oauth2/token_rev"

    ae = cli._endpoint("authorization_endpoint")
    assert ae == "https://example.org/oauth2/as"
    te = cli._endpoint("token_endpoint")
    assert te == "https://example.org/oauth2/token"
    tre = cli._endpoint("token_revocation_endpoint")
    assert tre == "https://example.org/oauth2/token_rev"

    ae = cli._endpoint("authorization_endpoint", **{"authorization_endpoint": "https://example.com/as"})
    assert ae == "https://example.com/as"

    cli.token_endpoint = ""
    raises(Exception, 'cli._endpoint("token_endpoint")')
    raises(Exception, 'cli._endpoint("foo_endpoint")')
Example #42
0
def test_client_secret_jwt():
    cli = Client("Foo")
    cli.token_endpoint = "https://example.com/token"
    cli.client_secret = "foobar"

    csj = ClientSecretJWT(cli)
    cis = AccessTokenRequest()

    http_args = csj.construct(cis, algorithm="HS256")
    print http_args
    assert cis["client_assertion_type"] == JWT_BEARER
    assert "client_assertion" in cis
    cas = cis["client_assertion"]
    _jwt = JWT().unpack(cas)
    jso = json.loads(_jwt.part[1])
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print _jwt.headers
    assert _jwt.headers == {'alg': 'HS256'}

    _rj = JWS()
    info = _rj.verify_compact(cas, [SYMKey(key=cli.client_secret)])

    assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Example #43
0
def test_client_secret_jwt():
    cli = Client("Foo")
    cli.token_endpoint = "https://example.com/token"
    cli.client_secret = "foobar"

    csj = ClientSecretJWT(cli)
    cis = AccessTokenRequest()

    http_args = csj.construct(cis, algorithm="HS256")
    print http_args
    assert cis["client_assertion_type"] == JWT_BEARER
    assert "client_assertion" in cis
    cas = cis["client_assertion"]
    _jwt = JWT().unpack(cas)
    jso = json.loads(_jwt.part[1])
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print _jwt.headers
    assert _jwt.headers == {'alg': 'HS256'}

    _rj = JWS()
    info = _rj.verify_compact(cas, [SYMKey(key=cli.client_secret)])

    assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Example #44
0
def test_client_secret_jwt():
    cli = Client("Foo")
    cli.token_endpoint = "https://example.com/token"
    cli.client_secret = "foobar"

    csj = ClientSecretJWT(cli)
    cis = AccessTokenRequest()

    http_args = csj.construct(cis, algorithm="HS256")
    print http_args
    assert cis["client_assertion_type"] == JWT_BEARER
    assert "client_assertion" in cis
    cas = cis["client_assertion"]
    header, claim, crypto, header_b64, claim_b64 = jwkest.unpack(cas)
    jso = json.loads(claim)
    assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
    print header
    assert header == {'alg': 'HS256'}

    _rj = JWS()
    info = _rj.verify_compact(cas, [SYM_key(key=cli.client_secret)])

    _dict = json.loads(info)
    assert _eq(_dict.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Example #45
0
def test_bearer_body_get_token():
    client = Client("A")
    client.client_secret = "boarding pass"
    client.state = "state"

    resp1 = AuthorizationResponse(code="auth_grant", state="state")
    client.parse_response(AuthorizationResponse, resp1.to_urlencoded(), "urlencoded")
    resp2 = AccessTokenResponse(access_token="token1", token_type="Bearer", expires_in=0, state="state")
    client.parse_response(AccessTokenResponse, resp2.to_urlencoded(), "urlencoded")

    cis = ResourceRequest()

    oauth2.bearer_body(client, cis)

    assert "access_token" in cis
    assert cis["access_token"] == "token1"
Example #46
0
    def phaseN(self, environ, info, server_env, sid):
        session = server_env["CACHE"][sid]

        callback = server_env["base_url"] + self.social_endpoint

        client = Client(client_id=self.client_id,
                        client_authn_method=CLIENT_AUTHN_METHOD)
        response = client.parse_response(AuthorizationResponse, info, "dict")
        logger.info("Response: %s" % response)

        if isinstance(response, ErrorResponse):
            logger.info("%s" % response)
            session["authentication"] = "FAILED"
            return False, "Authentication failed or permission not granted"

        req_args = {
            "redirect_uri": callback,
            "client_secret": self.client_secret,
        }

        client.token_endpoint = self.extra["token_endpoint"]
        tokenresp = client.do_access_token_request(
            scope=self._scope,
            body_type=self.token_response_body_type,
            request_args=req_args,
            authn_method="client_secret_post",
            state=response["state"],
            response_cls=self.access_token_response)

        if isinstance(tokenresp, ErrorResponse):
            logger.info("%s" % tokenresp)
            session["authentication"] = "FAILED"
            return False, "Authentication failed or permission not granted"

        # Download the user profile and cache a local instance of the
        # basic profile info
        result = client.fetch_protected_resource(
            self.userinfo_endpoint(tokenresp), token=tokenresp["access_token"])

        logger.info("Userinfo: %s" % result.text)
        profile = json.loads(result.text)

        logger.info("PROFILE: %s" % (profile, ))
        session["service"] = self.name
        session["authentication"] = "OK"
        session["status"] = "SUCCESS"
        session["authn_auth"] = self.authenticating_authority
        session["permanent_id"] = profile["id"]

        server_env["CACHE"][sid] = session

        return True, self.convert(profile), session
Example #47
0
def test_get_authorization_request():
    client = Client()
    client.redirect_uris = ["https://www.example.com/authz"]
    client.client_id = "a1b2c3"
    args = {"response_type": ["code"]}
    ar = client.construct_AuthorizationRequest(request_args=args)
    assert ar["client_id"] == "a1b2c3"
    assert ar["redirect_uri"] == "https://www.example.com/authz"
    assert ar["response_type"] == ["code"]

    client = Client()
    client.client_id = "a1b2c3"
    args = {"response_type": ["code"], "redirect_uri": "https://www.example.com/authz"}
    ar = client.construct_AuthorizationRequest(request_args=args)
    assert ar["client_id"] == "a1b2c3"
    assert ar["redirect_uri"] == "https://www.example.com/authz"
    assert ar["response_type"] == ["code"]
Example #48
0
def test_bearer_body_get_token():
    client = Client("A")
    client.client_secret = "boarding pass"
    client.state = "state"

    resp1 = AuthorizationResponse(code="auth_grant", state="state")
    client.parse_response(AuthorizationResponse, resp1.to_urlencoded(),
                          "urlencoded")
    resp2 = AccessTokenResponse(access_token="token1",
                                token_type="Bearer",
                                expires_in=0,
                                state="state")
    client.parse_response(AccessTokenResponse, resp2.to_urlencoded(),
                          "urlencoded")

    cis = ResourceRequest()

    _ = BearerBody(client).construct(cis)

    assert "access_token" in cis
    assert cis["access_token"] == "token1"
Example #49
0
def test_parse_access_token_response():
    client = Client()

    at = AccessTokenResponse(access_token="SlAV32hkKG",
                             token_type="Bearer",
                             refresh_token="8xLOxBtZp8",
                             expire_in=3600)

    atj = at.to_json()

    ATR = AccessTokenResponse
    atr = client.parse_response(ATR, info=atj)

    assert _eq(atr.keys(),
               ['access_token', 'token_type', u'expire_in', 'refresh_token'])

    uec = at.to_urlencoded()
    raises(ValueError, 'client.parse_response(ATR, info=uec)')

    uatr = client.parse_response(ATR, info=uec, sformat="urlencoded")
    assert _eq(uatr.keys(),
               ['access_token', 'token_type', 'expire_in', 'refresh_token'])

    huec = "%s?%s" % ("https://example.com/token", uec)

    uatr = client.parse_response(ATR, info=huec, sformat="urlencoded")
    assert _eq(uatr.keys(),
               ['access_token', 'token_type', 'expire_in', 'refresh_token'])

    err = ErrorResponse(error="invalid_request",
                        error_description="Something was missing",
                        error_uri="http://example.com/error_message.html")

    jerr = err.to_json()
    uerr = err.to_urlencoded()

    _ = client.parse_response(ATR, info=jerr)
    _ = client.parse_response(ATR, info=uerr, sformat="urlencoded")

    raises(Exception,
           'client.parse_response(ATR, info=jerr, sformat="urlencoded")')

    raises(Exception, "client.parse_response(ATR, info=uerr)")

    raises(Exception, 'client.parse_response(ATR, info=jerr, sformat="focus")')
Example #50
0
def test_bearer_header_3():
    client = Client("A")
    client.client_secret = "boarding pass"
    client.state = "state"

    resp1 = AuthorizationResponse(code="auth_grant", state="state")
    client.parse_response(AuthorizationResponse, resp1.to_urlencoded(), "urlencoded")
    resp2 = AccessTokenResponse(access_token="token1", token_type="Bearer", expires_in=0, state="state")
    client.parse_response(AccessTokenResponse, resp2.to_urlencoded(), "urlencoded")

    cis = ResourceRequest()

    http_args = oauth2.bearer_header(client, cis)

    print cis
    assert "access_token" not in cis
    print http_args
    assert http_args == {"headers": {"Authorization": "Bearer token1"}}
Example #51
0
def test_device_flow():
    _client = Client()
    cli = DeviceFlowClient(_client)

    _server = Server()
    srv = DeviceFlowServer(_server)

    # init
    req = AuthorizationRequest(client_id=cli.host.client_id,
                               response_type='device_code')

    resp = srv.device_endpoint(req)

    # Polling

    req = TokenRequest(
        grant_type="urn:ietf:params:oauth:grant-type:device_code",
        device_code=resp['device_dode'], client_id=cli.host.client_id)

    resp = srv.token_endpoint(req)
Example #52
0
def test_bearer_header_3():
    client = Client("A")
    client.client_secret = "boarding pass"
    client.state = "state"

    resp1 = AuthorizationResponse(code="auth_grant", state="state")
    client.parse_response(AuthorizationResponse, resp1.to_urlencoded(),
                          "urlencoded")
    resp2 = AccessTokenResponse(access_token="token1",
                                token_type="Bearer",
                                expires_in=0,
                                state="state")
    client.parse_response(AccessTokenResponse, resp2.to_urlencoded(),
                          "urlencoded")

    cis = ResourceRequest()

    http_args = BearerHeader(client).construct(cis)

    print cis
    assert "access_token" not in cis
    print http_args
    assert http_args == {"headers": {"Authorization": "Bearer token1"}}
Example #53
0
def test_parse_access_token_response():
    client = Client()

    at = AccessTokenResponse(access_token="SlAV32hkKG",
                 token_type="Bearer", refresh_token="8xLOxBtZp8",
                 expire_in=3600)

    atj = at.to_json()

    ATR = AccessTokenResponse
    atr = client.parse_response(ATR, info=atj)

    assert _eq(atr.keys(), ['access_token', 'token_type', u'expire_in',
                            'refresh_token'])

    uec = at.to_urlencoded()
    raises(ValueError, 'client.parse_response(ATR, info=uec)')

    uatr = client.parse_response(ATR, info=uec, format="urlencoded")
    assert _eq(uatr.keys(), ['access_token', 'token_type', 'expire_in',
                             'refresh_token'])

    huec = "%s?%s" % ("https://example.com/token", uec)

    uatr = client.parse_response(ATR, info=huec, format="urlencoded")
    assert _eq(uatr.keys(), ['access_token', 'token_type', 'expire_in',
                             'refresh_token'])

    err = ErrorResponse(error="invalid_request",
                        error_description="Something was missing",
                        error_uri="http://example.com/error_message.html")

    jerr = err.to_json()
    uerr = err.to_urlencoded()

    _ = client.parse_response(ATR, info=jerr)
    _ = client.parse_response(ATR, info=uerr, format="urlencoded")

    raises(Exception,
           'client.parse_response(ATR, info=jerr, format="urlencoded")')

    raises(Exception, "client.parse_response(ATR, info=uerr)")

    raises(Exception,
           'client.parse_response(ATR, info=jerr, format="focus")')
Example #54
0
class TestClient(object):
    @pytest.fixture(autouse=True)
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"
        self.token_endpoint = "https://example.com/token"

        self.client = Client("1", config={"issuer": "https://example.com/as"})
        self.client.redirect_uris = [self.redirect_uri]
        self.client.authorization_endpoint = self.authorization_endpoint
        self.client.token_endpoint = self.token_endpoint

    def test_construct_authz_req_no_optional_params(self):
        areq = self.client.construct_AuthorizationRequest(
            request_args={"response_type": ["code"]})

        assert areq["redirect_uri"] == self.redirect_uri
        assert areq["response_type"] == ["code"]
        assert areq["client_id"] == "1"
        assert "state" not in areq
        assert "scope" not in areq

    def test_construct_authz_req_no_input(self):
        atr = self.client.construct_AuthorizationRequest()

        assert atr["redirect_uri"] == self.redirect_uri
        assert atr["response_type"] == ["code"]
        assert atr["client_id"] == "1"

    def test_construct_authz_req_optional_params(self):
        req_args = {
            "response_type": ["code"],
            "scope": ["foo", "bar"],
            "state": "abc"
        }
        areq = self.client.construct_AuthorizationRequest(
            request_args=req_args)

        assert areq["redirect_uri"] == self.redirect_uri
        assert areq["response_type"] == ["code"]
        assert areq["client_id"] == "1"
        assert areq["state"] == "abc"
        assert areq["scope"] == ["foo", "bar"]

    def test_construct_authz_req_replace_default_state(self):
        req_args = {
            "response_type": ["code"],
            "scope": ["foo", "bar"],
            "state": "efg"
        }
        areq = self.client.construct_AuthorizationRequest(
            request_args=req_args)

        assert areq["redirect_uri"] == self.redirect_uri
        assert areq["response_type"] == ["code"]
        assert areq["client_id"] == "1"
        assert areq["state"] == "efg"
        assert areq["scope"] == ["foo", "bar"]

    def test_parse_authz_resp_url(self):
        code = "SplxlOBeZQQYbYS6WxSbIA"
        state = "ghi"
        url = "{}?code={}&state={}".format(self.redirect_uri, code, state)
        aresp = self.client.parse_response(AuthorizationResponse,
                                           info=url,
                                           sformat="urlencoded")

        assert aresp["code"] == code
        assert aresp["state"] == state

        assert self.client.grant[state].code == aresp["code"]
        assert self.client.grant[state].grant_expiration_time

    def test_parse_authz_resp_query(self):
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state=hij"
        aresp = self.client.parse_response(AuthorizationResponse,
                                           info=query,
                                           sformat="urlencoded")

        assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA"
        assert aresp["state"] == "hij"

        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):
        code = "SplxlOBeZQQYbYS6WxSbIA"
        states = ["ghi", "hij", "klm"]

        for state in states:
            self.client.parse_response(
                AuthorizationResponse,
                info="code={}&state={}".format(code, state),
                sformat="urlencoded",
            )

        for state in states:
            assert self.client.grant[state].code == code

        assert _eq(self.client.grant.keys(), states)

    def test_parse_authz_resp_query_unknown_parameter(self):
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state=xyz&foo=bar"
        aresp = self.client.parse_response(AuthorizationResponse,
                                           info=query,
                                           sformat="urlencoded")

        assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA"
        assert aresp["state"] == "xyz"

        # assert "foo" not in aresp # TODO unknown parameter not discarded

        assert self.client.grant["xyz"]
        assert self.client.grant["xyz"].code == aresp["code"]
        assert self.client.grant["xyz"].grant_expiration_time

    def test_construct_access_token_req(self):
        grant = Grant()
        grant.code = "AbCdEf"
        grant.grant_expiration_time = time_util.utc_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"] == self.redirect_uri

    def test_construct_access_token_req_client_credentials(self):
        # scope is default=""
        request_args = {"grant_type": "client_credentials"}
        atr = self.client.construct_AccessTokenRequest(
            state="stat",
            request=CCAccessTokenRequest,
            request_args=request_args)

        assert atr["grant_type"] == "client_credentials"
        assert atr["state"] == "stat"

    def test_construct_access_token_req_extension_grant(self):
        request_args = {
            "grant_type": "urn:ietf:params:oauth:grant-type:saml2-bearer",
            "assertion": "saml assertion",
        }
        atr = self.client.construct_AccessTokenRequest(
            request=ExtensionTokenRequest, request_args=request_args)
        assert atr[
            "grant_type"] == "urn:ietf:params:oauth:grant-type:saml2-bearer"
        assert atr["assertion"] == "saml assertion"

    def test_construct_access_token_request_fail(self):
        with pytest.raises(GrantError):
            self.client.construct_AccessTokenRequest(state="unknown")

    def test_construct_access_token_req_override(self):
        grant = Grant()
        grant.code = "AbCdEf"
        grant.grant_expiration_time = time_util.utc_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"] == self.redirect_uri

    def test_parse_access_token_resp(self):
        atr = AccessTokenResponse(
            access_token="2YotnFZFEjr1zCsicMWpAA",
            token_type="example",
            expires_in=3600,
            refresh_token="tGzv3JOkF0XG5Qx2TlKWIA",
            example_parameter="example_value",
        )

        self.client.parse_response(AccessTokenResponse,
                                   info=json.dumps(atr.to_dict()))

        _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.token_expiration_time > time_util.time_sans_frac()
        assert token.refresh_token == "tGzv3JOkF0XG5Qx2TlKWIA"

    def test_get_access_token_refresh_with_refresh_token(self):
        self.client.grant["foo"] = Grant()
        _get = time_util.utc_time_sans_frac() + 60
        self.client.grant["foo"].grant_expiration_time = _get
        self.client.grant["foo"].code = "access_code"
        resp = AccessTokenResponse(refresh_token="refresh_with_me",
                                   access_token="access")
        token = Token(resp)
        self.client.grant["foo"].tokens.append(token)

        # Uses refresh_token from previous response
        atr = self.client.construct_RefreshAccessTokenRequest(token=token)

        assert atr["grant_type"] == "refresh_token"
        assert atr["refresh_token"] == "refresh_with_me"

    def test_get_access_token_refresh_from_state(self):
        self.client.grant["foo"] = Grant()
        _get = time_util.utc_time_sans_frac() + 60
        self.client.grant["foo"].grant_expiration_time = _get
        self.client.grant["foo"].code = "access_code"

        resp = AccessTokenResponse(refresh_token="refresh_with_me",
                                   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 isinstance(atr, RefreshAccessTokenRequest)
        assert atr["grant_type"] == "refresh_token"
        assert atr["refresh_token"] == "refresh_with_me"

    def test_parse_authz_err_resp(self):
        error = "access_denied"
        state = "xyz"
        ruri = "{}?error={}&state={}".format(self.redirect_uri, error, state)

        resp = self.client.parse_response(AuthorizationResponse,
                                          info=ruri,
                                          sformat="urlencoded")

        assert isinstance(resp, AuthorizationErrorResponse)
        assert resp["error"] == error
        assert resp["state"] == state

    def test_return_non_existant_grant(self):
        assert self.client.grant_from_state("123456abcdef") is None

    def test_get_grant(self):
        resp = AuthorizationResponse(code="code", state="state")
        grant = Grant()
        grant.add_code(resp)

        self.client.grant["state"] = grant
        new_grant = self.client.grant_from_state("state")
        assert new_grant is not None
        assert new_grant.code == "code"

    def test_construct_access_token_req_with_extra_args(self):
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state=abc"
        self.client.parse_response(AuthorizationResponse,
                                   info=query,
                                   sformat="urlencoded")

        req = self.client.construct_AccessTokenRequest(
            state="abc", extra_args={"foo": "bar"})

        assert _eq(
            req.keys(),
            [
                "code", "grant_type", "client_id", "redirect_uri", "foo",
                "state"
            ],
        )
        assert req["foo"] == "bar"

    def test_request_info_simple(self):
        req_args = {"state": "hmm", "response_type": "code"}
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest, request_args=req_args)

        assert uri == self.authorization_endpoint
        body_elts = body.split("&")
        expected_body = (
            "state=hmm&redirect_uri={}&response_type=code&client_id=1".format(
                quote(self.redirect_uri, safe="")))
        expected_body_elts = expected_body.split("&")
        assert set(body_elts) == set(expected_body_elts)
        assert h_args == {
            "headers": {
                "Content-Type": "application/x-www-form-urlencoded"
            }
        }
        assert isinstance(cis, AuthorizationRequest)

    def test_request_info_simple_get(self):
        uri, body, h_args, cis = self.client.request_info(AuthorizationRequest,
                                                          method="GET")
        assert url_compare(
            uri,
            "{}?redirect_uri={}&response_type=code&client_id=1".format(
                self.authorization_endpoint, quote(self.redirect_uri,
                                                   safe="")),
        )
        assert body is None
        assert h_args == {}

    def test_request_info_simple_get_with_req_args(self):
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest, method="GET", request_args={"state": "init"})

        assert url_compare(
            uri,
            "{}?state=init&redirect_uri={}&response_type=code&client_id=1".
            format(self.authorization_endpoint,
                   quote(self.redirect_uri, safe="")),
        )
        assert body is None
        assert h_args == {}
        assert isinstance(cis, AuthorizationRequest)

    def test_request_info_simple_get_with_extra_args(self):
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest, method="GET", extra_args={"rock": "little"})

        assert url_compare(
            uri,
            "{}?redirect_uri={}&response_type=code&client_id=1&rock=little".
            format(self.authorization_endpoint,
                   quote(self.redirect_uri, safe="")),
        )
        assert body is None
        assert h_args == {}
        assert isinstance(cis, AuthorizationRequest)

    def test_request_info_with_req_and_extra_args(self):
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest,
            method="GET",
            request_args={"state": "init"},
            extra_args={"rock": "little"},
        )

        expected = (
            "{}?state=init&redirect_uri={}&response_type=code&client_id=1&rock=little"
        )
        assert url_compare(
            uri,
            expected.format(self.authorization_endpoint,
                            quote(self.redirect_uri, safe="")),
        )
        assert body is None
        assert h_args == {}
        assert isinstance(cis, AuthorizationRequest)

    def test_construct_access_token_req_expired_grant(self):
        resp = AuthorizationResponse(code="code", state="state")
        grant = Grant(-10)  # expired grant
        grant.add_code(resp)

        client = Client()
        client.grant["openid"] = grant
        with pytest.raises(GrantExpired):
            client.construct_AccessTokenRequest(state="openid")

    def test_parse_access_token_resp_json(self):
        atr = self.client.parse_response(AccessTokenResponse,
                                         info=ACC_TOK_RESP.to_json())
        assert _eq(atr.keys(),
                   ["token_type", "scope", "access_token", "refresh_token"])

    def test_parse_access_token_resp_urlencoded(self):
        uatr = self.client.parse_response(AccessTokenResponse,
                                          info=ACC_TOK_RESP.to_urlencoded(),
                                          sformat="urlencoded")
        assert _eq(uatr.keys(),
                   ["token_type", "scope", "access_token", "refresh_token"])

    def test_parse_access_token_resp_url(self):
        url = "{}?{}".format("https://example.com/token",
                             ACC_TOK_RESP.to_urlencoded())
        uatr = self.client.parse_response(AccessTokenResponse,
                                          info=url,
                                          sformat="urlencoded")
        assert _eq(uatr.keys(),
                   ["token_type", "scope", "access_token", "refresh_token"])

    def test_parse_error_resp(self):
        err = ErrorResponse(
            error="invalid_request",
            error_description="Something was missing",
            error_uri="http://example.com/error_message.html",
        )
        jerr = err.to_json()
        uerr = err.to_urlencoded()

        self.client.parse_response(AccessTokenResponse, info=jerr)
        self.client.parse_response(AccessTokenResponse,
                                   info=uerr,
                                   sformat="urlencoded")

        with pytest.raises(ResponseError):
            self.client.parse_response(AccessTokenResponse,
                                       info=jerr,
                                       sformat="urlencoded")

        with pytest.raises(DecodeError):
            self.client.parse_response(AccessTokenResponse, info=uerr)

        with pytest.raises(FormatError):
            self.client.parse_response(
                AccessTokenResponse,
                info=jerr,
                sformat="focus"  # type: ignore
            )

    def test_parse_access_token_resp_missing_attribute(self):
        atresp = AccessTokenResponse(
            access_token="SlAV32hkKG",
            token_type="Bearer",
            refresh_token="8xLOxBtZp8",
            expire_in=3600,
        )
        atdict = atresp.to_dict()
        del atdict["access_token"]  # remove required access_token
        atj = json.dumps(atdict)

        with pytest.raises(MissingRequiredAttribute):
            self.client.parse_response(AccessTokenResponse, info=atj)

        with pytest.raises(MissingRequiredAttribute):
            self.client.parse_response(AccessTokenResponse,
                                       info=urlencode(atdict),
                                       sformat="urlencoded")

    def test_client_parse_args(self):
        args = {
            "response_type": "",
            "client_id": "client_id",
            "redirect_uri": "http://example.com/authz",
            "scope": "scope",
            "state": "state",
        }

        ar_args = self.client._parse_args(AuthorizationRequest, **args)

        assert _eq(
            ar_args.keys(),
            ["scope", "state", "redirect_uri", "response_type", "client_id"],
        )

    def test_client_parse_extra_args(self):
        args = {
            "response_type": "",
            "client_id": "client_id",
            "redirect_uri": "http://example.com/authz",
            "scope": "scope",
            "state": "state",
            "extra_session": "home",
        }
        ar_args = self.client._parse_args(AuthorizationRequest, **args)

        assert _eq(
            ar_args.keys(),
            [
                "state",
                "redirect_uri",
                "response_type",
                "client_id",
                "scope",
                "extra_session",
            ],
        )

    def test_client_endpoint(self):
        self.client.authorization_endpoint = "https://example.org/oauth2/as"
        self.client.token_endpoint = "https://example.org/oauth2/token"
        self.client.token_revocation_endpoint = "https://example.org/oauth2/token_rev"

        assert (self.client._endpoint("authorization_endpoint") ==
                "https://example.org/oauth2/as")
        assert (self.client._endpoint("token_endpoint") ==
                "https://example.org/oauth2/token")
        assert (self.client._endpoint("token_revocation_endpoint") ==
                "https://example.org/oauth2/token_rev")

        auth_endpoint = self.client._endpoint(
            "authorization_endpoint",
            **{"authorization_endpoint": "https://example.com/as"})
        assert auth_endpoint == "https://example.com/as"

        self.client.token_endpoint = ""
        with pytest.raises(MissingEndpoint):
            self.client._endpoint("token_endpoint")
            self.client._endpoint("foo_endpoint")

    def test_do_access_token_request_client_credentials(self):
        class CCMessageFactory(OauthMessageFactory):
            """We are doing client credentials."""

            token_endpoint = MessageTuple(CCAccessTokenRequest,
                                          AccessTokenResponse)

        self.client.message_factory = CCMessageFactory
        with responses.RequestsMock() as rsps:
            rsps.add(
                rsps.POST,
                self.token_endpoint,
                json={
                    "access_token": "Token",
                    "token_type": "bearer"
                },
            )

            resp = self.client.do_access_token_request()
            assert rsps.calls[
                0].request.body == "grant_type=client_credentials"

        assert isinstance(resp, AccessTokenResponse)
        assert resp["access_token"] == "Token"

    def test_do_access_token_request_extension_grant(self):
        class ExtensionMessageFactory(OauthMessageFactory):
            """We are doing Extension grant."""

            token_endpoint = MessageTuple(ExtensionTokenRequest,
                                          AccessTokenResponse)

        self.client.message_factory = ExtensionMessageFactory
        request_args = {
            "assertion": "saml assertion",
            "grant_type": "urn:ietf:params:oauth:grant-type:saml2-bearer",
        }
        with responses.RequestsMock() as rsps:
            rsps.add(
                rsps.POST,
                self.token_endpoint,
                json={
                    "access_token": "Token",
                    "token_type": "bearer"
                },
            )

            resp = self.client.do_access_token_request(
                request_args=request_args)
            request = parse_qs(rsps.calls[0].request.body)
            assert request["assertion"][0] == "saml assertion"
            assert (request["grant_type"][0] ==
                    "urn:ietf:params:oauth:grant-type:saml2-bearer")

        assert isinstance(resp, AccessTokenResponse)
        assert resp["access_token"] == "Token"
Example #55
0
class TestOAuthClient():
    def setup_class(self):
        self.client = Client("1")
        self.client.redirect_uris = ["http://example.com/redirect"]

    def test_areq_1(self):
        ar = self.client.construct_AuthorizationRequest(
            request_args={"response_type": ["code"]})

        assert ar["redirect_uri"] == "http://example.com/redirect"
        assert ar["response_type"] == ["code"]
        assert ar["client_id"] == "1"
        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"] == "1"
        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"] == "1"
        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, sformat="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, sformat="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, sformat="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, sformat="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.utc_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.utc_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"] == "1"

    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)

        print atr.to_dict()
        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()
        _get = time_util.utc_time_sans_frac() + 60
        self.client.grant["foo"].grant_expiration_time = _get
        self.client.grant["foo"].code = "access_code"

        print self.client.grant["foo"]
        resp = AccessTokenResponse(refresh_token="refresh_with_me",
                                   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(AuthorizationResponse,
                                          info=ruri, sformat="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):
        print self.client.__dict__.items()
        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',
                                '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'
        assert body == "redirect_uri=http%3A%2F%2Fclient.example.com%2Fauthz&response_type=code&client_id=1"
        assert h_args == {'headers': {'content-type':
                                          'application/x-www-form-urlencoded'}}
        assert cis.type() == "AuthorizationRequest"

    def test_request_info_simple_get(self):
        #self.client.authorization_endpoint = "https://example.com/authz"
        uri, body, h_args, cis = self.client.request_info(AuthorizationRequest,
                                                          method="GET")

        assert uri == 'https://example.com/authz?redirect_uri=http%3A%2F%2Fclient.example.com%2Fauthz&response_type=code&client_id=1'
        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
        assert uri == 'https://example.com/authz?state=init&redirect_uri=http%3A%2F%2Fclient.example.com%2Fauthz&response_type=code&client_id=1'
        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
        assert uri == 'https://example.com/authz?redirect_uri=http%3A%2F%2Fclient.example.com%2Fauthz&response_type=code&client_id=1&rock=little'
        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
        assert uri == 'https://example.com/authz?state=init&redirect_uri=http%3A%2F%2Fclient.example.com%2Fauthz&response_type=code&client_id=1&rock=little'
        assert body is None
        assert h_args == {}
        assert cis.type() == "AuthorizationRequest"
Example #56
0
 def setup_class(self):
     self.client = Client("1")
     self.client.redirect_uris = ["http://example.com/redirect"]
Example #57
0
def client():
    cli = Client(**CLIENT_CONF)
    cli.client_secret = "boarding pass"
    return cli
Example #58
0
class TestClient(object):
    @pytest.fixture(autouse=True)
    def create_client(self):
        self.redirect_uri = "https://example.com/redirect"
        self.authorization_endpoint = "https://example.com/authz"

        self.client = Client("1")  # pylint: disable=attribute-defined-outside-init
        self.client.redirect_uris = [self.redirect_uri]
        self.client.response_type = "code"
        self.client.authorization_endpoint = self.authorization_endpoint

    def test_construct_authz_req_no_optional_params(self):
        areq = self.client.construct_AuthorizationRequest(request_args={"response_type": ["code"]})

        assert areq["redirect_uri"] == self.redirect_uri
        assert areq["response_type"] == ["code"]
        assert areq["client_id"] == "1"
        assert "state" not in areq
        assert "scope" not in areq

    def test_construct_authz_req_no_input(self):
        self.client.response_type = ["code"]
        atr = self.client.construct_AuthorizationRequest()

        assert atr["redirect_uri"] == self.redirect_uri
        assert atr["response_type"] == ["code"]
        assert atr["client_id"] == "1"

    def test_construct_authz_req_optional_params(self):
        req_args = {"response_type": ["code"], "scope": ["foo", "bar"], "state": "abc"}
        areq = self.client.construct_AuthorizationRequest(request_args=req_args)

        assert areq["redirect_uri"] == self.redirect_uri
        assert areq["response_type"] == ["code"]
        assert areq["client_id"] == "1"
        assert areq["state"] == "abc"
        assert areq["scope"] == ["foo", "bar"]

    def test_construct_authz_req_replace_default_state(self):
        req_args = {"response_type": ["code"], "scope": ["foo", "bar"], "state": "efg"}
        areq = self.client.construct_AuthorizationRequest(request_args=req_args)

        assert areq["redirect_uri"] == self.redirect_uri
        assert areq["response_type"] == ["code"]
        assert areq["client_id"] == "1"
        assert areq["state"] == "efg"
        assert areq["scope"] == ["foo", "bar"]

    def test_parse_authz_resp_url(self):
        code = "SplxlOBeZQQYbYS6WxSbIA"
        state = "ghi"
        url = "{}?code={}&state={}".format(self.redirect_uri, code, state)
        aresp = self.client.parse_response(AuthorizationResponse, info=url, sformat="urlencoded")

        assert aresp["code"] == code
        assert aresp["state"] == state

        assert self.client.grant[state].code == aresp["code"]
        assert self.client.grant[state].grant_expiration_time

    def test_parse_authz_resp_query(self):
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state=hij"
        aresp = self.client.parse_response(AuthorizationResponse, info=query, sformat="urlencoded")

        assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA"
        assert aresp["state"] == "hij"

        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):
        code = "SplxlOBeZQQYbYS6WxSbIA"
        states = ["ghi", "hij", "klm"]

        for state in states:
            self.client.parse_response(
                AuthorizationResponse, info="code={}&state={}".format(code, state), sformat="urlencoded"
            )

        for state in states:
            assert self.client.grant[state].code == code

        assert _eq(self.client.grant.keys(), states)

    def test_parse_authz_resp_query_unknown_parameter(self):
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state=xyz&foo=bar"
        aresp = self.client.parse_response(AuthorizationResponse, info=query, sformat="urlencoded")

        assert aresp["code"] == "SplxlOBeZQQYbYS6WxSbIA"
        assert aresp["state"] == "xyz"

        # assert "foo" not in aresp # TODO unknown parameter not discarded

        assert self.client.grant["xyz"]
        assert self.client.grant["xyz"].code == aresp["code"]
        assert self.client.grant["xyz"].grant_expiration_time

    def test_construct_access_token_req(self):
        grant = Grant()
        grant.code = "AbCdEf"
        grant.grant_expiration_time = time_util.utc_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"] == self.redirect_uri

    def test_construct_access_token_request_fail(self):
        with pytest.raises(GrantError):
            self.client.construct_AccessTokenRequest(state="unknown")

    def test_construct_access_token_req_override(self):
        grant = Grant()
        grant.code = "AbCdEf"
        grant.grant_expiration_time = time_util.utc_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"] == self.redirect_uri

    def test_parse_access_token_resp(self):
        atr = AccessTokenResponse(
            access_token="2YotnFZFEjr1zCsicMWpAA",
            token_type="example",
            expires_in=3600,
            refresh_token="tGzv3JOkF0XG5Qx2TlKWIA",
            example_parameter="example_value",
        )

        self.client.parse_response(AccessTokenResponse, info=json.dumps(atr.to_dict()))

        _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
        # with pytest.raises(AttributeError): # TODO not satisfied
        #     nothing = token.example_parameter

    def test_get_access_token_refresh_with_refresh_token(self):
        self.client.grant["foo"] = Grant()
        _get = time_util.utc_time_sans_frac() + 60
        self.client.grant["foo"].grant_expiration_time = _get
        self.client.grant["foo"].code = "access_code"
        resp = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access")
        token = Token(resp)
        self.client.grant["foo"].tokens.append(token)

        # Uses refresh_token from previous response
        atr = self.client.construct_RefreshAccessTokenRequest(token=token)

        assert atr["grant_type"] == "refresh_token"
        assert atr["refresh_token"] == "refresh_with_me"

    def test_get_access_token_refresh_from_state(self):
        self.client.grant["foo"] = Grant()
        _get = time_util.utc_time_sans_frac() + 60
        self.client.grant["foo"].grant_expiration_time = _get
        self.client.grant["foo"].code = "access_code"

        resp = AccessTokenResponse(refresh_token="refresh_with_me", 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 isinstance(atr, RefreshAccessTokenRequest)
        assert atr["grant_type"] == "refresh_token"
        assert atr["refresh_token"] == "refresh_with_me"

    def test_parse_authz_err_resp(self):
        error = "access_denied"
        state = "xyz"
        ruri = "{}?error={}&state={}".format(self.redirect_uri, error, state)

        resp = self.client.parse_response(AuthorizationResponse, info=ruri, sformat="urlencoded")

        assert isinstance(resp, AuthorizationErrorResponse)
        assert resp["error"] == error
        assert resp["state"] == state

    def test_return_non_existant_grant(self):
        assert self.client.grant_from_state("123456abcdef") is None

    def test_get_grant(self):
        resp = AuthorizationResponse(code="code", state="state")
        grant = Grant()
        grant.add_code(resp)

        self.client.grant["state"] = grant
        assert self.client.grant_from_state("state").code == "code"

    def test_construct_access_token_req_with_extra_args(self):
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state=abc"
        self.client.parse_response(AuthorizationResponse, info=query, sformat="urlencoded")

        req = self.client.construct_AccessTokenRequest(state="abc", extra_args={"foo": "bar"})

        assert _eq(req.keys(), ["code", "grant_type", "client_id", "redirect_uri", "foo"])
        assert req["foo"] == "bar"

    def test_construct_TokenRevocationRequest(self):
        self.client.grant["foo"] = Grant()
        _get = time_util.utc_time_sans_frac() + 60
        self.client.grant["foo"].grant_expiration_time = _get
        self.client.grant["foo"].code = "access_code"
        resp = AccessTokenResponse(refresh_token="refresh_with_me", access_token="access")
        token = Token(resp)
        self.client.grant["foo"].tokens.append(token)

        state = "foo"
        query = "code=SplxlOBeZQQYbYS6WxSbIA&state={}".format(state)
        self.client.parse_response(AuthorizationResponse, info=query, sformat="urlencoded")

        req = self.client.construct_TokenRevocationRequest(state=state)
        assert _eq(req.keys(), ["token"])
        assert req["token"] == "access"

    def test_request_info_simple(self):
        req_args = {"state": "hmm", "response_type": "code"}
        uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, request_args=req_args)

        # default == "POST"
        assert uri == self.authorization_endpoint
        body_elts = body.split("&")
        expected_body = "state=hmm&redirect_uri={}&response_type=code&client_id=1".format(
            quote(self.redirect_uri, safe="")
        )
        expected_body_elts = expected_body.split("&")
        assert set(body_elts) == set(expected_body_elts)
        assert h_args == {"headers": {"Content-type": "application/x-www-form-urlencoded"}}
        assert isinstance(cis, AuthorizationRequest)

    def test_request_info_simple_get(self):
        uri, body, h_args, cis = self.client.request_info(AuthorizationRequest, method="GET")
        assert url_compare(
            uri,
            "{}?redirect_uri={}&response_type=code&client_id=1".format(
                self.authorization_endpoint, quote(self.redirect_uri, safe="")
            ),
        )
        assert body is None
        assert h_args == {}

    def test_request_info_simple_get_with_req_args(self):
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest, method="GET", request_args={"state": "init"}
        )

        assert url_compare(
            uri,
            "{}?state=init&redirect_uri={}&response_type=code&client_id=1".format(
                self.authorization_endpoint, quote(self.redirect_uri, safe="")
            ),
        )
        assert body is None
        assert h_args == {}
        assert isinstance(cis, AuthorizationRequest)

    def test_request_info_simple_get_with_extra_args(self):
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest, method="GET", extra_args={"rock": "little"}
        )

        assert url_compare(
            uri,
            "{}?redirect_uri={}&response_type=code&client_id=1&rock=little".format(
                self.authorization_endpoint, quote(self.redirect_uri, safe="")
            ),
        )
        assert body is None
        assert h_args == {}
        assert isinstance(cis, AuthorizationRequest)

    def test_request_info_with_req_and_extra_args(self):
        uri, body, h_args, cis = self.client.request_info(
            AuthorizationRequest, method="GET", request_args={"state": "init"}, extra_args={"rock": "little"}
        )

        expected = "{}?state=init&redirect_uri={}&response_type=code&client_id=1&rock=little"
        assert url_compare(uri, expected.format(self.authorization_endpoint, quote(self.redirect_uri, safe="")))
        assert body is None
        assert h_args == {}
        assert isinstance(cis, AuthorizationRequest)

    def test_construct_access_token_req_expired_grant(self):
        resp = AuthorizationResponse(code="code", state="state")
        grant = Grant(-10)  # expired grant
        grant.add_code(resp)

        client = Client()
        client.grant["openid"] = grant
        with pytest.raises(GrantExpired):
            client.construct_AccessTokenRequest(state="openid")

    def test_parse_access_token_resp_json(self):
        atr = self.client.parse_response(AccessTokenResponse, info=ACC_TOK_RESP.to_json())
        assert _eq(atr.keys(), ["token_type", "scope", "access_token", "refresh_token"])

    def test_parse_access_token_resp_urlencoded(self):
        uatr = self.client.parse_response(AccessTokenResponse, info=ACC_TOK_RESP.to_urlencoded(), sformat="urlencoded")
        assert _eq(uatr.keys(), ["token_type", "scope", "access_token", "refresh_token"])

    def test_parse_access_token_resp_url(self):
        url = "{}?{}".format("https://example.com/token", ACC_TOK_RESP.to_urlencoded())
        uatr = self.client.parse_response(AccessTokenResponse, info=url, sformat="urlencoded")
        assert _eq(uatr.keys(), ["token_type", "scope", "access_token", "refresh_token"])

    def test_parse_error_resp(self):
        err = ErrorResponse(
            error="invalid_request",
            error_description="Something was missing",
            error_uri="http://example.com/error_message.html",
        )
        jerr = err.to_json()
        uerr = err.to_urlencoded()

        _ = self.client.parse_response(AccessTokenResponse, info=jerr)
        _ = self.client.parse_response(AccessTokenResponse, info=uerr, sformat="urlencoded")

        with pytest.raises(ResponseError):
            self.client.parse_response(AccessTokenResponse, info=jerr, sformat="urlencoded")

        with pytest.raises(ValueError):
            self.client.parse_response(AccessTokenResponse, info=uerr)

        with pytest.raises(FormatError):
            self.client.parse_response(AccessTokenResponse, info=jerr, sformat="focus")

    def test_parse_access_token_resp_missing_attribute(self):
        atresp = AccessTokenResponse(
            access_token="SlAV32hkKG", token_type="Bearer", refresh_token="8xLOxBtZp8", expire_in=3600
        )
        atdict = atresp.to_dict()
        del atdict["access_token"]  # remove required access_token
        atj = json.dumps(atdict)

        with pytest.raises(MissingRequiredAttribute):
            self.client.parse_response(AccessTokenResponse, info=atj)

        with pytest.raises(MissingRequiredAttribute):
            self.client.parse_response(AccessTokenResponse, info=urlencode(atdict), sformat="urlencoded")

    def test_client_parse_args(self):
        args = {
            "response_type": "",
            "client_id": "client_id",
            "redirect_uri": "http://example.com/authz",
            "scope": "scope",
            "state": "state",
        }

        ar_args = self.client._parse_args(AuthorizationRequest, **args)

        assert _eq(ar_args.keys(), ["scope", "state", "redirect_uri", "response_type", "client_id"])

    def test_client_parse_extra_args(self):
        args = {
            "response_type": "",
            "client_id": "client_id",
            "redirect_uri": "http://example.com/authz",
            "scope": "scope",
            "state": "state",
            "extra_session": "home",
        }
        ar_args = self.client._parse_args(AuthorizationRequest, **args)

        assert _eq(ar_args.keys(), ["state", "redirect_uri", "response_type", "client_id", "scope", "extra_session"])

    def test_client_endpoint(self):
        self.client.authorization_endpoint = "https://example.org/oauth2/as"
        self.client.token_endpoint = "https://example.org/oauth2/token"
        self.client.token_revocation_endpoint = "https://example.org/oauth2/token_rev"

        assert self.client._endpoint("authorization_endpoint") == "https://example.org/oauth2/as"
        assert self.client._endpoint("token_endpoint") == "https://example.org/oauth2/token"
        assert self.client._endpoint("token_revocation_endpoint") == "https://example.org/oauth2/token_rev"

        auth_endpoint = self.client._endpoint(
            "authorization_endpoint", **{"authorization_endpoint": "https://example.com/as"}
        )
        assert auth_endpoint == "https://example.com/as"

        self.client.token_endpoint = ""
        with pytest.raises(MissingEndpoint):
            self.client._endpoint("token_endpoint")
            self.client._endpoint("foo_endpoint")
Example #59
0
    def __init__(
        self,
        session_db,
        client_config=None,
        server_info=None,
        authz_page="",
        response_type="",
        scope="",
        flow_type="",
        password=None,
        settings=None,
    ):
        """
        Initialize a Consumer instance.

        Keyword Args:
            settings
                Instance of :class:`OauthConsumerSettings` with configuration options.
                Currently used settings are:
                 - verify_ssl
                 - client_cert
                 - timeout

        :param session_db: Where info are kept about sessions acts like a
            dictionary
        :param client_config: Client configuration
        :param server_info: Information about the server
        :param authz_page:
        :param response_type:
        :param scope:
        :param flow_type:
        """
        self.settings = settings or OauthConsumerSettings()
        if client_config is None:
            client_config = {}
        if "verify_ssl" in client_config:
            warnings.warn(
                "Setting `verify_ssl` in `client_config` is deprecated, please use `settings` instead if you need "
                "to set a non-default value.",
                DeprecationWarning,
                stacklevel=2,
            )
            self.settings.verify_ssl = client_config.pop("verify_ssl")
        if "client_cert" in client_config:
            warnings.warn(
                "Setting `client_cert` in `client_config` is deprecated, please use `settings` instead if you need "
                "to set a non-default value.",
                DeprecationWarning,
                stacklevel=2,
            )
            self.settings.client_cert = client_config.pop("client_cert")
        if "timeout" in client_config:
            warnings.warn(
                "Setting `timeout` in `client_config` is deprecated, please use `settings` instead if you need "
                "to set a non-default value.",
                DeprecationWarning,
                stacklevel=2,
            )
            self.settings.timeout = client_config.pop("timeout")

        Client.__init__(self, settings=self.settings, **client_config)

        self.authz_page = authz_page
        self.response_type = response_type
        self.scope = scope
        self.flow_type = flow_type
        self.password = password

        if server_info:
            for endpoint in ENDPOINTS:
                try:
                    setattr(self, endpoint, server_info[endpoint])
                except KeyError:
                    setattr(self, endpoint, None)
        else:
            for endpoint in ENDPOINTS:
                setattr(self, endpoint, None)

        self.sdb = session_db
        self.seed = rndstr().encode("utf-8")
        self._request = None