WIP reg page

broken/ef
Paul Schneider 2 years ago
parent 14206ac477
commit fececb327e
36 changed files with 264 additions and 211 deletions

@ -5,7 +5,8 @@ namespace isnd.Entities
public static class ApiConfig public static class ApiConfig
{ {
public const string Publish = "put"; public const string Publish = "put";
public const string Base = "index.json"; public const string Index = "index";
public const string IndexDotJson = Index + ".json";
public const string Catalog = "catalog"; public const string Catalog = "catalog";
public const string CatalogPage = "catalog-page"; public const string CatalogPage = "catalog-page";
public const string GetPackage = Constants.PaquetFileEstension; public const string GetPackage = Constants.PaquetFileEstension;

@ -4,5 +4,6 @@ namespace isn.abst
{ {
public const string PaquetFileEstension = "nupkg"; public const string PaquetFileEstension = "nupkg";
public const string SpecFileEstension = "nuspec"; public const string SpecFileEstension = "nuspec";
public const string JsonFileEstension = "json";
} }
} }

@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<PackageVersion>1.0.1</PackageVersion> <PackageVersion>1.0.1</PackageVersion>
<Version>0.1.175</Version> <Version>1.0.5</Version>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
<NoWarn>NETSDK1138</NoWarn> <NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>0.1.175.0</AssemblyVersion> <AssemblyVersion>1.0.5.0</AssemblyVersion>
<FileVersion>0.1.175.0</FileVersion> <FileVersion>1.0.5.0</FileVersion>
<InformationalVersion>0.1.175+Branch.main.Sha.3e09afcbfe0eff74c0b3aa0fb974e0801f4708b6</InformationalVersion> <InformationalVersion>1.0.5+Branch.main.Sha.14206ac477d0f07566d5e8125dc52cbd7f474ca2</InformationalVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.1" />

@ -23,37 +23,5 @@ namespace isn
return result; return result;
} }
public static async Task<ApiIndexViewModel> GetServerResourcesUsingWebRequestAsync(string url)
{
ApiIndexViewModel viewModel=null;
var uri = new Uri(url);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "GET";
httpWebRequest.AllowAutoRedirect = false;
try{
using (var resp = await httpWebRequest.GetResponseAsync())
{
using (var stream = resp.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
var json = await reader.ReadToEndAsync();
Console.Write("got json : "+json);
viewModel = JsonConvert.DeserializeObject<ApiIndexViewModel>(json);
}
}
}
}
catch(Exception ex)
{
Console.Error.WriteLine(ex.Message);
}
return viewModel;
}
} }
} }

@ -4,23 +4,23 @@
<TargetFrameworks>netcoreapp2.1</TargetFrameworks> <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<RootNamespace>nuget_cli</RootNamespace> <RootNamespace>nuget_cli</RootNamespace>
<UserSecretsId>45b74c62-05bc-4603-95b4-3e80ae2fdf50</UserSecretsId> <UserSecretsId>45b74c62-05bc-4603-95b4-3e80ae2fdf50</UserSecretsId>
<Version>0.1.175</Version> <Version>1.0.5</Version>
<PackageVersion>1.0.1</PackageVersion> <PackageVersion>1.0.1</PackageVersion>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<PackageLicenseExpression>WTFPL</PackageLicenseExpression> <PackageLicenseExpression>WTFPL</PackageLicenseExpression>
<IsTool>true</IsTool> <IsTool>true</IsTool>
<NoWarn>NETSDK1138</NoWarn> <NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>0.1.175.0</AssemblyVersion> <AssemblyVersion>1.0.5.0</AssemblyVersion>
<FileVersion>0.1.175.0</FileVersion> <FileVersion>1.0.5.0</FileVersion>
<InformationalVersion>0.1.175+Branch.main.Sha.3e09afcbfe0eff74c0b3aa0fb974e0801f4708b6</InformationalVersion> <InformationalVersion>1.0.5+Branch.main.Sha.14206ac477d0f07566d5e8125dc52cbd7f474ca2</InformationalVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Mono.Options" Version="5.3.0" /> <PackageReference Include="Mono.Options" Version="5.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="unleash.client" Version="1.6.1" /> <PackageReference Include="unleash.client" Version="1.6.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="microsoft.codeanalysis.analyzers" Version="1.1.0" /> <PackageReference Include="microsoft.codeanalysis.analyzers" Version="1.1.0" />
<Reference Include="System.Net.Http" Version="4.0.0" /> <Reference Include="System.Net.Http" Version="4.0.0" />
<PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="../isn.abst/isn.abst.csproj" /> <ProjectReference Include="../isn.abst/isn.abst.csproj" />

