Example #1
0
        public IHttpActionResult Get(ODataQueryOptions <V1FeedPackage> options)
        {
            if (!_featureFlagService.IsODataV1GetAllEnabled())
            {
                return(BadRequest(Strings.ODataDisabled));
            }

            if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Packages,
                                                           _configurationService.Current.IsODataFilterEnabled, nameof(Get)))
            {
                return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options)));
            }

            bool result = TryShouldIgnoreOrderById(options, out var shouldIgnoreOrderById);

            if (!result)
            {
                return(BadRequest("Invalid OrderBy parameter"));
            }

            var queryable = GetAll()
                            .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available)
                            .Where(SemVerLevelKey.IsUnknownPredicate())
                            .WithoutSortOnColumn(Version)
                            .WithoutSortOnColumn(Id, shouldIgnoreOrderById)
                            .ToV1FeedPackageQuery(_configurationService.GetSiteRoot(UseHttps()));

            return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery: true));
        }
Example #2
0
        public IHttpActionResult Get(ODataQueryOptions <V1FeedPackage> options)
        {
            if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Packages,
                                                           _configurationService.Current.IsODataFilterEnabled, nameof(Get)))
            {
                return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options)));
            }
            var queryable = _packagesRepository.GetAll()
                            .Where(p => !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available)
                            .Where(SemVerLevelKey.IsUnknownPredicate())
                            .WithoutSortOnColumn(Version)
                            .WithoutSortOnColumn(Id, ShouldIgnoreOrderById(options))
                            .ToV1FeedPackageQuery(_configurationService.GetSiteRoot(UseHttps()));

            return(QueryResult(options, queryable, MaxPageSize));
        }
        public async Task <IHttpActionResult> Search(
            ODataQueryOptions <V1FeedPackage> options,
            [FromODataUri] string searchTerm      = "",
            [FromODataUri] string targetFramework = "")
        {
            // 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];
                }
            }

            // Perform actual search
            var packages = GetAll()
                           .Include(p => p.PackageRegistration)
                           .Include(p => p.PackageRegistration.Owners)
                           .Where(p => p.Listed && !p.IsPrerelease && p.PackageStatusKey == PackageStatus.Available)
                           .Where(SemVerLevelKey.IsUnknownPredicate())
                           .OrderBy(p => p.PackageRegistration.Id).ThenBy(p => p.Version)
                           .AsNoTracking();

            // todo: search hijack should take queryOptions instead of manually parsing query options
            var searchService       = _searchServiceFactory.GetService();
            var searchAdaptorResult = await SearchAdaptor.SearchCore(
                searchService,
                GetTraditionalHttpContext().Request,
                packages,
                searchTerm,
                targetFramework,
                includePrerelease : false,
                semVerLevel : null);

            // Packages provided by search service (even when not hijacked)
            var  query       = searchAdaptorResult.Packages;
            bool?customQuery = null;

            // If intercepted, create a paged queryresult
            if (searchAdaptorResult.ResultsAreProvidedBySearchService)
            {
                customQuery = false;

                // Add explicit Take() needed to limit search hijack result set size if $top is specified
                var totalHits      = query.LongCount();
                var pagedQueryable = query
                                     .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize)
                                     .ToV1FeedPackageQuery(GetSiteRoot());

                return(TrackedQueryResult(
                           options,
                           pagedQueryable,
                           MaxPageSize,
                           totalHits,
                           (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { searchTerm, targetFramework }, o, s),
                           customQuery));
            }
            else
            {
                customQuery = true;
            }

            if (!ODataQueryVerifier.AreODataOptionsAllowed(options, ODataQueryVerifier.V1Search,
                                                           _configurationService.Current.IsODataFilterEnabled, nameof(Search)))
            {
                return(BadRequest(ODataQueryVerifier.GetValidationFailedMessage(options)));
            }

            // If not, just let OData handle things
            var queryable = query.ToV1FeedPackageQuery(GetSiteRoot());

            return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery));
        }
        private async Task <IHttpActionResult> GetCore(ODataQueryOptions <V1FeedPackage> options, string id, string version, bool return404NotFoundWhenNoResults)
        {
            var packages = GetAll()
                           .Include(p => p.PackageRegistration)
                           .Where(p => p.PackageRegistration.Id.Equals(id, StringComparison.OrdinalIgnoreCase) &&
                                  !p.IsPrerelease &&
                                  p.PackageStatusKey == PackageStatus.Available)
                           .Where(SemVerLevelKey.IsUnknownPredicate());

            if (!string.IsNullOrEmpty(version))
            {
                packages = packages.Where(p => p.Version == version);
            }

            bool?customQuery = null;

            // try the search service
            try
            {
                var searchService       = _searchServiceFactory.GetService();
                var searchAdaptorResult = await SearchAdaptor.FindByIdAndVersionCore(
                    searchService,
                    GetTraditionalHttpContext().Request,
                    packages,
                    id,
                    version,
                    semVerLevel : null);

                // If intercepted, create a paged queryresult
                if (searchAdaptorResult.ResultsAreProvidedBySearchService)
                {
                    customQuery = false;

                    // Packages provided by search service
                    packages = searchAdaptorResult.Packages;

                    // Add explicit Take() needed to limit search hijack result set size if $top is specified
                    var totalHits = packages.LongCount();

                    if (return404NotFoundWhenNoResults && totalHits == 0)
                    {
                        _telemetryService.TrackODataCustomQuery(customQuery);
                        return(NotFound());
                    }

                    var pagedQueryable = packages
                                         .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize)
                                         .ToV1FeedPackageQuery(GetSiteRoot());

                    return(TrackedQueryResult(
                               options,
                               pagedQueryable,
                               MaxPageSize,
                               totalHits,
                               (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { id }, o, s),
                               customQuery));
                }
                else
                {
                    customQuery = true;
                }
            }
            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);
            }

            if (return404NotFoundWhenNoResults && !packages.Any())
            {
                _telemetryService.TrackODataCustomQuery(customQuery);
                return(NotFound());
            }

            var queryable = packages.ToV1FeedPackageQuery(GetSiteRoot());

            return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery));
        }
