fix: properly handle SAML Index and Key errors (#31882)
This commit is contained in:
@@ -90,15 +90,15 @@ class SAMLAuthBackend(SAMLAuth): # pylint: disable=abstract-method
|
||||
"""
|
||||
try:
|
||||
return super().get_user_id(details, response)
|
||||
except KeyError as ex:
|
||||
except (KeyError, IndexError) as ex:
|
||||
log.warning(
|
||||
'[THIRD_PARTY_AUTH] Error in SAML authentication flow. '
|
||||
'Provider: {idp_name}, Message: {message}'.format(
|
||||
message=ex.message, # lint-amnesty, pylint: disable=no-member
|
||||
message=str(ex),
|
||||
idp_name=response.get('idp_name')
|
||||
)
|
||||
)
|
||||
raise IncorrectConfigurationException(self) # lint-amnesty, pylint: disable=raise-missing-from
|
||||
raise IncorrectConfigurationException(self) from ex
|
||||
|
||||
def generate_metadata_xml(self, idp_name=None): # pylint: disable=arguments-differ
|
||||
"""
|
||||
|
||||
@@ -22,6 +22,7 @@ from social_django.models import UserSocialAuth
|
||||
from testfixtures import LogCapture
|
||||
|
||||
from common.djangoapps.third_party_auth import pipeline
|
||||
from common.djangoapps.third_party_auth.exceptions import IncorrectConfigurationException
|
||||
from common.djangoapps.third_party_auth.saml import SapSuccessFactorsIdentityProvider
|
||||
from common.djangoapps.third_party_auth.saml import log as saml_log
|
||||
from common.djangoapps.third_party_auth.tasks import fetch_saml_metadata
|
||||
@@ -141,6 +142,82 @@ class SamlIntegrationTestUtilities:
|
||||
)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@utils.skip_unless_thirdpartyauth()
|
||||
class TestIndexExceptionTest(SamlIntegrationTestUtilities, IntegrationTestMixin, testutil.SAMLTestCase):
|
||||
"""
|
||||
To test SAML error handling when presented with an empty-list attribute value
|
||||
"""
|
||||
|
||||
TOKEN_RESPONSE_DATA = {
|
||||
'access_token': 'access_token_value',
|
||||
'expires_in': 'expires_in_value',
|
||||
}
|
||||
USER_RESPONSE_DATA = {
|
||||
'lastName': 'lastName_value',
|
||||
'id': 'id_value',
|
||||
'firstName': 'firstName_value',
|
||||
'idp_name': 'testshib',
|
||||
'attributes': {'urn:oid:0.9.2342.19200300.100.1.1': [], 'name_id': '1'},
|
||||
'session_index': '1',
|
||||
}
|
||||
|
||||
def test_index_error_from_empty_list_saml_attribute(self):
|
||||
"""
|
||||
The `urn:oid:0.9.2342.19200300.100.1.1` attribute is an empty list,
|
||||
should throw a specific exception NOT an IndexException
|
||||
"""
|
||||
self.provider = self._configure_testshib_provider()
|
||||
request, strategy = self.get_request_and_strategy(
|
||||
auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
|
||||
with self.assertRaises(IncorrectConfigurationException):
|
||||
request.backend.auth_complete = MagicMock(return_value=self.fake_auth_complete(strategy))
|
||||
|
||||
def get_response_data(self):
|
||||
"""Gets dict (string -> object) of merged data about the user."""
|
||||
response_data = dict(self.TOKEN_RESPONSE_DATA)
|
||||
response_data.update(self.USER_RESPONSE_DATA)
|
||||
return response_data
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@utils.skip_unless_thirdpartyauth()
|
||||
class TestKeyExceptionTest(SamlIntegrationTestUtilities, IntegrationTestMixin, testutil.SAMLTestCase):
|
||||
"""
|
||||
To test SAML error handling when presented with missing attributes
|
||||
"""
|
||||
|
||||
TOKEN_RESPONSE_DATA = {
|
||||
'access_token': 'access_token_value',
|
||||
'expires_in': 'expires_in_value',
|
||||
}
|
||||
USER_RESPONSE_DATA = {
|
||||
'lastName': 'lastName_value',
|
||||
'id': 'id_value',
|
||||
'firstName': 'firstName_value',
|
||||
'idp_name': 'testshib',
|
||||
'attributes': {'name_id': '1'},
|
||||
'session_index': '1',
|
||||
}
|
||||
|
||||
def test_key_error_from_missing_saml_attributes(self):
|
||||
"""
|
||||
The `urn:oid:0.9.2342.19200300.100.1.1` attribute is missing,
|
||||
should throw a specific exception NOT a Key Error
|
||||
"""
|
||||
self.provider = self._configure_testshib_provider()
|
||||
request, strategy = self.get_request_and_strategy(
|
||||
auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete')
|
||||
with self.assertRaises(IncorrectConfigurationException):
|
||||
request.backend.auth_complete = MagicMock(return_value=self.fake_auth_complete(strategy))
|
||||
|
||||
def get_response_data(self):
|
||||
"""Gets dict (string -> object) of merged data about the user."""
|
||||
response_data = dict(self.TOKEN_RESPONSE_DATA)
|
||||
response_data.update(self.USER_RESPONSE_DATA)
|
||||
return response_data
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@utils.skip_unless_thirdpartyauth()
|
||||
class TestShibIntegrationTest(SamlIntegrationTestUtilities, IntegrationTestMixin, testutil.SAMLTestCase):
|
||||
|
||||
Reference in New Issue
Block a user