feat: link local library
This commit is contained in:
+212
@@ -0,0 +1,212 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
|
||||
from spid_cie_oidc.provider.tests.settings import op_conf, op_conf_priv_jwk
|
||||
from spid_cie_oidc.authority.tests.settings import rp_conf, INTERMEDIARY_JWK1
|
||||
from spid_cie_oidc.entity.jwtse import create_jws, create_jwe
|
||||
from spid_cie_oidc.entity.utils import iat_now, exp_from_now, get_key, KeyUsage
|
||||
from spid_cie_oidc.entity.utils import get_jwks
|
||||
from cryptojwt.jws.utils import left_hash
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MockedTokenEndPointResponse:
|
||||
def __init__(self):
|
||||
self.status_code = 200
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
id_token = {
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'nonce': 'ljbvL3rpscgS4ZGda7cgibXHr7vrNREW',
|
||||
'at_hash': '',
|
||||
'c_hash': 'tij0h-zL_bSrsVXy-d3qHw',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'iss': op_conf["sub"],
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
access_token = {
|
||||
'iss': op_conf["sub"],
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'client_id': rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
'scope': 'openid',
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
jwt_at = create_jws(access_token, op_conf_priv_jwk, typ="at+jwt")
|
||||
id_token['at_hash'] = left_hash(jwt_at, "HS256")
|
||||
jwt_id = create_jws(id_token, op_conf_priv_jwk)
|
||||
|
||||
self.access_token = jwt_at
|
||||
self.id_token = jwt_id
|
||||
|
||||
res = {
|
||||
"access_token": jwt_at,
|
||||
"id_token": jwt_id,
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 3600,
|
||||
"scope": "openid",
|
||||
}
|
||||
return json.dumps(res).encode()
|
||||
|
||||
|
||||
class MockedTokenEndPointNoCorrectResponse:
|
||||
def __init__(self):
|
||||
self.status_code = 200
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
id_token = {
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'nonce': 'ljbvL3rpscgS4ZGda7cgibXHr7vrNREW',
|
||||
'at_hash': '',
|
||||
'c_hash': 'tij0h-zL_bSrsVXy-d3qHw',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'iss': op_conf["sub"],
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
access_token = {
|
||||
'iss': op_conf["sub"],
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'client_id': rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
'scope': 'openid',
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
jwt_at = create_jws(access_token, op_conf_priv_jwk, typ="at+jwt")
|
||||
id_token['at_hash'] = left_hash(jwt_at, "HS256")
|
||||
jwt_id = create_jws(id_token, op_conf_priv_jwk)
|
||||
|
||||
self.access_token = jwt_at
|
||||
self.id_token = jwt_id
|
||||
|
||||
res = {
|
||||
"access_token": jwt_at,
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 3600,
|
||||
"scope": "openid",
|
||||
}
|
||||
return json.dumps(res).encode()
|
||||
|
||||
|
||||
class MockedTokenEndPointNoCorrectIdTokenResponse:
|
||||
def __init__(self):
|
||||
self.status_code = 200
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
id_token = {
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'nonce': 'ljbvL3rpscgS4ZGda7cgibXHr7vrNREW',
|
||||
'at_hash': '',
|
||||
'c_hash': 'tij0h-zL_bSrsVXy-d3qHw',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'iss': op_conf["sub"],
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
access_token = {
|
||||
'iss': op_conf["sub"],
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'client_id': rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
'scope': 'openid',
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
jwt_at = create_jws(access_token, op_conf_priv_jwk, typ="at+jwt")
|
||||
id_token['at_hash'] = left_hash(jwt_at, "HS256")
|
||||
jwt_id = create_jws(id_token, INTERMEDIARY_JWK1)
|
||||
|
||||
self.access_token = jwt_at
|
||||
self.id_token = jwt_id
|
||||
|
||||
res = {
|
||||
"access_token": jwt_at,
|
||||
"token_type": "Bearer",
|
||||
"id_token": jwt_id,
|
||||
"expires_in": 3600,
|
||||
"scope": "openid",
|
||||
}
|
||||
return json.dumps(res).encode()
|
||||
|
||||
|
||||
class MockedTokenEndPointNoCorrectAtHashResponse:
|
||||
def __init__(self):
|
||||
self.status_code = 200
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
id_token = {
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'nonce': 'ljbvL3rpscgS4ZGda7cgibXHr7vrNREW',
|
||||
'at_hash': '45e66ce53e48273dca5a446',
|
||||
'c_hash': 'tij0h-zL_bSrsVXy-d3qHw',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'iss': op_conf["sub"],
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
access_token = {
|
||||
'iss': op_conf["sub"],
|
||||
'sub': '2ed008b45e66ce53e48273dca5a4463bc8ebd036ebaa824f4582627683c2451b',
|
||||
'aud': [rp_conf["metadata"]["openid_relying_party"]["client_id"],],
|
||||
'client_id': rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
'scope': 'openid',
|
||||
'jti': '402e61bd-950c-4934-83d4-c09a05468828',
|
||||
'exp': exp_from_now(),
|
||||
'iat': iat_now()
|
||||
}
|
||||
jwt_at = create_jws(access_token, op_conf_priv_jwk, typ="at+jwt")
|
||||
jwt_id = create_jws(id_token, op_conf_priv_jwk)
|
||||
|
||||
self.access_token = jwt_at
|
||||
self.id_token = jwt_id
|
||||
|
||||
res = {
|
||||
"access_token": jwt_at,
|
||||
"id_token": jwt_id,
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 3600,
|
||||
"scope": "openid",
|
||||
}
|
||||
return json.dumps(res).encode()
|
||||
|
||||
|
||||
class MockedUserInfoResponse:
|
||||
def __init__(self):
|
||||
self.status_code = 200
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
jwt = {
|
||||
"sub": 'asdasdasdasasdasdas',
|
||||
"https://attributes.eid.gov.it/fiscal_number": "sdfsfs908df09s8df90s8fd0"
|
||||
}
|
||||
jws = create_jws(jwt, op_conf_priv_jwk)
|
||||
jwks = get_jwks(rp_conf["metadata"]["openid_relying_party"])
|
||||
key = get_key(jwks, KeyUsage.encryption)
|
||||
jwe = create_jwe(
|
||||
jws,
|
||||
key
|
||||
)
|
||||
return jwe.encode()
|
||||
|
||||
class MockedLogout:
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
pass
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
from django.test import Client, TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from spid_cie_oidc.relying_party.models import OidcAuthenticationToken
|
||||
from spid_cie_oidc.relying_party.utils import html_json_preview
|
||||
|
||||
|
||||
class OidcRpTest(TestCase):
|
||||
# TODO: re enable
|
||||
def _test_stupid_logout(self):
|
||||
# a stupid logout that MUST fail
|
||||
url = f'{reverse("spid_cie_rpinitiated_logout")}'
|
||||
req = Client()
|
||||
res = req.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
# end stupid logout test
|
||||
|
||||
# TODO: re enable
|
||||
def _test_session(self):
|
||||
url = f'{reverse("spid_cie_rp_begin")}?issuer_id=op_test'
|
||||
req = Client()
|
||||
res = req.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
|
||||
authz_url = f'{reverse("op_test:spid_oidc_op_authz")}?{res.url.split("?")[1]}'
|
||||
res = req.get(authz_url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
self.assertIn("code=", res.url)
|
||||
|
||||
url = f'{reverse("spid_cie_rp_callback")}?{res.url.split("?")[1]}'
|
||||
res = req.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
|
||||
url = f'{reverse("spid_cie_rp_echo_attributes")}'
|
||||
res = req.get(url)
|
||||
self.assertIn("sando", res.content.decode())
|
||||
|
||||
# test models
|
||||
tokens = OidcAuthenticationToken.objects.first()
|
||||
|
||||
tokens.access_token_preview
|
||||
tokens.id_token_preview
|
||||
|
||||
# and now logout
|
||||
url = f'{reverse("spid_cie_rpinitiated_logout")}'
|
||||
res = req.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
|
||||
# TODO: re enable
|
||||
def _test_html_json_preview(self):
|
||||
html_json_preview('{"a" : 34, "b" : 78}')
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class OidcRPCliTests(TestCase):
|
||||
def setUp(self):
|
||||
# create a FederationEntityConfiguration SP
|
||||
pass
|
||||
|
||||
def test_fetch_openid_providers(self):
|
||||
overrides = dict(OIDCFED_IDENTITY_PROVIDERS="", OIDCFED_REQUIRED_TRUST_MARKS="")
|
||||
|
||||
with self.settings(**overrides):
|
||||
pass
|
||||
# out = self.call_command('fetch_openid_providers', '--start')
|
||||
# self.assertEqual(out.splitlines()[0], "test arbitrary command")
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
import urllib
|
||||
|
||||
from copy import deepcopy
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.http import HttpRequest
|
||||
from django.test import Client, TestCase, override_settings
|
||||
from django.urls import reverse
|
||||
from spid_cie_oidc.authority.tests.settings import rp_conf
|
||||
from spid_cie_oidc.entity.models import (
|
||||
FederationEntityConfiguration,
|
||||
FetchedEntityStatement,
|
||||
TrustChain,
|
||||
)
|
||||
from spid_cie_oidc.entity.jwtse import unpad_jwt_payload
|
||||
from spid_cie_oidc.entity.tests.settings import TA_SUB
|
||||
from spid_cie_oidc.entity.utils import datetime_from_timestamp, exp_from_now, iat_now
|
||||
from spid_cie_oidc.provider.tests.settings import op_conf
|
||||
|
||||
def create_tc():
|
||||
NOW = datetime_from_timestamp(iat_now())
|
||||
EXP = datetime_from_timestamp(exp_from_now(33))
|
||||
ta_fes = FetchedEntityStatement.objects.create(
|
||||
sub=TA_SUB,
|
||||
iss=TA_SUB,
|
||||
exp=EXP,
|
||||
iat=NOW,
|
||||
)
|
||||
return TrustChain.objects.create(
|
||||
sub=op_conf["sub"],
|
||||
exp=EXP,
|
||||
jwks = [],
|
||||
status="valid",
|
||||
trust_anchor=ta_fes,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
def create_tc_metadata_no_correct():
|
||||
NOW = datetime_from_timestamp(iat_now())
|
||||
EXP = datetime_from_timestamp(exp_from_now(33))
|
||||
ta_fes = FetchedEntityStatement.objects.create(
|
||||
sub=TA_SUB,
|
||||
iss=TA_SUB,
|
||||
exp=EXP,
|
||||
iat=NOW,
|
||||
)
|
||||
local_op_conf = deepcopy(op_conf)
|
||||
metadata = local_op_conf["metadata"]
|
||||
metadata["openid_provider"]["jwks"] = {"keys": []}
|
||||
return TrustChain.objects.create(
|
||||
sub=op_conf["sub"],
|
||||
exp=EXP,
|
||||
status="valid",
|
||||
jwks = [],
|
||||
metadata=metadata,
|
||||
trust_anchor=ta_fes,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
class RPBeginTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.req = HttpRequest()
|
||||
NOW = datetime_from_timestamp(iat_now())
|
||||
EXP = datetime_from_timestamp(exp_from_now(33))
|
||||
self.rp_conf = FederationEntityConfiguration.objects.create(**rp_conf)
|
||||
self.ta_fes = FetchedEntityStatement.objects.create(
|
||||
sub=TA_SUB,
|
||||
iss=TA_SUB,
|
||||
exp=EXP,
|
||||
iat=NOW,
|
||||
)
|
||||
metadata = deepcopy(op_conf["metadata"])
|
||||
self.trust_chain = TrustChain.objects.create(
|
||||
sub=op_conf["sub"],
|
||||
exp=EXP,
|
||||
jwks = [],
|
||||
metadata=metadata,
|
||||
status="valid",
|
||||
trust_anchor=self.ta_fes,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_rp_begin(self):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
self.assertTrue(res.status_code == 302)
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_begin.SpidCieOidcRpBeginView.get_oidc_op", return_value=None)
|
||||
def test_rp_begin_no_tc(self, mocked):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
|
||||
def test_no_request(self):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"request": {}})
|
||||
self.assertTrue(res.status_code == 404)
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
self.assertTrue("Missing provider url" in res.content.decode())
|
||||
|
||||
# I changed the code to get a smarter solution
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_no_unallowed_tc(self):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": "provider"})
|
||||
self.assertTrue(res.status_code == 403)
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
# self.assertTrue("Unallowed Trust Anchor" in res.content.decode())
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_no_rp_entity_conf(self):
|
||||
FederationEntityConfiguration.objects.all().delete()
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
self.assertTrue(res.status_code == 404)
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
self.assertTrue("Missing configuration" in res.content.decode())
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_invalid_provider_metadata(self):
|
||||
metadata = deepcopy(op_conf["metadata"])
|
||||
metadata["openid_provider"].pop("jwks")
|
||||
self.trust_chain.metadata = metadata
|
||||
self.trust_chain.save()
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
self.assertTrue(res.status_code == 404)
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
self.assertTrue("Invalid provider Metadata" in res.content.decode())
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_tc_no_active(self):
|
||||
self.trust_chain.is_active = False
|
||||
self.trust_chain.save()
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
self.assertTrue(res.status_code == 404)
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
self.assertTrue("found but DISABLED at" in res.content.decode())
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_failed_to_get_jwks(self):
|
||||
metadata = deepcopy(op_conf["metadata"])
|
||||
metadata['openid_provider'].pop("jwks")
|
||||
metadata["jwks_uri"] = "jwks_uri"
|
||||
self.trust_chain.metadata = metadata
|
||||
self.trust_chain.save()
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
|
||||
self.assertTrue(res.status_code == 404)
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
|
||||
def test_rp_begin_tc_no_metadata(self):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
self.patcher = patch(
|
||||
"spid_cie_oidc.relying_party.views.rp_begin.SpidCieOidcRpBeginView.get_oidc_op",
|
||||
return_value = create_tc()
|
||||
)
|
||||
self.patcher.start()
|
||||
res = client.get(url, {"provider": op_conf["sub"], "trust_anchor": TA_SUB})
|
||||
self.assertTrue("request rejected" in res.content.decode())
|
||||
self.patcher.stop()
|
||||
|
||||
@override_settings(OIDCFED_DEFAULT_TRUST_ANCHOR=TA_SUB, OIDCFED_TRUST_ANCHORS=[TA_SUB])
|
||||
def test_rp_begin_tc_no_redirect_uri(self):
|
||||
red_url = "http://rp-test.it/oidc/rp/callback-test/"
|
||||
FederationEntityConfiguration.objects.all().delete()
|
||||
local_rp_conf = deepcopy(rp_conf)
|
||||
local_rp_conf["metadata"]["openid_relying_party"]["redirect_uris"] = [red_url],
|
||||
self.rp_conf = FederationEntityConfiguration.objects.create(**local_rp_conf)
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_begin")
|
||||
TrustChain.objects.all()
|
||||
res = client.get(
|
||||
url,
|
||||
{
|
||||
"provider": op_conf["sub"],
|
||||
"trust_anchor": TA_SUB,
|
||||
"redirect_uri": "http://rp-test.it/oidc/rp/callback"
|
||||
}
|
||||
)
|
||||
req = urllib.parse.parse_qs(res.url)['request'][0]
|
||||
req_data = unpad_jwt_payload(req)
|
||||
self.assertTrue(red_url in req_data['redirect_uri'])
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
from copy import deepcopy
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import Client, TestCase, override_settings
|
||||
from django.urls import reverse
|
||||
from spid_cie_oidc.accounts.models import User
|
||||
from spid_cie_oidc.entity.models import FederationEntityConfiguration
|
||||
from spid_cie_oidc.entity.utils import get_jwks
|
||||
|
||||
from spid_cie_oidc.relying_party.models import OidcAuthentication
|
||||
from spid_cie_oidc.authority.tests.settings import rp_conf
|
||||
from spid_cie_oidc.provider.tests.settings import op_conf
|
||||
from spid_cie_oidc.provider.tests.authn_request_settings import AUTHN_REQUEST_SPID
|
||||
|
||||
from spid_cie_oidc.relying_party.tests.mocked_response import (
|
||||
MockedTokenEndPointNoCorrectIdTokenResponse,
|
||||
MockedTokenEndPointNoCorrectResponse,
|
||||
MockedTokenEndPointResponse,
|
||||
MockedTokenEndPointNoCorrectAtHashResponse,
|
||||
MockedUserInfoResponse
|
||||
)
|
||||
|
||||
|
||||
STATE = "fyZiOL9Lf2CeKuNT2JzxiLRDink0uPcd"
|
||||
CODE = "usDwMnEzJPpG5oaV8x3j&"
|
||||
|
||||
|
||||
class RpCallBack(TestCase):
|
||||
def setUp(self):
|
||||
self.rp_jwk = {
|
||||
'use': 'sig',
|
||||
'kty': 'RSA',
|
||||
'kid': '19xSsWuFOo5bFBUECA5G3V5GEhC0s7X8TTCEykdzsmo',
|
||||
'e': 'AQAB',
|
||||
'n': 'vfzFzFAv4e1IPfH6XMeB_L3f9sRZuaOtRsAs7s6ujGv6PwVMPsdELqd2NzrmKrLih3ZysJ6RoRe87rGZUZu2GbDtZhupCPb-1MuxB810svua9PwCrQK2wADM8q26colAiAOGSt912LUPC6MOYus44xd7TUDtQcsm-3VXWu4DA19NQXOaUh2TRal6GKXr7D8teod0fo736oHTObWoDZ0KdAGlwxI6IbQKpipgTD6lZ3l9L6WSmdLI9T-TyyNV9fW6rNqhnbySCEGkCM-Up6C2GQqLTq76kQNSMGasXrd3qH07KnTLBZsFy4JV4L-ws3zgaB4PLBOdfYAYe-xSp9-H_Q', 'd': 'MYc9FXduFCrko2l6yEcmhvoE8fLcJT4bRQ-CZzswW-EmWtmJt_AAwVzcv6c2K7l4vrHNUmf0NRfYJC3ed1ztiyMJsI3TckfZxSXY39za6HIZQnaUSAAmHkXXKAjMS2Gmlg69KrW4picFZhY7AOSrbuBHP6uGbpmEbxd3D3hvBqiU6cn_TAwbIhsJniTuSYYbvHd8z93QCKBfp_nDMltz6WG8YUXFiqtzRKv62Y4K2J_zjyd7-JKiWEBh5FUNuqZ2txEV3-q6bwoh3lSGA1qZtVgU61CwHqGQK3uxfEGPV68O48NVJNEe4YgNE806IfREgprTe3osGHd2S96s-t8oYQ',
|
||||
'p': '9pwMs9MCfes5vYzXb8n1BqAL3LGdPp48jg7iKD4mZ6oLpeCbwNqtB7zN24OqrOnP2nREL2ugkSU2bBrsMy1hZ6k2DnN7cZkNgv4CZ_lO35Bc9CF9j1sCTxUnXQknympL8HVZoG2TdxUL0P09TgiBYz8SVH-uxFnlCuVZBLx35Lk',
|
||||
'q': 'xTjFHi0QGPYSXGgbUN5cl9LOw7K2ifULDbEPiYSnbzd_oVneA-q6BmanMM5CLrj8qKJPy2Cuz3do-ZZPG_SN5AU_x23K9Vga3honcomo7G0cYKi9wGPBKzAMCRNRFHp3f3BAcp6HUJRn02Q_F_xDmXeC8JiPeATSBIDCXv41I2U'
|
||||
}
|
||||
data = deepcopy(AUTHN_REQUEST_SPID)
|
||||
self.rp_config = deepcopy(rp_conf)
|
||||
authz_entry = dict(
|
||||
client_id=self.rp_config["metadata"]["openid_relying_party"]["client_id"],
|
||||
provider_id=op_conf["sub"],
|
||||
data=json.dumps(data),
|
||||
state=STATE,
|
||||
provider_configuration=op_conf["metadata"]["openid_provider"],
|
||||
)
|
||||
OidcAuthentication.objects.create(**authz_entry)
|
||||
self.rp_config["sub"] = self.rp_config["metadata"]["openid_relying_party"]["client_id"]
|
||||
FederationEntityConfiguration.objects.create(**self.rp_config)
|
||||
rp_conf_saved = FederationEntityConfiguration.objects.all().first()
|
||||
get_jwks(rp_conf_saved.metadata['openid_relying_party'])[0]["kid"] = rp_conf_saved.jwks_core[0]["kid"]
|
||||
rp_conf_saved.save()
|
||||
self.op_conf = FederationEntityConfiguration.objects.create(**op_conf)
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback(self, mocked, mocked_2):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
user = get_user_model().objects.first()
|
||||
self.assertTrue(
|
||||
user.attributes['fiscal_number'] == "sdfsfs908df09s8df90s8fd0"
|
||||
)
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_mixups_attacks(self, mocked, mocked_2):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE, "iss": "WRONG"})
|
||||
self.assertTrue(res.status_code == 400)
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_callback.process_user_attributes", return_value=None)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_no_rp_attr_map(self, mocked, mocked_2, mocked_3):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue(res.status_code == 403)
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_callback.process_user_attributes", return_value=None)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_incorret_request(self, mocked, mocked_2, mocked_3):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {})
|
||||
self.assertTrue("error" in res.json())
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_callback.process_user_attributes", return_value=None)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_callback.SpidCieOidcRpCallbackView.get_userinfo", return_value=None)
|
||||
def test_rp_callback_no_userinfo(self, mocked, mocked_2, mocked_3):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue(res.status_code == 400)
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_callback.process_user_attributes", return_value=None)
|
||||
@patch("spid_cie_oidc.relying_party.views.rp_callback.SpidCieOidcRpCallbackView.access_token_request", return_value=None)
|
||||
def test_rp_callback_no_token_response(self, mocked, mocked_2):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue(res.status_code == 400)
|
||||
self.assertTrue("invalid token response" in res.content.decode())
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_no_rp_conf(self, mocked, mocked_2):
|
||||
FederationEntityConfiguration.objects.filter(
|
||||
sub = self.rp_config["sub"]
|
||||
).delete()
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue("Relying party not found" in res.content.decode())
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_no_authz(self, mocked, mocked_2):
|
||||
OidcAuthentication.objects.all().delete()
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue("Authentication not found" in res.content.decode())
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_reunification(self, mocked, mocked_2):
|
||||
user = User.objects.create(username = "username", attributes = {"fiscal_number" : "sdfsfs908df09s8df90s8fd0"}),
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
user = get_user_model().objects.first()
|
||||
self.assertTrue(
|
||||
user.attributes['fiscal_number'] == "sdfsfs908df09s8df90s8fd0"
|
||||
)
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointNoCorrectResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_no_correct_token_response(self, mocked, mocked1):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue(res.status_code == 400)
|
||||
self.assertTrue("invalid_request" in res.content.decode())
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointNoCorrectIdTokenResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_no_correct_id_token_response(self, mocked, mocked1):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue(res.status_code == 403)
|
||||
self.assertTrue("invalid_token" in res.content.decode())
|
||||
|
||||
@override_settings(HTTP_CLIENT_SYNC=True)
|
||||
@patch("requests.post", return_value=MockedTokenEndPointNoCorrectAtHashResponse())
|
||||
@patch("requests.get", return_value=MockedUserInfoResponse())
|
||||
def test_rp_callback_no_correct_at_hash_response(self, mocked, mocked1):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_callback")
|
||||
res = client.get(url, {"state": STATE, "code": CODE})
|
||||
self.assertTrue(res.status_code == 403)
|
||||
self.assertTrue("at_hash verification failed" in res.content.decode())
|
||||
Vendored
+77
@@ -0,0 +1,77 @@
|
||||
from copy import deepcopy
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import Client, TestCase
|
||||
from django.urls import reverse
|
||||
from spid_cie_oidc.authority.tests.settings import rp_conf
|
||||
from spid_cie_oidc.entity.models import FederationEntityConfiguration
|
||||
from spid_cie_oidc.provider.tests.settings import op_conf
|
||||
from spid_cie_oidc.relying_party.models import (
|
||||
OidcAuthentication,
|
||||
OidcAuthenticationToken
|
||||
)
|
||||
from spid_cie_oidc.relying_party.tests.mocked_response import MockedLogout
|
||||
|
||||
|
||||
class RpIntiatedLogoutTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.user = get_user_model().objects.create(
|
||||
username="test",
|
||||
first_name="test",
|
||||
last_name="test",
|
||||
email="[email protected]",
|
||||
)
|
||||
self.user.set_password("test")
|
||||
self.user.save()
|
||||
authz_request = OidcAuthentication.objects.create(
|
||||
client_id=rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
provider_configuration=op_conf["metadata"]["openid_provider"],
|
||||
)
|
||||
self.authz_token = OidcAuthenticationToken.objects.create(
|
||||
user= self.user,
|
||||
authz_request = authz_request,
|
||||
)
|
||||
FederationEntityConfiguration.objects.create(**rp_conf)
|
||||
self.admin_user = get_user_model().objects.create_superuser(
|
||||
username="superuser", password="secret", email="[email protected]"
|
||||
)
|
||||
|
||||
|
||||
@patch("requests.post", return_value=MockedLogout())
|
||||
def test_rpinitiated_logout(self, mokced):
|
||||
c = Client()
|
||||
c.login(username="test", password="test")
|
||||
url = reverse("spid_cie_rpinitiated_logout")
|
||||
res = c.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
self.assertTrue(res.url == "/oidc/rp/landing")
|
||||
|
||||
def test_rpinitiated_logout_no_revocation_endpoint(self):
|
||||
OidcAuthentication.objects.all().delete()
|
||||
op_conf_local = deepcopy(op_conf["metadata"]["openid_provider"])
|
||||
op_conf_local.pop("revocation_endpoint")
|
||||
authz_request = OidcAuthentication.objects.create(
|
||||
client_id=rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
provider_configuration=op_conf_local,
|
||||
)
|
||||
self.authz_token = OidcAuthenticationToken.objects.create(
|
||||
user= self.user,
|
||||
authz_request = authz_request,
|
||||
)
|
||||
c = Client()
|
||||
c.login(username="test", password="test")
|
||||
url = reverse("spid_cie_rpinitiated_logout")
|
||||
res = c.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
self.assertTrue(res.url == "/oidc/rp/landing")
|
||||
|
||||
def test_rpinitiated_logout_no_auth_token(self):
|
||||
OidcAuthenticationToken.objects.all().delete()
|
||||
c = Client()
|
||||
c.login(username="test", password="test")
|
||||
url = reverse("spid_cie_rpinitiated_logout")
|
||||
res = c.get(url)
|
||||
self.assertTrue(res.status_code == 302)
|
||||
self.assertTrue(res.url == "/oidc/rp/landing")
|
||||
Vendored
+65
@@ -0,0 +1,65 @@
|
||||
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, override_settings
|
||||
from spid_cie_oidc.entity.models import FetchedEntityStatement, TrustChain
|
||||
from spid_cie_oidc.entity.tests.settings import TA_SUB
|
||||
from spid_cie_oidc.entity.utils import (
|
||||
datetime_from_timestamp,
|
||||
exp_from_now,
|
||||
iat_now
|
||||
)
|
||||
from spid_cie_oidc.provider.tests.settings import op_conf
|
||||
|
||||
EXP = datetime_from_timestamp(exp_from_now(33))
|
||||
NOW = datetime_from_timestamp(iat_now())
|
||||
|
||||
|
||||
def create_tc():
|
||||
ta_fes = FetchedEntityStatement.objects.create(
|
||||
sub=TA_SUB,
|
||||
iss=TA_SUB,
|
||||
exp=EXP,
|
||||
iat=NOW
|
||||
)
|
||||
return TrustChain.objects.create(
|
||||
sub=op_conf["sub"],
|
||||
exp=EXP,
|
||||
jwks = [],
|
||||
metadata=op_conf["metadata"],
|
||||
status="valid",
|
||||
trust_anchor=ta_fes,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
|
||||
class FetchProviderTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.ta_fes = FetchedEntityStatement.objects.create(
|
||||
sub=TA_SUB,
|
||||
iss=TA_SUB,
|
||||
exp=datetime_from_timestamp(exp_from_now(33)),
|
||||
iat=datetime_from_timestamp(iat_now()),
|
||||
)
|
||||
|
||||
def exec(self, cmd_name:str, *args, **kwargs):
|
||||
call_command(
|
||||
cmd_name,
|
||||
*args,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@override_settings(OIDCFED_IDENTITY_PROVIDERS = {"spid": {"http://127.0.0.1:8000/oidc/op/" :"http://testserver/"}, "cie":{}})
|
||||
def test_fetch_provider(self):
|
||||
self.patcher = patch(
|
||||
"spid_cie_oidc.entity.trust_chain_operations.get_or_create_trust_chain",
|
||||
return_value = create_tc()
|
||||
)
|
||||
self.patcher.start()
|
||||
self.exec('fetch_openid_providers', '--start')
|
||||
self.patcher.stop()
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
from django.test import Client, TestCase
|
||||
from django.urls import reverse
|
||||
from spid_cie_oidc.entity.models import FetchedEntityStatement, TrustChain
|
||||
from spid_cie_oidc.entity.tests.settings import TA_SUB
|
||||
from spid_cie_oidc.entity.utils import (
|
||||
datetime_from_timestamp,
|
||||
exp_from_now,
|
||||
iat_now
|
||||
)
|
||||
from spid_cie_oidc.provider.tests.settings import op_conf
|
||||
|
||||
|
||||
class RpLandingTest(TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
NOW = datetime_from_timestamp(iat_now())
|
||||
EXP = datetime_from_timestamp(exp_from_now(33))
|
||||
self.ta_fes = FetchedEntityStatement.objects.create(
|
||||
sub=TA_SUB,
|
||||
iss=TA_SUB,
|
||||
exp=EXP,
|
||||
iat=NOW,
|
||||
)
|
||||
|
||||
self.trust_chain = TrustChain.objects.create(
|
||||
sub=op_conf["sub"],
|
||||
exp=EXP,
|
||||
jwks = [],
|
||||
metadata=op_conf["metadata"],
|
||||
status="valid",
|
||||
trust_anchor=self.ta_fes,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
def test_rp_landing(self):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_landing")
|
||||
res = client.get(url)
|
||||
self.assertTrue(res.status_code == 200)
|
||||
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
from django.test import Client, TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
class CallBackEchoAttributesTest(TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
return super().setUp()
|
||||
|
||||
def test_call_back_echo_attributes(self):
|
||||
client = Client()
|
||||
url = reverse("spid_cie_rp_echo_attributes")
|
||||
session = client.session
|
||||
session.update({"oidc_rp_user_attrs": {"email":"[email protected]"}})
|
||||
session.save()
|
||||
res = client.get(url)
|
||||
self.assertTrue(res.status_code == 200)
|
||||
self.assertTrue("[email protected]" in res.content.decode())
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
import json
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.test import TestCase
|
||||
from spid_cie_oidc.authority.tests.settings import rp_conf
|
||||
from spid_cie_oidc.entity.jwtse import create_jws
|
||||
from spid_cie_oidc.provider.tests.settings import (
|
||||
op_conf,
|
||||
op_conf_priv_jwk
|
||||
)
|
||||
from spid_cie_oidc.relying_party.models import (
|
||||
OidcAuthentication,
|
||||
OidcAuthenticationToken
|
||||
)
|
||||
|
||||
RP_SUB = rp_conf["sub"]
|
||||
RP_CLIENT_ID = rp_conf["metadata"]["openid_relying_party"]["client_id"]
|
||||
|
||||
class RpModelTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.user = get_user_model().objects.create(
|
||||
username="test",
|
||||
first_name="test",
|
||||
last_name="test",
|
||||
email="[email protected]",
|
||||
)
|
||||
self.user.set_password("test")
|
||||
self.user.save()
|
||||
authz_request = OidcAuthentication.objects.create(
|
||||
client_id=rp_conf["metadata"]["openid_relying_party"]["client_id"],
|
||||
provider_configuration=op_conf["metadata"]["openid_provider"],
|
||||
)
|
||||
self.token = {
|
||||
"iss": op_conf["sub"],
|
||||
"sub": RP_SUB,
|
||||
"aud": [RP_CLIENT_ID],
|
||||
"client_id": RP_CLIENT_ID,
|
||||
"scope": "openid",
|
||||
}
|
||||
self.rt_jws = create_jws(self.token, op_conf_priv_jwk)
|
||||
self.authz_token = OidcAuthenticationToken.objects.create(
|
||||
user= self.user,
|
||||
authz_request = authz_request,
|
||||
code = "code",
|
||||
access_token = self.rt_jws,
|
||||
id_token = self.rt_jws,
|
||||
)
|
||||
|
||||
def test_token_preview(self):
|
||||
result = OidcAuthenticationToken.token_preview(self.authz_token, self.rt_jws)
|
||||
self.assertTrue(json.loads(result)["iss"] == "http://op-test/oidc/op/")
|
||||
result = OidcAuthenticationToken.token_preview(self.authz_token, "")
|
||||
self.assertTrue(result == "--")
|
||||
result = OidcAuthenticationToken.token_preview(self.authz_token, "token")
|
||||
self.assertTrue(result == None)
|
||||
result = OidcAuthenticationToken.__str__(self.authz_token)
|
||||
self.assertTrue("code" in result)
|
||||
result = self.authz_token.access_token_preview
|
||||
self.assertTrue(json.loads(result)["iss"] == "http://op-test/oidc/op/")
|
||||
result = self.authz_token.id_token_preview
|
||||
self.assertTrue(json.loads(result)["iss"] == "http://op-test/oidc/op/")
|
||||
Reference in New Issue
Block a user