Example #1
0
    def __init__(self, name, sdb, cdb, authn_method, userinfo, authz,
                 client_authn, symkey, urlmap=None, ca_certs="", keyjar=None,
                 hostname=""):

        AProvider.__init__(self, name, sdb, cdb, authn_method, authz,
                           client_authn, symkey, urlmap)
        self.userinfo = userinfo
        self.server = Server(ca_certs=ca_certs)

        if keyjar:
            self.server.keyjar = keyjar

        self.keyjar = self.server.keyjar
        self.endpoints = []
        self.baseurl = ""
        self.cert = []
        self.cert_encryption = []

        if authn_method:
            self.cookie_func = authn_method.create_cookie
        else:
            self.cookie_func = None

        self.cookie_name = "pyoidc"
        self.seed = ""
        self.sso_ttl = 0
        self.test_mode = False
        self.jwks_uri = []

        self.authn_as = None
        self.preferred_id_type = "public"
        self.hostname = hostname or socket.gethostname
        self.register_endpoint = "%s%s" % (self.baseurl, "register")
Example #2
0
def test_provider_authenticated_token():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)
    _session_db = {}
    cons = Consumer(_session_db, client_config = CLIENT_CONFIG,
                    server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True
    cons.response_type = "token"
    environ = BASE_ENVIRON

    location = cons.begin(environ, start_response)

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = location.split("?")[1]

    resp = provider.authorization_endpoint(environ, start_response)

    sid = resp[0][len("FORM with "):]
    environ2 = create_return_form_env("user", "password", sid)

    resp2 = provider.authenticated(environ2, start_response)

    assert len(resp2) == 1
    txt = resp2[0]
    assert "access_token=" in txt
    assert "token_type=Bearer" in txt
Example #3
0
def test_provider_authenticated():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN_BROKER, AUTHZ,
                        verify_client, symkey=rndstr(16))
    _session_db = {}
    cons = Consumer(_session_db, client_config=CLIENT_CONFIG,
                    server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True

    location = cons.begin("http://localhost:8087",
                          "http://localhost:8088/authorization")

    query_string = location.split("?")[1]

    resp = provider.authorization_endpoint(query_string)
    assert resp.status == "302 Found"
    print resp.headers
    print resp.message
    if content_type(resp.headers) == "json":
        resp = resp.message
    else:
        resp = resp.message.split("?")[1]
    aresp = cons.handle_authorization_response(query=resp)

    print aresp.keys()
    assert aresp.type() == "AuthorizationResponse"
    assert _eq(aresp.keys(), ['state', 'code'])

    print cons.grant[cons.state].keys()
    assert _eq(cons.grant[cons.state].keys(), ['tokens', 'code', 'exp_in',
                                               'seed', 'id_token',
                                               'grant_expiration_time'])
Example #4
0
 def test_complete_authz_pyoidc_cookie_exists(self, session_db_factory):
     provider = Provider("pyoicserver",
                         session_db_factory(ISSUER),
                         CDB,
                         AUTHN_BROKER,
                         AUTHZ,
                         verify_client,
                         baseurl='https://example.com/as')
     areq = {
         'client_id': 'client1',
         'response_type': ['code'],
         'redirect_uri': 'http://localhost:8087/authz'
     }
     sid = provider.sdb.access_token.key(user='******', areq=areq)
     access_code = provider.sdb.access_token(sid=sid)
     provider.sdb[sid] = {
         'oauth_state': 'authz',
         'sub': 'sub',
         'client_id': 'client1',
         'code': access_code,
         'redirect_uri': 'http://localhost:8087/authz'
     }
     cookie = 'pyoidc_sso=test::test'
     response, header, redirect, fragment = provider._complete_authz(
         'sub', areq, sid, cookie=cookie)
     assert len(header) == 0
     assert not fragment
     assert redirect == 'http://localhost:8087/authz'
     assert 'code' in response
Example #5
0
def test_provider_authenticated_none():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)
    _session_db = {}
    cons = Consumer(_session_db, client_config = CLIENT_CONFIG,
                    server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True
    cons.response_type = "none"
    environ = BASE_ENVIRON

    location = cons.begin(environ, start_response)

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = location.split("?")[1]

    resp = provider.authorization_endpoint(environ, start_response)

    sid = resp[0][len("FORM with "):]
    environ2 = create_return_form_env("user", "password", sid)

    resp2 = provider.authenticated(environ2, start_response)

    assert len(resp2) == 1
    txt = resp2[0]
    pos0 = txt.index("<title>") + len("<title>Redirecting to ")
    pos1 = txt.index("</title>")
    location = txt[pos0:pos1]
    print location

    assert location.startswith("http://localhost:8087/authz")
    query = location.split("?")[1]
    assert query.startswith("state=")
    assert "&" not in query
Example #6
0
    def __init__(self, name, sdb, cdb, authn_broker, userinfo, authz,
                 client_authn, symkey, urlmap=None, ca_certs="", keyjar=None,
                 hostname="", template_lookup=None, verify_login_template=None):

        AProvider.__init__(self, name, sdb, cdb, authn_broker, authz,
                           client_authn, symkey, urlmap)

        self.endp.extend([UserinfoEndpoint, RegistrationEndpoint,
                          EndSessionEndpoint])

        self.userinfo = userinfo
        self.server = Server(ca_certs=ca_certs)

        if keyjar:
            self.server.keyjar = keyjar
        self.template_lookup = template_lookup
        self.verify_login_template = verify_login_template
        self.keyjar = self.server.keyjar
        self.baseurl = ""
        self.cert = []
        self.cert_encryption = []

        self.cookie_name = "pyoidc"
        self.seed = ""
        self.sso_ttl = 0
        self.test_mode = False
        self.jwks_uri = []

        self.authn_as = None
        self.preferred_id_type = "public"
        self.hostname = hostname or socket.gethostname
        self.register_endpoint = "%s%s" % (self.baseurl, "register")
Example #7
0
def test_token_endpoint_unauth():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN_BROKER, AUTHZ,
                        verify_client, symkey=rndstr(16))

    authreq = AuthorizationRequest(state="state",
                                   redirect_uri="http://example.com/authz",
                                   client_id="client1")

    _sdb = provider.sdb
    sid = _sdb.token.key(user="******", areq=authreq)
    access_grant = _sdb.token(sid=sid)
    _sdb[sid] = {
        "oauth_state": "authz",
        "user_id": "user_id",
        "authzreq": "",
        "client_id": "client1",
        "code": access_grant,
        "code_used": False,
        "redirect_uri": "http://example.com/authz"
    }

    # Construct Access token request
    areq = AccessTokenRequest(code=access_grant,
                              redirect_uri="http://example.com/authz",
                              client_id="client2", client_secret="hemlighet",)

    print areq.to_dict()
    resp = provider.token_endpoint(request=areq.to_urlencoded())
    print resp.message
    atr = TokenErrorResponse().deserialize(resp.message, "json")
    print atr.keys()
    assert _eq(atr.keys(), ['error_description', 'error'])
