using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NuGet.Versioning; using isn.Data; using isn.Entities; using Unleash.ClientFactory; using Unleash; using System.Collections.Generic; using isnd.Services; using isnd.Entities; using Microsoft.AspNetCore.Hosting; using isnd.Helpers; namespace isn.Controllers { [AllowAnonymous] public partial class PackagesController : Controller { const int maxTake = 100; const string _pkgRootPrefix = "~/package"; const string defaultSemVer = "2.0.0"; private readonly Resource[] _ressources; private readonly ILogger _logger; private readonly IDataProtector _protector; private readonly NugetSettings _nugetSettings; readonly ApplicationDbContext _dbContext; private readonly PackageManager _packageManager; private readonly IUnleash _unleashĈlient; public PackagesController( ILoggerFactory loggerFactory, IDataProtectionProvider provider, IOptions nugetOptions, IUnleash unleashĈlient, ApplicationDbContext dbContext) { _logger = loggerFactory.CreateLogger(); _nugetSettings = nugetOptions.Value; _protector = provider.CreateProtector(_nugetSettings.ProtectionTitle); _dbContext = dbContext; _packageManager = new PackageManager(dbContext); _unleashĈlient = unleashĈlient; _ressources = _packageManager.GetResources(_unleashĈlient).ToArray(); } // dotnet add . package -s http://localhost:5000/packages isn // packages/FindPackagesById()?id='isn'&semVerLevel=2.0.0 // Search // GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE} [HttpGet("~/index.json")] public IActionResult ApiIndex() { return Ok(_ressources); } [HttpGet(_pkgRootPrefix + "/index.json")] public IActionResult Index( string q, string semVerLevel, bool prerelease = false, string packageType = null, int skip = 0, int take = 25) { if (string.IsNullOrEmpty(q)) { ModelState.AddModelError("q", "no value"); } if (take > maxTake) { ModelState.AddModelError("take", "Maximum exceeded"); } if (semVerLevel != defaultSemVer) { _logger.LogWarning("Unexpected sementic version : "+semVerLevel); } if (ModelState.IsValid) { return Ok(_packageManager.SearchByName(q,skip,take,prerelease,packageType)); } return BadRequest(new { error = ModelState }); } // GET /autocomplete?id=nuget.protocol&prerelease=true [HttpGet(_pkgRootPrefix + "/autocomplete")] public IActionResult AutoComplete( string id, string semVerLevel, bool prerelease = false, string packageType = null, int skip = 0, int take = 25) { if (take > maxTake) { ModelState.AddModelError("take", "Maximum exceeded"); return BadRequest(ModelState); } if (semVerLevel != defaultSemVer) { ModelState.AddModelError("semVerLevel", defaultSemVer + " expected"); } return Ok(_packageManager.AutoComplete(id,skip,take,prerelease,packageType)); } // TODO GET {@id}/{LOWER_ID}/index.json // LOWER_ID URL string yes The package ID, lowercased // response : versions array of strings yes The versions available [HttpGet(_pkgRootPrefix + "/{id}/{lower}/index.json")] public IActionResult GetVersions( string id, string lower, bool prerelease = false, string packageType = null, int skip = 0, int take = 25) { if (take > maxTake) { ModelState.AddModelError("take", "Maximum exceeded"); } // NugetVersion if (!NuGetVersion.TryParse(lower, out NuGetVersion parsedVersion)) { ModelState.AddModelError("lower", "invalid version string"); } if (!ModelState.IsValid) { return BadRequest(ModelState); } return Ok(new { versions = _packageManager.GetVersions( id, parsedVersion, prerelease, packageType, skip, take) }); } // TODO GET GET {@id}/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.{LOWER_VERSION}.nupkg // LOWER_ID URL string yes The package ID, lowercase // LOWER_VERSION URL string yes The package version, normalized and lowercased // response 200 : the package [HttpGet(_pkgRootPrefix + "/{id}/{lower}/{idf}.{lowerf}.nupkg")] public IActionResult GetPackage( [FromRoute] string id, [FromRoute] string lower, [FromRoute] string idf, [FromRoute] string lowerf) { var pkgpath = Path.Combine(_nugetSettings.PackagesRootDir, id, lower, $"{idf}.{lowerf}.nupkg" ); FileInfo pkgfi = new FileInfo(pkgpath); return File(pkgfi.OpenRead(), "application/zip; charset=binary"); } // TODO GET {@id}/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.nuspec // response 200 : the nuspec [HttpGet(_pkgRootPrefix + "/{id}/{lower}/{idf}.{lowerf}.nuspec")] public IActionResult GetNuspec( [FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string lower, [FromRoute][SafeName][Required] string idf, [FromRoute][SafeName][Required] string lowerf) { var pkgpath = Path.Combine(_nugetSettings.PackagesRootDir, id, lower, $"{idf}.{lowerf}.nuspec"); FileInfo pkgfi = new FileInfo(pkgpath); return File(pkgfi.OpenRead(), "text/xml; charset=utf-8"); } } }