Example #1
0
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            var curatedFeedName = GetCuratedFeedName();
            var curatedFeedKey  = _curatedFeedService.GetKey(curatedFeedName);

            if (curatedFeedKey == null)
            {
                throw new DataServiceException(404, "Not Found");
            }

            var curatedPackages = _curatedFeedService.GetPackages(curatedFeedName);

            return(SearchAdaptor.SearchCore(SearchService, HttpContext.Request, curatedPackages, searchTerm, targetFramework, includePrerelease, curatedFeedKey: curatedFeedKey)
                   .ToV2FeedPackageQuery(Configuration.GetSiteRoot(UseHttps()), Configuration.Features.FriendlyLicenses));
        }
            private async Task TestOrderBy(string queryString, SortOrder?expected)
            {
                RawUrl += "&" + queryString;

                var result = await SearchAdaptor.SearchCore(
                    SearchService.Object,
                    Request.Object,
                    Packages,
                    SearchTerm,
                    TargetFramework,
                    IncludePrerelease,
                    SemVerLevel);

                VerifySortOrder(expected);
            }
            public void GeneratesNextLinkForComplexUrlWithSemVerLevel2()
            {
                // Arrange
                var requestUri  = new Uri("https://localhost:8081/api/v2/Search()?searchTerm='foo'&$orderby=Id&$skip=100&$top=1000&semVerLevel=2.0.0");
                var resultCount = 2000; // our result set contains 2000 elements

                // Act
                var nextLink = SearchAdaptor.GetNextLink(requestUri, resultCount, new { searchTerm = "foo" },
                                                         GetODataQueryOptionsForTest(requestUri),
                                                         GetODataQuerySettingsForTest(),
                                                         SemVerLevelKey.SemVer2);

                // Assert
                Assert.Equal(new Uri("https://localhost:8081/api/v2/Search()?searchTerm='foo'&$orderby=Id&$skip=200&$top=1000&semVerLevel=2.0.0"), nextLink);
            }
        public virtual async Task <ActionResult> ListPackages(string curatedFeedName, string q, int page = 1, bool prerel = true)
        {
            if (page < 1)
            {
                page = 1;
            }

            q = (q ?? string.Empty).Trim();

            var searchFilter = SearchAdaptor.GetSearchFilter(
                q,
                page,
                includePrerelease: prerel,
                sortOrder: null,
                context: SearchFilter.UISearchContext,
                semVerLevel: SemVerLevelKey.SemVerLevel2);

            searchFilter.CuratedFeed = CuratedFeedService.GetFeedByName(curatedFeedName, includePackages: false);
            if (searchFilter.CuratedFeed == null)
            {
                return(HttpNotFound());
            }

            SearchResults results = await SearchService.Search(searchFilter);

            int totalHits = results.Hits;

            if (page == 1 && !results.Data.Any())
            {
                // In the event the index wasn't updated, we may get an incorrect count.
                totalHits = 0;
            }

            var viewModel = new PackageListViewModel(
                results.Data,
                results.IndexTimestampUtc,
                q,
                totalHits,
                page - 1,
                Constants.DefaultPackageListPageSize,
                Url,
                curatedFeedName,
                includePrerelease: prerel);

            ViewBag.SearchTerm = q;

            return(View("ListPackages", viewModel));
        }
Example #5
0
        private async Task <SearchResults> SearchAsync(ISearchService searchService, string searchTerm)
        {
            await Task.Yield();

            var searchFilter = SearchAdaptor.GetSearchFilter(
                searchTerm,
                page: 1,
                includePrerelease: true,
                sortOrder: null,
                context: SearchFilter.UISearchContext,
                semVerLevel: SemVerLevelKey.SemVerLevel2);

            searchFilter.Take = 10;

            return(await searchService.Search(searchFilter));
        }
        public virtual ActionResult ListPackages(string curatedFeedName, string q, string sortOrder = null, int page = 1, bool prerelease = false)
        {
            if (page < 1)
            {
                page = 1;
            }

            q = (q ?? "").Trim();

            if (String.IsNullOrEmpty(sortOrder))
            {
                // Determine the default sort order. If no query string is specified, then the sortOrder is DownloadCount
                // If we are searching for something, sort by relevance.
                sortOrder = q.IsEmpty() ? Constants.PopularitySortOrder : Constants.RelevanceSortOrder;
            }

            var searchFilter = SearchAdaptor.GetSearchFilter(q, sortOrder, page, prerelease);

            searchFilter.CuratedFeedKey = CuratedFeedService.GetKey(curatedFeedName);
            if (searchFilter.CuratedFeedKey == 0)
            {
                return(HttpNotFound());
            }

            int totalHits;
            IQueryable <Package> packageVersions = SearchService.Search(searchFilter, out totalHits);

            if (page == 1 && !packageVersions.Any())
            {
                // In the event the index wasn't updated, we may get an incorrect count.
                totalHits = 0;
            }

            var viewModel = new PackageListViewModel(
                packageVersions,
                q,
                sortOrder,
                totalHits,
                page - 1,
                Constants.DefaultPackageListPageSize,
                Url,
                prerelease);

            ViewBag.SearchTerm = q;

            return(View("~/Views/Packages/ListPackages.cshtml", viewModel));
        }
