예제 #1
0
        /// <summary>
        /// Creates a new selection candidate.
        /// </summary>
        /// <param name="feedUri">The file name or URL of the feed listing the implementation.</param>
        /// <param name="feedPreferences">The <see cref="FeedPreferences"/> for <see cref="FeedUri"/>.</param>
        /// <param name="implementation">The implementation this selection candidate references.</param>
        /// <param name="requirements">A set of requirements/restrictions the <paramref name="implementation"/> needs to fullfill for <see cref="IsSuitable"/> to be <c>true</c>.</param>
        /// <param name="offlineUncached">Mark this candidate as unsuitable because it is uncached and <see cref="Config.NetworkUse"/> is set to <see cref="NetworkLevel.Offline"/>.</param>
        /// <exception cref="InvalidDataException"><paramref name="implementation"/>'s <see cref="ImplementationBase.ID"/> is empty.</exception>
        public SelectionCandidate([NotNull] FeedUri feedUri, [NotNull] FeedPreferences feedPreferences, [NotNull] Implementation implementation, [NotNull] Requirements requirements, bool offlineUncached = false)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException(nameof(feedUri));
            }
            if (feedPreferences == null)
            {
                throw new ArgumentNullException(nameof(feedPreferences));
            }
            if (implementation == null)
            {
                throw new ArgumentNullException(nameof(implementation));
            }
            if (requirements == null)
            {
                throw new ArgumentNullException(nameof(requirements));
            }
            #endregion

            if (string.IsNullOrEmpty(implementation.ID))
            {
                throw new InvalidDataException(string.Format(Resources.ImplementationMissingID, implementation, feedUri));
            }

            FeedUri         = feedUri;
            FeedPreferences = feedPreferences;
            Implementation  = implementation;

            _implementationPreferences = feedPreferences[implementation.ID];

            CheckSuitabilty(requirements, offlineUncached);
        }
예제 #2
0
        private IEnumerable <SelectionCandidate> GetCandidates(FeedUri feedUri, Feed feed, Requirements requirements)
        {
            var feedPreferences = FeedPreferences.LoadForSafe(feedUri);

            foreach (var element in feed.Elements)
            {
                var packageImplementation = element as PackageImplementation;
                if (packageImplementation != null)
                { // Each <package-implementation> provides 0..n selection candidates
                    var externalImplementations = _packageManager.Query(packageImplementation, requirements.Distributions.ToArray());
                    foreach (var externalImplementation in externalImplementations)
                    {
                        _externalImplementations[externalImplementation.ID] = externalImplementation;
                        yield return(new SelectionCandidate(new FeedUri(FeedUri.FromDistributionPrefix + feedUri), feedPreferences, externalImplementation, requirements));
                    }
                }
                else if (requirements.Distributions.ContainsOrEmpty(Restriction.DistributionZeroInstall))
                {
                    var implementation = element as Implementation;
                    if (implementation != null)
                    { // Each <implementation> provides 1 selection candidate
                        yield return(new SelectionCandidate(feedUri, feedPreferences, implementation, requirements,
                                                            offlineUncached: (_config.NetworkUse == NetworkLevel.Offline) && !_isCached(implementation)));
                    }
                }
            }
        }
예제 #3
0
        /// <inheritdoc/>
        public void ImportFeed(string path, FeedUri uri, FeedUri mirrorUrl = null)
        {
            #region Sanity checks
            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
            #endregion

            if (uri.IsFile)
            {
                throw new UriFormatException(Resources.FeedUriLocal);
            }
            Log.Debug("Importing feed " + uri.ToStringRfc() + " from: " + path);

            var data = File.ReadAllBytes(path);

            var newSignature = _trustManager.CheckTrust(data, uri, mirrorUrl);
            DetectAttacks(data, uri, newSignature);

            // Add to cache and remember time
            _feedCache.Add(uri, data);
            var preferences = FeedPreferences.LoadForSafe(uri);
            preferences.LastChecked = DateTime.UtcNow;
            preferences.Normalize();
            preferences.SaveFor(uri);
        }
예제 #4
0
        public void TestNormalize()
        {
            var keep = new ImplementationPreferences {ID = "id1", UserStability = Stability.Testing};
            var superflous = new ImplementationPreferences {ID = "id2"};
            var preferences = new FeedPreferences {Implementations = {keep, superflous}};

            preferences.Normalize();
            preferences.Implementations.Should().BeEquivalentTo(keep);
        }
        public void TestNormalize()
        {
            var keep = new ImplementationPreferences {ID = "id1", UserStability = Stability.Testing};
            var superflous = new ImplementationPreferences {ID = "id2"};
            var preferences = new FeedPreferences {Implementations = {keep, superflous}};

            preferences.Normalize();
            CollectionAssert.AreEquivalent(new[] {keep}, preferences.Implementations);
        }
