public static void Access(IOwinContext context, string tenantId, SecureSearcherManager searcherManager, string connectionString, int accessDuration) { string relativeUri = context.Request.Path.ToString(); string[] parts = relativeUri.Split('/'); if (!(parts.Length >= 4)) { context.Response.StatusCode = (int)HttpStatusCode.NotFound; return; } if (!parts[1].Equals("resource")) { context.Response.StatusCode = (int)HttpStatusCode.NotFound; return; } string containerName = parts[2]; string blobName = string.Join("/", parts, 3, parts.Length - 3); if (IsAuthorized(searcherManager, tenantId, containerName, blobName)) { Redirect(context, containerName, blobName, connectionString, accessDuration); } else { context.Response.Write("unauthorized"); context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; } }
static JToken FindById(SecureSearcherManager searcherManager, string id, string tenantId, string scheme) { IndexSearcher searcher = searcherManager.Get(); try { string analyzedId = id.ToLowerInvariant(); BooleanQuery query = new BooleanQuery(); query.Add(new BooleanClause(new TermQuery(new Term("FullId", analyzedId)), Occur.MUST)); Filter filter = searcherManager.GetFilter(tenantId, new string [] { "http://schema.nuget.org/schema#ApiAppPackage" }); TopDocs topDocs = searcher.Search(query, 1000); if (topDocs.TotalHits > 0) { Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme]; JObject registrationObj = new JObject(); string registrationRelativeAddress = string.Format("{0}/index.json", id.ToLowerInvariant()); registrationObj["registration"] = new Uri(registrationBaseAddress, registrationRelativeAddress).AbsoluteUri; JArray data = new JArray(); for (int i = 0; i < topDocs.ScoreDocs.Length; i++) { Document document = searcher.Doc(topDocs.ScoreDocs[i].Doc); JObject versionObj = new JObject(); ServiceHelpers.AddField(versionObj, document, "version", "Version"); ServiceHelpers.AddField(versionObj, document, "packageContent", "PackageContent"); ServiceHelpers.AddField(versionObj, document, "catalogEntry", "CatalogEntry"); data.Add(versionObj); } registrationObj["data"] = data; return(registrationObj); } else { return(null); } } finally { searcherManager.Release(searcher); } }
public static async Task Query(IOwinContext context, SecureSearcherManager searcherManager, string tenantId, string currentOwner) { int skip; if (!int.TryParse(context.Request.Query["skip"], out skip)) { skip = 0; } int take; if (!int.TryParse(context.Request.Query["take"], out take)) { take = 50; } bool countOnly; if (!bool.TryParse(context.Request.Query["countOnly"], out countOnly)) { countOnly = false; } bool includePrerelease; if (!bool.TryParse(context.Request.Query["prerelease"], out includePrerelease)) { includePrerelease = false; } bool includeExplanation = false; if (!bool.TryParse(context.Request.Query["explanation"], out includeExplanation)) { includeExplanation = false; } string q = context.Request.Query["q"] ?? string.Empty; string scheme = context.Request.Uri.Scheme; JToken result = Search(searcherManager, tenantId, currentOwner, scheme, q, countOnly, includePrerelease, skip, take, includeExplanation); await ServiceHelpers.WriteResponse(context, HttpStatusCode.OK, result); }
public static JToken Search(SecureSearcherManager searcherManager, string tenantId, string currentOwner, string scheme, string q, bool countOnly, bool includePrerelease, int skip, int take, bool includeExplanation) { IndexSearcher searcher = searcherManager.Get(); try { Filter filter = searcherManager.GetFilter(tenantId, new[] { "http://schema.nuget.org/schema#ApiAppPackage" }, includePrerelease, false); Query query = MakeQuery(q); TopDocs topDocs = searcher.Search(query, filter, skip + take); return MakeResult(searcher, currentOwner, scheme, topDocs, skip, take, searcherManager, includeExplanation, query); } finally { searcherManager.Release(searcher); } }
static bool IsAuthorized(SecureSearcherManager searcherManager, string tenantId, string containerName, string blobName) { searcherManager.MaybeReopen(); IndexSearcher searcher = searcherManager.Get(); try { Filter filter = searcherManager.GetFilter(tenantId, new string[] { "http://schema.nuget.org/schema#ApiAppPackage", "http://schema.nuget.org/schema#CatalogInfrastructure" }); string relativePath = string.Format("/{0}/{1}", containerName, blobName); Query query = new TermQuery(new Term("StoragePath", relativePath)); TopDocs topDocs = searcher.Search(query, 1); return(topDocs.TotalHits > 0); } finally { searcherManager.Release(searcher); } }
static bool IsAuthorized(SecureSearcherManager searcherManager, string tenantId, string containerName, string blobName) { searcherManager.MaybeReopen(); IndexSearcher searcher = searcherManager.Get(); try { Filter filter = searcherManager.GetFilter(tenantId, new string[] { "http://schema.nuget.org/schema#ApiAppPackage", "http://schema.nuget.org/schema#CatalogInfrastructure" }); string relativePath = string.Format("/{0}/{1}", containerName, blobName); Query query = new TermQuery(new Term("StoragePath", relativePath)); TopDocs topDocs = searcher.Search(query, 1); return (topDocs.TotalHits > 0); } finally { searcherManager.Release(searcher); } }
public static JToken Search(SecureSearcherManager searcherManager, string tenantId, string currentOwner, string scheme, string q, bool countOnly, bool includePrerelease, int skip, int take, bool includeExplanation) { IndexSearcher searcher = searcherManager.Get(); try { Filter filter = searcherManager.GetFilter(tenantId, new string [] { "http://schema.nuget.org/schema#ApiAppPackage" }, includePrerelease, false); Query query = MakeQuery(q); TopDocs topDocs = searcher.Search(query, filter, skip + take); return(MakeResult(searcher, currentOwner, scheme, topDocs, skip, take, searcherManager, includeExplanation, query)); } finally { searcherManager.Release(searcher); } }
public static async Task Find(IOwinContext context, SecureSearcherManager searcherManager, string tenantId) { string id = context.Request.Query["id"]; string version = context.Request.Query["version"]; HttpStatusCode statusCode; JToken result; if (!string.IsNullOrEmpty(id)) { if (string.IsNullOrEmpty(version)) { result = FindById(searcherManager, id, tenantId, context.Request.Uri.Scheme); } else { result = FindByIdAndVersion(searcherManager, id, version, tenantId, context.Request.Uri.Scheme); } if (result == null) { result = new JObject { { "error", "not found" } }; statusCode = HttpStatusCode.NotFound; } else { statusCode = HttpStatusCode.OK; } } else { result = new JObject { { "error", "id is a required parameter" } }; statusCode = HttpStatusCode.BadRequest; } await ServiceHelpers.WriteResponse(context, statusCode, result); }
public static async Task Query(IOwinContext context, SecureSearcherManager searcherManager, string tenantId, string currentOwner) { int skip; if (!int.TryParse(context.Request.Query["skip"], out skip)) { skip = 0; } int take; if (!int.TryParse(context.Request.Query["take"], out take)) { take = 50; } bool countOnly; if (!bool.TryParse(context.Request.Query["countOnly"], out countOnly)) { countOnly = false; } bool includePrerelease; if (!bool.TryParse(context.Request.Query["prerelease"], out includePrerelease)) { includePrerelease = false; } bool includeExplanation; if (!bool.TryParse(context.Request.Query["explanation"], out includeExplanation)) { includeExplanation = false; } string q = context.Request.Query["q"] ?? string.Empty; string scheme = context.Request.Uri.Scheme; JToken result = Search(searcherManager, tenantId, currentOwner, scheme, q, countOnly, includePrerelease, skip, take, includeExplanation); await ServiceHelpers.WriteResponse(context, HttpStatusCode.OK, result); }
static JToken FindByIdAndVersion(SecureSearcherManager searcherManager, string id, string version, string tenantId, string scheme) { IndexSearcher searcher = searcherManager.Get(); try { string analyzedId = id.ToLowerInvariant(); string analyzedVersion = NuGetVersion.Parse(version).ToNormalizedString(); BooleanQuery query = new BooleanQuery(); query.Add(new BooleanClause(new TermQuery(new Term("FullId", analyzedId)), Occur.MUST)); query.Add(new BooleanClause(new TermQuery(new Term("Version", analyzedVersion)), Occur.MUST)); Filter filter = searcherManager.GetFilter(tenantId, new string [] { "http://schema.nuget.org/schema#ApiAppPackage" }); TopDocs topDocs = searcher.Search(query, filter, 1); if (topDocs.TotalHits > 0) { Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme]; JObject obj = new JObject(); obj["registration"] = new Uri(registrationBaseAddress, string.Format("{0}/index.json", id.ToLowerInvariant())).AbsoluteUri; Document document = searcher.Doc(topDocs.ScoreDocs[0].Doc); ServiceHelpers.AddField(obj, document, "packageContent", "PackageContent"); ServiceHelpers.AddField(obj, document, "catalogEntry", "CatalogEntry"); return(obj); } else { return(null); } } finally { searcherManager.Release(searcher); } }
static JToken FindByIdAndVersion(SecureSearcherManager searcherManager, string id, string version, string tenantId, string scheme) { IndexSearcher searcher = searcherManager.Get(); try { string analyzedId = id.ToLowerInvariant(); string analyzedVersion = NuGetVersion.Parse(version).ToNormalizedString(); BooleanQuery query = new BooleanQuery(); query.Add(new BooleanClause(new TermQuery(new Term("FullId", analyzedId)), Occur.MUST)); query.Add(new BooleanClause(new TermQuery(new Term("Version", analyzedVersion)), Occur.MUST)); Filter filter = searcherManager.GetFilter(tenantId, new string [] { "http://schema.nuget.org/schema#ApiAppPackage" }); TopDocs topDocs = searcher.Search(query, filter, 1); if (topDocs.TotalHits > 0) { Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme]; JObject obj = new JObject(); obj["registration"] = new Uri(registrationBaseAddress, string.Format("{0}/index.json", id.ToLowerInvariant())).AbsoluteUri; Document document = searcher.Doc(topDocs.ScoreDocs[0].Doc); ServiceHelpers.AddField(obj, document, "packageContent", "PackageContent"); ServiceHelpers.AddField(obj, document, "catalogEntry", "CatalogEntry"); return obj; } else { return null; } } finally { searcherManager.Release(searcher); } }
public static JToken MakeResultData(IndexSearcher searcher, string currentOwner, string scheme, TopDocs topDocs, int skip, int take, SecureSearcherManager searcherManager, bool includeExplanation, Query query) { Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme]; JArray array = new JArray(); for (int i = skip; i < Math.Min(skip + take, topDocs.ScoreDocs.Length); i++) { ScoreDoc scoreDoc = topDocs.ScoreDocs[i]; Document document = searcher.Doc(scoreDoc.Doc); string url = document.Get("Url"); string id = document.Get("Id"); string version = document.Get("Version"); string owner = document.Get("Owner"); string ns = document.Get("Namespace"); if (ns != null) { id = string.Format("{0}.{1}", ns, id); } JObject obj = new JObject(); obj["@id"] = new Uri(registrationBaseAddress, url).AbsoluteUri; obj["@type"] = document.Get("@type"); obj["registration"] = new Uri(registrationBaseAddress, string.Format("{0}/index.json", id.ToLowerInvariant())).AbsoluteUri; obj["id"] = id; obj["isOwner"] = (owner == currentOwner); ServiceHelpers.AddField(obj, document, "packageContent", "PackageContent"); ServiceHelpers.AddField(obj, document, "catalogEntry", "CatalogEntry"); ServiceHelpers.AddFieldBool(obj, document, "listed", "Listed"); ServiceHelpers.AddField(obj, document, "tenantId", "TenantId"); ServiceHelpers.AddField(obj, document, "namespace", "Namespace"); ServiceHelpers.AddField(obj, document, "visibility", "Visibility"); ServiceHelpers.AddField(obj, document, "description", "Description"); ServiceHelpers.AddField(obj, document, "summary", "Summary"); ServiceHelpers.AddField(obj, document, "title", "Title"); ServiceHelpers.AddField(obj, document, "iconUrl", "IconUrl"); ServiceHelpers.AddFieldAsObject(obj, document, "owner", "OwnerDetails"); ServiceHelpers.AddFieldAsArray(obj, document, "tags", "Tags"); ServiceHelpers.AddFieldAsArray(obj, document, "authors", "Authors"); obj["version"] = version; obj["versions"] = searcherManager.GetVersions(scheme, scoreDoc.Doc); if (includeExplanation) { Explanation explanation = searcher.Explain(query, scoreDoc.Doc); obj["explanation"] = explanation.ToString(); } array.Add(obj); } return(array); }
static JToken MakeResult(IndexSearcher searcher, string currentOwner, string scheme, TopDocs topDocs, int skip, int take, SecureSearcherManager searcherManager, bool includeExplanation, Query query) { JToken data = MakeResultData(searcher, currentOwner, scheme, topDocs, skip, take, searcherManager, includeExplanation, query); JObject result = new JObject(); result.Add("@context", new JObject { { "@vocab", "http://schema.nuget.org/schema#" } }); result.Add("totalHits", topDocs.TotalHits); result.Add("lastReopen", searcherManager.LastReopen.ToString("o")); result.Add("index", searcherManager.IndexName); result.Add("data", data); result.Add("currentOwner", currentOwner); return(result); }
public static JToken MakeResultData(IndexSearcher searcher, string currentOwner, string scheme, TopDocs topDocs, int skip, int take, SecureSearcherManager searcherManager, bool includeExplanation, Query query) { Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme]; JArray array = new JArray(); for (int i = skip; i < Math.Min(skip + take, topDocs.ScoreDocs.Length); i++) { ScoreDoc scoreDoc = topDocs.ScoreDocs[i]; Document document = searcher.Doc(scoreDoc.Doc); string url = document.Get("Url"); string id = document.Get("Id"); string version = document.Get("Version"); string owner = document.Get("Owner"); string ns = document.Get("Namespace"); if (ns != null) { id = string.Format("{0}.{1}", ns, id); } JObject obj = new JObject(); obj["@id"] = new Uri(registrationBaseAddress, url).AbsoluteUri; obj["@type"] = document.Get("@type"); obj["registration"] = new Uri(registrationBaseAddress, string.Format("{0}/index.json", id.ToLowerInvariant())).AbsoluteUri; obj["id"] = id; obj["isOwner"] = (owner == currentOwner); ServiceHelpers.AddField(obj, document, "packageContent", "PackageContent"); ServiceHelpers.AddField(obj, document, "catalogEntry", "CatalogEntry"); ServiceHelpers.AddFieldBool(obj, document, "listed", "Listed"); ServiceHelpers.AddField(obj, document, "tenantId", "TenantId"); ServiceHelpers.AddField(obj, document, "namespace", "Namespace"); ServiceHelpers.AddField(obj, document, "visibility", "Visibility"); ServiceHelpers.AddField(obj, document, "description", "Description"); ServiceHelpers.AddField(obj, document, "summary", "Summary"); ServiceHelpers.AddField(obj, document, "title", "Title"); ServiceHelpers.AddField(obj, document, "iconUrl", "IconUrl"); ServiceHelpers.AddField(obj, document, "homepage", "Homepage"); ServiceHelpers.AddField(obj, document, "licenseUrl", "LicenseUrl"); ServiceHelpers.AddField(obj, document, "projectUrl", "ProjectUrl"); ServiceHelpers.AddFieldAsObject(obj, document, "license", "LicenseDetails"); ServiceHelpers.AddFieldAsObject(obj, document, "owner", "OwnerDetails"); ServiceHelpers.AddFieldAsArray(obj, document, "tags", "Tags"); ServiceHelpers.AddFieldAsArray(obj, document, "authors", "Authors"); ServiceHelpers.AddFieldAsArray(obj, document, "categories", "Categories"); obj["version"] = version; obj["versions"] = searcherManager.GetVersions(scheme, scoreDoc.Doc); if (includeExplanation) { Explanation explanation = searcher.Explain(query, scoreDoc.Doc); obj["explanation"] = explanation.ToString(); } array.Add(obj); } return array; }
public void Configuration(IAppBuilder app) { app.UseErrorPage(); // search test console app.Use(async (context, next) => { if (String.Equals(context.Request.Path.Value, "/console", StringComparison.OrdinalIgnoreCase)) { // Redirect to trailing slash to maintain relative links context.Response.Redirect(context.Request.PathBase + context.Request.Path + "/"); context.Response.StatusCode = 301; return; } else if (String.Equals(context.Request.Path.Value, "/console/", StringComparison.OrdinalIgnoreCase)) { context.Request.Path = new PathString("/console/Index.html"); } await next(); }); app.UseStaticFiles(new StaticFileOptions(new SharedOptions { RequestPath = new PathString("/console"), FileSystem = new EmbeddedResourceFileSystem(typeof(Startup).Assembly, "NuGet.Services.Metadata.Console") })); // AAD integration - adding this middleware gives us the claims string audience = _configurationService.Get("ida.Audience"); string tenant = _configurationService.Get("ida.Tenant"); string aadInstance = _configurationService.Get("ida.AADInstance"); string metadataAddress = string.Format(aadInstance, tenant) + "/federationmetadata/2007-06/federationmetadata.xml"; app.UseWindowsAzureActiveDirectoryBearerAuthentication(new WindowsAzureActiveDirectoryBearerAuthenticationOptions { TokenValidationParameters = new TokenValidationParameters { ValidAudience = audience, ValidateIssuer = true, IssuerValidator = (string issuer, SecurityToken securityToken, TokenValidationParameters validationParameters) => issuer }, Tenant = tenant, MetadataAddress = metadataAddress }); // start the service running - the Lucene index needs to be reopened regularly on a background thread string searchIndexRefresh = _configurationService.Get("Search.IndexRefresh") ?? "15"; int seconds; if (!int.TryParse(searchIndexRefresh, out seconds)) { seconds = 60; } _searcherManager = null; _gate = 0; _timer = new Timer(ReopenCallback, 0, 10, seconds * 1000); app.Run(Invoke); }
public void TryMaybeReopen() { try { _searcherManager.MaybeReopen(); } catch (StorageException) { _searcherManager = null; } }
public void TrySetSearcherManager() { try { _searcherManager = CreateSearcherManager(); _searcherManager.Open(); } catch (FileNotFoundException) { _searcherManager = null; } }
static JToken FindById(SecureSearcherManager searcherManager, string id, string tenantId, string scheme) { IndexSearcher searcher = searcherManager.Get(); try { string analyzedId = id.ToLowerInvariant(); BooleanQuery query = new BooleanQuery(); query.Add(new BooleanClause(new TermQuery(new Term("FullId", analyzedId)), Occur.MUST)); Filter filter = searcherManager.GetFilter(tenantId, new string [] { "http://schema.nuget.org/schema#ApiAppPackage" }); TopDocs topDocs = searcher.Search(query, 1000); if (topDocs.TotalHits > 0) { Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme]; JObject registrationObj = new JObject(); string registrationRelativeAddress = string.Format("{0}/index.json", id.ToLowerInvariant()); registrationObj["registration"] = new Uri(registrationBaseAddress, registrationRelativeAddress).AbsoluteUri; JArray data = new JArray(); for (int i = 0; i < topDocs.ScoreDocs.Length; i++) { Document document = searcher.Doc(topDocs.ScoreDocs[i].Doc); JObject versionObj = new JObject(); ServiceHelpers.AddField(versionObj, document, "version", "Version"); ServiceHelpers.AddField(versionObj, document, "packageContent", "PackageContent"); ServiceHelpers.AddField(versionObj, document, "catalogEntry", "CatalogEntry"); data.Add(versionObj); } registrationObj["data"] = data; return registrationObj; } else { return null; } } finally { searcherManager.Release(searcher); } }
static JToken MakeResult(IndexSearcher searcher, string currentOwner, string scheme, TopDocs topDocs, int skip, int take, SecureSearcherManager searcherManager, bool includeExplanation, Query query) { JToken data = MakeResultData(searcher, currentOwner, scheme, topDocs, skip, take, searcherManager, includeExplanation, query); JObject result = new JObject(); result.Add("@context", new JObject { { "@vocab", "http://schema.nuget.org/schema#" } }); result.Add("totalHits", topDocs.TotalHits); result.Add("lastReopen", searcherManager.LastReopen.ToString("o")); result.Add("index", searcherManager.IndexName); result.Add("data", data); result.Add("currentOwner", currentOwner); return result; }