public FindPackageByIdAndVersion ( string id, string version, bool allowPrerelease = true ) : |
||
id | string | |
version | string | |
allowPrerelease | bool | |
return |
public virtual async Task <ActionResult> PublishPackage(string id, string version) { var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } User user = GetCurrentUser(); if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "publish"))); } // Check if API key allows listing/unlisting the current package id if (!ApiKeyScopeAllows( subject: id, requestedActions: NuGetScopes.PackageUnlist)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } await PackageService.MarkPackageListedAsync(package); IndexingService.UpdatePackage(package); return(new EmptyResult()); }
private async Task <HttpStatusCodeWithBodyResult> VerifyPackageKeyInternalAsync(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version, semVerLevelKey: SemVerLevelKey.SemVer2); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Verify)); string[] requestedActions; if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { requestedActions = new[] { NuGetScopes.PackageVerify }; } else { requestedActions = new[] { NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion }; } var apiScopeEvaluationResult = EvaluateApiScope(ActionsRequiringPermissions.VerifyPackage, package.PackageRegistration, requestedActions); if (!apiScopeEvaluationResult.IsSuccessful()) { return(GetHttpResultFromFailedApiScopeEvaluation(apiScopeEvaluationResult, id, version)); } return(null); }
private async Task <HttpStatusCodeWithBodyResult> VerifyPackageKeyInternalAsync(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version, semVerLevelKey: SemVerLevelKey.SemVer2); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } // Write an audit record await AuditingService.SaveAuditRecordAsync( new PackageAuditRecord(package, AuditedPackageAction.Verify)); if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { // Secure path: verify that verification key matches package scope. if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackageVerify)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } else { // Insecure path: verify that API key is legacy or matches package scope. if (!HasAnyScopeThatAllows(package.PackageRegistration, NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } return(null); }
public virtual async Task <ActionResult> GetPackage(string id, string version) { // some security paranoia about URL hacking somehow creating e.g. open redirects // validate user input: explicit calls to the same validators used during Package Registrations // Ideally shouldn't be necessary? if (!PackageIdValidator.IsValidPackageId(id ?? "")) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid")); } // if version is non-null, check if it's semantically correct and normalize it. if (!String.IsNullOrEmpty(version)) { NuGetVersion dummy; if (!NuGetVersion.TryParse(version, out dummy)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version")); } // Normalize the version version = NuGetVersionNormalizer.Normalize(version); } else { // if version is null, get the latest version from the database. // This ensures that on package restore scenario where version will be non null, we don't hit the database. try { var package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false); if (package == null) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } version = package.NormalizedVersion; } catch (SqlException e) { QuietLog.LogHandledException(e); // Database was unavailable and we don't have a version, return a 503 return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion)); } catch (DataException e) { QuietLog.LogHandledException(e); // Database was unavailable and we don't have a version, return a 503 return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion)); } } if (ConfigurationService.Features.TrackPackageDownloadCountInLocalDatabase) { await PackageService.IncrementDownloadCountAsync(id, version); } return(await PackageFileService.CreateDownloadPackageActionResultAsync( HttpContext.Request.Url, id, version)); }
private HttpStatusCodeWithBodyResult VerifyPackageKeyInternal(User user, Credential credential, string id, string version) { // Verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } if (CredentialTypes.IsPackageVerificationApiKey(credential.Type)) { // Secure path: verify that verification key matches package scope. if (!ApiKeyScopeAllows(id, NuGetScopes.PackageVerify)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } else { // Insecure path: verify that API key is legacy or matches package scope. if (!ApiKeyScopeAllows(id, NuGetScopes.PackagePush, NuGetScopes.PackagePushVersion)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } return(null); }
public virtual ActionResult PublishPackage(string apiKey, string id, string version) { var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } User user = GetUserByApiKey(apiKey); if (user == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "publish"))); } if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "publish"))); } PackageService.MarkPackageListed(package); IndexingService.UpdatePackage(package); return(new EmptyResult()); }
private OwnerRequestsListItemViewModel CreateOwnerRequestsListItemViewModel(PackageOwnerRequest request, User currentUser) { var package = PackageService.FindPackageByIdAndVersion(request.PackageRegistration.Id, version: null, semVerLevelKey: SemVerLevelKey.SemVer2, allowPrerelease: true); var packageViewModel = _listPackageItemViewModelFactory.Create(package, currentUser); return(new OwnerRequestsListItemViewModel { Request = request, Package = packageViewModel, CanAccept = ActionsRequiringPermissions.HandlePackageOwnershipRequest.CheckPermissions(currentUser, request.NewOwner) == PermissionsCheckResult.Allowed, CanCancel = packageViewModel.CanManageOwners, }); }
public virtual ActionResult VerifyPackageKey(string id, string version) { if (!String.IsNullOrEmpty(id)) { // If the partialId is present, then verify that the user has permission to push for the specific Id \ version combination. var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } var user = GetCurrentUser(); if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } } return(new EmptyResult()); }
public virtual async Task <ActionResult> DeletePackage(string id, string version) { var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } var user = GetCurrentUser(); if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } await PackageService.MarkPackageUnlistedAsync(package); IndexingService.UpdatePackage(package); return(new EmptyResult()); }
public virtual ActionResult DeletePackage(string apiKey, string id, string version) { Guid parsedApiKey; if (!Guid.TryParse(apiKey, out parsedApiKey)) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.BadRequest, String.Format(CultureInfo.CurrentCulture, Strings.InvalidApiKey, apiKey))); } var user = UserService.FindByApiKey(parsedApiKey); if (user == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "delete"))); } var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.Forbidden, String.Format(CultureInfo.CurrentCulture, Strings.ApiKeyNotAuthorized, "delete"))); } PackageService.MarkPackageUnlisted(package); IndexingService.UpdatePackage(package); return(new EmptyResult()); }
public virtual async Task <ActionResult> DeletePackage(string id, string version) { var package = PackageService.FindPackageByIdAndVersion(id, version); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } var user = GetCurrentUser(); if (!package.IsOwner(user)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } // Check if API key allows listing/unlisting the current package id if (!ApiKeyScopeAllows( subject: id, requestedActions: NuGetScopes.PackageUnlist)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.Forbidden, Strings.ApiKeyNotAuthorized)); } await PackageService.MarkPackageUnlistedAsync(package); // Handle in separate transaction because of concurrency check with retry. Due to using // separate transactions, we must always call UpdateIsLatest on delete/unlist. This is // because a concurrent thread could be marking the package as latest before this thread // is able to commit the delete /unlist. await PackageService.UpdateIsLatestAsync(package.PackageRegistration); IndexingService.UpdatePackage(package); return(new EmptyResult()); }
public virtual async Task <ActionResult> GetPackage(string id, string version) { // some security paranoia about URL hacking somehow creating e.g. open redirects // validate user input: explicit calls to the same validators used during Package Registrations // Ideally shouldn't be necessary? if (!PackageIdValidator.IsValidPackageId(id ?? "")) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid")); } if (!String.IsNullOrEmpty(version)) { SemanticVersion dummy; if (!SemanticVersion.TryParse(version, out dummy)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version")); } } // Normalize the version version = SemanticVersionExtensions.Normalize(version); // if the version is null, the user is asking for the latest version. Presumably they don't want includePrerelease release versions. // The allow prerelease flag is ignored if both partialId and version are specified. // In general we want to try to add download statistics for any package regardless of whether a version was specified. Package package = null; try { package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false); if (package == null) { return(new HttpStatusCodeWithBodyResult( HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } try { var stats = new PackageStatistics { // IMPORTANT: Timestamp is managed by the database. IPAddress = Request.UserHostAddress, UserAgent = Request.UserAgent, Package = package, Operation = Request.Headers["NuGet-Operation"], DependentPackage = Request.Headers["NuGet-DependentPackage"], ProjectGuids = Request.Headers["NuGet-ProjectGuids"], }; PackageService.AddDownloadStatistics(stats); } catch (ReadOnlyModeException) { // *gulp* Swallowed. It's OK not to add statistics and ok to not log errors in read only mode. } catch (SqlException e) { // Log the error and continue QuietLog.LogHandledException(e); } catch (DataException e) { // Log the error and continue QuietLog.LogHandledException(e); } } catch (SqlException e) { QuietLog.LogHandledException(e); } catch (DataException e) { QuietLog.LogHandledException(e); } // Fall back to constructing the URL based on the package version and ID. if (String.IsNullOrEmpty(version) && package == null) { // Database was unavailable and we don't have a version, return a 503 return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion)); } return(await PackageFileService.CreateDownloadPackageActionResultAsync( HttpContext.Request.Url, id, String.IsNullOrEmpty(version)?package.NormalizedVersion : version)); }
public virtual async Task <ActionResult> GetPackage(string id, string version) { // some security paranoia about URL hacking somehow creating e.g. open redirects // validate user input: explicit calls to the same validators used during Package Registrations // Ideally shouldn't be necessary? if (!PackageIdValidator.IsValidPackageId(id ?? "")) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The format of the package id is invalid")); } // if version is non-null, check if it's semantically correct and normalize it. if (!String.IsNullOrEmpty(version)) { NuGetVersion dummy; if (!NuGetVersion.TryParse(version, out dummy)) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.BadRequest, "The package version is not a valid semantic version")); } // Normalize the version version = NuGetVersionNormalizer.Normalize(version); } else { // if version is null, get the latest version from the database. // This ensures that on package restore scenario where version will be non null, we don't hit the database. try { var package = PackageService.FindPackageByIdAndVersion(id, version, allowPrerelease: false); if (package == null) { return(new HttpStatusCodeWithBodyResult(HttpStatusCode.NotFound, String.Format(CultureInfo.CurrentCulture, Strings.PackageWithIdAndVersionNotFound, id, version))); } version = package.NormalizedVersion; } catch (SqlException e) { QuietLog.LogHandledException(e); // Database was unavailable and we don't have a version, return a 503 return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion)); } catch (DataException e) { QuietLog.LogHandledException(e); // Database was unavailable and we don't have a version, return a 503 return(new HttpStatusCodeWithBodyResult(HttpStatusCode.ServiceUnavailable, Strings.DatabaseUnavailable_TrySpecificVersion)); } } // If metrics service is specified we post the data to it asynchronously. Else we skip stats. if (_config != null && _config.MetricsServiceUri != null) { try { var userHostAddress = Request.UserHostAddress; var userAgent = Request.UserAgent; var operation = Request.Headers["NuGet-Operation"]; var dependentPackage = Request.Headers["NuGet-DependentPackage"]; var projectGuids = Request.Headers["NuGet-ProjectGuids"]; HostingEnvironment.QueueBackgroundWorkItem(cancellationToken => PostDownloadStatistics(id, version, userHostAddress, userAgent, operation, dependentPackage, projectGuids, cancellationToken)); } catch (Exception ex) { QuietLog.LogHandledException(ex); } } return(await PackageFileService.CreateDownloadPackageActionResultAsync( HttpContext.Request.Url, id, version)); }