Example #8
0
def test_provider_authenticated_token():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN_BROKER, AUTHZ, verify_client)
    _session_db = {}
    cons = Consumer(_session_db, client_config=CLIENT_CONFIG, server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True

    location = cons.begin("http://localhost:8087", "http://localhost:8088/authorization", "token")

    QUERY_STRING = location.split("?")[1]
    resp = provider.authorization_endpoint(QUERY_STRING)
    print resp.headers
    print resp.message
    txt = resp.message
    assert "access_token=" in txt
    assert "token_type=Bearer" in txt
def test_provider_init():
    provider = Provider("pyoicserv", sdb.SessionDB(SERVER_INFO["issuer"]), CDB,
                        AUTHN_BROKER, AUTHZ, verify_client)

    assert provider

    provider = Provider("pyoicserv",
                        sdb.SessionDB(SERVER_INFO["issuer"]),
                        CDB,
                        AUTHN_BROKER,
                        AUTHZ,
                        verify_client,
                        urlmap={"client1": ["https://example.com/authz"]})

    assert provider.urlmap["client1"] == ["https://example.com/authz"]
Example #10
0
def test_provider_authenticated():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)
    _session_db = {}
    cons = Consumer(_session_db, client_config = CLIENT_CONFIG,
                    server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True
    environ = BASE_ENVIRON

    location = cons.begin(environ, start_response)

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = location.split("?")[1]

    resp = provider.authorization_endpoint(environ, start_response)

    sid = resp[0][len("FORM with "):]
    environ2 = create_return_form_env("user", "password", sid)

    resp2 = provider.authenticated(environ2, start_response)

    print resp2[0]
    assert len(resp2) == 1
    txt = resp2[0]
    pos0 = txt.index("<title>") + len("<title>Redirecting to ")
    pos1 = txt.index("</title>")
    location = txt[pos0:pos1]
    print location

    assert location.startswith("http://localhost:8087/authz")

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = location.split("?")[1]

    aresp = cons.handle_authorization_response(environ, start_response)

    #aresp = client.parse_response(AuthorizationResponse, location,
    #                              format="urlencoded",
    #                              state="id-6da9ca0cc23959f5f33e8becd9b08cae")

    print aresp.keys()
    assert aresp.type() == "AuthorizationResponse"
    assert _eq(aresp.keys(), ['state', 'code'])

    print cons.grant[cons.state].keys()
    assert _eq(cons.grant[cons.state].keys(), ['tokens', 'code', 'exp_in',
                                               'seed', 'id_token',
                                               'grant_expiration_time'])
Example #11
0
def test_provider_authorization_endpoint():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN_BROKER, AUTHZ,
                        verify_client)

    bib = {"scope": ["openid"],
           "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
           "redirect_uri": "http://localhost:8087authz",
           "response_type": ["code"],
           "client_id": "a1b2c3"}

    arq = AuthorizationRequest(**bib)

    QUERY_STRING = arq.to_urlencoded()

    resp = provider.authorization_endpoint(request=QUERY_STRING)

    assert isinstance(resp, Response)
Example #12
0
def test_failed_authenticated():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)
    environ0 = create_return_form_env("haden", "secret", "sid1")
    resp1 = provider.authenticated(environ0, start_response)
    print resp1
    assert resp1 == ['<html>Wrong password</html>']

    environ1 = create_return_form_env("", "secret", "sid2")
    resp2 = provider.authenticated(environ1, start_response)
    print resp2
    assert resp2 == ["<html>Authentication failed</html>"]

    environ2 = create_return_form_env("hannibal", "hemligt", "sid3")
    print environ2
    resp = provider.authenticated(environ2, start_response)
    print resp
    assert resp == ['<html>Authentication failure: Not allowed to use this service (hannibal)</html>']
Example #13
0
def test_provider_authorization_endpoint():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)

    bib = {"scope": ["openid"],
           "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
           "redirect_uri": "http://localhost:8087authz",
           "response_type": ["code"],
           "client_id": "a1b2c3"}

    arq = AuthorizationRequest(**bib)

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = arq.to_urlencoded()

    resp = provider.authorization_endpoint(environ, start_response)

    print resp
    assert resp[0].startswith("FORM with")
Example #14
0
def test_provider_authenticated_1():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)
    _session_db = {}
    cons = Consumer(_session_db, client_config = CLIENT_CONFIG,
                    server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True
    environ = BASE_ENVIRON

    location = cons.begin(environ, start_response)

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = location.split("?")[1]

    _ = provider.authorization_endpoint(environ, start_response)

    #sid = resp[0][len("FORM with "):]
    environ2 = create_return_form_env("user", "password", "abcd")

    resp2 = provider.authenticated(environ2, start_response)
    print resp2
    assert resp2 == ['<html>Unknown session identifier</html>']
Example #15
0
    def test_init(self, session_db_factory):
        provider = Provider(
            "pyoicserv",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
        )
        assert provider

        provider = Provider(
            "pyoicserv",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            urlmap={"client1": ["https://example.com/authz"]},
        )
        assert provider.urlmap["client1"] == ["https://example.com/authz"]
Example #16
0
def test_token_endpoint():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, FUNCTIONS)

    authreq = AuthorizationRequest(state="state",
                                   redirect_uri="http://example.com/authz",
                                   client_id="client1")

    _sdb = provider.sdb
    sid = _sdb.token.key(user="******", areq=authreq)
    access_grant = _sdb.token(sid=sid)
    _sdb[sid] = {
        "oauth_state": "authz",
        "user_id": "user_id",
        "authzreq": "",
        "client_id": "client1",
        "code": access_grant,
        "code_used": False,
        "redirect_uri":"http://example.com/authz"
    }

    # Construct Access token request
    areq = AccessTokenRequest(code=access_grant,
                              redirect_uri="http://example.com/authz")


    str = areq.to_urlencoded()
    fil = StringIO.StringIO(buf=str)
    environ = BASE_ENVIRON.copy()
    environ["CONTENT_LENGTH"] = len(str)
    environ["wsgi.input"] = fil
    environ["REMOTE_USER"] = "******"

    resp = provider.token_endpoint(environ, start_response)
    print resp
    atr = AccessTokenResponse().deserialize(resp[0], "json")

    print atr.keys()
    assert _eq(atr.keys(), ['access_token', 'expires_in', 'token_type',
                            'refresh_token'])
Example #17
0
    def __init__(self, name, sdb, cdb, function, userdb, urlmap=None,
                 ca_certs="", jwt_keys=None):

        AProvider.__init__(self, name, sdb, cdb, function, urlmap)

        self.server = Server(jwt_keys=jwt_keys, ca_certs=ca_certs)

        self.keystore = self.server.keystore
        self.userdb = userdb

        self.function = function
        self.endpoints = []
        self.baseurl = ""
        self.cert = []
        self.cert_encryption = []

        self.cookie_func = None
        self.cookie_name = "pyoidc"
        self.seed = ""
        self.cookie_ttl = 0
        self.test_mode = False
        self.jwk = []
Example #18
0
def test_provider_authenticated_none():
    provider = Provider("pyoicserv", sdb.SessionDB(), CDB, AUTHN, AUTHZ,
                        verify_client)
    _session_db = {}
    cons = Consumer(_session_db, client_config=CLIENT_CONFIG,
                    server_info=SERVER_INFO, **CONSUMER_CONFIG)
    cons.debug = True

    location = cons.begin("http://localhost:8087",
                          "http://localhost:8088/authorization",
                          "none")

    QUERY_STRING = location.split("?")[1]

    resp2 = provider.authorization_endpoint(request=QUERY_STRING)

    location = resp2.message
    print location

    assert location.startswith("http://localhost:8087/authz")
    query = location.split("?")[1]
    assert query.startswith("state=")
    assert "&" not in query
Example #19
0
 def create_provider(self):
     self.provider = Provider("pyoicserv",
                              sdb.SessionDB(ISSUER), CDB,
                              AUTHN_BROKER, AUTHZ, verify_client,
                              baseurl='https://example.com/as')