@ -27,7 +27,10 @@ namespace isnd
// GET: PackageVersion // GET: PackageVersion
public async Task<IActionResult> Index(PackageVersionIndexViewModel model) public async Task<IActionResult> Index(PackageVersionIndexViewModel model)
{ {
var applicationDbContext = _context.PackageVersions.Include(p => p.Package).Where( var applicationDbContext = _context.PackageVersions.Include(p => p.Package)
.Include(p => p.Package.Owner)
.Include(p => p.Package.Versions)
.Where(
p => (model.Prerelease || !p.IsPrerelease) p => (model.Prerelease || !p.IsPrerelease)
&& ((model.PackageId == null) || p.PackageId.StartsWith(model.PackageId))); && ((model.PackageId == null) || p.PackageId.StartsWith(model.PackageId)));
model.Versions = await applicationDbContext.ToArrayAsync(); model.Versions = await applicationDbContext.ToArrayAsync();

@ -16,12 +16,13 @@ using isnd.ViewModels;
using System.Threading.Tasks; using System.Threading.Tasks;
using isnd.Interfaces; using isnd.Interfaces;
using isn.Abstract; using isn.Abstract;
using isn.abst;
namespace isnd.Controllers namespace isnd.Controllers
{ {
public partial class PackagesController : Controller public partial class PackagesController : Controller
{ {
[HttpGet(_pkgRootPrefix + ApiConfig.Base)] [HttpGet(_pkgRootPrefix + ApiConfig.IndexDotJson)]
public IActionResult ApiIndex() public IActionResult ApiIndex()
{ {
return Ok(new ApiIndexViewModel{ Version = PackageManager.BASE_API_LEVEL, Resources = resources }); return Ok(new ApiIndexViewModel{ Version = PackageManager.BASE_API_LEVEL, Resources = resources });

@ -1,18 +1,15 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using isnd.Helpers;
using isnd.Services; using isnd.Services;
using isnd.Entities; using isnd.Entities;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic; using System.Collections.Generic;
using NuGet.Versioning;
namespace isnd.Controllers namespace isnd.Controllers
{ {
public partial class PackagesController public partial class PackagesController
{ {
// https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning // https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning
[HttpGet(_pkgRootPrefix + ApiConfig.Catalog)] [HttpGet(_pkgRootPrefix + ApiConfig.Catalog)]
public IActionResult CatalogIndex() public IActionResult CatalogIndex()
@ -27,40 +24,46 @@ namespace isnd.Controllers
return Ok(PackageManager.CurrentCatalogPages[int.Parse(id)]); return Ok(PackageManager.CurrentCatalogPages[int.Parse(id)]);
} }
[HttpGet(_pkgRootPrefix + "{apiVersion}/" + ApiConfig.Registration + "/{id}/{*lower}")] [HttpGet(_pkgRootPrefix + "{apiVersion}/" + ApiConfig.Registration
+ "/{id}/index.json")]
public async Task<IActionResult> CatalogRegistrationAsync(string apiVersion, string id, string lower) public async Task<IActionResult> CatalogRegistrationAsync(string apiVersion, string id, string lower)
{ {
bool askForindex = lower != null && lower.EndsWith(ApiConfig.Base); bool askForindex = lower == null;
if (askForindex) if (askForindex)
{ {
lower = lower.Substring(0, lower.Length - ApiConfig.Base.Length); string sublower = lower.Substring(0, lower.Length - ApiConfig.IndexDotJson.Length);
var pkgFromname = packageManager.SearchByName(id, 0, 1);
if (pkgFromname == null) return NotFound();
foreach (var item in pkgFromname.Items)
{
item.Id = this.Url.Action();
}
return Ok(pkgFromname);
} }
string pkgType = ParamHelpers.Optional(ref lower); else
var pkgFromname = packageManager.SearchByName(id, 0, 1); {
if (pkgFromname == null) return NotFound(); if (!NuGetVersion.TryParse(lower, out NuGetVersion version))
return Ok(pkgFromname); return BadRequest(lower);
}
var pkgFromname = packageManager.GetVersions(id, version, true);
if (pkgFromname == null) return NotFound();
return Ok(pkgFromname);
}
}
[HttpGet(_pkgRootPrefix + ApiConfig.CatalogLeaf + "/{id}/{version}/{*lower}")] [HttpGet(_pkgRootPrefix + ApiConfig.CatalogLeaf + "/{id}/{version}/{lower}/index.json")]
public async Task<IActionResult> CatalogLeafAsync(string id, string version, string lower) public async Task<IActionResult> CatalogLeafAsync(string id, string version, string lower)
{ {
var pkgvs = this.packageManager.GetCatalogLeaf(id, version, lower) var pkgvs = this.packageManager.GetCatalogLeaf(id, version, lower).ToArray();
.ToArray();
if (pkgvs.Count() == 0) return NotFound(); if (pkgvs.Count() == 0) return NotFound();
List<string> types = pkgvs.Select(
List<string> types = pkgvs
.Select(
v => v.Type ?? "Dependency" v => v.Type ?? "Dependency"
) ).Distinct().ToList();
.Distinct().ToList();
if (!types.Contains("PackageDelete")) if (!types.Contains("PackageDelete"))
types.Add("PackageDetails"); types.Add("PackageDetails");
var last = pkgvs.Last(); var last = pkgvs.Last();
var pub = last.LatestCommit.CommitTimeStamp; var pub = last.LatestCommit.CommitTimeStamp;
return Ok(new Data.Packages.Catalog.CatalogLeaf return Ok(new Data.Packages.Catalog.CatalogLeaf
{ {
CommitId = last.CommitId, CommitId = last.CommitId,
@ -68,10 +71,8 @@ namespace isnd.Controllers
CommitTimeStamp = pub, CommitTimeStamp = pub,
Version = last.FullString, Version = last.FullString,
Published = pub, Published = pub,
RefType = types.ToArray(), RefType = types.ToArray()
}); });
} }
} }
} }

@ -4,17 +4,20 @@ using isnd.Helpers;
using isnd.Entities; using isnd.Entities;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using isnd.Attributes; using isnd.Attributes;
using System.Security.Claims;
namespace isnd.Controllers namespace isnd.Controllers
{ {
public partial class PackagesController public partial class PackagesController
{ {
[HttpDelete(_pkgRootPrefix + ApiConfig.Delete + "/{id}/{*lower}")] [HttpDelete(_pkgRootPrefix + ApiConfig.Delete + "/{id}/{lower?}/{type?}")]
public async Task<IActionResult> Delete( public async Task<IActionResult> ApiDelete(
[FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower) [FromRoute][SafeName][Required] string lower,
[FromRoute] string type)
{ {
string pkgtype = ParamHelpers.Optional(ref lower); var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
var report = await packageManager.DeletePackageAsync(id, lower, pkgtype); var report = await packageManager.UserAskForPackageDeletionAsync(uid, id, lower, type);
return Ok(report); return Ok(report);
} }
} }

@ -1,12 +1,13 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NuGet.Versioning; using NuGet.Versioning;
using isnd.Entities; using isnd.Entities;
using isn.abst;
namespace isnd.Controllers namespace isnd.Controllers
{ {
public partial class PackagesController public partial class PackagesController
{ {
[HttpGet(_pkgRootPrefix + ApiConfig.GetVersion + "/{id}/{lower}/" + ApiConfig.Base)] [HttpGet(_pkgRootPrefix + ApiConfig.GetVersion + "/{id}/{lower}/" + ApiConfig.IndexDotJson)]
public IActionResult GetVersions( public IActionResult GetVersions(
string id, string id,
string lower, string lower,

@ -15,15 +15,9 @@ namespace isnd.Controllers
public partial class PackagesController public partial class PackagesController
{ {
// Web search // Web search
public async Task<IActionResult> Index(PackageRegistrationIndexViewModel model) public async Task<IActionResult> Index(PackageRegistrationIndexQuery model)
{ {
var applicationDbContext = dbContext.Packages.Include(p => p.Versions) return View(packageManager.GetCatalogIndex());
.Include(p => p.Owner)
.Where(
p => (model.Prerelease || p.Versions.Any(v => !v.IsPrerelease))
&& ((model.Query == null) || p.Id.StartsWith(model.Query)));
model.Data = await applicationDbContext.Select(p => p.ToLeave()).ToArrayAsync();
return View(model);
} }
public async Task<IActionResult> Details(string pkgid) public async Task<IActionResult> Details(string pkgid)
@ -64,6 +58,7 @@ namespace isnd.Controllers
{ {
return NotFound(); return NotFound();
} }
// var report = await packageManager.DeletePackageAsync(id, lower, type);
var packageVersion = await dbContext.PackageVersions.Include(p => p.Package) var packageVersion = await dbContext.PackageVersions.Include(p => p.Package)
.FirstOrDefaultAsync(m => m.PackageId == pkgid .FirstOrDefaultAsync(m => m.PackageId == pkgid

@ -9,7 +9,7 @@ namespace isnd.Data.Catalog
/// The URL to the document used to produce this object /// The URL to the document used to produce this object
/// </summary> /// </summary>
/// <value></value> /// <value></value>
[Key][Required] [Key][Required,JsonRequired]
[StringLength(1024)] [StringLength(1024)]
[JsonProperty("@id")] [JsonProperty("@id")]
public string Id { get; set; } public string Id { get; set; }
@ -70,7 +70,7 @@ namespace isnd.Data.Catalog
/// The full version string after normalization /// The full version string after normalization
/// </summary> /// </summary>
/// <value></value> /// <value></value>
[Required] [Required,JsonRequired]
public string version { get; set; } // string yes public string version { get; set; } // string yes
/// <summary> /// <summary>
/// The security vulnerabilities of the package /// The security vulnerabilities of the package

@ -2,14 +2,11 @@ using Newtonsoft.Json;
namespace isnd.Data.Catalog namespace isnd.Data.Catalog
{ {
public class PackageRegistrationIndexViewModel public class PackageRegistrationIndexQuery : RegistrationPageIndex
{ {
[JsonProperty("prerelease")] [JsonProperty("prerelease")]
public bool Prerelease { get; set; } public bool Prerelease { get; set; }
[JsonProperty("data")]
public RegistrationLeaf[] Data {get; set;}
[JsonProperty("query")] [JsonProperty("query")]
public string Query { get; set; } public string Query { get; set; }

@ -25,6 +25,7 @@ namespace isnd.Data.Catalog
[JsonProperty("commitTimeStamp")] [JsonProperty("commitTimeStamp")]
public DateTime CommitTimeStamp { get; set; } public DateTime CommitTimeStamp { get; set; }
} }

@ -0,0 +1,51 @@
using System;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class RegistrationPage
{
/// <summary>
/// The URL to the registration page
/// </summary>
/// <value></value>
[JsonProperty("@id"), JsonRequired]
public string Id { get; set; }
/// <summary>
/// The number of registration leaves in the page
/// </summary>
/// <value></value>
[JsonProperty("count"), JsonRequired]
public int Count { get; set; }
/// <summary>
/// no The array of registration leaves and their associate metadata
/// </summary>
/// <value></value>
[JsonProperty("items")]
public RegistrationLeaf[] Items { get; set; }
/// <summary>
/// The highest SemVer 2.0.0 version in the page (inclusive)
/// </summary>
/// <value></value>
[JsonProperty("upper"), JsonRequired]
public Version Upper { get; set; }
/// <summary>
/// The lowest SemVer 2.0.0 version in the page (inclusive)
/// </summary>
/// <value></value>
[JsonProperty("lower"), JsonRequired]
public Version Lower { get; set; }
/// <summary>
/// The URL to the registration index
/// </summary>
/// <value></value>
[JsonProperty("parent")]
public string Parent { get; set; }
}
}

@ -0,0 +1,13 @@
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class RegistrationPageIndex
{
[JsonProperty("count")]
public int Count { get => Items?.Length ?? 0; }
[JsonProperty("items")]
public RegistrationPage[] Items { get; set; }
}
}

@ -1,34 +0,0 @@
using System;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class RegistrationPage
{
/*
@id string yes The URL to the registration page
count integer yes The number of registration leaves in the page
items array of objects no The array of registration leaves and their associate metadata
lower string yes The lowest SemVer 2.0.0 version in the page (inclusive)
parent string no The URL to the registration index
upper string yes The highest SemVer 2.0.0 version in the page (inclusive) */
[JsonProperty("@id")]
public string Id { get; set; }
[JsonProperty("count")]
public int Count { get; set; }
[JsonProperty("items")]
public RegistrationLeaf[] Items { get; set; }
[JsonProperty("upper")]
public Version Upper { get; set; }
[JsonProperty("lower")]
public Version Lower { get; set; }
[JsonProperty("parent")]
public string Parent { get; set; }
}
}

@ -46,17 +46,22 @@ namespace isnd.Data.Packages
public virtual Commit LatestVersion{ get; set; } public virtual Commit LatestVersion{ get; set; }
public DateTime CommitTimeStamp { get; set; } public DateTime CommitTimeStamp { get; set; }
/// <summary>
internal RegistrationLeaf ToLeave() /// Returns the leaf
/// </summary>
/// <param name="bid">base url tu use for building the id property</param>
/// <returns></returns>
internal RegistrationLeaf ToLeave(string bid)
{ {
if (!(Versions != null && if (Versions.Count == 0) throw new Exception("NO VERSION");
Versions.Count > 0)) throw new Exception("NO VERSION");
var v = Versions.First(); var v = Versions.First();
RegistrationLeaf leave = new RegistrationLeaf RegistrationLeaf leave = new RegistrationLeaf
{ {
Id = bid + Id + ".json",
PackageContent = v.NugetLink, PackageContent = v.NugetLink,
Entry = new CatalogEntry Entry = new CatalogEntry
{ {
Id = bid + Id + ".json",
idp = Id, idp = Id,
version = v.FullString, version = v.FullString,
authors = $"{Owner.FullName} <${Owner.Email}>" authors = $"{Owner.FullName} <${Owner.Email}>"

@ -43,7 +43,7 @@ namespace isnd.Data
public string CommitId { get => CommitNId.ToString(); } public string CommitId { get => CommitNId.ToString(); }
public virtual Commit LatestCommit{ get; set; } public virtual Commit LatestCommit {get; set; }
public string NugetLink => $"/{Constants.PaquetFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}." public string NugetLink => $"/{Constants.PaquetFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}."
+ Constants.PaquetFileEstension; + Constants.PaquetFileEstension;
public string NuspecLink => $"/{Constants.SpecFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}." public string NuspecLink => $"/{Constants.SpecFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}."

@ -1,15 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using isn.abst;
using isnd.Data; using isnd.Data;
using isnd.Data.Catalog;
using isnd.Entities;
namespace isnd.Helpers namespace isnd.Helpers
{ {
public static class PackageVersionHelpers public static class PackageVersionHelpers
{ {
public static bool IsOwner(this ClaimsPrincipal user, PackageVersion v) public static bool IsOwner(this ClaimsPrincipal user, PackageVersion v)
{ {
var userId = user.FindFirstValue(ClaimTypes.NameIdentifier); var userId = user.FindFirstValue(ClaimTypes.NameIdentifier);
return v.Package.OwnerId == userId; return v.Package.OwnerId == userId;
} }
public static RegistrationPage[] CreateRegistrationPages(this IEnumerable<RegistrationLeaf> leaves,
string bid)
{
List<RegistrationPage> pages = new List<RegistrationPage>();
var ids = leaves.Select(l => l.Entry.Id).Distinct().ToArray();
foreach (var id in ids)
{
var lbi = leaves.Where(l=>l.Entry.Id == id).OrderBy(l=>
new Version(l.Entry.version));
var latest = new Version(lbi.Last().Entry.version);
pages.Add(new RegistrationPage
{
Id = bid + id + "/" + latest.Major + "."
+ latest.Minor + "."
+ latest.Build,
Count = lbi.Count(),
Lower = new Version(lbi.First().Entry.version),
Upper = latest,
Items = lbi.ToArray(),
Parent = bid + id + "/" + ApiConfig.IndexDotJson,
});
}
return pages.ToArray();
}
} }
} }

@ -10,7 +10,7 @@ namespace isnd.Helpers
{ {
public static class UnleashHelpers public static class UnleashHelpers
{ {
public static IUnleash CreateUnleahClient(this IHostingEnvironment env, public static IUnleash CreateUnleahClient(this IHostingEnvironment env,
UnleashClientSettings unleashClientSettings) UnleashClientSettings unleashClientSettings)
{ {

@ -15,14 +15,16 @@ namespace isnd.Interfaces
{ {
public interface IPackageManager public interface IPackageManager
{ {
string CatalogBaseUrl { get; }
AutoCompleteResult AutoComplete(string pkgid, int skip, int take, bool prerelease = false, string packageType = null); AutoCompleteResult AutoComplete(string pkgid, int skip, int take, bool prerelease = false, string packageType = null);
CatalogIndex GetCatalogIndex(); CatalogIndex GetCatalogIndex();
string[] GetVersions(string pkgid, NuGetVersion parsedVersion, bool prerelease = false, string packageType = null, int skip = 0, int take = 25); string[] GetVersions(string pkgid, NuGetVersion parsedVersion, bool prerelease = false, string packageType = null, int skip = 0, int take = 25);
PackageRegistrationIndexViewModel SearchByName(string query, int skip, int take, bool prerelease = false, string packageType = null); RegistrationPageIndex SearchByName(string query, int skip, int take, bool prerelease = false, string packageType = null);
IEnumerable<Resource> GetResources(IUnleash unleashĈlient); IEnumerable<Resource> GetResources(IUnleash unleashĈlient);
void ÛpdateCatalogFor(Commit commit); void ÛpdateCatalogFor(Commit commit);
Task<PackageDeletionReport> DeletePackageAsync(string pkgid, string version, string type); Task<PackageDeletionReport> DeletePackageAsync(string pkgid, string version, string type);
Task<PackageDeletionReport> UserAskForPackageDeletionAsync(string uid, string id, string lower, string type);
Task<PackageVersion> GetPackageAsync(string pkgid, string version, string type); Task<PackageVersion> GetPackageAsync(string pkgid, string version, string type);
IEnumerable<PackageVersion> GetCatalogLeaf(string id, string version, string lower); IEnumerable<PackageVersion> GetCatalogLeaf(string id, string version, string lower);
} }

@ -3,7 +3,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using MailKit.Net.Smtp; using MailKit.Net.Smtp;
using MimeKit; using MimeKit;
@ -16,13 +15,13 @@ namespace isnd.Services
public class EmailSender : IEmailSender, IMailer public class EmailSender : IEmailSender, IMailer
{ {
public EmailSender(IOptions<SmtpSettings> smtpSettings, public EmailSender(IOptions<SmtpSettings> smtpSettings,
Microsoft.AspNetCore.Hosting.IHostingEnvironment env) IHostingEnvironment env)
{ {
Options = smtpSettings.Value; Options = smtpSettings.Value;
Env = env; Env = env;
} }
public SmtpSettings Options { get; } //set only via Secret Manager public SmtpSettings Options { get; } //set only via Secret Manager
public Microsoft.AspNetCore.Hosting.IHostingEnvironment Env { get; } public IHostingEnvironment Env { get; }
public Task SendEmailAsync(string email, string subject, string message) public Task SendEmailAsync(string email, string subject, string message)
{ {
return Execute(Options.SenderName, subject, message, email); return Execute(Options.SenderName, subject, message, email);

@ -4,7 +4,6 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using isn.Abstract; using isn.Abstract;
using isnd.Controllers;
using isnd.Data; using isnd.Data;
using isnd.Data.Catalog; using isnd.Data.Catalog;
using isnd.Data.Packages; using isnd.Data.Packages;
@ -119,16 +118,17 @@ namespace isnd.Services
Type = "RegistrationsBaseUrl/3.6.0", Type = "RegistrationsBaseUrl/3.6.0",
Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages." Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
}); });
return res; return res;
} }
public PackageRegistrationIndexViewModel SearchByName(string query, public RegistrationPageIndex SearchByName(string query,
int skip, int take, bool prerelease = false, int skip, int take, bool prerelease = false,
string packageType = null) string packageType = null)
{ {
var scope = dbContext.Packages var scope = dbContext.Packages
.Include(p=>p.Versions) .Include(p => p.Versions)
.Include(p => p.Owner) .Include(p => p.Owner)
.Where( .Where(
p => (PackageIdHelpers.CamelCaseMatch(p.Id, query) || PackageIdHelpers.SeparatedByMinusMatch(p.Id, query)) p => (PackageIdHelpers.CamelCaseMatch(p.Id, query) || PackageIdHelpers.SeparatedByMinusMatch(p.Id, query))
@ -137,12 +137,11 @@ namespace isnd.Services
); );
var total = scope.Count(); var total = scope.Count();
var pkgs = scope.Skip(skip).Take(take).ToArray(); var pkgs = scope.Skip(skip).Take(take).ToArray();
string bid = $"{extUrl}v3.4.0/{ApiConfig.Registration}/";
return new PackageRegistrationIndexViewModel var leaves = pkgs.Select(p => p.ToLeave(bid));
return new RegistrationPageIndex
{ {
Query = query, Items = leaves.CreateRegistrationPages(bid)
TotalHits = total,
Data = pkgs.Select(p => p.ToLeave()).ToArray()
}; };
} }
@ -187,6 +186,9 @@ namespace isnd.Services
public static CatalogIndex CurrentCatalogIndex { get; protected set; } public static CatalogIndex CurrentCatalogIndex { get; protected set; }
public static List<Page> CurrentCatalogPages { get; protected set; } public static List<Page> CurrentCatalogPages { get; protected set; }
public string CatalogBaseUrl => extUrl;
private IsndSettings isndSettings; private IsndSettings isndSettings;
private string extUrl; private string extUrl;
@ -320,7 +322,7 @@ namespace isnd.Services
v.Type == type v.Type == type
); );
} }
public IEnumerable<PackageVersion> GetCatalogLeaf(string id, string version, string lower) public IEnumerable<PackageVersion> GetCatalogLeaf(string id, string version, string lower)
{ {
return dbContext.PackageVersions return dbContext.PackageVersions
@ -329,5 +331,18 @@ namespace isnd.Services
.Where(v => v.PackageId == id && v.FullString == version .Where(v => v.PackageId == id && v.FullString == version
&& (lower == null || lower == v.Type)); && (lower == null || lower == v.Type));
} }
public async Task<PackageDeletionReport> UserAskForPackageDeletionAsync(string uid, string id, string lower, string type)
{
PackageVersion packageVersion = await dbContext.PackageVersions
.Include(pv => pv.Package)
.FirstOrDefaultAsync(m => m.PackageId == id
&& m.FullString == lower && m.Type == type);
if (packageVersion == null) return null;
if (packageVersion.Package.OwnerId != uid) return null;
return new PackageDeletionReport { Deleted = true, DeletedVersion = packageVersion };
}
} }
} }

@ -1,11 +1,8 @@
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Hosting;
using isnd.Data; using isnd.Data;
using isnd.Interfaces; using isnd.Interfaces;
using isnd.Services; using isnd.Services;
@ -17,8 +14,8 @@ using Unleash;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using isnd.Helpers; using isnd.Helpers;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Microsoft.AspNetCore.HttpOverrides; using Microsoft.Extensions.Configuration;
using System.Net; using Microsoft.Extensions.DependencyInjection;
namespace isnd namespace isnd
{ {
@ -86,7 +83,7 @@ namespace isnd
throw new System.Exception("No unleash client ApiUrl"); throw new System.Exception("No unleash client ApiUrl");
if (config.Value.ClientApiKey==null) if (config.Value.ClientApiKey==null)
throw new System.Exception("No unleash client ClientApiKey"); throw new System.Exception("No unleash client ClientApiKey");
return s.GetRequiredService<Microsoft.AspNetCore.Hosting.IHostingEnvironment>().CreateUnleahClient(config.Value); return s.GetRequiredService<IHostingEnvironment>().CreateUnleahClient(config.Value);
}); });
services.AddAuthentication("Bearer") services.AddAuthentication("Bearer")
@ -106,25 +103,27 @@ namespace isnd
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, public void Configure(IApplicationBuilder app,
Microsoft.AspNetCore.Hosting.IHostingEnvironment env, IHostingEnvironment env,
ApplicationDbContext dbContext) ApplicationDbContext dbContext)
{ {
app.UseForwardedHeaders(); // app.UseForwardedHeaders();
// Not using Apache cert : // app.UseDeveloperExceptionPage();
// app.UseHttpsRedirection(); // app.UseHttpsRedirection();
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint(); app.UseMigrationsEndPoint();
app.UseBrowserLink();
} }
else else
{ {
app.UseExceptionHandler("/Home/Error"); app.UseExceptionHandler("/Home/Error");
dbContext.Database.Migrate(); dbContext.Database.Migrate();
} }
app
_ = app
.UseStaticFiles() .UseStaticFiles()
.UseAuthentication() .UseAuthentication()
.UseMvc(routes => .UseMvc(routes =>

@ -1,7 +1,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace isnd.Controllers namespace isnd.ViewModels
{ {
public class CatalogRegistration public class CatalogRegistration
{ {

@ -4,9 +4,6 @@
} }
<div class="text-center"> <div class="text-center">
<h1 class="display-4">Bienvenue</h1> <h1 class="display-4">Bienvenue</h1>
<h1> <h1>Bienvenue dans isn</h1>
<img src="~/icon.png" >
Bienvenue dans isnd
</h1>
<strong>@Model.PkgCount identifiant(s) de paquet dans le SI</strong> <strong>@Model.PkgCount identifiant(s) de paquet dans le SI</strong>
</div> </div>

@ -28,7 +28,7 @@
<thead> <thead>
<tr> <tr>
<th> <th>
@Html.DisplayNameFor(model => model.Versions[0].Package.Id) @Html.DisplayNameFor(model => model.Versions[0].PackageId)
</th> </th>
<th> <th>
@Html.DisplayNameFor(model => model.Versions[0].FullString) @Html.DisplayNameFor(model => model.Versions[0].FullString)

@ -1,4 +1,4 @@
@model PackageRegistrationIndexViewModel @model PackageRegistrationIndexQuery
@{ @{
ViewData["Title"] = "Index"; ViewData["Title"] = "Index";
@ -25,16 +25,17 @@
<thead> <thead>
<tr> <tr>
<th> <th>
@Html.DisplayNameFor(model => model.Data[0].Id) @Html.DisplayNameFor(model => model.Items[0].Items[0].Id)
</th> </th>
<th> <th>
@Html.DisplayNameFor(model => model.Data[0].Entry.Description) @Html.DisplayNameFor(model => model.Items[0].Items[0].Entry.Description)
</th> </th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var item in Model.Data) { @foreach (var page in Model.Items) {
@foreach (var item in page.Items) {
<tr> <tr>
<td> <td>
@Html.DisplayFor(modelItem => item.Id) @Html.DisplayFor(modelItem => item.Id)
@ -47,6 +48,6 @@
@Html.ActionLink("Details", "Details", new { pkgid = item.Id }) @Html.ActionLink("Details", "Details", new { pkgid = item.Id })
</td> </td>
</tr> </tr>
} }}
</tbody> </tbody>
</table> </table>

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - isnd</title> <title>@ViewData["Title"] - isn</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="~/css/site.css" /> <link rel="stylesheet" href="~/css/site.css" />
<link rel="shortcut icon" href="favicon.ico#1" > <link rel="shortcut icon" href="favicon.ico#1" >
@ -12,7 +12,7 @@
<header> <header>
<nav class="navbar navbar-dark bg-dark navbar-expand-sm" > <nav class="navbar navbar-dark bg-dark navbar-expand-sm" >
<div class="container"> <div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">isnd</a> <a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index"><img src="~/icon.png" alt="isn"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -27,6 +27,7 @@
</ul> </ul>
<form class="form-inline my-2 my-lg-0" asp-action="Index" asp-controller="Packages"> <form class="form-inline my-2 my-lg-0" asp-action="Index" asp-controller="Packages">
<input name="Query" id="Query" class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"> <input name="Query" id="Query" class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<input name="IsPrerelease" id="IsPrerelease" class="form-control mr-sm-2" type="checkbox" checked><label for="IsPrerelease"> <i>Pre-release </i></Label>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form> </form>
<partial name="_LoginPartial" /> <partial name="_LoginPartial" />

@ -2,14 +2,13 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFramework>netcoreapp2.1</TargetFramework>
<UserSecretsId>85fd766d-5d23-4476-aed1-463b2942e86a</UserSecretsId> <UserSecretsId>85fd766d-5d23-4476-aed1-463b2942e86a</UserSecretsId>
<PackageVersion>1.0.1</PackageVersion>
<Version>0.1.175</Version>
<IsPackable>true</IsPackable> <IsPackable>true</IsPackable>
<PackageLicenseExpression>WTFPL</PackageLicenseExpression> <PackageLicenseExpression>WTFPL</PackageLicenseExpression>
<NoWarn>NETSDK1138</NoWarn> <NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>0.1.175.0</AssemblyVersion> <AssemblyVersion>1.0.5.0</AssemblyVersion>
<FileVersion>0.1.175.0</FileVersion> <FileVersion>1.0.5.0</FileVersion>
<InformationalVersion>0.1.175+Branch.main.Sha.3e09afcbfe0eff74c0b3aa0fb974e0801f4708b6</InformationalVersion> <InformationalVersion>1.0.5+Branch.main.Sha.14206ac477d0f07566d5e8125dc52cbd7f474ca2</InformationalVersion>
<Version>1.0.5</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="2.1.1" />

@ -1,11 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<PropertyGroup> <OutputType>Exe</OutputType>
<OutputType>Exe</OutputType> <TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework> <RootNamespace>test_isn</RootNamespace>
<RootNamespace>test_isn</RootNamespace> <ImplicitUsings>enable</ImplicitUsings>
<ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable>
<Nullable>enable</Nullable> <AssemblyVersion>1.0.5.0</AssemblyVersion>
</PropertyGroup> <FileVersion>1.0.5.0</FileVersion>
<InformationalVersion>1.0.5+Branch.main.Sha.14206ac477d0f07566d5e8125dc52cbd7f474ca2</InformationalVersion>
</Project> <Version>1.0.5</Version>
</PropertyGroup>
</Project>

@ -27,53 +27,53 @@ namespace isn.tests
string unprotectedpass = _protector.UnProtect(protectedpass); string unprotectedpass = _protector.UnProtect(protectedpass);
Console.WriteLine(protectedpass); Console.WriteLine(protectedpass);
Assert.Equal(pass, unprotectedpass); Assert.Equal(pass, unprotectedpass);
Assert.True(protectedpass!=null); Assert.True(protectedpass != null);
Assert.True(protectedpass.Length>0); Assert.True(protectedpass.Length > 0);
} }
[Fact] [Fact]
public void Test() public void Test()
{ {
System.Data.DataTable dataTable = new System.Data.DataTable(); System.Data.DataTable dataTable = new System.Data.DataTable();
dataTable.Columns.Add(new DataColumn("x")); dataTable.Columns.Add(new DataColumn("x"));
dataTable.Columns.Add(new DataColumn("y")); dataTable.Columns.Add(new DataColumn("y"));
dataRow = dataTable.NewRow(); dataRow = dataTable.NewRow();
dataRow[0]= 1; dataRow[0] = 1;
dataRow[1]= 2; dataRow[1] = 2;
dataTable.Rows.Add(dataRow); dataTable.Rows.Add(dataRow);
} }
[Fact] [Fact]
public async Task TestHttpClient() public async Task TestHttpClient()
{ {
string url = "http://isn.pschneider.fr/" + ApiConfig.Base; string url = "http://isn.pschneider.fr/" + ApiConfig.IndexDotJson;
HttpClient client = new HttpClient(); HttpClient client = new HttpClient();
// var json = await client.GetStringAsync(new System.Uri(url)); // var json = await client.GetStringAsync(new System.Uri(url));
var response = await client.GetAsync(url); var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync(); var json = await response.Content.ReadAsStringAsync();
var vm = JsonConvert.DeserializeObject<ApiIndexViewModel>(json); var vm = JsonConvert.DeserializeObject<ApiIndexViewModel>(json);
Console.WriteLine( JsonConvert.SerializeObject(vm)); Console.WriteLine(JsonConvert.SerializeObject(vm));
Assert.NotNull(vm); Assert.NotNull(vm);
Assert.NotNull(vm.Resources); Assert.NotNull(vm.Resources);
} }
[Fact] [Fact]
public void TestPush() public void TestPush()
{ {
Program.LoadConfig(); Program.LoadConfig();
var report = Program.PushPkg(new string[] { "/home/paul/Nupkgs/Yavsc.Abstract.1.0.8." var report = Program.PushPkg(new string[] { "/home/paul/Nupkgs/Yavsc.Abstract.1.0.8."
+ Constants.PaquetFileEstension }); + Constants.PaquetFileEstension });
} }
[Fact] [Fact]
public async Task GetServerResourcesUsingHttpClientAsyncTest() public async Task GetServerResourcesUsingHttpClientAsyncTest()
{ {
var model = SourceHelpers.GetServerResources("Http://isn.pschneider.fr/index.json"); var model = SourceHelpers.GetServerResources("Http://isn.pschneider.fr/index.json");
Console.WriteLine(JsonConvert.SerializeObject(model)); Console.WriteLine(JsonConvert.SerializeObject(model));
Assert.NotNull(model.Resources); Assert.NotNull(model.Resources);
var pub = model.Resources.FirstOrDefault((r) => r.Type.StartsWith("PackagePublish/")); var pub = model.Resources.FirstOrDefault((r) => r.Type.StartsWith("PackagePublish/"));
Assert.True(pub!=null); Assert.True(pub != null);
} }
} }

@ -3,10 +3,10 @@
<TargetFrameworks>netcoreapp2.1</TargetFrameworks> <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<NoWarn>NETSDK1138</NoWarn> <NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>0.1.175.0</AssemblyVersion> <AssemblyVersion>1.0.5.0</AssemblyVersion>
<FileVersion>0.1.175.0</FileVersion> <FileVersion>1.0.5.0</FileVersion>
<InformationalVersion>0.1.175+Branch.main.Sha.3e09afcbfe0eff74c0b3aa0fb974e0801f4708b6</InformationalVersion> <InformationalVersion>1.0.5+Branch.main.Sha.14206ac477d0f07566d5e8125dc52cbd7f474ca2</InformationalVersion>
<Version>0.1.175</Version> <Version>1.0.5</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />

@ -4,10 +4,10 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<UserSecretsId>d7144e46-4e63-4391-ba86-64b61f6e7be4</UserSecretsId> <UserSecretsId>d7144e46-4e63-4391-ba86-64b61f6e7be4</UserSecretsId>
<NoWarn>NETSDK1138</NoWarn> <NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>0.1.175.0</AssemblyVersion> <AssemblyVersion>1.0.5.0</AssemblyVersion>
<FileVersion>0.1.175.0</FileVersion> <FileVersion>1.0.5.0</FileVersion>
<InformationalVersion>0.1.175+Branch.main.Sha.3e09afcbfe0eff74c0b3aa0fb974e0801f4708b6</InformationalVersion> <InformationalVersion>1.0.5+Branch.main.Sha.14206ac477d0f07566d5e8125dc52cbd7f474ca2</InformationalVersion>
<Version>0.1.175</Version> <Version>1.0.5</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="XunitXml.TestLogger" Version="3.0.70" /> <PackageReference Include="XunitXml.TestLogger" Version="3.0.70" />

Loading…