Example #7
0
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            var packages = PackageRepository.GetAll()
                           .Include(p => p.PackageRegistration)
                           .Include(p => p.PackageRegistration.Owners)
                           .Where(p => p.Listed);

            return(SearchAdaptor.SearchCore(
                       SearchService,
                       HttpContext.Request,
                       packages,
                       searchTerm,
                       targetFramework,
                       includePrerelease,
                       curatedFeed: null)
                   // TODO: Async this when I can figure out OData async stuff...
                   .Result
                   .ToV2FeedPackageQuery(GetSiteRoot(), Configuration.Features.FriendlyLicenses));
        }
            public void ReturnsDefaultSearchFilterOnNull()
            {
                var searchFilter = SearchAdaptor.GetSearchFilter(
                    q: null,
                    page: -1,
                    includePrerelease: true,
                    packageType: null,
                    sortOrder: null,
                    context: null,
                    semVerLevel: null);

                Assert.Null(searchFilter.SearchTerm);
                Assert.Equal(0, searchFilter.Skip);
                Assert.Equal(GalleryConstants.DefaultPackageListPageSize, searchFilter.Take);
                Assert.True(searchFilter.IncludePrerelease);
                Assert.Null(searchFilter.Context);
                Assert.Null(searchFilter.SemVerLevel);
                Assert.Equal(string.Empty, searchFilter.PackageType);
                Assert.Equal(SortOrder.Relevance, searchFilter.SortOrder);
            }
Example #9
0
        public IQueryable <V1FeedPackage> Search(string searchTerm, string targetFramework)
        {
            var packages = PackageRepository.GetAll()
                           .Include(p => p.PackageRegistration)
                           .Include(p => p.PackageRegistration.Owners)
                           .Where(p => p.Listed && !p.IsPrerelease);

            // For v1 feed, only allow stable package versions.
            packages = SearchAdaptor.SearchCore(
                SearchService,
                HttpContext.Request,
                packages,
                searchTerm,
                targetFramework,
                includePrerelease: false,
                curatedFeed: null)
                       // TODO: Async once I figure Odata Async stuff out
                       .Result;
            return(packages.ToV1FeedPackageQuery(Configuration.GetSiteRoot(UseHttps())));
        }
            public void MapsAllSortOrders(SortOrder sortOrder)
            {
                var searchFilter = SearchAdaptor.GetSearchFilter(
                    q: string.Empty,
                    page: 1,
                    includePrerelease: true,
                    packageType: "Dependency",
                    sortOrder: SortNames[sortOrder],
                    context: string.Empty,
                    semVerLevel: "SomeSemVer");

                Assert.Equal(string.Empty, searchFilter.SearchTerm);
                Assert.Equal(0, searchFilter.Skip);
                Assert.Equal(GalleryConstants.DefaultPackageListPageSize, searchFilter.Take);
                Assert.Equal(true, searchFilter.IncludePrerelease);
                Assert.Equal(string.Empty, searchFilter.Context);
                Assert.Equal("SomeSemVer", searchFilter.SemVerLevel);
                Assert.Equal("Dependency", searchFilter.PackageType);
                Assert.Equal(sortOrder, searchFilter.SortOrder);
            }
Example #11
0
            public void GeneratesNextLinkForSimpleUrl1()
            {
                // Arrange
                var requestUri  = new Uri("https://localhost:8081/api/v2/Packages");
                var resultCount = 200; // our result set contains 200 elements

                // Act
                var nextLink = SearchAdaptor.GetNextLink(requestUri, resultCount, null,
                                                         GetODataQueryOptionsForTest(requestUri),
                                                         GetODataQuerySettingsForTest());

                // Assert
                Assert.Equal(new Uri("https://localhost:8081/api/v2/Packages?$skip=100"), nextLink);

                // Act 2
                nextLink = SearchAdaptor.GetNextLink(nextLink, resultCount, null,
                                                     GetODataQueryOptionsForTest(nextLink),
                                                     GetODataQuerySettingsForTest());

                // Assert 2
                Assert.Null(nextLink);
            }
