using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NuGet.Packaging; using NuGet.Packaging.Core; using nuget_host.Data; using nuget_host.Entities; using nuget_host.Helpers; namespace nuget_host.Controllers { [AllowAnonymous] public class PackagesController : Controller { private readonly ILogger logger; private readonly IDataProtector protector; private readonly NugetSettings nugetSettings; ApplicationDbContext dbContext; public PackagesController( ILoggerFactory loggerFactory, IDataProtectionProvider provider, IOptions nugetOptions, ApplicationDbContext dbContext) { logger = loggerFactory.CreateLogger(); nugetSettings = nugetOptions.Value; protector = provider.CreateProtector(nugetSettings.ProtectionTitle); this.dbContext = dbContext; } [HttpPut("packages")] public IActionResult Put() { string path = null; var clientVersionId = Request.Headers["X-NuGet-Client-Version"]; var apiKey = Request.Headers["X-NuGet-ApiKey"]; ViewData["clientVersionId"] = clientVersionId; var files = new List(); ViewData["files"] = files; var clearkey = protector.Unprotect(apiKey); var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey); if (apikey == null) return new BadRequestObjectResult(new { error = "api-key" }); foreach (var file in Request.Form.Files) { try { files.Add(file.Name); string initpath = file.Name; using (FileStream fw = new FileStream(initpath, FileMode.Create)) { file.CopyTo(fw); } using (FileStream fw = new FileStream(initpath, FileMode.Open)) { var archive = new System.IO.Compression.ZipArchive(fw); foreach (var entry in archive.Entries) { if (entry.FullName.EndsWith(".nuspec")) { // var entry = archive.GetEntry(filename); var specstr = entry.Open(); NuGet.Packaging.Core.NuspecCoreReader reader = new NuspecCoreReader(specstr); string pkgdesc = reader.GetDescription(); string pkgid = reader.GetId(); var version = reader.GetVersion(); path = Path.Combine(nugetSettings.PackagesRootDir, Path.Combine(pkgid, Path.Combine(version.Version.ToString()), $"{pkgid}-{version}.nupkg")); var source = new FileInfo(initpath); var dest = new FileInfo(path); var destdir = new DirectoryInfo(dest.DirectoryName); if (dest.Exists) return BadRequest(new { error = "existant" }); if (!destdir.Exists) destdir.Create(); source.MoveTo(path); logger.LogWarning($"200: {entry.Name}"); } } } } catch (Exception ex) { logger.LogError($"400: {file.Name}"); logger.LogError(ex.Message); return new BadRequestObjectResult(ViewData); } } return Ok(ViewData); } [HttpGet("packages/{spec}")] public IActionResult Index(string spec) { if (string.IsNullOrEmpty(spec)) { ViewData["warn"] = "no spec"; } else { ViewData["spec"] = spec; // TODO Assert valid sem ver spec var filelst = new DirectoryInfo(nugetSettings.PackagesRootDir); var fi = new FileInfo(spec); var lst = filelst.GetDirectories(spec); ViewData["lst"] = lst.Select(entry => entry.Name); } return Ok(ViewData); } [Authorize] [HttpGet("api/get-key/{*apikey}")] public IActionResult GetApiKey(string apiKey) { return Ok(protector.Protect(apiKey)); } } }