Example #20
0
class TestProvider(object):
    @pytest.fixture(autouse=True)
    def create_provider(self):
        self.provider = Provider("pyoicserv",
                                 sdb.SessionDB(ISSUER), CDB,
                                 AUTHN_BROKER, AUTHZ, verify_client,
                                 baseurl='https://example.com/as')

    def test_init(self):
        provider = Provider("pyoicserv", sdb.SessionDB(ISSUER),
                            CDB,
                            AUTHN_BROKER, AUTHZ, verify_client)
        assert provider

        provider = Provider("pyoicserv", sdb.SessionDB(ISSUER),
                            CDB,
                            AUTHN_BROKER, AUTHZ, verify_client,
                            urlmap={"client1": ["https://example.com/authz"]})
        assert provider.urlmap["client1"] == ["https://example.com/authz"]

    def test_authorization_endpoint_faulty_redirect_uri(self):
        bib = {"scope": ["openid"],
               "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
               "redirect_uri": "http://localhost:8087/authz",
               # faulty redirect uri
               "response_type": ["code"],
               "client_id": "a1b2c3"}

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(request=arq.to_urlencoded())
        assert resp.status == "400 Bad Request"
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authenticated(self):
        _session_db = {}
        cons = Consumer(_session_db, client_config=CLIENT_CONFIG,
                        server_info=SERVER_INFO, **CONSUMER_CONFIG)

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization")

        resp = self.provider.authorization_endpoint(urlparse(location).query)
        assert resp.status == "303 See Other"
        resp = urlparse(resp.message).query
        aresp = cons.handle_authorization_response(query=resp)

        assert isinstance(aresp, AuthorizationResponse)
        assert _eq(aresp.keys(), ['state', 'code', 'client_id', 'iss'])
        assert _eq(cons.grant[sid].keys(), ['tokens', 'code', 'exp_in',
                                            'seed', 'id_token',
                                            'grant_expiration_time'])

    def test_authenticated_token(self):
        _session_db = {}
        cons = Consumer(_session_db, client_config=CLIENT_CONFIG,
                        server_info=SERVER_INFO, **CONSUMER_CONFIG)

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization",
                                   "token")

        QUERY_STRING = location.split("?")[1]
        resp = self.provider.authorization_endpoint(QUERY_STRING)
        auth_resp = parse_qs(urlparse(resp.message).fragment)

        assert "access_token" in auth_resp
        assert auth_resp["token_type"][0] == "Bearer"

    def test_token_endpoint(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client1",
                                  client_secret="hemlighet",
                                  grant_type='authorization_code')

        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ['access_token', 'token_type', 'refresh_token'])

    def test_token_endpoint_unauth(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client2",
                                  client_secret="hemlighet",
                                  grant_type='authorization_code')

        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ['error_description', 'error'])
Example #21
0
    from oic.utils.sdb import SessionDB

    parser = argparse.ArgumentParser()
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.add_argument('-d', dest='debug', action='store_true')
    parser.add_argument('-p', dest='port', default=80, type=int)
    parser.add_argument('-A', dest='authn_as', default="")
    parser.add_argument('-P', dest='provider_conf')
    parser.add_argument(dest="config")
    args = parser.parse_args()


    config = importlib.import_module(args.config)

    OAS = Provider(config.issuer, SessionDB(), config.CLIENT, FUNCTIONS,
                   config.USERDB)

    try:
        OAS.cookie_ttl = config.COOKIETTL
    except AttributeError:
        pass

    try:
        OAS.cookie_name = config.COOKIENAME
    except AttributeError:
        pass

    OAS.cookie_func = http_util.cookie

    #print URLS
    if args.debug:
Example #22
0
class TestProvider(object):
    @pytest.fixture(autouse=True)
    def create_provider(self, session_db_factory):
        self.provider = Provider("pyoicserv",
                                 session_db_factory(ISSUER), CDB,
                                 AUTHN_BROKER, AUTHZ, verify_client,
                                 baseurl='https://example.com/as')

    def test_init(self, session_db_factory):
        provider = Provider("pyoicserv", session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER, AUTHZ, verify_client)
        assert provider

        provider = Provider("pyoicserv", session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER, AUTHZ, verify_client,
                            urlmap={"client1": ["https://example.com/authz"]})
        assert provider.urlmap["client1"] == ["https://example.com/authz"]

    def test_authorization_endpoint_faulty_redirect_uri(self):
        bib = {"scope": ["openid"],
               "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
               "redirect_uri": "http://*****:*****@pytest.mark.parametrize("response_types", [
        ['token id_token', 'id_token'],
        ['id_token token']
    ])
    def test_response_types(self, response_types):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1",
                                       response_type='id_token token')

        self.provider.cdb = {
            "client1": {
                "client_secret": "hemlighet",
                "redirect_uris": [("http://example.com/authz", None)],
                'token_endpoint_auth_method': 'client_secret_post',
                'response_types': response_types
            }
        }

        res = self.provider.auth_init(authreq.to_urlencoded())
        assert isinstance(res, dict) and "areq" in res

    @pytest.mark.parametrize("response_types", [
        ['token id_token', 'id_token'],
        ['id_token token'],
        ['code id_token'],
        ['id_token code']
    ])
    def test_response_types_fail(self, response_types):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1",
                                       response_type='code')

        self.provider.cdb = {
            "client1": {
                "client_secret": "hemlighet",
                "redirect_uris": [("http://example.com/authz", None)],
                'token_endpoint_auth_method': 'client_secret_post',
                'response_types': response_types
            }
        }

        res = self.provider.auth_init(authreq.to_urlencoded())
        assert isinstance(res, Response)

        _res = json.loads(res.message)
        assert _res['error'] == 'invalid_request'
Example #23
0
 def create_provider(self, session_db_factory):
     self.provider = Provider("pyoicserv",
                              session_db_factory(ISSUER), CDB,
                              AUTHN_BROKER, AUTHZ, verify_client,
                              baseurl='https://example.com/as')
