diff --git a/pyproject.toml b/pyproject.toml index eee84f5b..09d623f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ "lxml>=4.6.5,!=4.7.0", "xmlsec>=1.3.9", "isodate>=0.6.1", + "requests", ] requires-python = ">=3.7" @@ -119,4 +120,4 @@ ignore_errors = true [tool.coverage.html] -directory = "coverage_html_report" \ No newline at end of file +directory = "coverage_html_report" diff --git a/src/onelogin/saml2/idp_metadata_parser.py b/src/onelogin/saml2/idp_metadata_parser.py index 6710ff1f..60ce4a66 100644 --- a/src/onelogin/saml2/idp_metadata_parser.py +++ b/src/onelogin/saml2/idp_metadata_parser.py @@ -7,10 +7,7 @@ from copy import deepcopy -try: - import urllib.request as urllib2 -except ImportError: - import urllib2 +import requests import ssl @@ -30,6 +27,13 @@ class OneLogin_Saml2_IdPMetadataParser(object): def get_metadata(cls, url, validate_cert=True, timeout=None, headers=None): """ Gets the metadata XML from the provided URL + + The metadata is retrieved with the ``requests`` library. If you need to support + server certificates that are not readily available in the trust store, use the + ``REQUESTS_CA_BUNDLE`` environment variable. See the + `advanced documentation `_ + for more information. + :param url: Url where the XML of the Identity Provider Metadata is published. :type url: string @@ -46,16 +50,9 @@ def get_metadata(cls, url, validate_cert=True, timeout=None, headers=None): """ valid = False - request = urllib2.Request(url, headers=headers or {}) - - if validate_cert: - response = urllib2.urlopen(request, timeout=timeout) - else: - ctx = ssl.create_default_context() - ctx.check_hostname = False - ctx.verify_mode = ssl.CERT_NONE - response = urllib2.urlopen(request, context=ctx, timeout=timeout) - xml = response.read() + response = requests.get(url, headers=headers, verify=validate_cert, timeout=timeout) + response.raise_for_status() + xml = response.content if xml: try: diff --git a/tests/src/OneLogin/saml2_tests/idp_metadata_parser_test.py b/tests/src/OneLogin/saml2_tests/idp_metadata_parser_test.py index cff9418b..5c4f6168 100644 --- a/tests/src/OneLogin/saml2_tests/idp_metadata_parser_test.py +++ b/tests/src/OneLogin/saml2_tests/idp_metadata_parser_test.py @@ -1,15 +1,10 @@ # -*- coding: utf-8 -*- - -try: - from urllib.error import URLError -except ImportError: - from urllib2 import URLError - from copy import deepcopy import json from os.path import dirname, join, exists from lxml.etree import XMLSyntaxError +from requests import RequestException import unittest from onelogin.saml2.idp_metadata_parser import OneLogin_Saml2_IdPMetadataParser @@ -51,7 +46,7 @@ def testGetMetadata(self): try: data = OneLogin_Saml2_IdPMetadataParser.get_metadata("https://raw.githubusercontent.com/SAML-Toolkits/python3-saml/master/tests/data/metadata/testshib-providers.xml", validate_cert=False) self.assertTrue(data is not None and data is not {}) - except URLError: + except RequestException: pass def testGetMetadataWithHeaders(self): @@ -70,7 +65,7 @@ def testParseRemote(self): try: data = OneLogin_Saml2_IdPMetadataParser.parse_remote("https://raw.githubusercontent.com/SAML-Toolkits/python3-saml/master/tests/data/metadata/testshib-providers.xml", validate_cert=False) - except URLError: + except RequestException: xml = self.file_contents(join(self.data_path, "metadata", "testshib-providers.xml")) data = OneLogin_Saml2_IdPMetadataParser.parse(xml) @@ -162,7 +157,7 @@ def test_parse_testshib_required_binding_sso_redirect(self): """ try: xmldoc = OneLogin_Saml2_IdPMetadataParser.get_metadata("https://idp.testshib.org/idp/shibboleth") - except URLError: + except RequestException: xmldoc = self.file_contents(join(self.data_path, "metadata", "testshib-providers.xml")) # Parse, require SSO REDIRECT binding, implicitly. @@ -196,7 +191,7 @@ def test_parse_testshib_required_binding_sso_post(self): """ try: xmldoc = OneLogin_Saml2_IdPMetadataParser.get_metadata("https://idp.testshib.org/idp/shibboleth") - except URLError: + except RequestException: xmldoc = self.file_contents(join(self.data_path, "metadata", "testshib-providers.xml")) # Parse, require POST binding.