Example #12
0
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            // Handle OData-style |-separated list of frameworks.
            string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries);

            // For now, we'll just filter on the first one.
            if (targetFrameworkList.Length > 0)
            {
                // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50.
                if (targetFrameworkList.Contains("aspnet50"))
                {
                    targetFramework = "aspnet50";
                }
                else
                {
                    targetFramework = targetFrameworkList[0];
                }
            }

            var packages = PackageRepository.GetAll()
                           .Include(p => p.PackageRegistration)
                           .Include(p => p.PackageRegistration.Owners)
                           .Where(p => p.Listed);
            var query = SearchAdaptor.SearchCore(
                SearchService,
                HttpContext.Request,
                packages,
                searchTerm,
                targetFramework,
                includePrerelease,
                curatedFeed: null)
                        // TODO: Async this when I can figure out OData async stuff...
                        .Result
                        .ToV2FeedPackageQuery(GetSiteRoot(), Configuration.Features.FriendlyLicenses);
            var result = query.ToList();

            return(query);
        }
Example #13
0
        public IQueryable <V2FeedPackage> FindPackagesById(string id)
        {
            var packages = PackageRepository.GetAll()
                           .Include(p => p.PackageRegistration)
                           .Where(p => p.PackageRegistration.Id.Equals(id, StringComparison.OrdinalIgnoreCase));

            if (Configuration.Features.PackageRestoreViaSearch)
            {
                try
                {
                    packages = SearchAdaptor.FindByIdCore(SearchService, HttpContext.Request, packages, id, curatedFeed: null).Result;
                }
                catch (Exception ex)
                {
                    // Swallowing Exception intentionally. If *anything* goes wrong in search, just fall back to the database.
                    // We don't want to break package restores. We do want to know if this happens, so here goes:
                    QuietLog.LogHandledException(ex);
                }
            }

            var query = packages.ToV2FeedPackageQuery(GetSiteRoot(), Configuration.Features.FriendlyLicenses);

            return(query);
        }
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            var curatedFeedName = GetCuratedFeedName();
            var curatedFeed     = _curatedFeedService.GetFeedByName(curatedFeedName, includePackages: false);

            if (curatedFeed == null)
            {
                throw new DataServiceException(404, "Not Found");
            }

            var curatedPackages = _curatedFeedService.GetPackages(curatedFeedName);

            return(SearchAdaptor.SearchCore(
                       SearchService,
                       HttpContext.Request,
                       curatedPackages,
                       searchTerm,
                       targetFramework,
                       includePrerelease,
                       curatedFeed)
                   // TODO: Async this when I can figure out OData async stuff...
                   .Result
                   .ToV2FeedPackageQuery(Configuration.GetSiteRoot(UseHttps()), Configuration.Features.FriendlyLicenses));
        }
Example #15
0
        public virtual async Task <ActionResult> ListPackages(string q, int page = 1)
        {
            if (page < 1)
            {
                page = 1;
            }

            q = (q ?? string.Empty).Trim();

            // We are not going to SQL here anyway, but our request logs do show some attempts to SQL injection.
            // The below code just fails out those requests early.
            if (q.ToLowerInvariant().Contains("char(") ||
                q.ToLowerInvariant().Contains("union select") ||
                q.ToLowerInvariant().Contains("/*") ||
                q.ToLowerInvariant().Contains("--"))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            SearchResults results;

            // fetch most common query from cache to relieve load on the search service
            if (string.IsNullOrEmpty(q) && page == 1)
            {
                var cachedResults = HttpContext.Cache.Get("DefaultSearchResults");
                if (cachedResults == null)
                {
                    var searchFilter = SearchAdaptor.GetSearchFilter(q, page, null, SearchFilter.UISearchContext);
                    results = await _searchService.Search(searchFilter);

                    // note: this is a per instance cache
                    HttpContext.Cache.Add(
                        "DefaultSearchResults",
                        results,
                        null,
                        DateTime.UtcNow.AddMinutes(10),
                        Cache.NoSlidingExpiration,
                        CacheItemPriority.Default, null);
                }
                else
                {
                    // default for /packages view
                    results = (SearchResults)cachedResults;
                }
            }
            else
            {
                var searchFilter = SearchAdaptor.GetSearchFilter(q, page, null, SearchFilter.UISearchContext);
                results = await _searchService.Search(searchFilter);
            }

            int totalHits = results.Hits;

            if (page == 1 && !results.Data.Any())
            {
                // In the event the index wasn't updated, we may get an incorrect count.
                totalHits = 0;
            }

            var viewModel = new PackageListViewModel(
                results.Data,
                results.IndexTimestampUtc,
                q,
                totalHits,
                page - 1,
                Constants.DefaultPackageListPageSize,
                Url);

            ViewBag.SearchTerm = q;

            return(View(viewModel));
        }