Example #24
0
class TestProvider(object):
    @pytest.fixture(autouse=True)
    def create_provider(self, session_db_factory):
        self.provider = Provider("pyoicserv",
                                 session_db_factory(ISSUER),
                                 CDB,
                                 AUTHN_BROKER,
                                 AUTHZ,
                                 verify_client,
                                 baseurl='https://example.com/as')

    def test_init(self, session_db_factory):
        provider = Provider("pyoicserv", session_db_factory(ISSUER), CDB,
                            AUTHN_BROKER, AUTHZ, verify_client)
        assert provider

        provider = Provider("pyoicserv",
                            session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER,
                            AUTHZ,
                            verify_client,
                            urlmap={"client1": ["https://example.com/authz"]})
        assert provider.urlmap["client1"] == ["https://example.com/authz"]

    def test_providerinfo(self):
        self.provider.baseurl = 'http://example.com/path1/path2'
        resp = self.provider.create_providerinfo()
        assert resp.to_dict(
        )['authorization_endpoint'] == 'http://example.com/path1/path2/authorization'

    def test_providerinfo_trailing(self):
        self.provider.baseurl = 'http://example.com/path1/path2/'
        resp = self.provider.create_providerinfo()
        assert resp.to_dict(
        )['authorization_endpoint'] == 'http://example.com/path1/path2/authorization'

    def test_verify_capabilities(self):
        capabilities = {
            'grant_types_supported': ['authorization_code'],
            'version': '3.0',
            'response_types_supported': ['code', 'token']
        }
        assert self.provider.verify_capabilities(capabilities)

    def test_verify_capabilities_mismatch_list(self):
        capabilities = {
            'grant_types_supported': ['authorization_code'],
            'response_types_supported': ['code token']
        }  # this is not supported
        assert not self.provider.verify_capabilities(capabilities)

    def test_verify_capabilities_mismatch_str(self):
        capabilities = {
            'grant_types_supported': ['authorization_code'],
            'version': '5.0'
        }  # this is not matching
        assert not self.provider.verify_capabilities(capabilities)

    def test_verify_capabilities_missing(self):
        capabilities = {
            'grant_types_supported': ['authorization_code'],
            'str_value': 'test',  # this is not supported
            'we_dont_know_this': True
        }  # this is not supported
        assert not self.provider.verify_capabilities(capabilities)

    def test_authorization_endpoint_faulty_redirect_uri(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": "http://localhost:8087/authz",
            # faulty redirect uri
            "response_type": ["code"],
            "client_id": "a1b2c3"
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authorization_endpoint_wronge_response_mode(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": "http://example.com",
            "response_type": ["code"],
            "response_mode": "fragment",
            "client_id": "a1b2c3"
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authorization_endpoint_faulty_redirect_uri_nwalker(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": " https://example.com.evil.com",
            # faulty redirect uri
            "response_type": ["code"],
            "client_id": "a1b2c3"
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authorization_endpoint_missing_client_id(self):
        # Url encoded request with missing client_id
        arq = 'scope=openid&state=id-6da9ca0cc23959f5f33e8becd9b08cae&' \
              'redirect_uri=+https%3A%2F%2Fexample.com&response_type=code'
        resp = self.provider.authorization_endpoint(request=arq)
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authenticated(self):
        _session_db = {}
        cons = Consumer(_session_db,
                        client_config=CLIENT_CONFIG,
                        server_info=SERVER_INFO,
                        **CONSUMER_CONFIG)

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization")

        resp = self.provider.authorization_endpoint(urlparse(location).query)
        assert resp.status_code == 303
        resp = urlparse(resp.message).query
        with LogCapture(level=logging.DEBUG) as logcap:
            aresp = cons.handle_authorization_response(query=resp)

        assert isinstance(aresp, AuthorizationResponse)
        assert _eq(aresp.keys(), ['state', 'code', 'client_id', 'iss'])
        assert _eq(cons.grant[sid].keys(), [
            'tokens', 'code', 'exp_in', 'seed', 'id_token',
            'grant_expiration_time'
        ])

        state = aresp['state']
        assert _eq(logcap.records[0].msg, '- authorization - code flow -')
        assert verify_outcome(logcap.records[1].msg, 'QUERY: ', [
            'state={}'.format(state), 'code=<REDACTED>', 'client_id=client1',
            'iss=https://example.com/as'
        ])

        expected = {
            'iss': 'https://example.com/as',
            'state': state,
            'code': '<REDACTED>',
            'client_id': 'client1'
        }
        # Eval here to avoid intermittent failures due to dict ordering
        assert _eq(eval(logcap.records[2].msg[29:-1]), expected)
        expected = [
            "'client_id': 'client1'", "'iss': 'https://example.com/as'",
            "'keyjar': <KeyJar(issuers=[])>"
        ]
        assert _eq(sorted(logcap.records[3].msg[22:-1].split(', ')), expected)

    def test_authenticated_token(self):
        _session_db = {}
        cons = Consumer(_session_db,
                        client_config=CLIENT_CONFIG,
                        server_info=SERVER_INFO,
                        **CONSUMER_CONFIG)

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization",
                                   "token")

        QUERY_STRING = location.split("?")[1]
        resp = self.provider.authorization_endpoint(QUERY_STRING)
        auth_resp = parse_qs(urlparse(resp.message).fragment)

        assert "access_token" in auth_resp
        assert auth_resp["token_type"][0] == "Bearer"

    def test_token_endpoint(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client1",
                                  client_secret="hemlighet",
                                  grant_type='authorization_code')
        with LogCapture(level=logging.DEBUG) as logcap:
            resp = self.provider.token_endpoint(request=areq.to_urlencoded())

        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ['access_token', 'token_type', 'refresh_token'])

        expected = (
            'token_request: code=<REDACTED>&client_secret=<REDACTED>&grant_type=authorization_code'
            '&client_id=client1&redirect_uri=http%3A%2F%2Fexample.com%2Fauthz')
        assert _eq(parse_qs(logcap.records[1].msg[15:]),
                   parse_qs(expected[15:]))
        expected = {
            u'code': '<REDACTED>',
            u'client_secret': '<REDACTED>',
            u'redirect_uri': u'http://example.com/authz',
            u'client_id': 'client1',
            u'grant_type': 'authorization_code'
        }
        # Don't try this at home, kids!
        # We have to eval() to a dict here because otherwise the arbitrary
        # ordering of the string causes the test to fail intermittently.
        assert _eq(eval(logcap.records[2].msg[4:]), expected)
        assert _eq(logcap.records[3].msg, 'Verified Client ID: client1')
        expected = {
            'redirect_uri': u'http://example.com/authz',
            'client_secret': '<REDACTED>',
            'code': u'<REDACTED>',
            'client_id': 'client1',
            'grant_type': 'authorization_code'
        }
        assert eval(logcap.records[4].msg[20:]) == expected
        expected = {
            'code': '<REDACTED>',
            'authzreq': '',
            'sub': 'sub',
            'access_token': '<REDACTED>',
            'token_type': 'Bearer',
            'redirect_uri': 'http://example.com/authz',
            'code_used': True,
            'client_id': 'client1',
            'oauth_state': 'token',
            'refresh_token': '<REDACTED>',
            'access_token_scope': '?'
        }
        assert _eq(eval(logcap.records[5].msg[7:]), expected)
        expected = {
            'access_token': u'<REDACTED>',
            'token_type': 'Bearer',
            'refresh_token': '<REDACTED>'
        }
        assert _eq(eval(logcap.records[6].msg[21:]), expected)

    def test_token_endpoint_no_cache(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id="client1",
                                  client_secret="hemlighet",
                                  grant_type='authorization_code')
        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        assert resp.headers == [('Pragma', 'no-cache'),
                                ('Cache-Control', 'no-store'),
                                ('Content-type', 'application/json')]

    def test_token_endpoint_unauth(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  redirect_uri="http://example.com/authz",
                                  client_id='<REDACTED>',
                                  client_secret="hemlighet",
                                  grant_type='authorization_code')

        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ['error_description', 'error'])

    def test_token_endpoint_malformed_code(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id='client1',
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": '',
            "authzreq": '',
            "client_id": 'client1',
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant[0:len(access_grant) - 1],
                                  client_id='client1',
                                  redirect_uri="http://example.com/authz",
                                  client_secret='hemlighet',
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr['error'] == "unauthorized_client"

    def test_token_endpoint_bad_redirect_uri(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id='client1',
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": '',
            "authzreq": '',
            "client_id": 'client1',
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  client_id='client1',
                                  redirect_uri="http://example.com/authz2",
                                  client_secret='hemlighet',
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr['error'] == "unauthorized_client"

    def test_token_endpoint_ok_state(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id='client1',
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": ae.to_json(),
            "authzreq": '',
            "client_id": 'client1',
            "code": access_grant,
            'state': 'state',
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  client_id='client1',
                                  redirect_uri="http://example.com/authz",
                                  client_secret='hemlighet',
                                  grant_type='authorization_code',
                                  state='state')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert atr['token_type'] == "Bearer"

    def test_token_endpoint_bad_state(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id='client1',
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": '',
            "authzreq": '',
            "client_id": 'client1',
            "code": access_grant,
            'state': 'state',
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  client_id='client1',
                                  redirect_uri="http://example.com/authz",
                                  client_secret='hemlighet',
                                  grant_type='authorization_code',
                                  state='other_state')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr['error'] == "unauthorized_client"

    def test_token_endpoint_client_credentials(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
            'token_endpoint_auth_method': 'client_secret_basic',
        }
        areq = CCAccessTokenRequest(grant_type='client_credentials')
        authn = 'Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0='
        resp = self.provider.token_endpoint(request=areq.to_urlencoded(),
                                            authn=authn)
        parsed = TokenErrorResponse().from_json(resp.message)
        assert parsed['error'] == "unsupported_grant_type"

    def test_token_endpoint_password(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
            'token_endpoint_auth_method': 'client_secret_basic',
        }
        areq = ROPCAccessTokenRequest(grant_type='password',
                                      username='******',
                                      password='******')
        authn = 'Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0='
        resp = self.provider.token_endpoint(request=areq.to_urlencoded(),
                                            authn=authn)
        parsed = TokenErrorResponse().from_json(resp.message)
        assert parsed['error'] == "unsupported_grant_type"

    def test_token_endpoint_other(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
            'token_endpoint_auth_method': 'client_secret_basic',
        }
        areq = Message(grant_type='some_other')
        authn = 'Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0='
        with pytest.raises(UnSupported):
            self.provider.token_endpoint(request=areq.to_urlencoded(),
                                         authn=authn)

    def test_code_grant_type_used(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id='client1',
                                       response_type="code",
                                       scope=["openid"])

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": '',
            "authzreq": '',
            "client_id": 'client1',
            "code": access_grant,
            "code_used": True,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(code=access_grant,
                                  client_id='client1',
                                  redirect_uri="http://example.com/authz",
                                  client_secret='hemlighet',
                                  grant_type='authorization_code')

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr['error'] == "invalid_grant"

    @pytest.mark.parametrize(
        "response_types", [['token id_token', 'id_token'], ['id_token token']])
    def test_response_types(self, response_types):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1",
                                       response_type='id_token token')

        self.provider.cdb = {
            "client1": {
                "client_secret": "hemlighet",
                "redirect_uris": [("http://example.com/authz", None)],
                'token_endpoint_auth_method': 'client_secret_post',
                'response_types': response_types
            }
        }

        res = self.provider.auth_init(authreq.to_urlencoded())
        assert isinstance(res, dict) and "areq" in res

    @pytest.mark.parametrize(
        "response_types", [['token id_token', 'id_token'], ['id_token token'],
                           ['code id_token'], ['id_token code']])
    def test_response_types_fail(self, response_types):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1",
                                       response_type='code')

        self.provider.cdb = {
            "client1": {
                "client_secret": "hemlighet",
                "redirect_uris": [("http://example.com/authz", None)],
                'token_endpoint_auth_method': 'client_secret_post',
                'response_types': response_types
            }
        }

        res = self.provider.auth_init(authreq.to_urlencoded())
        assert isinstance(res, Response)

        _res = json.loads(res.message)
        assert _res['error'] == 'invalid_request'

    def test_complete_authz_no_cookie(self, session_db_factory):
        provider = Provider("pyoicserver",
                            session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER2,
                            AUTHZ,
                            verify_client,
                            baseurl='https://example.com/as')
        areq = {
            'client_id': 'client1',
            'response_type': ['code'],
            'redirect_uri': 'http://localhost:8087/authz'
        }
        sid = provider.sdb.access_token.key(user='******', areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            'oauth_state': 'authz',
            'sub': 'sub',
            'client_id': 'client1',
            'code': access_code,
            'redirect_uri': 'http://localhost:8087/authz'
        }
        response, header, redirect, fragment = provider._complete_authz(
            'sub', areq, sid)
        assert header == []
        assert not fragment
        assert redirect == 'http://localhost:8087/authz'
        assert 'code' in response

    def test_complete_authz_cookie(self, session_db_factory):
        provider = Provider("pyoicserver",
                            session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER,
                            AUTHZ,
                            verify_client,
                            baseurl='https://example.com/as')
        areq = {
            'client_id': 'client1',
            'response_type': ['code'],
            'redirect_uri': 'http://localhost:8087/authz'
        }
        sid = provider.sdb.access_token.key(user='******', areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            'oauth_state': 'authz',
            'sub': 'sub',
            'client_id': 'client1',
            'code': access_code,
            'redirect_uri': 'http://localhost:8087/authz'
        }
        response, header, redirect, fragment = provider._complete_authz(
            'sub', areq, sid)
        assert len(header) == 1
        cookie_header = header[0]
        assert cookie_header[0] == 'Set-Cookie'
        assert cookie_header[1].startswith('pyoidc_sso="sub][client1')
        assert not fragment
        assert redirect == 'http://localhost:8087/authz'
        assert 'code' in response

    def test_complete_authz_other_cookie_exists(self, session_db_factory):
        provider = Provider("pyoicserver",
                            session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER,
                            AUTHZ,
                            verify_client,
                            baseurl='https://example.com/as')
        areq = {
            'client_id': 'client1',
            'response_type': ['code'],
            'redirect_uri': 'http://localhost:8087/authz'
        }
        sid = provider.sdb.access_token.key(user='******', areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            'oauth_state': 'authz',
            'sub': 'sub',
            'client_id': 'client1',
            'code': access_code,
            'redirect_uri': 'http://localhost:8087/authz'
        }
        cookie = 'Some-cookie=test::test'
        response, header, redirect, fragment = provider._complete_authz(
            'sub', areq, sid, cookie=cookie)
        assert len(header) == 1
        cookie_header = header[0]
        assert cookie_header[1].startswith('pyoidc_sso="sub][client1')
        assert not fragment
        assert redirect == 'http://localhost:8087/authz'
        assert 'code' in response

    def test_complete_authz_pyoidc_cookie_exists(self, session_db_factory):
        provider = Provider("pyoicserver",
                            session_db_factory(ISSUER),
                            CDB,
                            AUTHN_BROKER,
                            AUTHZ,
                            verify_client,
                            baseurl='https://example.com/as')
        areq = {
            'client_id': 'client1',
            'response_type': ['code'],
            'redirect_uri': 'http://localhost:8087/authz'
        }
        sid = provider.sdb.access_token.key(user='******', areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            'oauth_state': 'authz',
            'sub': 'sub',
            'client_id': 'client1',
            'code': access_code,
            'redirect_uri': 'http://localhost:8087/authz'
        }
        cookie = 'pyoidc_sso=test::test'
        response, header, redirect, fragment = provider._complete_authz(
            'sub', areq, sid, cookie=cookie)
        assert len(header) == 0
        assert not fragment
        assert redirect == 'http://localhost:8087/authz'
        assert 'code' in response
