Esempio n. 1
0
	def testFeeds(self):
		iface = model.Interface('http://test/test')
		main_feed = model.ZeroInstallFeed(test_feed, local_path = '/Hello')
		self.config.iface_cache._feeds[iface.uri] = main_feed
		iface.stability_policy = model.developer
		main_feed.last_checked = 100
		iface.extra_feeds.append(model.Feed('http://sys-feed', None, False))
		iface.extra_feeds.append(model.Feed('http://user-feed', 'Linux-*', True))
		writer.save_interface(iface)
		writer.save_feed(main_feed)

		iface = model.Interface('http://test/test')
		self.assertEqual(None, iface.stability_policy)
		main_feed = model.ZeroInstallFeed(test_feed, local_path = '/Hello')
		self.config.iface_cache._feeds[iface.uri] = main_feed
		reader.update_user_overrides(iface)
		reader.update_user_feed_overrides(main_feed)
		self.assertEqual(model.developer, iface.stability_policy)
		self.assertEqual(100, main_feed.last_checked)
		self.assertEqual("[<Feed from http://user-feed>]", str(iface.extra_feeds))

		feed = iface.extra_feeds[0]
		self.assertEqual('http://user-feed', feed.uri)
		self.assertEqual('Linux', feed.os)
		self.assertEqual(None, feed.machine)
Esempio n. 2
0
	def get_feed(self, url, force = False, selections_ok = False):
		"""Get a feed from the cache.
		@param url: the URL of the feed
		@type url: str
		@param force: load the file from disk again
		@type force: bool
		@param selections_ok: if url is a local selections file, return that instead
		@type selections_ok: bool
		@return: the feed, or None if it isn't cached
		@rtype: L{model.ZeroInstallFeed}"""
		if not force:
			feed = self._feeds.get(url, False)
			if feed != False:
				return feed

		if url.startswith('distribution:'):
			master_feed = self.get_feed(url.split(':', 1)[1])
			if not master_feed:
				return None	# Can't happen?
			feed = self.distro.get_feed(master_feed)
		else:
			feed = reader.load_feed_from_cache(url, selections_ok = selections_ok)
			if selections_ok and feed and not isinstance(feed, model.ZeroInstallFeed):
				assert feed.selections is not None
				return feed	# (it's actually a selections document)
		if feed:
			reader.update_user_feed_overrides(feed)
		self._feeds[url] = feed
		return feed
Esempio n. 3
0
    def testFeeds(self):
        iface = model.Interface('http://test/test')
        main_feed = model.ZeroInstallFeed(test_feed, local_path='/Hello')
        self.config.iface_cache._feeds[iface.uri] = main_feed
        iface.stability_policy = model.developer
        main_feed.last_checked = 100
        iface.extra_feeds.append(model.Feed('http://sys-feed', None, False))
        iface.extra_feeds.append(
            model.Feed('http://user-feed', 'Linux-*', True))
        writer.save_interface(iface)
        writer.save_feed(main_feed)

        iface = model.Interface('http://test/test')
        self.assertEquals(None, iface.stability_policy)
        main_feed = model.ZeroInstallFeed(test_feed, local_path='/Hello')
        self.config.iface_cache._feeds[iface.uri] = main_feed
        reader.update_user_overrides(iface)
        reader.update_user_feed_overrides(main_feed)
        self.assertEquals(model.developer, iface.stability_policy)
        self.assertEquals(100, main_feed.last_checked)
        self.assertEquals("[<Feed from http://user-feed>]",
                          str(iface.extra_feeds))

        feed = iface.extra_feeds[0]
        self.assertEquals('http://user-feed', feed.uri)
        self.assertEquals('Linux', feed.os)
        self.assertEquals(None, feed.machine)
