Skip to content

Commit 3f90130

Browse files
committed
Merge pull request #68 from open-craft/edx3-expiry-settings
Allow configuration of metadata caching/expiry via settings
2 parents b753ea7 + 5860526 commit 3f90130

File tree

3 files changed

+54
-15
lines changed

3 files changed

+54
-15
lines changed

src/onelogin/saml2/metadata.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ def builder(sp, authnsign=False, wsign=False, valid_until=None, cache_duration=N
4141
:param wsign: wantAssertionsSigned attribute
4242
:type wsign: string
4343
44-
:param valid_until: Metadata's valid time
45-
:type valid_until: string|DateTime
44+
:param valid_until: Metadata's expiry date
45+
:type valid_until: string|DateTime|Timestamp
4646
4747
:param cache_duration: Duration of the cache in seconds
48-
:type cache_duration: string|Timestamp
48+
:type cache_duration: int|string
4949
5050
:param contacts: Contacts info
5151
:type contacts: dict
@@ -56,15 +56,18 @@ def builder(sp, authnsign=False, wsign=False, valid_until=None, cache_duration=N
5656
if valid_until is None:
5757
valid_until = int(datetime.now().strftime("%s")) + OneLogin_Saml2_Metadata.TIME_VALID
5858
if not isinstance(valid_until, basestring):
59-
valid_until_time = gmtime(valid_until)
60-
valid_until_time = strftime(r'%Y-%m-%dT%H:%M:%SZ', valid_until_time)
59+
if isinstance(valid_until, datetime):
60+
valid_until_time = valid_until
61+
else:
62+
valid_until_time = gmtime(valid_until)
63+
valid_until_str = strftime(r'%Y-%m-%dT%H:%M:%SZ', valid_until_time)
6164
else:
62-
valid_until_time = valid_until
65+
valid_until_str = valid_until
6366

6467
if cache_duration is None:
65-
cache_duration = int(datetime.now().strftime("%s")) + OneLogin_Saml2_Metadata.TIME_CACHED
68+
cache_duration = OneLogin_Saml2_Metadata.TIME_CACHED
6669
if not isinstance(cache_duration, basestring):
67-
cache_duration_str = 'PT%sS' % cache_duration
70+
cache_duration_str = 'PT%sS' % cache_duration # 'P'eriod of 'T'ime x 'S'econds
6871
else:
6972
cache_duration_str = cache_duration
7073

@@ -121,8 +124,8 @@ def builder(sp, authnsign=False, wsign=False, valid_until=None, cache_duration=N
121124

122125
metadata = """<?xml version="1.0"?>
123126
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
124-
validUntil="%(valid)s"
125-
cacheDuration="%(cache)s"
127+
%(valid)s
128+
%(cache)s
126129
entityID="%(entity_id)s">
127130
<md:SPSSODescriptor AuthnRequestsSigned="%(authnsign)s" WantAssertionsSigned="%(wsign)s" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
128131
%(sls)s <md:NameIDFormat>%(name_id_format)s</md:NameIDFormat>
@@ -134,8 +137,8 @@ def builder(sp, authnsign=False, wsign=False, valid_until=None, cache_duration=N
134137
%(contacts)s
135138
</md:EntityDescriptor>""" % \
136139
{
137-
'valid': valid_until_time,
138-
'cache': cache_duration_str,
140+
'valid': ('validUntil="%s"' % valid_until_str) if valid_until_str else '',
141+
'cache': ('cacheDuration="%s"' % cache_duration_str) if cache_duration_str else '',
139142
'entity_id': sp['entityId'],
140143
'authnsign': str_authnsign,
141144
'wsign': str_wsign,

src/onelogin/saml2/settings.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,12 @@ def __add_default_values(self):
266266
if 'nameIdEncrypted' not in self.__security:
267267
self.__security['nameIdEncrypted'] = False
268268

269+
# Metadata format
270+
if 'metadataValidUntil' not in self.__security.keys():
271+
self.__security['metadataValidUntil'] = None # None means use default
272+
if 'metadataCacheDuration' not in self.__security.keys():
273+
self.__security['metadataCacheDuration'] = None # None means use default
274+
269275
# Sign provided
270276
if 'authnRequestsSigned' not in self.__security.keys():
271277
self.__security['authnRequestsSigned'] = False
@@ -548,7 +554,9 @@ def get_sp_metadata(self):
548554
"""
549555
metadata = OneLogin_Saml2_Metadata.builder(
550556
self.__sp, self.__security['authnRequestsSigned'],
551-
self.__security['wantAssertionsSigned'], None, None,
557+
self.__security['wantAssertionsSigned'],
558+
self.__security['metadataValidUntil'],
559+
self.__security['metadataCacheDuration'],
552560
self.get_contacts(), self.get_organization()
553561
)
554562
cert = self.get_sp_cert()

tests/src/OneLogin/saml2_tests/metadata_test.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,43 @@ def testBuilder(self):
8484
sp_data, security['authnRequestsSigned'],
8585
security['wantAssertionsSigned'],
8686
'2014-10-01T11:04:29Z',
87-
'PT1412593469S',
87+
'P1Y',
8888
contacts,
8989
organization
9090
)
9191
self.assertIsNotNone(metadata3)
9292
self.assertIn('<md:SPSSODescriptor', metadata3)
93-
self.assertIn('cacheDuration="PT1412593469S"', metadata3)
93+
self.assertIn('cacheDuration="P1Y"', metadata3)
9494
self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata3)
9595

96+
# Test no validUntil, only cacheDuration:
97+
metadata4 = OneLogin_Saml2_Metadata.builder(
98+
sp_data, security['authnRequestsSigned'],
99+
security['wantAssertionsSigned'],
100+
'',
101+
86400 * 10, # 10 days
102+
contacts,
103+
organization
104+
)
105+
self.assertIsNotNone(metadata4)
106+
self.assertIn('<md:SPSSODescriptor', metadata4)
107+
self.assertIn('cacheDuration="PT864000S"', metadata4)
108+
self.assertNotIn('validUntil', metadata4)
109+
110+
# Test no cacheDuration, only validUntil:
111+
metadata5 = OneLogin_Saml2_Metadata.builder(
112+
sp_data, security['authnRequestsSigned'],
113+
security['wantAssertionsSigned'],
114+
'2014-10-01T11:04:29Z',
115+
'',
116+
contacts,
117+
organization
118+
)
119+
self.assertIsNotNone(metadata5)
120+
self.assertIn('<md:SPSSODescriptor', metadata5)
121+
self.assertNotIn('cacheDuration', metadata5)
122+
self.assertIn('validUntil="2014-10-01T11:04:29Z"', metadata5)
123+
96124
def testSignMetadata(self):
97125
"""
98126
Tests the signMetadata method of the OneLogin_Saml2_Metadata

0 commit comments

Comments
 (0)