Example #25
0
class TestProvider(object):
    @pytest.fixture(autouse=True)
    def create_provider(self, session_db_factory):
        self.provider = Provider(
            "pyoicserv",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            baseurl="https://example.com/as",
        )

    def test_init(self, session_db_factory):
        provider = Provider(
            "pyoicserv",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
        )
        assert provider

        provider = Provider(
            "pyoicserv",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            urlmap={"client1": ["https://example.com/authz"]},
        )
        assert provider.urlmap["client1"] == ["https://example.com/authz"]

    def test_init_capabilities(self, session_db_factory):
        provider = Provider(
            "pyoicserv",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            capabilities={
                "grant_types_supported": ["authorization_code"],
                "version": "1.0",
                "response_types_supported": ["code", "token"],
            },
        )
        assert provider
        assert provider.capabilities["version"] == "1.0"
        assert provider.capabilities["grant_types_supported"] == [
            "authorization_code"
        ]

    def test_providerinfo(self):
        self.provider.baseurl = "http://example.com/path1/path2"
        resp = self.provider.create_providerinfo()
        assert (resp.to_dict()["authorization_endpoint"] ==
                "http://example.com/path1/path2/authorization")

    def test_providerinfo_trailing(self):
        self.provider.baseurl = "http://example.com/path1/path2/"
        resp = self.provider.create_providerinfo()
        assert (resp.to_dict()["authorization_endpoint"] ==
                "http://example.com/path1/path2/authorization")

    def test_verify_capabilities(self):
        capabilities = {
            "grant_types_supported": ["authorization_code"],
            "version": "3.0",
            "response_types_supported": ["code", "token"],
        }
        assert self.provider.verify_capabilities(capabilities)

    def test_verify_capabilities_mismatch_list(self):
        capabilities = {
            "grant_types_supported": ["authorization_code"],
            "response_types_supported": ["code token"],
        }  # this is not supported
        assert not self.provider.verify_capabilities(capabilities)

    def test_verify_capabilities_mismatch_str(self):
        capabilities = {
            "grant_types_supported": ["authorization_code"],
            "version": "5.0",
        }  # this is not matching
        assert not self.provider.verify_capabilities(capabilities)

    def test_verify_capabilities_missing(self):
        capabilities = {
            "grant_types_supported": ["authorization_code"],
            "str_value": "test",  # this is not supported
            "we_dont_know_this": True,
        }  # this is not supported
        assert not self.provider.verify_capabilities(capabilities)

    def test_authorization_endpoint_faulty_redirect_uri(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": "http://localhost:8087/authz",
            # faulty redirect uri
            "response_type": ["code"],
            "client_id": "a1b2c3",
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authorization_endpoint_wronge_response_mode(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": "http://example.com",
            "response_type": ["code"],
            "response_mode": "fragment",
            "client_id": "a1b2c3",
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authorization_endpoint_faulty_redirect_uri_nwalker(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": " https://example.com.evil.com",
            # faulty redirect uri
            "response_type": ["code"],
            "client_id": "a1b2c3",
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authorization_endpoint_missing_client_id(self):
        # Url encoded request with missing client_id
        arq = ("scope=openid&state=id-6da9ca0cc23959f5f33e8becd9b08cae&"
               "redirect_uri=+https%3A%2F%2Fexample.com&response_type=code")
        resp = self.provider.authorization_endpoint(request=arq)
        assert resp.status_code == 400
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authenticated(self):
        _session_db = DictSessionBackend()
        cons = Consumer(
            _session_db,
            client_config=CLIENT_CONFIG,
            server_info=SERVER_INFO,
            **CONSUMER_CONFIG,
        )

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization")

        resp = self.provider.authorization_endpoint(urlparse(location).query)
        assert resp.status_code == 303
        resp = urlparse(resp.message).query
        with LogCapture(level=logging.DEBUG) as logcap:
            aresp = cons.handle_authorization_response(query=resp)

        assert isinstance(aresp, AuthorizationResponse)
        assert _eq(aresp.keys(), ["state", "code", "client_id", "iss"])
        assert _eq(
            cons.grant[sid].keys(),
            [
                "tokens", "code", "exp_in", "seed", "id_token",
                "grant_expiration_time"
            ],
        )

        state = aresp["state"]
        assert _eq(logcap.records[0].msg, "- authorization - code flow -")
        assert verify_outcome(
            logcap.records[1].msg,
            "QUERY: ",
            [
                "state={}".format(state),
                "code=<REDACTED>",
                "client_id=client1",
                "iss=https://example.com/as",
            ],
        )

        expected = {
            "iss": "https://example.com/as",
            "state": state,
            "code": "<REDACTED>",
            "client_id": "client1",
        }
        # Eval here to avoid intermittent failures due to dict ordering
        assert _eq(eval(logcap.records[2].msg[29:-1]), expected)
        expected2 = [
            "'client_id': 'client1'",
            "'iss': 'https://example.com/as'",
            "'keyjar': <KeyJar(issuers=[])>",
        ]
        assert _eq(sorted(logcap.records[3].msg[22:-1].split(", ")), expected2)

    def test_authenticated_token(self):
        _session_db = DictSessionBackend()
        cons = Consumer(
            _session_db,
            client_config=CLIENT_CONFIG,
            server_info=SERVER_INFO,
            **CONSUMER_CONFIG,
        )

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization",
                                   "token")

        QUERY_STRING = location.split("?")[1]
        resp = self.provider.authorization_endpoint(QUERY_STRING)
        auth_resp = parse_qs(urlparse(resp.message).fragment)

        assert "access_token" in auth_resp
        assert auth_resp["token_type"][0] == "Bearer"

    def test_token_endpoint(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            redirect_uri="http://example.com/authz",
            client_id="client1",
            client_secret="hemlighet",
            grant_type="authorization_code",
        )
        with LogCapture(level=logging.DEBUG) as logcap:
            resp = self.provider.token_endpoint(request=areq.to_urlencoded())

        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ["access_token", "token_type", "refresh_token"])

        expected = (
            "token_request: code=<REDACTED>&client_secret=<REDACTED>&grant_type=authorization_code"
            "&client_id=client1&redirect_uri=http%3A%2F%2Fexample.com%2Fauthz")
        assert _eq(parse_qs(logcap.records[1].msg[15:]),
                   parse_qs(expected[15:]))
        expected2 = {
            "code": "<REDACTED>",
            "client_secret": "<REDACTED>",
            "redirect_uri": "http://example.com/authz",
            "client_id": "client1",
            "grant_type": "authorization_code",
        }
        # Don't try this at home, kids!
        # We have to eval() to a dict here because otherwise the arbitrary
        # ordering of the string causes the test to fail intermittently.
        assert _eq(eval(logcap.records[2].msg[4:]), expected2)
        assert _eq(logcap.records[3].msg, "Verified Client ID: client1")
        expected3 = {
            "redirect_uri": "http://example.com/authz",
            "client_secret": "<REDACTED>",
            "code": "<REDACTED>",
            "client_id": "client1",
            "grant_type": "authorization_code",
        }
        assert eval(logcap.records[4].msg[20:]) == expected3
        expected4 = {
            "code": "<REDACTED>",
            "authzreq": "",
            "sub": "sub",
            "access_token": "<REDACTED>",
            "token_type": "Bearer",
            "redirect_uri": "http://example.com/authz",
            "code_used": True,
            "client_id": "client1",
            "oauth_state": "token",
            "refresh_token": "<REDACTED>",
            "access_token_scope": "?",
        }
        assert _eq(eval(logcap.records[5].msg[7:]), expected4)
        expected5 = {
            "access_token": "<REDACTED>",
            "token_type": "Bearer",
            "refresh_token": "<REDACTED>",
        }
        assert _eq(eval(logcap.records[6].msg[21:]), expected5)

    def test_token_endpoint_no_cache(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            redirect_uri="http://example.com/authz",
            client_id="client1",
            client_secret="hemlighet",
            grant_type="authorization_code",
        )
        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        assert resp.headers == [
            ("Pragma", "no-cache"),
            ("Cache-Control", "no-store"),
            ("Content-type", "application/json"),
        ]

    def test_token_endpoint_unauth(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            redirect_uri="http://example.com/authz",
            client_id="<REDACTED>",
            client_secret="hemlighet",
            grant_type="authorization_code",
        )

        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ["error_description", "error"])

    def test_token_endpoint_malformed_code(self):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="code",
            scope=["openid"],
        )

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant[0:len(access_grant) - 1],
            client_id="client1",
            redirect_uri="http://example.com/authz",
            client_secret="hemlighet",
            grant_type="authorization_code",
        )

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr["error"] == "unauthorized_client"

    def test_token_endpoint_bad_redirect_uri(self):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="code",
            scope=["openid"],
        )

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            client_id="client1",
            redirect_uri="http://example.com/authz2",
            client_secret="hemlighet",
            grant_type="authorization_code",
        )

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr["error"] == "unauthorized_client"

    def test_token_endpoint_ok_state(self):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="code",
            scope=["openid"],
        )

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        ae = AuthnEvent("user", "salt")
        _sdb[sid] = {
            "oauth_state": "authz",
            "authn_event": ae.to_json(),
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "state": "state",
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }
        _sdb.do_sub(sid, "client_salt")

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            client_id="client1",
            redirect_uri="http://example.com/authz",
            client_secret="hemlighet",
            grant_type="authorization_code",
            state="state",
        )

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert atr["token_type"] == "Bearer"

    def test_token_endpoint_bad_state(self):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="code",
            scope=["openid"],
        )

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "state": "state",
            "code_used": False,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            client_id="client1",
            redirect_uri="http://example.com/authz",
            client_secret="hemlighet",
            grant_type="authorization_code",
            state="other_state",
        )

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr["error"] == "unauthorized_client"

    def test_token_endpoint_client_credentials(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
            "token_endpoint_auth_method": "client_secret_basic",
        }
        areq = CCAccessTokenRequest(grant_type="client_credentials")
        authn = "Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0="
        resp = self.provider.token_endpoint(request=areq.to_urlencoded(),
                                            authn=authn)
        parsed = TokenErrorResponse().from_json(resp.message)
        assert parsed["error"] == "unsupported_grant_type"

    def test_token_endpoint_password(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
            "token_endpoint_auth_method": "client_secret_basic",
        }
        areq = ROPCAccessTokenRequest(grant_type="password",
                                      username="******",
                                      password="******")
        authn = "Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0="
        resp = self.provider.token_endpoint(request=areq.to_urlencoded(),
                                            authn=authn)
        parsed = TokenErrorResponse().from_json(resp.message)
        assert parsed["error"] == "unsupported_grant_type"

    def test_token_endpoint_other(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz",
            "token_endpoint_auth_method": "client_secret_basic",
        }
        areq = Message(grant_type="some_other")
        authn = "Basic Y2xpZW50Mjp2ZXJ5c2VjcmV0="
        with pytest.raises(UnSupported):
            self.provider.token_endpoint(request=areq.to_urlencoded(),
                                         authn=authn)

    def test_code_grant_type_used(self):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="code",
            scope=["openid"],
        )

        _sdb = self.provider.sdb
        sid = _sdb.access_token.key(user="******", areq=authreq)
        access_grant = _sdb.access_token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": True,
            "scope": ["openid"],
            "redirect_uri": "http://example.com/authz",
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            client_id="client1",
            redirect_uri="http://example.com/authz",
            client_secret="hemlighet",
            grant_type="authorization_code",
        )

        txt = areq.to_urlencoded()

        resp = self.provider.token_endpoint(request=txt)
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert atr["error"] == "invalid_grant"

    @pytest.mark.parametrize(
        "response_types", [["token id_token", "id_token"], ["id_token token"]])
    def test_response_types(self, response_types):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="id_token token",
        )

        self.provider.cdb = {
            "client1": {
                "client_secret": "hemlighet",
                "redirect_uris": [("http://example.com/authz", None)],
                "token_endpoint_auth_method": "client_secret_post",
                "response_types": response_types,
            }
        }

        res = self.provider.auth_init(authreq.to_urlencoded())
        assert isinstance(res, dict) and "areq" in res

    @pytest.mark.parametrize(
        "response_types",
        [
            ["token id_token", "id_token"],
            ["id_token token"],
            ["code id_token"],
            ["id_token code"],
        ],
    )
    def test_response_types_fail(self, response_types):
        authreq = AuthorizationRequest(
            state="state",
            redirect_uri="http://example.com/authz",
            client_id="client1",
            response_type="code",
        )

        self.provider.cdb = {
            "client1": {
                "client_secret": "hemlighet",
                "redirect_uris": [("http://example.com/authz", None)],
                "token_endpoint_auth_method": "client_secret_post",
                "response_types": response_types,
            }
        }

        res = self.provider.auth_init(authreq.to_urlencoded())
        assert isinstance(res, Response)

        _res = json.loads(res.message)
        assert _res["error"] == "invalid_request"

    def test_complete_authz_no_cookie(self, session_db_factory):
        provider = Provider(
            "pyoicserver",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER2,
            AUTHZ,
            verify_client,
            baseurl="https://example.com/as",
        )
        areq = {
            "client_id": "client1",
            "response_type": ["code"],
            "redirect_uri": "http://localhost:8087/authz",
        }
        sid = provider.sdb.access_token.key(user="******", areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "client_id": "client1",
            "code": access_code,
            "redirect_uri": "http://localhost:8087/authz",
        }
        response, header, redirect, fragment = provider._complete_authz(
            "sub", areq, sid)
        assert header == []
        assert not fragment
        assert redirect == "http://localhost:8087/authz"
        assert "code" in response

    def test_complete_authz_cookie(self, session_db_factory):
        provider = Provider(
            "pyoicserver",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            baseurl="https://example.com/as",
        )
        areq = {
            "client_id": "client1",
            "response_type": ["code"],
            "redirect_uri": "http://localhost:8087/authz",
        }
        sid = provider.sdb.access_token.key(user="******", areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "client_id": "client1",
            "code": access_code,
            "redirect_uri": "http://localhost:8087/authz",
        }
        response, header, redirect, fragment = provider._complete_authz(
            "sub", areq, sid)
        assert len(header) == 1
        cookie_header = header[0]
        assert cookie_header[0] == "Set-Cookie"
        assert cookie_header[1].startswith('pyoidc_sso="sub][client1')
        assert not fragment
        assert redirect == "http://localhost:8087/authz"
        assert "code" in response

    def test_complete_authz_other_cookie_exists(self, session_db_factory):
        provider = Provider(
            "pyoicserver",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            baseurl="https://example.com/as",
        )
        areq = {
            "client_id": "client1",
            "response_type": ["code"],
            "redirect_uri": "http://localhost:8087/authz",
        }
        sid = provider.sdb.access_token.key(user="******", areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "client_id": "client1",
            "code": access_code,
            "redirect_uri": "http://localhost:8087/authz",
        }
        cookie = "Some-cookie=test::test"
        response, header, redirect, fragment = provider._complete_authz(
            "sub", areq, sid, cookie=cookie)
        assert len(header) == 1
        cookie_header = header[0]
        assert cookie_header[1].startswith('pyoidc_sso="sub][client1')
        assert not fragment
        assert redirect == "http://localhost:8087/authz"
        assert "code" in response

    def test_complete_authz_pyoidc_cookie_exists(self, session_db_factory):
        provider = Provider(
            "pyoicserver",
            session_db_factory(ISSUER),
            CDB,
            AUTHN_BROKER,
            AUTHZ,
            verify_client,
            baseurl="https://example.com/as",
        )
        areq = {
            "client_id": "client1",
            "response_type": ["code"],
            "redirect_uri": "http://localhost:8087/authz",
        }
        sid = provider.sdb.access_token.key(user="******", areq=areq)
        access_code = provider.sdb.access_token(sid=sid)
        provider.sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "client_id": "client1",
            "code": access_code,
            "redirect_uri": "http://localhost:8087/authz",
        }
        cookie = "pyoidc_sso=test::test"
        response, header, redirect, fragment = provider._complete_authz(
            "sub", areq, sid, cookie=cookie)
        assert len(header) == 0
        assert not fragment
        assert redirect == "http://localhost:8087/authz"
        assert "code" in response