Esempio n. 4
0
    def get_feed(self, url, force=False, selections_ok=False):
        """Get a feed from the cache.
		@param url: the URL of the feed
		@type url: str
		@param force: load the file from disk again
		@type force: bool
		@param selections_ok: if url is a local selections file, return that instead
		@type selections_ok: bool
		@return: the feed, or None if it isn't cached
		@rtype: L{model.ZeroInstallFeed}"""
        if not force:
            feed = self._feeds.get(url, False)
            if feed != False:
                return feed

        if url.startswith('distribution:'):
            master_feed = self.get_feed(url.split(':', 1)[1])
            if not master_feed:
                return None  # e.g. when checking a selections document
            feed = self.distro.get_feed(master_feed)
        else:
            feed = reader.load_feed_from_cache(url,
                                               selections_ok=selections_ok)
            if selections_ok and feed and not isinstance(
                    feed, model.ZeroInstallFeed):
                assert feed.selections is not None
                return feed  # (it's actually a selections document)
        if feed:
            reader.update_user_feed_overrides(feed)
        self._feeds[url] = feed
        return feed
Esempio n. 5
0
def do_import_feed(config, xml):
	if gui_driver is not None: config = gui_driver.config

	feed = model.ZeroInstallFeed(xml)
	reader.update_user_feed_overrides(feed)
	feed_url = xml.attrs['uri']
	config.iface_cache._feeds[feed_url] = feed
Esempio n. 6
0
	def testStoreStability(self):
		main_feed = reader.load_feed('Hello.xml', local = True)
		impl = main_feed.implementations['sha1=3ce644dc725f1d21cfcf02562c76f375944b266a']
		impl.user_stability = model.developer
		writer.save_feed(main_feed)

		# Rating now visible
		main_feed = reader.load_feed('Hello.xml', local = True)
		reader.update_user_feed_overrides(main_feed)
		self.assertEqual(1, len(main_feed.implementations))

		impl = main_feed.implementations['sha1=3ce644dc725f1d21cfcf02562c76f375944b266a']
		self.assertEqual(model.developer, impl.user_stability)
Esempio n. 7
0
	def testStoreStability(self):
		main_feed = reader.load_feed('Hello.xml', local = True)
		impl = main_feed.implementations['sha1=3ce644dc725f1d21cfcf02562c76f375944b266a']
		impl.user_stability = model.developer
		writer.save_feed(main_feed)

		# Rating now visible
		main_feed = reader.load_feed('Hello.xml', local = True)
		reader.update_user_feed_overrides(main_feed)
		self.assertEqual(1, len(main_feed.implementations))

		impl = main_feed.implementations['sha1=3ce644dc725f1d21cfcf02562c76f375944b266a']
		self.assertEqual(model.developer, impl.user_stability)
Esempio n. 8
0
	def _import_new_feed(self, feed_url, new_xml, modified_time, dry_run):
		"""Write new_xml into the cache.
		@param feed_url: the URL for the feed being updated
		@type feed_url: str
		@param new_xml: the data to write
		@type new_xml: str
		@param modified_time: when new_xml was modified
		@type modified_time: int
		@type dry_run: bool
		@raises ReplayAttack: if the new mtime is older than the current one"""
		assert modified_time
		assert isinstance(new_xml, bytes), repr(new_xml)

		upstream_dir = basedir.save_cache_path(config_site, 'interfaces')
		cached = os.path.join(upstream_dir, escape(feed_url))

		old_modified = None
		if os.path.exists(cached):
			with open(cached, 'rb') as stream:
				old_xml = stream.read()
			if old_xml == new_xml:
				logger.debug(_("No change"))
				# Update in-memory copy, in case someone else updated the disk copy
				self.get_feed(feed_url, force = True)
				return
			old_modified = int(os.stat(cached).st_mtime)

		if dry_run:
			print(_("[dry-run] would cache feed {url} as {cached}").format(
				url = feed_url,
				cached = cached))
			from io import BytesIO
			from zeroinstall.injector import qdom
			root = qdom.parse(BytesIO(new_xml), filter_for_version = True)
			feed = model.ZeroInstallFeed(root)
			reader.update_user_feed_overrides(feed)
			self._feeds[feed_url] = feed
			return

		# Do we need to write this temporary file now?
		try:
			with open(cached + '.new', 'wb') as stream:
				stream.write(new_xml)
			os.utime(cached + '.new', (modified_time, modified_time))
			new_mtime = reader.check_readable(feed_url, cached + '.new')
			assert new_mtime == modified_time

			old_modified = self._get_signature_date(feed_url) or old_modified

			if old_modified:
				if new_mtime < old_modified:
					raise ReplayAttack(_("New feed's modification time is "
						"before old version!\nInterface: %(iface)s\nOld time: %(old_time)s\nNew time: %(new_time)s\n"
						"Refusing update.")
						% {'iface': feed_url, 'old_time': _pretty_time(old_modified), 'new_time': _pretty_time(new_mtime)})
				if new_mtime == old_modified:
					# You used to have to update the modification time manually.
					# Now it comes from the signature, this check isn't useful
					# and often causes problems when the stored format changes
					# (e.g., when we stopped writing last-modified attributes)
					pass
					#raise SafeException("Interface has changed, but modification time "
					#		    "hasn't! Refusing update.")
		except:
			os.unlink(cached + '.new')
			raise

		portable_rename(cached + '.new', cached)
		logger.debug(_("Saved as %s") % cached)

		self.get_feed(feed_url, force = True)