예제 #6
0
        private void AddToCache(byte[] data, FeedUri feedUri)
        {
            _feedCache.Add(feedUri, data);

            var preferences = FeedPreferences.LoadForSafe(feedUri);

            preferences.LastChecked = DateTime.UtcNow;
            preferences.Normalize();
            preferences.SaveFor(feedUri);
        }
        public void TestGetImplementationPreferences()
        {
            var preferences = new FeedPreferences();
            var prefs1 = preferences["id1"];
            Assert.AreSame(prefs1, preferences["id1"], "Second call with same ID should return same reference");

            var prefs2 = new ImplementationPreferences {ID = "id2"};
            preferences.Implementations.Add(prefs2);
            Assert.AreSame(prefs2, preferences["id2"], "Call with pre-existing ID should return existing reference");

            CollectionAssert.AreEquivalent(new[] {prefs1, prefs2}, preferences.Implementations);
        }
예제 #8
0
        /// <inheritdoc/>
        public bool IsStale(FeedUri feedUri)
        {
            #region Sanity checks
            if (feedUri == null)
            {
                throw new ArgumentNullException(nameof(feedUri));
            }
            #endregion

            var      preferences      = FeedPreferences.LoadForSafe(feedUri);
            TimeSpan lastChecked      = DateTime.UtcNow - preferences.LastChecked;
            TimeSpan lastCheckAttempt = DateTime.UtcNow - GetLastCheckAttempt(feedUri);
            return(lastChecked > _config.Freshness && lastCheckAttempt > _failedCheckDelay);
        }
예제 #9
0
        private IEnumerable <SelectionCandidate> GenerateDummyCandidates(FeedUri feedUri)
        {
            if (feedUri.IsFromDistribution)
            {
                return(Enumerable.Empty <SelectionCandidate>());
            }

            try
            {
                var feed            = _feedManager[feedUri];
                var feedPreferences = FeedPreferences.LoadForSafe(feedUri);
                return(feed.Implementations.Select(implementation => GenerateDummyCandidate(feedUri, feedPreferences, implementation)));
            }
            #region Error handling
            catch (KeyNotFoundException)
            {
                return(Enumerable.Empty <SelectionCandidate>());
            }
            #endregion
        }
예제 #10
0
        private static void ApplyVersionRestrictions(Requirements requirements, Selections selections)
        {
            if (requirements.ExtraRestrictions.Count == 0)
            {
                return;
            }

            // TODO
            Log.Warn($"You have applied a version restriction to this app. Zero Install will continue to apply this restriction to any future updates. You will need to run '0install select --customize {requirements.InterfaceUri}' to undo this.");

            foreach (var restriction in requirements.ExtraRestrictions)
            {
                var selection = selections.GetImplementation(restriction.Key);
                if (selection != null)
                {
                    var pref = FeedPreferences.LoadForSafe(restriction.Key);
                    pref.Implementations.Clear();
                    pref[selection.ID].UserStability = Stability.Preferred;
                    pref.SaveFor(restriction.Key);
                }
            }
        }
예제 #11
0
 private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation)
 {
     return new SelectionCandidate(feedUri, feedPreferences, implementation,
         new Requirements(_interfaceUri, Command.NameRun, new Architecture(Architecture.CurrentSystem.OS, Cpu.All)));
 }
예제 #12
0
 private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation)
 => new SelectionCandidate(feedUri, feedPreferences, implementation,
                           new Requirements(_interfaceUri, "", new Architecture(Architecture.CurrentSystem.OS, Cpu.All)));
예제 #13
0
        public void TestGetImplementationPreferences()
        {
            var preferences = new FeedPreferences();
            var prefs1 = preferences["id1"];
            preferences["id1"].Should().BeSameAs(prefs1, because: "Second call with same ID should return same reference");

            var prefs2 = new ImplementationPreferences {ID = "id2"};
            preferences.Implementations.Add(prefs2);
            preferences["id2"].Should().BeSameAs(prefs2, because: "Call with pre-existing ID should return existing reference");

            preferences.Implementations.Should().BeEquivalentTo(prefs1, prefs2);
        }
예제 #14
0
 private SelectionCandidate GenerateDummyCandidate(FeedUri feedUri, FeedPreferences feedPreferences, Implementation implementation)
 => new(feedUri, feedPreferences, implementation,