def _download_certificate_test_template(self, ifneeded, createcert):
        """
        All download client certificate tests have the same structure,
        so this is a parametrized test for that.

        :param ifneeded: sets _download_if_needed
        :type ifneeded: bool
        :param createcert: if True it creates a dummy file to play the
                           part of a downloaded certificate
        :type createcert: bool

        :returns: the temp eip cert path and the dummy cert contents
        :rtype: tuple of str, str
        """
        pc = ProviderConfig()
        ec = EIPConfig()
        self.eb._provider_config = pc
        self.eb._eip_config = ec

        pc.get_domain = mock.MagicMock(
            return_value="localhost:%s" % (self.https_port))
        pc.get_api_uri = mock.MagicMock(
            return_value="https://%s" % (pc.get_domain()))
        pc.get_api_version = mock.MagicMock(return_value="1")
        pc.get_ca_cert_path = mock.MagicMock(return_value=False)

        path_prefix = tempfile.mkdtemp()
        util.get_path_prefix = mock.MagicMock(return_value=path_prefix)
        EIPConfig.save = mock.MagicMock()
        EIPConfig.load = mock.MagicMock()

        self.eb._download_if_needed = ifneeded

        provider_dir = os.path.join(util.get_path_prefix(),
                                    "leap",
                                    "providers",
                                    "somedomain")
        mkdir_p(provider_dir)
        eip_cert_path = os.path.join(provider_dir,
                                     "cert")

        ec.get_client_cert_path = mock.MagicMock(
            return_value=eip_cert_path)

        cert_content = "A"
        if createcert:
            with open(eip_cert_path, "w") as ec:
                ec.write(cert_content)

        return eip_cert_path, cert_content
    def _download_certificate_test_template(self, ifneeded, createcert):
        """
        All download client certificate tests have the same structure,
        so this is a parametrized test for that.

        :param ifneeded: sets _download_if_needed
        :type ifneeded: bool
        :param createcert: if True it creates a dummy file to play the
                           part of a downloaded certificate
        :type createcert: bool

        :returns: the temp eip cert path and the dummy cert contents
        :rtype: tuple of str, str
        """
        pc = ProviderConfig()
        ec = EIPConfig()
        self.eb._provider_config = pc
        self.eb._eip_config = ec

        pc.get_domain = mock.MagicMock(
            return_value="localhost:%s" % (self.https_port))
        pc.get_api_uri = mock.MagicMock(
            return_value="https://%s" % (pc.get_domain()))
        pc.get_api_version = mock.MagicMock(return_value="1")
        pc.get_ca_cert_path = mock.MagicMock(return_value=False)

        path_prefix = tempfile.mkdtemp()
        util.get_path_prefix = mock.MagicMock(return_value=path_prefix)
        EIPConfig.save = mock.MagicMock()
        EIPConfig.load = mock.MagicMock()

        self.eb._download_if_needed = ifneeded

        provider_dir = os.path.join(util.get_path_prefix(),
                                    "leap",
                                    "providers",
                                    "somedomain")
        mkdir_p(provider_dir)
        eip_cert_path = os.path.join(provider_dir,
                                     "cert")

        ec.get_client_cert_path = mock.MagicMock(
            return_value=eip_cert_path)

        cert_content = "A"
        if createcert:
            with open(eip_cert_path, "w") as ec:
                ec.write(cert_content)

        return eip_cert_path, cert_content
    def _download_config_test_template(self, ifneeded, new):
        """
        All download config tests have the same structure, so this is
        a parametrized test for that.

        :param ifneeded: sets _download_if_needed
        :type ifneeded: bool
        :param new: if True uses time.time() as mtime for the mocked
                    eip-service file, otherwise it uses 100 (a really
                    old mtime)
        :type new: float or int (will be coersed)
        """
        pc = ProviderConfig()
        pc.get_domain = mock.MagicMock(
            return_value="localhost:%s" % (self.https_port))
        self.eb._provider_config = pc

        pc.get_api_uri = mock.MagicMock(
            return_value="https://%s" % (pc.get_domain()))
        pc.get_api_version = mock.MagicMock(return_value="1")

        # This is to ignore https checking, since it's not the point
        # of this test
        pc.get_ca_cert_path = mock.MagicMock(return_value=False)

        path_prefix = tempfile.mkdtemp()
        util.get_path_prefix = mock.MagicMock(return_value=path_prefix)
        EIPConfig.save = mock.MagicMock()
        EIPConfig.load = mock.MagicMock()

        self.eb._download_if_needed = ifneeded

        provider_dir = os.path.join(util.get_path_prefix(),
                                    "leap",
                                    "providers",
                                    pc.get_domain())
        mkdir_p(provider_dir)
        eip_config_path = os.path.join(provider_dir,
                                       "eip-service.json")

        with open(eip_config_path, "w") as ec:
            ec.write("A")

        # set mtime to something really new
        if new:
            os.utime(eip_config_path, (-1, time.time()))
        else:
            os.utime(eip_config_path, (-1, 100))
    def _download_config_test_template(self, ifneeded, new):
        """
        All download config tests have the same structure, so this is
        a parametrized test for that.

        :param ifneeded: sets _download_if_needed
        :type ifneeded: bool
        :param new: if True uses time.time() as mtime for the mocked
                    eip-service file, otherwise it uses 100 (a really
                    old mtime)
        :type new: float or int (will be coersed)
        """
        pc = ProviderConfig()
        pc.get_domain = mock.MagicMock(
            return_value="localhost:%s" % (self.https_port))
        self.eb._provider_config = pc

        pc.get_api_uri = mock.MagicMock(
            return_value="https://%s" % (pc.get_domain()))
        pc.get_api_version = mock.MagicMock(return_value="1")

        # This is to ignore https checking, since it's not the point
        # of this test
        pc.get_ca_cert_path = mock.MagicMock(return_value=False)

        path_prefix = tempfile.mkdtemp()
        util.get_path_prefix = mock.MagicMock(return_value=path_prefix)
        EIPConfig.save = mock.MagicMock()
        EIPConfig.load = mock.MagicMock()

        self.eb._download_if_needed = ifneeded

        provider_dir = os.path.join(util.get_path_prefix(),
                                    "leap",
                                    "providers",
                                    pc.get_domain())
        mkdir_p(provider_dir)
        eip_config_path = os.path.join(provider_dir,
                                       "eip-service.json")

        with open(eip_config_path, "w") as ec:
            ec.write("A")

        # set mtime to something really new
        if new:
            os.utime(eip_config_path, (-1, time.time()))
        else:
            os.utime(eip_config_path, (-1, 100))
    def _download_provider_info(self, *args):
        """
        Downloads the provider.json defition
        """
        leap_assert(self._domain,
                    "Cannot download provider info without a domain")
        logger.debug("Downloading provider info for %r" % (self._domain))

        # --------------------------------------------------------------
        # TODO factor out with the download routines in services.
        # Watch out! We're handling the verify paramenter differently here.

        headers = {}
        domain = self._domain.encode(sys.getfilesystemencoding())
        provider_json = os.path.join(util.get_path_prefix(),
                                     get_provider_path(domain))

        if domain in PinnedProviders.domains() and \
           not os.path.exists(provider_json):
            mkdir_p(os.path.join(os.path.dirname(provider_json),
                                 "keys", "ca"))
            cacert = os.path.join(os.path.dirname(provider_json),
                                  "keys", "ca", "cacert.pem")
            PinnedProviders.save_hardcoded(domain, provider_json, cacert)

        mtime = get_mtime(provider_json)

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        uri = "https://%s/%s" % (self._domain, "provider.json")
        verify = self.verify

        if mtime:  # the provider.json exists
            # So, we're getting it from the api.* and checking against
            # the provider ca.
            try:
                provider_config = ProviderConfig()
                provider_config.load(provider_json)
                uri = provider_config.get_api_uri() + '/provider.json'
                verify = provider_config.get_ca_cert_path()
            except MissingCACert:
                # no ca? then download from main domain again.
                pass

        if verify:
            verify = verify.encode(sys.getfilesystemencoding())
        logger.debug("Requesting for provider.json... "
                     "uri: {0}, verify: {1}, headers: {2}".format(
                         uri, verify, headers))
        res = self._session.get(uri.encode('idna'), verify=verify,
                                headers=headers, timeout=REQUEST_TIMEOUT)
        res.raise_for_status()
        logger.debug("Request status code: {0}".format(res.status_code))

        min_client_version = res.headers.get(self.MIN_CLIENT_VERSION, '0')

        # Not modified
        if res.status_code == 304:
            logger.debug("Provider definition has not been modified")
        # --------------------------------------------------------------
        # end refactor, more or less...
        # XXX Watch out, have to check the supported api yet.
        else:
            if flags.APP_VERSION_CHECK:
                # TODO split
                if not provider.supports_client(min_client_version):
                    self._signaler.signal(
                        self._signaler.prov_unsupported_client)
                    raise UnsupportedClientVersionError()

            provider_definition, mtime = get_content(res)

            provider_config = ProviderConfig()
            provider_config.load(data=provider_definition, mtime=mtime)
            provider_config.save(["leap", "providers",
                                  domain, "provider.json"])

            if flags.API_VERSION_CHECK:
                # TODO split
                api_version = provider_config.get_api_version()
                if provider.supports_api(api_version):
                    logger.debug("Provider definition has been modified")
                else:
                    api_supported = ', '.join(provider.SUPPORTED_APIS)
                    error = ('Unsupported provider API version. '
                             'Supported versions are: {0}. '
                             'Found: {1}.').format(api_supported, api_version)

                    logger.error(error)
                    self._signaler.signal(self._signaler.prov_unsupported_api)
                    raise UnsupportedProviderAPI(error)
