isn/src/isnd/Controllers/PackagesController.cs

217 lines
7.7 KiB
C#
Raw Normal View History

2021-06-22 23:03:38 +01:00
using System.ComponentModel.DataAnnotations;
2021-04-08 02:03:17 +01:00
using System.IO;
using System.Linq;
2021-04-08 03:08:20 +01:00
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection;
2021-04-08 02:03:17 +01:00
using Microsoft.AspNetCore.Mvc;
2021-06-21 23:38:05 +01:00
using Microsoft.EntityFrameworkCore;
2021-04-08 02:03:17 +01:00
using Microsoft.Extensions.Logging;
2021-05-02 15:22:46 +01:00
using Microsoft.Extensions.Options;
2021-06-22 01:25:28 +01:00
using NuGet.Versioning;
2021-08-15 19:09:01 +01:00
using isnd.Data;
using isnd.Entities;
2021-07-05 12:55:52 +01:00
using Unleash;
using isnd.Services;
2021-08-15 19:09:01 +01:00
using isnd.ViewModels;
using System.Threading.Tasks;
2021-08-23 03:21:08 +01:00
using isnd.Interfaces;
2021-04-08 02:03:17 +01:00
2021-08-15 19:09:01 +01:00
namespace isnd.Controllers
2021-04-08 02:03:17 +01:00
{
2021-05-09 03:06:23 +01:00
[AllowAnonymous]
2021-06-21 23:38:05 +01:00
public partial class PackagesController : Controller
2021-04-08 02:03:17 +01:00
{
2021-07-05 12:55:52 +01:00
const int maxTake = 100;
const string defaultSemVer = "2.0.0";
2021-07-12 03:23:11 +01:00
private readonly Resource[] _ressources;
private readonly ILogger<PackagesController> _logger;
private readonly IDataProtector _protector;
2021-04-08 02:03:17 +01:00
2021-08-15 01:50:07 +01:00
private readonly IsndSettings _isndSettings;
2021-07-12 03:23:11 +01:00
readonly ApplicationDbContext _dbContext;
2021-08-23 03:21:08 +01:00
private readonly IPackageManager _packageManager;
2021-07-11 18:08:49 +01:00
private readonly IUnleash _unleashĈlient;
2021-05-02 15:22:46 +01:00
public PackagesController(
ILoggerFactory loggerFactory,
IDataProtectionProvider provider,
2021-08-15 01:50:07 +01:00
IOptions<IsndSettings> isndOptions,
2021-07-11 22:13:48 +01:00
IUnleash unleashĈlient,
2021-08-23 03:21:08 +01:00
ApplicationDbContext dbContext,
IPackageManager pm)
2021-04-08 02:03:17 +01:00
{
2021-07-12 03:23:11 +01:00
_logger = loggerFactory.CreateLogger<PackagesController>();
2021-08-15 01:50:07 +01:00
_isndSettings = isndOptions.Value;
_protector = provider.CreateProtector(_isndSettings.ProtectionTitle);
2021-07-12 03:23:11 +01:00
_dbContext = dbContext;
2021-08-23 03:21:08 +01:00
_packageManager = pm;
2021-07-11 22:13:48 +01:00
_unleashĈlient = unleashĈlient;
2021-07-12 03:23:11 +01:00
_ressources = _packageManager.GetResources(_unleashĈlient).ToArray();
2021-04-08 02:03:17 +01:00
}
2021-07-05 12:55:52 +01:00
// dotnet add . package -s http://localhost:5000/packages isn
// packages/FindPackagesById()?id='isn'&semVerLevel=2.0.0
2021-06-21 23:38:05 +01:00
// Search
// GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
2021-06-22 23:03:38 +01:00
2021-08-15 19:09:01 +01:00
// GET: PackageVersion
public async Task<IActionResult> Index(PackageIndexViewModel model)
{
var applicationDbContext = _dbContext.Packages.Include(p => p.Versions).Where(
p => ( model.Prerelease || p.Versions.Any(v => !v.IsPrerelease))
&& ((model.query == null) || p.Id.StartsWith(model.query)));
model.data = await applicationDbContext.ToArrayAsync();
return View(model);
}
// GET: PackageVersion/Details/5
public async Task<IActionResult> Details(string pkgid)
{
if (pkgid == null)
{
return NotFound();
}
var packageVersion = _dbContext.PackageVersions
.Include(p => p.Package)
.Where(m => m.PackageId == pkgid)
.OrderByDescending(p => p)
;
if (packageVersion == null)
{
return NotFound();
}
bool results = await packageVersion.AnyAsync();
var latest = await packageVersion.FirstAsync();
return View("Details", new PackageDetailViewModel { latest = latest, pkgid = pkgid, totalHits = packageVersion.Count(), data = packageVersion.Take(10).ToArray() } );
}
2021-09-04 13:41:00 +01:00
const string _pkgRootPrefix = "~/" + ApiConfig.BaseApiPath ;
2021-08-15 19:09:01 +01:00
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.Base)]
2021-06-22 23:03:38 +01:00
public IActionResult ApiIndex()
{
2021-07-12 03:23:11 +01:00
return Ok(_ressources);
2021-06-22 23:03:38 +01:00
}
2021-08-23 03:21:08 +01:00
//
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.Catalog)]
public IActionResult CatalogIndex()
2021-04-08 02:03:17 +01:00
{
2021-08-29 00:08:34 +01:00
// https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning
2021-08-23 03:21:08 +01:00
return Ok(PackageManager.CurrentCatalogIndex);
2021-04-08 02:03:17 +01:00
}
2021-08-29 00:08:34 +01:00
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.Catalog + "-{id}")]
2021-08-29 00:08:34 +01:00
public IActionResult Index(string id)
{
// https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning
return Ok(PackageManager.CurrentCatalogPages[int.Parse(id)]);
}
2021-04-08 03:08:20 +01:00
2021-08-13 18:55:25 +01:00
// GET /autocomplete?id=isn.protocol&prerelease=true
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.AutoComplete)]
2021-06-22 00:10:01 +01:00
public IActionResult AutoComplete(
string id,
2021-07-11 18:08:49 +01:00
string semVerLevel,
2021-06-22 00:10:01 +01:00
bool prerelease = false,
string packageType = null,
int skip = 0,
int take = 25)
{
2021-06-22 01:25:28 +01:00
if (take > maxTake)
{
ModelState.AddModelError("take", "Maximum exceeded");
return BadRequest(ModelState);
}
2021-07-11 18:08:49 +01:00
if (semVerLevel != defaultSemVer)
{
ModelState.AddModelError("semVerLevel", defaultSemVer + " expected");
}
2021-07-05 12:55:52 +01:00
2021-07-12 03:23:11 +01:00
return Ok(_packageManager.AutoComplete(id,skip,take,prerelease,packageType));
2021-06-22 01:25:28 +01:00
}
// 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
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.Get + "/{id}/{lower}/index.json")]
2021-06-22 01:25:28 +01:00
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);
}
2021-06-22 00:10:01 +01:00
return Ok(new
{
2021-07-12 03:23:11 +01:00
versions = _packageManager.GetVersions(
2021-07-05 12:55:52 +01:00
id, parsedVersion, prerelease, packageType, skip, take)
2021-06-22 00:10:01 +01:00
});
}
2021-06-22 01:25:28 +01:00
// 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
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.Get + "/{id}/{lower}/{idf}-{lowerf}.nupkg")]
2021-06-22 23:03:38 +01:00
public IActionResult GetPackage(
[FromRoute] string id, [FromRoute] string lower,
[FromRoute] string idf, [FromRoute] string lowerf)
{
2021-08-15 01:50:07 +01:00
var pkgpath = Path.Combine(_isndSettings.PackagesRootDir,
2021-08-12 01:04:39 +01:00
id, lower, $"{id}-{lower}.nupkg"
2021-06-22 23:03:38 +01:00
);
FileInfo pkgfi = new FileInfo(pkgpath);
2021-08-12 00:38:16 +01:00
if (!pkgfi.Exists)
{
return BadRequest("!pkgfi.Exists");
}
2021-06-22 23:03:38 +01:00
return File(pkgfi.OpenRead(), "application/zip; charset=binary");
}
2021-06-22 01:25:28 +01:00
// TODO GET {@id}/{LOWER_ID}/{LOWER_VERSION}/{LOWER_ID}.nuspec
// response 200 : the nuspec
2021-09-02 23:37:28 +01:00
[HttpGet(_pkgRootPrefix + ApiConfig.Get + "/{id}/{lower}/{idf}-{lowerf}.nuspec")]
2021-06-22 23:03:38 +01:00
public IActionResult GetNuspec(
[FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower,
[FromRoute][SafeName][Required] string idf,
[FromRoute][SafeName][Required] string lowerf)
{
2021-08-15 01:50:07 +01:00
var pkgpath = Path.Combine(_isndSettings.PackagesRootDir,
2021-08-12 01:04:39 +01:00
id, lower, $"{id}.nuspec");
2021-06-22 00:10:01 +01:00
2021-06-22 23:03:38 +01:00
FileInfo pkgfi = new FileInfo(pkgpath);
2021-08-12 00:38:16 +01:00
if (!pkgfi.Exists)
{
return BadRequest("!pkgfi.Exists");
}
2021-06-22 23:03:38 +01:00
return File(pkgfi.OpenRead(), "text/xml; charset=utf-8");
}
2021-04-08 02:03:17 +01:00
}
}