コード例 #1
0
ファイル: test_parser.py プロジェクト: lhuabu/circulation
    def test_parse_does_not_raise_exception_when_xml_metadata_does_not_have_display_names(
            self):
        # Arrange
        metadata_parser = SAMLMetadataParser()

        # Act
        result = metadata_parser.parse(
            fixtures.CORRECT_ONE_IDP_METADATA_WITHOUT_DISPLAY_NAMES)

        # Assert
        assert isinstance(result, list)
        eq_(len(result), 1)

        [result] = result

        eq_(
            result,
            IdentityProviderMetadata(
                entity_id=fixtures.IDP_1_ENTITY_ID,
                ui_info=UIInfo(),
                organization=Organization(),
                name_id_format=fixtures.NAME_ID_FORMAT_1,
                sso_service=Service(fixtures.IDP_1_SSO_URL,
                                    fixtures.IDP_1_SSO_BINDING),
                want_authn_requests_signed=False,
                signing_certificates=[
                    strip_certificate(fixtures.SIGNING_CERTIFICATE)
                ],
                encryption_certificates=[
                    strip_certificate(fixtures.ENCRYPTION_CERTIFICATE)
                ]))
コード例 #2
0
from nose.tools import eq_
from parameterized import parameterized

from api.saml.configuration import SAMLConfiguration, SAMLOneLoginConfiguration, SAMLConfigurationStorage
from api.saml.metadata import ServiceProviderMetadata, UIInfo, Service, NameIDFormat, IdentityProviderMetadata, \
    Organization
from api.saml.parser import SAMLMetadataParser
from tests.saml import fixtures
from tests.saml.fixtures import strip_certificate

SERVICE_PROVIDER_WITHOUT_CERTIFICATE = ServiceProviderMetadata(
    fixtures.SP_ENTITY_ID,
    UIInfo(),
    Organization(),
    NameIDFormat.UNSPECIFIED.value,
    Service(fixtures.SP_ACS_URL, fixtures.SP_ACS_BINDING),
)

SERVICE_PROVIDER_WITH_CERTIFICATE = ServiceProviderMetadata(
    fixtures.SP_ENTITY_ID,
    UIInfo(),
    Organization(),
    NameIDFormat.UNSPECIFIED.value,
    Service(fixtures.SP_ACS_URL, fixtures.SP_ACS_BINDING),
    certificate=fixtures.SIGNING_CERTIFICATE,
    private_key=fixtures.PRIVATE_KEY)