Example #16
0
        public virtual async Task <ActionResult> DisplayPackage(string id, string version)
        {
            string normalized = NuGetVersionNormalizer.Normalize(version);

            if (!string.Equals(version, normalized))
            {
                // Permanent redirect to the normalized one (to avoid multiple URLs for the same content)
                return(RedirectToActionPermanent("DisplayPackage", new { id = id, version = normalized }));
            }

            var package = _packageService.FindPackageByIdAndVersion(id, version);

            if (package == null)
            {
                return(HttpNotFound());
            }

            var packageHistory = package.PackageRegistration.Packages.ToList()
                                 .OrderByDescending(p => new NuGetVersion(p.Version));

            var model = new DisplayPackageViewModel(package, packageHistory);

            if (package.IsOwner(User))
            {
                // Tell logged-in package owners not to cache the package page,
                // so they won't be confused about the state of pending edits.
                Response.Cache.SetCacheability(HttpCacheability.NoCache);
                Response.Cache.SetNoStore();
                Response.Cache.SetMaxAge(TimeSpan.Zero);
                Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);

                var pendingMetadata = _editPackageService.GetPendingMetadata(package);
                if (pendingMetadata != null)
                {
                    model.SetPendingMetadata(pendingMetadata);
                }
            }

            var externalSearchService = _searchService as ExternalSearchService;

            if (_searchService.ContainsAllVersions && externalSearchService != null)
            {
                var isIndexedCacheKey = $"IsIndexed_{package.PackageRegistration.Id}_{package.Version}";
                var isIndexed         = HttpContext.Cache.Get(isIndexedCacheKey) as bool?;
                if (!isIndexed.HasValue)
                {
                    var searchFilter = SearchAdaptor.GetSearchFilter(
                        "id:\"" + package.PackageRegistration.Id + "\" AND version:\"" + package.Version + "\"",
                        1, null, SearchFilter.ODataSearchContext);
                    var results = await externalSearchService.RawSearch(searchFilter);

                    isIndexed = results.Hits > 0;

                    var expiration = Cache.NoAbsoluteExpiration;
                    if (!isIndexed.Value)
                    {
                        expiration = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30));
                    }

                    HttpContext.Cache.Add(isIndexedCacheKey,
                                          isIndexed,
                                          null,
                                          expiration,
                                          Cache.NoSlidingExpiration,
                                          CacheItemPriority.Default, null);
                }

                model.IsIndexed = isIndexed;
            }

            ViewBag.FacebookAppID = _config.FacebookAppId;
            return(View(model));
        }
Example #17
0
        public virtual async Task <ActionResult> ListPackages(string q, int page = 1)
        {
            if (page < 1)
            {
                page = 1;
            }

            q = (q ?? string.Empty).Trim();

            SearchResults results;

            // fetch most common query from cache to relieve load on the search service
            if (string.IsNullOrEmpty(q) && page == 1)
            {
                var cachedResults = HttpContext.Cache.Get("DefaultSearchResults");
                if (cachedResults == null)
                {
                    var searchFilter = SearchAdaptor.GetSearchFilter(q, page, null, SearchFilter.UISearchContext);
                    results = await _searchService.Search(searchFilter);

                    // note: this is a per instance cache
                    HttpContext.Cache.Add(
                        "DefaultSearchResults",
                        results,
                        null,
                        DateTime.UtcNow.AddMinutes(10),
                        Cache.NoSlidingExpiration,
                        CacheItemPriority.Default, null);
                }
                else
                {
                    // default for /packages view
                    results = (SearchResults)cachedResults;
                }
            }
            else
            {
                var searchFilter = SearchAdaptor.GetSearchFilter(q, page, null, SearchFilter.UISearchContext);
                results = await _searchService.Search(searchFilter);
            }

            int totalHits = results.Hits;

            if (page == 1 && !results.Data.Any())
            {
                // In the event the index wasn't updated, we may get an incorrect count.
                totalHits = 0;
            }

            var viewModel = new PackageListViewModel(
                results.Data,
                results.IndexTimestampUtc,
                q,
                totalHits,
                page - 1,
                Constants.DefaultPackageListPageSize,
                Url);

            ViewBag.SearchTerm = q;

            return(View(viewModel));
        }