Example #5
0
        private async Task <IHttpActionResult> GetCore(
            ODataQueryOptions <V1FeedPackage> options,
            string id,
            string version,
            bool return404NotFoundWhenNoResults,
            bool isNonHijackEnabled)
        {
            var packages = GetAll()
                           .Include(p => p.PackageRegistration)
                           .Where(p => p.PackageRegistration.Id.Equals(id, StringComparison.OrdinalIgnoreCase) &&
                                  !p.IsPrerelease &&
                                  p.PackageStatusKey == PackageStatus.Available)
                           .Where(SemVerLevelKey.IsUnknownPredicate());

            if (!string.IsNullOrEmpty(version))
            {
                packages = packages.Where(p => p.Version == version);
            }

            bool?customQuery = null;

            // try the search service
            try
            {
                var searchService       = _searchServiceFactory.GetService();
                var searchAdaptorResult = await SearchAdaptor.FindByIdAndVersionCore(
                    searchService,
                    GetTraditionalHttpContext().Request,
                    packages,
                    id,
                    version,
                    semVerLevel : null);

                // If intercepted, create a paged queryresult
                if (searchAdaptorResult.ResultsAreProvidedBySearchService)
                {
                    customQuery = false;

                    // Packages provided by search service
                    packages = searchAdaptorResult.Packages;

                    // Add explicit Take() needed to limit search hijack result set size if $top is specified
                    var totalHits = packages.LongCount();

                    if (return404NotFoundWhenNoResults && totalHits == 0)
                    {
                        _telemetryService.TrackODataCustomQuery(customQuery);
                        return(NotFound());
                    }

                    var pagedQueryable = packages
                                         .Take(options.Top != null ? Math.Min(options.Top.Value, MaxPageSize) : MaxPageSize)
                                         .ToV1FeedPackageQuery(GetSiteRoot());

                    return(TrackedQueryResult(
                               options,
                               pagedQueryable,
                               MaxPageSize,
                               totalHits,
                               (o, s, resultCount) => SearchAdaptor.GetNextLink(Request.RequestUri, resultCount, new { id }, o, s),
                               customQuery));
                }
                else
                {
                    customQuery = true;
                }
            }
            catch (Exception ex) when(isNonHijackEnabled)
            {
                // Swallowing exception intentionally if we are allowing a fallback to database. If non-hijacked
                // queries are disabled, let the exception bubble out and the client will retry.
                QuietLog.LogHandledException(ex);
            }

            // If we've reached this point, the hijack to the search service has failed or is not applicable. If
            // non-hijacked queries are disabled, stop here.
            if (!isNonHijackEnabled)
            {
                return(BadRequest(Strings.ODataParametersDisabled));
            }

            if (return404NotFoundWhenNoResults && !packages.Any())
            {
                _telemetryService.TrackODataCustomQuery(customQuery);
                return(NotFound());
            }

            var queryable = packages.ToV1FeedPackageQuery(GetSiteRoot());

            return(TrackedQueryResult(options, queryable, MaxPageSize, customQuery));
        }