Exemple #6
0
    def _download_provider_info(self, *args):
        """
        Downloads the provider.json defition
        """
        leap_assert(self._domain,
                    "Cannot download provider info without a domain")
        logger.debug("Downloading provider info for %r" % (self._domain))

        # --------------------------------------------------------------
        # TODO factor out with the download routines in services.
        # Watch out! We're handling the verify paramenter differently here.

        headers = {}
        domain = self._domain.encode(sys.getfilesystemencoding())
        provider_json = os.path.join(util.get_path_prefix(),
                                     get_provider_path(domain))

        if domain in PinnedProviders.domains() and \
           not os.path.exists(provider_json):
            mkdir_p(os.path.join(os.path.dirname(provider_json), "keys", "ca"))
            cacert = os.path.join(os.path.dirname(provider_json), "keys", "ca",
                                  "cacert.pem")
            PinnedProviders.save_hardcoded(domain, provider_json, cacert)

        mtime = get_mtime(provider_json)

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        uri = "https://%s/%s" % (self._domain, "provider.json")
        verify = self.verify

        if mtime:  # the provider.json exists
            # So, we're getting it from the api.* and checking against
            # the provider ca.
            try:
                provider_config = ProviderConfig()
                provider_config.load(provider_json)
                uri = provider_config.get_api_uri() + '/provider.json'
                verify = provider_config.get_ca_cert_path()
            except MissingCACert:
                # no ca? then download from main domain again.
                pass

        if verify:
            verify = verify.encode(sys.getfilesystemencoding())
        logger.debug("Requesting for provider.json... "
                     "uri: {0}, verify: {1}, headers: {2}".format(
                         uri, verify, headers))
        res = self._session.get(uri.encode('idna'),
                                verify=verify,
                                headers=headers,
                                timeout=REQUEST_TIMEOUT)
        res.raise_for_status()
        logger.debug("Request status code: {0}".format(res.status_code))

        min_client_version = res.headers.get(self.MIN_CLIENT_VERSION, '0')

        # Not modified
        if res.status_code == 304:
            logger.debug("Provider definition has not been modified")
        # --------------------------------------------------------------
        # end refactor, more or less...
        # XXX Watch out, have to check the supported api yet.
        else:
            if flags.APP_VERSION_CHECK:
                # TODO split
                if not provider.supports_client(min_client_version):
                    if self._signaler is not None:
                        self._signaler.signal(
                            self._signaler.prov_unsupported_client)
                    raise UnsupportedClientVersionError()

            provider_definition, mtime = get_content(res)

            provider_config = ProviderConfig()
            provider_config.load(data=provider_definition, mtime=mtime)
            provider_config.save(
                ["leap", "providers", domain, "provider.json"])

            if flags.API_VERSION_CHECK:
                # TODO split
                api_version = provider_config.get_api_version()
                if provider.supports_api(api_version):
                    logger.debug("Provider definition has been modified")
                else:
                    api_supported = ', '.join(provider.SUPPORTED_APIS)
                    error = ('Unsupported provider API version. '
                             'Supported versions are: {0}. '
                             'Found: {1}.').format(api_supported, api_version)

                    logger.error(error)
                    if self._signaler is not None:
                        self._signaler.signal(
                            self._signaler.prov_unsupported_api)
                    raise UnsupportedProviderAPI(error)
    def _download_provider_info(self, *args):
        """
        Downloads the provider.json defition
        """
        leap_assert(self._domain,
                    "Cannot download provider info without a domain")

        logger.debug("Downloading provider info for %s" % (self._domain))

        headers = {}

        provider_json = os.path.join(
            ProviderConfig().get_path_prefix(), "leap", "providers",
            self._domain, "provider.json")
        mtime = get_mtime(provider_json)

        if self._download_if_needed and mtime:
            headers['if-modified-since'] = mtime

        uri = "https://%s/%s" % (self._domain, "provider.json")
        verify = not self._bypass_checks

        if mtime:  # the provider.json exists
            provider_config = ProviderConfig()
            provider_config.load(provider_json)
            try:
                verify = provider_config.get_ca_cert_path()
                uri = provider_config.get_api_uri() + '/provider.json'
            except MissingCACert:
                # get_ca_cert_path fails if the certificate does not exists.
                pass

        logger.debug("Requesting for provider.json... "
                     "uri: {0}, verify: {1}, headers: {2}".format(
                         uri, verify, headers))
        res = self._session.get(uri, verify=verify,
                                headers=headers, timeout=REQUEST_TIMEOUT)
        res.raise_for_status()
        logger.debug("Request status code: {0}".format(res.status_code))

        # Not modified
        if res.status_code == 304:
            logger.debug("Provider definition has not been modified")
        else:
            provider_definition, mtime = get_content(res)

            provider_config = ProviderConfig()
            provider_config.load(data=provider_definition, mtime=mtime)
            provider_config.save(["leap",
                                  "providers",
                                  self._domain,
                                  "provider.json"])

            api_version = provider_config.get_api_version()
            if SupportedAPIs.supports(api_version):
                logger.debug("Provider definition has been modified")
            else:
                api_supported = ', '.join(SupportedAPIs.SUPPORTED_APIS)
                error = ('Unsupported provider API version. '
                         'Supported versions are: {}. '
                         'Found: {}.').format(api_supported, api_version)

                logger.error(error)
                raise UnsupportedProviderAPI(error)