Example #26
0
        authn = CasAuthnMethod(
            None,
            config.CAS_SERVER,
            config.SERVICE_URL,
            "%s/authorization" % config.issuer,
            UserLDAPMemberValidation(**config.LDAP_EXTRAVALIDATION),
        )
    else:
        from oic.utils.authn.user import UsernamePasswordMako

        authn = UsernamePasswordMako(None, "login.mako", LOOKUP, PASSWD, "%s/authorization" % config.issuer)

    # dealing with authorization
    authz = AuthzHandling()
    # User info database
    OAS = Provider(config.issuer, SessionDB(), cdb, authn, authz, verify_client, config.SYM_KEY)

    authn.srv = OAS

    try:
        OAS.cookie_ttl = config.COOKIETTL
    except AttributeError:
        pass

    try:
        OAS.cookie_name = config.COOKIENAME
    except AttributeError:
        pass

    OAS.cookie_func = http_util.make_cookie
    # print URLS
Example #27
0
File: as.py Project: ghedin/pyoidc
    for cnf in config.AUTHN_METHOD.values():
        try:
            cnf["config"]["return_to"] = cnf["config"]["return_to"] % args.port
        except KeyError:
            pass

    # Initiate the authentication broker. This is the service that
    # chooses which authentication method that is to be used.

    broker = authn_setup(config)

    # dealing with authorization, this is just everything goes.
    authz = Implicit()

    # Initiate the OAuth2 provider instance
    OAS = Provider(config.issuer, SessionDB(), cdb, broker, authz, client_authn=verify_client, symkey=config.SYM_KEY)

    # set some parameters
    try:
        OAS.cookie_ttl = config.COOKIETTL
    except AttributeError:
        pass

    try:
        OAS.cookie_name = config.COOKIENAME
    except AttributeError:
        pass

    if args.debug:
        LOGGER.setLevel(logging.DEBUG)
        OAS.debug = True
