Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add get metadata timeout #259

Merged
merged 3 commits into from
May 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,12 +520,18 @@ The method above requires a little extra work to manually specify attributes abo

There's an easier method -- use a metadata exchange. Metadata is just an XML file that defines the capabilities of both the IdP and the SP application. It also contains the X.509 public key certificates which add to the trusted relationship. The IdP administrator can also configure custom settings for an SP based on the metadata.

Using ````parse_remote```` IdP metadata can be obtained and added to the settings withouth further ado.
Using ````parse_remote```` IdP metadata can be obtained and added to the settings without further ado.

``
idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://example.com/auth/saml2/idp/metadata')
``

You can specify a timeout in seconds for metadata retrieval, without it is not guaranteed that the request will complete

``
idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote('https://example.com/auth/saml2/idp/metadata', timeout=5)
``

If the Metadata contains several entities, the relevant ``EntityDescriptor`` can be specified when retrieving the settings from the ``IdpMetadataParser`` by its ``entityId`` value:

``idp_data = OneLogin_Saml2_IdPMetadataParser.parse_remote(https://example.com/metadatas, entity_id='idp_entity_id')``
Expand Down
16 changes: 11 additions & 5 deletions src/onelogin/saml2/idp_metadata_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class OneLogin_Saml2_IdPMetadataParser(object):
"""

@classmethod
def get_metadata(cls, url, validate_cert=True):
def get_metadata(cls, url, validate_cert=True, timeout=None):
"""
Gets the metadata XML from the provided URL
:param url: Url where the XML of the Identity Provider Metadata is published.
Expand All @@ -35,18 +35,21 @@ def get_metadata(cls, url, validate_cert=True):
:param validate_cert: If the url uses https schema, that flag enables or not the verification of the associated certificate.
:type validate_cert: bool

:param timeout: Timeout in seconds to wait for metadata response
:type timeout: int

:returns: metadata XML
:rtype: string
"""
valid = False

if validate_cert:
response = urllib2.urlopen(url)
response = urllib2.urlopen(url, timeout=timeout)
else:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
response = urllib2.urlopen(url, context=ctx)
response = urllib2.urlopen(url, context=ctx, timeout=timeout)
xml = response.read()

if xml:
Expand All @@ -64,7 +67,7 @@ def get_metadata(cls, url, validate_cert=True):
return xml

@classmethod
def parse_remote(cls, url, validate_cert=True, entity_id=None, **kwargs):
def parse_remote(cls, url, validate_cert=True, entity_id=None, timeout=None, **kwargs):
"""
Gets the metadata XML from the provided URL and parse it, returning a dict with extracted data
:param url: Url where the XML of the Identity Provider Metadata is published.
Expand All @@ -77,10 +80,13 @@ def parse_remote(cls, url, validate_cert=True, entity_id=None, **kwargs):
that contains multiple EntityDescriptor.
:type entity_id: string

:param timeout: Timeout in seconds to wait for metadata response
:type timeout: int

:returns: settings dict with extracted data
:rtype: dict
"""
idp_metadata = cls.get_metadata(url, validate_cert)
idp_metadata = cls.get_metadata(url, validate_cert, timeout)
return cls.parse(idp_metadata, entity_id=entity_id, **kwargs)

@classmethod
Expand Down