Add SAML metadata refresh control flag

mattdrayer: Change model fieldname, revise code, fix bad tests.
This commit is contained in:
Matt Drayer
2017-03-28 16:00:26 -04:00
parent 4ef009cf4f
commit b64503848c
6 changed files with 111 additions and 50 deletions

View File

@@ -25,14 +25,19 @@ class Command(BaseCommand):
log = logging.getLogger('third_party_auth.tasks')
log.propagate = False
log.addHandler(log_handler)
num_changed, num_failed, num_total, failure_messages = fetch_saml_metadata()
total, skipped, attempted, updated, failed, failure_messages = fetch_saml_metadata()
self.stdout.write(
"\nDone. Fetched {num_total} total. {num_changed} were updated and {num_failed} failed.\n".format(
num_changed=num_changed, num_failed=num_failed, num_total=num_total
"\nDone."
"\n{total} provider(s) found in database."
"\n{skipped} skipped and {attempted} attempted."
"\n{updated} updated and {failed} failed.\n".format(
total=total,
skipped=skipped, attempted=attempted,
updated=updated, failed=failed,
)
)
if num_failed > 0:
if failed > 0:
raise CommandError(
"Command finished with the following exceptions:\n\n{failures}".format(
failures="\n\n".join(failure_messages)

View File

@@ -92,10 +92,9 @@ class TestSAMLCommand(TestCase):
Test that management command completes without errors and logs correct information when no
saml configurations are enabled/present.
"""
# Capture command output log for testing.
expected = "\nDone.\n1 provider(s) found in database.\n1 skipped and 0 attempted.\n0 updated and 0 failed.\n"
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn('Done. Fetched 0 total. 0 were updated and 0 failed.', self.stdout.getvalue())
self.assertIn(expected, self.stdout.getvalue())
@mock.patch("requests.get", mock_get())
def test_fetch_saml_metadata(self):
@@ -106,10 +105,9 @@ class TestSAMLCommand(TestCase):
# Create enabled configurations
self.__create_saml_configurations__()
# Capture command output log for testing.
expected = "\nDone.\n1 provider(s) found in database.\n0 skipped and 1 attempted.\n1 updated and 0 failed.\n"
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn('Done. Fetched 1 total. 1 were updated and 0 failed.', self.stdout.getvalue())
self.assertIn(expected, self.stdout.getvalue())
@mock.patch("requests.get", mock_get(status_code=404))
def test_fetch_saml_metadata_failure(self):
@@ -120,11 +118,11 @@ class TestSAMLCommand(TestCase):
# Create enabled configurations
self.__create_saml_configurations__()
with self.assertRaisesRegexp(CommandError, r"HTTPError: 404 Client Error"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
expected = "\nDone.\n1 provider(s) found in database.\n0 skipped and 1 attempted.\n0 updated and 1 failed.\n"
self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue())
with self.assertRaisesRegexp(CommandError, r"HTTPError: 404 Client Error"):
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn(expected, self.stdout.getvalue())
@mock.patch("requests.get", mock_get(status_code=200))
def test_fetch_multiple_providers_data(self):
@@ -162,11 +160,31 @@ class TestSAMLCommand(TestCase):
}
)
expected = '\n3 provider(s) found in database.\n0 skipped and 3 attempted.\n2 updated and 1 failed.\n'
with self.assertRaisesRegexp(CommandError, r"MetadataParseError: Can't find EntityDescriptor for entityID"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn(expected, self.stdout.getvalue())
self.assertIn('Done. Fetched 3 total. 2 were updated and 1 failed.', self.stdout.getvalue())
# Now add a fourth configuration, and indicate that it should not be included in the update
self.__create_saml_configurations__(
saml_config={
"site__domain": "fourth.testserver.fake",
},
saml_provider_config={
"site__domain": "fourth.testserver.fake",
"idp_slug": "fourth-test-shib",
"automatic_refresh_enabled": False,
# Note: This invalid entity id will not be present in the refresh set
"entity_id": "https://idp.testshib.org/idp/fourth-shibboleth",
"metadata_source": "https://www.testshib.org/metadata/fourth/testshib-providers.xml",
}
)
# Four configurations -- one will be skipped and three attempted, with similar results.
expected = '\nDone.\n4 provider(s) found in database.\n1 skipped and 3 attempted.\n0 updated and 1 failed.\n'
with self.assertRaisesRegexp(CommandError, r"MetadataParseError: Can't find EntityDescriptor for entityID"):
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn(expected, self.stdout.getvalue())
@mock.patch("requests.get")
def test_saml_request_exceptions(self, mocked_get):
@@ -178,27 +196,23 @@ class TestSAMLCommand(TestCase):
mocked_get.side_effect = exceptions.SSLError
with self.assertRaisesRegexp(CommandError, "SSLError:"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
expected = "\nDone.\n1 provider(s) found in database.\n0 skipped and 1 attempted.\n0 updated and 1 failed.\n"
self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue())
with self.assertRaisesRegexp(CommandError, "SSLError:"):
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn(expected, self.stdout.getvalue())
mocked_get.side_effect = exceptions.ConnectionError
with self.assertRaisesRegexp(CommandError, "ConnectionError:"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue())
self.assertIn(expected, self.stdout.getvalue())
mocked_get.side_effect = exceptions.HTTPError
with self.assertRaisesRegexp(CommandError, "HTTPError:"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue())
self.assertIn(expected, self.stdout.getvalue())
@mock.patch("requests.get", mock_get(status_code=200))
def test_saml_parse_exceptions(self):
@@ -219,11 +233,11 @@ class TestSAMLCommand(TestCase):
}
)
with self.assertRaisesRegexp(CommandError, "MetadataParseError: Can't find EntityDescriptor for entityID"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
expected = "\nDone.\n2 provider(s) found in database.\n1 skipped and 1 attempted.\n0 updated and 1 failed.\n"
self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue())
with self.assertRaisesRegexp(CommandError, "MetadataParseError: Can't find EntityDescriptor for entityID"):
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn(expected, self.stdout.getvalue())
@mock.patch("requests.get")
def test_xml_parse_exceptions(self, mocked_get):
@@ -239,8 +253,8 @@ class TestSAMLCommand(TestCase):
# create enabled configuration
self.__create_saml_configurations__()
with self.assertRaisesRegexp(CommandError, "XMLSyntaxError:"):
# Capture command output log for testing.
call_command("saml", pull=True, stdout=self.stdout)
expected = "\nDone.\n1 provider(s) found in database.\n0 skipped and 1 attempted.\n0 updated and 1 failed.\n"
self.assertIn('Done. Fetched 1 total. 0 were updated and 1 failed.', self.stdout.getvalue())
with self.assertRaisesRegexp(CommandError, "XMLSyntaxError:"):
call_command("saml", pull=True, stdout=self.stdout)
self.assertIn(expected, self.stdout.getvalue())