Commit 45bca67f by Jesse Shapiro

Set up type conversion in third_party_auth to allow cacheDuration attribute to work

parent 5b7f48c5
...@@ -6,6 +6,7 @@ Code to manage fetching and storing the metadata of IdPs. ...@@ -6,6 +6,7 @@ Code to manage fetching and storing the metadata of IdPs.
from celery.task import task from celery.task import task
import datetime import datetime
import dateutil.parser import dateutil.parser
import pytz
import logging import logging
from lxml import etree from lxml import etree
import requests import requests
...@@ -106,6 +107,7 @@ def _parse_metadata_xml(xml, entity_id): ...@@ -106,6 +107,7 @@ def _parse_metadata_xml(xml, entity_id):
expires_at = dateutil.parser.parse(xml.attrib["validUntil"]) expires_at = dateutil.parser.parse(xml.attrib["validUntil"])
if "cacheDuration" in xml.attrib: if "cacheDuration" in xml.attrib:
cache_expires = OneLogin_Saml2_Utils.parse_duration(xml.attrib["cacheDuration"]) cache_expires = OneLogin_Saml2_Utils.parse_duration(xml.attrib["cacheDuration"])
cache_expires = datetime.datetime.fromtimestamp(cache_expires, tz=pytz.utc)
if expires_at is None or cache_expires < expires_at: if expires_at is None or cache_expires < expires_at:
expires_at = cache_expires expires_at = cache_expires
......
...@@ -16,6 +16,7 @@ from .base import IntegrationTestMixin ...@@ -16,6 +16,7 @@ from .base import IntegrationTestMixin
TESTSHIB_ENTITY_ID = 'https://idp.testshib.org/idp/shibboleth' TESTSHIB_ENTITY_ID = 'https://idp.testshib.org/idp/shibboleth'
TESTSHIB_METADATA_URL = 'https://mock.testshib.org/metadata/testshib-providers.xml' TESTSHIB_METADATA_URL = 'https://mock.testshib.org/metadata/testshib-providers.xml'
TESTSHIB_METADATA_URL_WITH_CACHE_DURATION = 'https://mock.testshib.org/metadata/testshib-providers-cache.xml'
TESTSHIB_SSO_URL = 'https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO' TESTSHIB_SSO_URL = 'https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO'
...@@ -47,7 +48,19 @@ class TestShibIntegrationTest(IntegrationTestMixin, testutil.SAMLTestCase): ...@@ -47,7 +48,19 @@ class TestShibIntegrationTest(IntegrationTestMixin, testutil.SAMLTestCase):
def metadata_callback(_request, _uri, headers): def metadata_callback(_request, _uri, headers):
""" Return a cached copy of TestShib's metadata by reading it from disk """ """ Return a cached copy of TestShib's metadata by reading it from disk """
return (200, headers, self.read_data_file('testshib_metadata.xml')) return (200, headers, self.read_data_file('testshib_metadata.xml'))
httpretty.register_uri(httpretty.GET, TESTSHIB_METADATA_URL, content_type='text/xml', body=metadata_callback) httpretty.register_uri(httpretty.GET, TESTSHIB_METADATA_URL, content_type='text/xml', body=metadata_callback)
def cache_duration_metadata_callback(_request, _uri, headers):
"""Return a cached copy of TestShib's metadata with a cacheDuration attribute"""
return (200, headers, self.read_data_file('testshib_metadata_with_cache_duration.xml'))
httpretty.register_uri(
httpretty.GET,
TESTSHIB_METADATA_URL_WITH_CACHE_DURATION,
content_type='text/xml',
body=cache_duration_metadata_callback
)
self.addCleanup(httpretty.disable) self.addCleanup(httpretty.disable)
self.addCleanup(httpretty.reset) self.addCleanup(httpretty.reset)
...@@ -123,6 +136,24 @@ class TestShibIntegrationTest(IntegrationTestMixin, testutil.SAMLTestCase): ...@@ -123,6 +136,24 @@ class TestShibIntegrationTest(IntegrationTestMixin, testutil.SAMLTestCase):
else: else:
self.assertFalse(mock_log.called) self.assertFalse(mock_log.called)
def test_configure_testshib_provider_with_cache_duration(self):
""" Enable and configure the TestShib SAML IdP as a third_party_auth provider """
kwargs = {}
kwargs.setdefault('name', self.PROVIDER_NAME)
kwargs.setdefault('enabled', True)
kwargs.setdefault('visible', True)
kwargs.setdefault('idp_slug', self.PROVIDER_IDP_SLUG)
kwargs.setdefault('entity_id', TESTSHIB_ENTITY_ID)
kwargs.setdefault('metadata_source', TESTSHIB_METADATA_URL_WITH_CACHE_DURATION)
kwargs.setdefault('icon_class', 'fa-university')
kwargs.setdefault('attr_email', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.6') # eduPersonPrincipalName
self.configure_saml_provider(**kwargs)
self.assertTrue(httpretty.is_enabled())
num_changed, num_failed, num_total = fetch_saml_metadata()
self.assertEqual(num_failed, 0)
self.assertEqual(num_changed, 1)
self.assertEqual(num_total, 1)
def _freeze_time(self, timestamp): def _freeze_time(self, timestamp):
""" Mock the current time for SAML, so we can replay canned requests/responses """ """ Mock the current time for SAML, so we can replay canned requests/responses """
now_patch = patch('onelogin.saml2.utils.OneLogin_Saml2_Utils.now', return_value=timestamp) now_patch = patch('onelogin.saml2.utils.OneLogin_Saml2_Utils.now', return_value=timestamp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment