def test( self, _, expression, expected_result, context=None, safe_classes=None, expected_exception=None, ): # Arrange parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) if safe_classes is None: safe_classes = [] # Act if expected_exception: with pytest.raises(expected_exception): evaluator.evaluate(expression, context, safe_classes) else: result = evaluator.evaluate(expression, context, safe_classes) # Assert assert expected_result == result
def validator_factory(): metadata_parser = SAMLMetadataParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) return SAMLSettingsValidator(metadata_parser, subject_filter)
def test_validate( self, _, sp_xml_metadata, idp_xml_metadata, patron_id_regular_expression, expected_validation_result, ): """Ensure that SAMLSettingsValidator correctly validates the input data. :param sp_xml_metadata: SP SAML metadata :type sp_xml_metadata: str :param idp_xml_metadata: IdP SAML metadata :type idp_xml_metadata: str :param patron_id_regular_expression: Regular expression used to extract a unique patron ID from SAML attributes :type patron_id_regular_expression: str :param expected_validation_result: Expected result: ProblemDetail object if validation must fail, None otherwise :type expected_validation_result: Optional[ProblemDetail] """ # Arrange submitted_form_data = MultiDict() if sp_xml_metadata is not None: submitted_form_data.add( SAMLConfiguration.service_provider_xml_metadata.key, sp_xml_metadata) if idp_xml_metadata is not None: submitted_form_data.add( SAMLConfiguration.non_federated_identity_provider_xml_metadata. key, idp_xml_metadata, ) if patron_id_regular_expression is not None: submitted_form_data.add( SAMLConfiguration.patron_id_regular_expression.key, patron_id_regular_expression, ) submitted_form = {"form": submitted_form_data} metadata_parser = SAMLMetadataParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) validator = SAMLSettingsValidator(metadata_parser, subject_filter) # Act settings = list(SAMLWebSSOAuthenticationProvider.SETTINGS) result = validator.validate(settings, submitted_form) # Assert if isinstance(result, ProblemDetail): assert expected_validation_result.response == result.response else: assert expected_validation_result == result
def test_start_authentication(self, _, service_provider, identity_providers): configuration = create_autospec(spec=SAMLConfiguration) configuration.service_provider_debug_mode = MagicMock( return_value=False) configuration.service_provider_strict_mode = MagicMock( return_value=False) configuration.get_service_provider = MagicMock( return_value=service_provider) configuration.get_identity_providers = MagicMock( return_value=identity_providers) onelogin_configuration = SAMLOneLoginConfiguration(configuration) subject_parser = SAMLSubjectParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) authentication_manager = SAMLAuthenticationManager( onelogin_configuration, subject_parser, subject_filter) with self.app.test_request_context("/"): result = authentication_manager.start_authentication( self._db, fixtures.IDP_1_ENTITY_ID, "") query_items = parse_qs(urlsplit(result).query) saml_request = query_items["SAMLRequest"][0] decoded_saml_request = OneLogin_Saml2_Utils.decode_base64_and_inflate( saml_request) validation_result = OneLogin_Saml2_XML.validate_xml( decoded_saml_request, "saml-schema-protocol-2.0.xsd", False) assert isinstance(validation_result, OneLogin_Saml2_XML._element_class) saml_request_dom = fromstring(decoded_saml_request) acs_url = saml_request_dom.get("AssertionConsumerServiceURL") assert acs_url == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS.acs_service.url acs_binding = saml_request_dom.get("ProtocolBinding") assert (acs_binding == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS. acs_service.binding.value) sso_url = saml_request_dom.get("Destination") assert sso_url == IDENTITY_PROVIDERS[0].sso_service.url name_id_policy_nodes = OneLogin_Saml2_XML.query( saml_request_dom, "./samlp:NameIDPolicy") assert name_id_policy_nodes is not None assert len(name_id_policy_nodes) == 1 name_id_policy_node = name_id_policy_nodes[0] name_id_format = name_id_policy_node.get("Format") assert (name_id_format == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS.name_id_format)
def test_authentication_document(self, _, identity_providers, expected_result): # Arrange configuration = create_autospec(spec=SAMLConfiguration) configuration.get_service_provider = MagicMock( return_value=SERVICE_PROVIDER) configuration.get_identity_providers = MagicMock( return_value=identity_providers) configuration.patron_id_use_name_id = "true" configuration.patron_id_attributes = [] configuration.patron_id_regular_expression = None configuration_factory_create_context_manager = MagicMock() configuration_factory_create_context_manager.__enter__ = MagicMock( return_value=configuration) configuration_factory = create_autospec(spec=SAMLConfigurationFactory) configuration_factory.create = MagicMock( return_value=configuration_factory_create_context_manager) onelogin_configuration = SAMLOneLoginConfiguration(configuration) subject_parser = SAMLSubjectParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) authentication_manager = SAMLAuthenticationManager( onelogin_configuration, subject_parser, subject_filter) authentication_manager_factory = create_autospec( spec=SAMLAuthenticationManagerFactory) authentication_manager_factory.create = MagicMock( return_value=authentication_manager) with patch("api.saml.provider.SAMLAuthenticationManagerFactory" ) as authentication_manager_factory_constructor_mock, patch( "api.saml.provider.SAMLConfigurationFactory" ) as configuration_factory_constructor_mock: authentication_manager_factory_constructor_mock.return_value = ( authentication_manager_factory) configuration_factory_constructor_mock.return_value = configuration_factory # Act provider = SAMLWebSSOAuthenticationProvider( self._default_library, self._integration) self.app.config["SERVER_NAME"] = "localhost" with self.app.test_request_context("/"): result = provider.authentication_flow_document(self._db) # Assert assert expected_result == result
def test_validate(self, _, expression, expected_exception): # Arrange parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) # Act if expected_exception: with pytest.raises(expected_exception): subject_filter.validate(expression) else: subject_filter.validate(expression)
def test_execute( self, _, expression, subject, expected_result, expected_exception=None ): # Arrange parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) # Act if expected_exception: with pytest.raises(expected_exception): subject_filter.execute(expression, subject) else: result = subject_filter.execute(expression, subject) # Assert assert expected_result == result
def create(self, configuration): """ Creates a new instance of SAMLAuthenticationManager class :param configuration: SAML authentication provider's configuration :type configuration: api.saml.configuration.model.SAMLConfiguration :return: SAML authentication manager :rtype: SAMLAuthenticationManager """ onelogin_configuration = SAMLOneLoginConfiguration(configuration) subject_parser = SAMLSubjectParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) authentication_manager = SAMLAuthenticationManager( onelogin_configuration, subject_parser, subject_filter) return authentication_manager
def test_finish_authentication( self, _, saml_response, current_time, filter_expression, expected_value, mock_validation=False, ): # Arrange identity_provider_entity_id = "http://idp.hilbertteam.net/idp/shibboleth" service_provider_host_name = "opds.hilbertteam.net" identity_providers = [ copy(identity_provider) for identity_provider in IDENTITY_PROVIDERS ] identity_providers[0].entity_id = identity_provider_entity_id if mock_validation: validate_mock = MagicMock(return_value=True) else: real_validate_sign = OneLogin_Saml2_Utils.validate_sign validate_mock = MagicMock(side_effect=lambda *args, **kwargs: real_validate_sign(*args, **kwargs)) filter_expression_mock = PropertyMock(return_value=filter_expression) service_provider_debug_mode_mock = PropertyMock(return_value=False) service_provider_strict_mode = PropertyMock(return_value=False) configuration = create_autospec(spec=SAMLConfiguration) type(configuration).filter_expression = filter_expression_mock type(configuration ).service_provider_debug_mode = service_provider_debug_mode_mock type(configuration ).service_provider_strict_mode = service_provider_strict_mode configuration.get_service_provider = MagicMock( return_value=SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS) configuration.get_identity_providers = MagicMock( return_value=identity_providers) onelogin_configuration = SAMLOneLoginConfiguration(configuration) subject_parser = SAMLSubjectParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) authentication_manager = SAMLAuthenticationManager( onelogin_configuration, subject_parser, subject_filter) saml_response = base64.b64encode(saml_response) # Act with freeze_time(current_time): with patch( "onelogin.saml2.response.OneLogin_Saml2_Utils.validate_sign", validate_mock, ): self.app.config["SERVER_NAME"] = service_provider_host_name with self.app.test_request_context( "/SAML2/POST", data={"SAMLResponse": saml_response}): result = authentication_manager.finish_authentication( self._db, identity_provider_entity_id) # Assert assert expected_value == result