IDENTITY_PROVIDERS = [
    IdentityProviderMetadata(
        fixtures.IDP_1_ENTITY_ID, UIInfo(), Organization(),
        NameIDFormat.UNSPECIFIED.value,
コード例 #3
0
ファイル: test_parser.py プロジェクト: lhuabu/circulation
    def test_parse_correctly_parses_one_idp_metadata(self):
        # Arrange
        metadata_parser = SAMLMetadataParser()

        # Act
        result = metadata_parser.parse(fixtures.CORRECT_ONE_IDP_METADATA)

        # Assert
        assert isinstance(result, list)
        eq_(len(result), 1)

        [result] = result

        eq_(
            result,
            IdentityProviderMetadata(
                entity_id=fixtures.IDP_1_ENTITY_ID,
                ui_info=UIInfo([
                    LocalizableMetadataItem(
                        fixtures.IDP_1_UI_INFO_EN_DISPLAY_NAME, 'en'),
                    LocalizableMetadataItem(
                        fixtures.IDP_1_UI_INFO_ES_DISPLAY_NAME, 'es')
                ], [
                    LocalizableMetadataItem(fixtures.IDP_1_UI_INFO_DESCRIPTION,
                                            'en')
                ], [
                    LocalizableMetadataItem(
                        fixtures.IDP_1_UI_INFO_INFORMATION_URL, 'en')
                ], [
                    LocalizableMetadataItem(
                        fixtures.IDP_1_UI_INFO_PRIVACY_STATEMENT_URL, 'en')
                ], [LocalizableMetadataItem(fixtures.IDP_1_UI_INFO_LOGO_URL)]),
                organization=Organization(
                    [
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_EN_ORGANIZATION_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_ES_ORGANIZATION_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.
                            IDP_1_ORGANIZATION_EN_ORGANIZATION_DISPLAY_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.
                            IDP_1_ORGANIZATION_ES_ORGANIZATION_DISPLAY_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_EN_ORGANIZATION_URL,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_ES_ORGANIZATION_URL,
                            'es')
                    ],
                ),
                name_id_format=fixtures.NAME_ID_FORMAT_1,
                sso_service=Service(fixtures.IDP_1_SSO_URL,
                                    fixtures.IDP_1_SSO_BINDING),
                want_authn_requests_signed=False,
                signing_certificates=[
                    strip_certificate(fixtures.SIGNING_CERTIFICATE)
                ],
                encryption_certificates=[
                    strip_certificate(fixtures.ENCRYPTION_CERTIFICATE)
                ]))
コード例 #4
0
ファイル: test_parser.py プロジェクト: lhuabu/circulation
    def test_parse_correctly_parses_one_sp_metadata(self):
        # Arrange
        metadata_parser = SAMLMetadataParser()

        # Act
        result = metadata_parser.parse(fixtures.CORRECT_ONE_SP_METADATA)

        # Assert
        assert isinstance(result, list)
        eq_(len(result), 1)

        [result] = result

        eq_(
            result,
            ServiceProviderMetadata(
                entity_id=fixtures.SP_ENTITY_ID,
                ui_info=UIInfo([
                    LocalizableMetadataItem(
                        fixtures.SP_UI_INFO_EN_DISPLAY_NAME, 'en'),
                    LocalizableMetadataItem(
                        fixtures.SP_UI_INFO_ES_DISPLAY_NAME, 'es')
                ], [
                    LocalizableMetadataItem(fixtures.SP_UI_INFO_DESCRIPTION,
                                            'en')
                ], [
                    LocalizableMetadataItem(
                        fixtures.SP_UI_INFO_INFORMATION_URL, 'en')
                ], [
                    LocalizableMetadataItem(
                        fixtures.SP_UI_INFO_PRIVACY_STATEMENT_URL, 'en')
                ], [LocalizableMetadataItem(fixtures.SP_UI_INFO_LOGO_URL)]),
                organization=Organization(
                    [
                        LocalizableMetadataItem(
                            fixtures.SP_ORGANIZATION_EN_ORGANIZATION_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.SP_ORGANIZATION_ES_ORGANIZATION_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.
                            SP_ORGANIZATION_EN_ORGANIZATION_DISPLAY_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.
                            SP_ORGANIZATION_ES_ORGANIZATION_DISPLAY_NAME, 'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.SP_ORGANIZATION_EN_ORGANIZATION_URL,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.SP_ORGANIZATION_ES_ORGANIZATION_URL, 'es')
                    ],
                ),
                name_id_format=NameIDFormat.UNSPECIFIED.value,
                acs_service=Service(fixtures.SP_ACS_URL,
                                    fixtures.SP_ACS_BINDING),
                authn_requests_signed=False,
                want_assertions_signed=False,
                certificate=strip_certificate(fixtures.SIGNING_CERTIFICATE)))
コード例 #5
0
ファイル: test_parser.py プロジェクト: lhuabu/circulation
    def test_parse_correctly_parses_metadata_with_multiple_descriptors(self):
        # Arrange
        metadata_parser = SAMLMetadataParser()

        # Act
        result = metadata_parser.parse(fixtures.CORRECT_MULTIPLE_IDPS_METADATA)

        # Assert
        assert isinstance(result, list)
        assert len(result) == 2

        eq_(
            result[0],
            IdentityProviderMetadata(
                entity_id=fixtures.IDP_1_ENTITY_ID,
                ui_info=UIInfo([
                    LocalizableMetadataItem(
                        fixtures.IDP_1_UI_INFO_EN_DISPLAY_NAME, 'en'),
                    LocalizableMetadataItem(
                        fixtures.IDP_1_UI_INFO_ES_DISPLAY_NAME, 'es')
                ]),
                organization=Organization(
                    [
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_EN_ORGANIZATION_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_ES_ORGANIZATION_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.
                            IDP_1_ORGANIZATION_EN_ORGANIZATION_DISPLAY_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.
                            IDP_1_ORGANIZATION_ES_ORGANIZATION_DISPLAY_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_EN_ORGANIZATION_URL,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.IDP_1_ORGANIZATION_ES_ORGANIZATION_URL,
                            'es')
                    ],
                ),
                name_id_format=fixtures.NAME_ID_FORMAT_1,
                sso_service=Service(fixtures.IDP_1_SSO_URL,
                                    fixtures.IDP_1_SSO_BINDING),
                want_authn_requests_signed=False,
                signing_certificates=[
                    strip_certificate(fixtures.SIGNING_CERTIFICATE)
                ],
                encryption_certificates=[
                    strip_certificate(fixtures.ENCRYPTION_CERTIFICATE)
                ]))

        eq_(
            result[1],
            IdentityProviderMetadata(
                entity_id=fixtures.IDP_2_ENTITY_ID,
                ui_info=UIInfo([
                    LocalizableMetadataItem(
                        fixtures.IDP_2_UI_INFO_EN_DISPLAY_NAME, 'en'),
                    LocalizableMetadataItem(
                        fixtures.IDP_2_UI_INFO_ES_DISPLAY_NAME, 'es')
                ]),
                organization=Organization(
                    [
                        LocalizableMetadataItem(
                            fixtures.IDP_2_ORGANIZATION_EN_ORGANIZATION_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.IDP_2_ORGANIZATION_ES_ORGANIZATION_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.
                            IDP_2_ORGANIZATION_EN_ORGANIZATION_DISPLAY_NAME,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.
                            IDP_2_ORGANIZATION_ES_ORGANIZATION_DISPLAY_NAME,
                            'es')
                    ],
                    [
                        LocalizableMetadataItem(
                            fixtures.IDP_2_ORGANIZATION_EN_ORGANIZATION_URL,
                            'en'),
                        LocalizableMetadataItem(
                            fixtures.IDP_2_ORGANIZATION_ES_ORGANIZATION_URL,
                            'es')
                    ],
                ),
                name_id_format=fixtures.NAME_ID_FORMAT_1,
                sso_service=Service(fixtures.IDP_2_SSO_URL,
                                    fixtures.IDP_2_SSO_BINDING),
                want_authn_requests_signed=False,
                signing_certificates=[
                    strip_certificate(fixtures.SIGNING_CERTIFICATE)
                ],
                encryption_certificates=[
                    strip_certificate(fixtures.ENCRYPTION_CERTIFICATE)
                ]))
コード例 #6
0
ファイル: parser.py プロジェクト: lhuabu/circulation
    def _parse_sp_metadata(
            self,
            provider_node,
            entity_id,
            ui_info,
            organization,
            required_acs_binding=Binding.HTTP_POST):
        """Parses SPSSODescriptor node and translates it into a ServiceProvider object

        :param provider_node: SPSSODescriptor node containing SP metadata
        :param provider_node: defusedxml.lxml.RestrictedElement

        :param entity_id: String containing IdP's entityID
        :type entity_id: string

        :param ui_info: UIInfo object containing IdP's description
        :type ui_info: UIInfo

        :param organization: Organization object containing basic information about an organization
            responsible for a SAML entity or role
        :type organization: Organization

        :param required_acs_binding: Required binding for Assertion Consumer Service (HTTP-Redirect by default)
        :type required_acs_binding: Binding

        :return: ServiceProvider containing SP metadata
        :rtype: ServiceProvider

        :raise: MetadataParsingError
        """
        authn_requests_signed = provider_node.get('AuthnRequestsSigned', False)
        want_assertions_signed = provider_node.get('WantAssertionsSigned', False)

        name_id_format = self._parse_name_id_format(provider_node)

        acs_service = None
        acs_service_nodes = OneLogin_Saml2_Utils.query(
            provider_node,
            "./md:AssertionConsumerService[@Binding='%s']" % required_acs_binding.value
        )
        if len(acs_service_nodes) > 0:
            acs_service_node = self._select_default_or_first_indexed_element(acs_service_nodes)
            acs_url = acs_service_node.get('Location', None)
            acs_service = Service(acs_url, required_acs_binding)
        else:
            raise SAMLMetadataParsingError(_('Missing {0} AssertionConsumerService'.format(required_acs_binding.value)))

        certificate_nodes = OneLogin_Saml2_Utils.query(
            provider_node,
            './md:KeyDescriptor/ds:KeyInfo/ds:X509Data/ds:X509Certificate')
        certificates = self._parse_certificates(certificate_nodes)

        if len(certificates) > 1:
            raise SAMLMetadataParsingError(
                _('There are more than 1 SP certificates'.format(required_acs_binding.value)))

        certificate = next(iter(certificates)) if certificates else None

        sp = ServiceProviderMetadata(
            entity_id,
            ui_info,
            organization,
            name_id_format,
            acs_service,
            authn_requests_signed,
            want_assertions_signed,
            certificate)

        return sp
コード例 #7
0
ファイル: parser.py プロジェクト: lhuabu/circulation
    def _parse_idp_metadata(
            self,
            provider_node,
            entity_id,
            ui_info,
            organization,
            required_sso_binding=Binding.HTTP_REDIRECT,
            required_slo_binding=Binding.HTTP_REDIRECT):
        """Parses IDPSSODescriptor node and translates it into an IdentityProviderMetadata object

        :param provider_node: IDPSSODescriptor node containing IdP metadata
        :param provider_node: defusedxml.lxml.RestrictedElement

        :param entity_id: String containing IdP's entityID
        :type entity_id: string

        :param ui_info: UIInfo object containing IdP's description
        :type ui_info: UIInfo

        :param organization: Organization object containing basic information about an organization
            responsible for a SAML entity or role
        :type organization: Organization

        :param required_sso_binding: Required binding for Single Sign-On profile (HTTP-Redirect by default)
        :type required_sso_binding: Binding

        :param required_slo_binding: Required binding for Single Sing-Out profile (HTTP-Redirect by default)
        :type required_slo_binding: Binding

        :return: IdentityProviderMetadata containing IdP metadata
        :rtype: IdentityProviderMetadata

        :raise: MetadataParsingError
        """
        want_authn_requests_signed = provider_node.get('WantAuthnRequestsSigned', False)

        name_id_format = self._parse_name_id_format(provider_node)

        sso_service = None
        sso_nodes = OneLogin_Saml2_Utils.query(
            provider_node,
            "./md:SingleSignOnService[@Binding='%s']" % required_sso_binding.value
        )
        if len(sso_nodes) > 0:
            sso_node = self._select_default_or_first_indexed_element(sso_nodes)
            sso_url = sso_node.get('Location', None)
            sso_service = Service(sso_url, required_sso_binding)
        else:
            raise SAMLMetadataParsingError(
                _('Missing {0} SingleSignOnService service declaration'.format(required_sso_binding.value)))

        slo_service = None
        slo_nodes = OneLogin_Saml2_Utils.query(
            provider_node,
            "./md:SingleLogoutService[@Binding='%s']" % required_slo_binding.value
        )
        if len(slo_nodes) > 0:
            slo_node = self._select_default_or_first_indexed_element(slo_nodes)
            slo_url = slo_node.get('Location', None)
            slo_service = Service(slo_url, required_slo_binding)

        signing_certificate_nodes = OneLogin_Saml2_Utils.query(
            provider_node,
            './md:KeyDescriptor[not(contains(@use, "encryption"))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate')
        signing_certificates = self._parse_certificates(signing_certificate_nodes)

        encryption_certificate_nodes = OneLogin_Saml2_Utils.query(
            provider_node,
            './md:KeyDescriptor[not(contains(@use, "signing"))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate')
        encryption_certificates = self._parse_certificates(encryption_certificate_nodes)

        idp = IdentityProviderMetadata(
            entity_id,
            ui_info,
            organization,
            name_id_format,
            sso_service,
            slo_service,
            want_authn_requests_signed,
            signing_certificates,
            encryption_certificates)

        return idp