Example #28
0
 def create_provider(self):
     self.provider = Provider("pyoicserv", sdb.SessionDB(ISSUER), CDB,
                              AUTHN_BROKER, AUTHZ, verify_client)
 def create_provider(self):
     self.provider = Provider("pyoicserv", sdb.SessionDB(ISSUER), CDB, AUTHN_BROKER, AUTHZ, verify_client)
Example #30
0
class TestProvider(object):
    @pytest.fixture(autouse=True)
    def create_provider(self):
        self.provider = Provider("pyoicserv", sdb.SessionDB(ISSUER), CDB,
                                 AUTHN_BROKER, AUTHZ, verify_client)

    def test_init(self):
        provider = Provider("pyoicserv", sdb.SessionDB(ISSUER), CDB,
                            AUTHN_BROKER, AUTHZ, verify_client)
        assert provider

        provider = Provider("pyoicserv",
                            sdb.SessionDB(ISSUER),
                            CDB,
                            AUTHN_BROKER,
                            AUTHZ,
                            verify_client,
                            urlmap={"client1": ["https://example.com/authz"]})
        assert provider.urlmap["client1"] == ["https://example.com/authz"]

    def test_authorization_endpoint_faulty_redirect_uri(self):
        bib = {
            "scope": ["openid"],
            "state": "id-6da9ca0cc23959f5f33e8becd9b08cae",
            "redirect_uri": "http://localhost:8087/authz",
            # faulty redirect uri
            "response_type": ["code"],
            "client_id": "a1b2c3"
        }

        arq = AuthorizationRequest(**bib)
        resp = self.provider.authorization_endpoint(
            request=arq.to_urlencoded())
        assert resp.status == "400 Bad Request"
        msg = json.loads(resp.message)
        assert msg["error"] == "invalid_request"

    def test_authenticated(self):
        _session_db = {}
        cons = Consumer(_session_db,
                        client_config=CLIENT_CONFIG,
                        server_info=SERVER_INFO,
                        **CONSUMER_CONFIG)

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization")

        resp = self.provider.authorization_endpoint(urlparse(location).query)
        assert resp.status == "302 Found"
        resp = urlparse(resp.message).query
        aresp = cons.handle_authorization_response(query=resp)

        assert isinstance(aresp, AuthorizationResponse)
        assert _eq(aresp.keys(), ['state', 'code'])
        assert _eq(cons.grant[sid].keys(), [
            'tokens', 'code', 'exp_in', 'seed', 'id_token',
            'grant_expiration_time'
        ])

    def test_authenticated_token(self):
        _session_db = {}
        cons = Consumer(_session_db,
                        client_config=CLIENT_CONFIG,
                        server_info=SERVER_INFO,
                        **CONSUMER_CONFIG)

        sid, location = cons.begin("http://localhost:8087",
                                   "http://localhost:8088/authorization",
                                   "token")

        QUERY_STRING = location.split("?")[1]
        resp = self.provider.authorization_endpoint(QUERY_STRING)
        auth_resp = parse_qs(urlparse(resp.message).fragment)

        assert "access_token" in auth_resp
        assert auth_resp["token_type"][0] == "Bearer"

    def test_token_endpoint(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.token.key(user="******", areq=authreq)
        access_grant = _sdb.token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            redirect_uri="http://example.com/authz",
            client_id="client1",
            client_secret="hemlighet",
        )

        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        atr = AccessTokenResponse().deserialize(resp.message, "json")
        assert _eq(
            atr.keys(),
            ['access_token', 'expires_in', 'token_type', 'refresh_token'])

    def test_token_endpoint_unauth(self):
        authreq = AuthorizationRequest(state="state",
                                       redirect_uri="http://example.com/authz",
                                       client_id="client1")

        _sdb = self.provider.sdb
        sid = _sdb.token.key(user="******", areq=authreq)
        access_grant = _sdb.token(sid=sid)
        _sdb[sid] = {
            "oauth_state": "authz",
            "sub": "sub",
            "authzreq": "",
            "client_id": "client1",
            "code": access_grant,
            "code_used": False,
            "redirect_uri": "http://example.com/authz"
        }

        # Construct Access token request
        areq = AccessTokenRequest(
            code=access_grant,
            redirect_uri="http://example.com/authz",
            client_id="client2",
            client_secret="hemlighet",
        )

        resp = self.provider.token_endpoint(request=areq.to_urlencoded())
        atr = TokenErrorResponse().deserialize(resp.message, "json")
        assert _eq(atr.keys(), ['error_description', 'error'])