Esempio n. 9
0
    def _import_new_feed(self, feed_url, new_xml, modified_time, dry_run):
        """Write new_xml into the cache.
		@param feed_url: the URL for the feed being updated
		@type feed_url: str
		@param new_xml: the data to write
		@type new_xml: str
		@param modified_time: when new_xml was modified
		@type modified_time: int
		@type dry_run: bool
		@raises ReplayAttack: if the new mtime is older than the current one"""
        assert modified_time
        assert isinstance(new_xml, bytes), repr(new_xml)

        upstream_dir = basedir.save_cache_path(config_site, 'interfaces')
        cached = os.path.join(upstream_dir, escape(feed_url))

        old_modified = None
        if os.path.exists(cached):
            with open(cached, 'rb') as stream:
                old_xml = stream.read()
            if old_xml == new_xml:
                logger.debug(_("No change"))
                # Update in-memory copy, in case someone else updated the disk copy
                self.get_feed(feed_url, force=True)
                return
            old_modified = int(os.stat(cached).st_mtime)

        if dry_run:
            print(
                _("[dry-run] would cache feed {url} as {cached}").format(
                    url=feed_url, cached=cached))
            from io import BytesIO
            from zeroinstall.injector import qdom
            root = qdom.parse(BytesIO(new_xml), filter_for_version=True)
            feed = model.ZeroInstallFeed(root)
            reader.update_user_feed_overrides(feed)
            self._feeds[feed_url] = feed
            return

        # Do we need to write this temporary file now?
        try:
            with open(cached + '.new', 'wb') as stream:
                stream.write(new_xml)
            os.utime(cached + '.new', (modified_time, modified_time))
            new_mtime = reader.check_readable(feed_url, cached + '.new')
            assert new_mtime == modified_time

            old_modified = self._get_signature_date(feed_url) or old_modified

            if old_modified:
                if new_mtime < old_modified:
                    raise ReplayAttack(
                        _("New feed's modification time is "
                          "before old version!\nInterface: %(iface)s\nOld time: %(old_time)s\nNew time: %(new_time)s\n"
                          "Refusing update.") % {
                              'iface': feed_url,
                              'old_time': _pretty_time(old_modified),
                              'new_time': _pretty_time(new_mtime)
                          })
                if new_mtime == old_modified:
                    # You used to have to update the modification time manually.
                    # Now it comes from the signature, this check isn't useful
                    # and often causes problems when the stored format changes
                    # (e.g., when we stopped writing last-modified attributes)
                    pass
                    #raise SafeException("Interface has changed, but modification time "
                    #		    "hasn't! Refusing update.")
        except:
            os.unlink(cached + '.new')
            raise

        portable_rename(cached + '.new', cached)
        logger.debug(_("Saved as %s") % cached)

        self.get_feed(feed_url, force=True)