18 Commits
1.0.0 ... 1.0.1

Author SHA1 Message Date
58f77a06ea A valid package index page 2022-10-15 18:26:55 +01:00
88c8480911 A valid registration page Index 2022-10-15 18:25:40 +01:00
c147eaf54a by Nuget version 2022-09-27 00:39:43 +01:00
e49db8e1a1 re_Vision 2022-09-26 23:34:13 +01:00
9aac183e2c Merge branch 'broken/ef' 2022-09-26 23:30:58 +01:00
037559a0b7 layout 2022-09-26 23:30:54 +01:00
9c4d45b97c + Revsion 2022-09-26 21:54:22 +01:00
9aa3140a11 WIP 2022-09-25 17:07:56 +01:00
7f9344d437 add a vscode task for ef db update 2022-09-25 16:47:31 +01:00
f46ca00de9 REORG 2022-09-25 02:24:21 +01:00
fcea41f8c1 Catalog++ 2022-09-24 12:32:00 +01:00
58f49af5f0 publish 2022-09-23 22:16:12 +01:00
fececb327e WIP reg page 2022-09-23 20:34:51 +01:00
14206ac477 catalog impl 2022-08-20 17:44:33 +01:00
fa9a12ad49 WIP Page leaf 2022-07-29 09:06:59 +01:00
7f9984b059 WIP page leaf 2022-07-10 17:05:16 +01:00
2dcf1a2806 refacts 2022-07-03 14:50:57 +01:00
a84e1d9750 Corrige la suppression de paquets 2022-06-19 21:40:31 +01:00
86 changed files with 1889 additions and 547 deletions

4
.gitignore vendored
View File

@ -17,3 +17,7 @@ appsettings.Development.json
/src/isn.abst/bin /src/isn.abst/bin
/src/isn.abst/obj /src/isn.abst/obj
/src/isnd/packages/ /src/isnd/packages/
/test/data/test-isn/bin/
/test/data/test-isn/obj
.fake
artifacts/

View File

@ -1,33 +1,23 @@
<Properties StartupConfiguration="{9D758F00-17FF-433D-B088-F9C2D97C9BD1}|Default"> <Properties StartupConfiguration="{9D758F00-17FF-433D-B088-F9C2D97C9BD1}|Default">
<MonoDevelop.Ide.Workbench ActiveDocument="src/isn/Program.cs"> <MonoDevelop.Ide.Workbench ActiveDocument="src/isnd/isnd.csproj">
<Files> <Files>
<File FileName="src/isn/Program.cs" Line="66" Column="10" /> <File FileName="src/isn/Program.cs" Line="55" Column="48" />
<File FileName="src/isnd/isnd.csproj" Line="15" Column="56" />
</Files> </Files>
<Pads> <Pads>
<Pad Id="ProjectPad"> <Pad Id="ProjectPad">
<State name="__root__"> <State name="__root__">
<Node name="isn" expanded="True"> <Node name="isn" expanded="True">
<Node name="src" expanded="True"> <Node name="src" expanded="True">
<Node name="isn" expanded="True" selected="True" /> <Node name="isnd" selected="True" />
<Node name="isn.abst" expanded="True" />
</Node>
<Node name="test" expanded="True">
<Node name="isnd.tests" expanded="True" />
</Node>
</Node>
</State>
</Pad>
<Pad Id="MonoDevelop.UnitTesting.TestPad">
<State name="__root__">
<Node name="isn" expanded="True">
<Node name="test" expanded="True">
<Node name="isn.tests" selected="True" />
</Node> </Node>
<Node name="test" expanded="True" />
</Node> </Node>
</State> </State>
</Pad> </Pad>
</Pads> </Pads>
</MonoDevelop.Ide.Workbench> </MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.ItemProperties.src.isnd PreferredExecutionTarget="MonoDevelop.Default" />
<MonoDevelop.Ide.DebuggingService.PinnedWatches /> <MonoDevelop.Ide.DebuggingService.PinnedWatches />
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" /> <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.ItemProperties.test.isnd.tests PreferredExecutionTarget="MonoDevelop.Default" /> <MonoDevelop.Ide.ItemProperties.test.isnd.tests PreferredExecutionTarget="MonoDevelop.Default" />
@ -35,4 +25,5 @@
<BreakpointStore /> <BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints> </MonoDevelop.Ide.DebuggingService.Breakpoints>
<MultiItemStartupConfigurations /> <MultiItemStartupConfigurations />
<MonoDevelop.Ide.ItemProperties.src.isn PreferredExecutionTarget="MonoDevelop.Default" />
</Properties> </Properties>

View File

@ -1,6 +1,6 @@
{ {
"omnisharp.msbuild": false, "omnisharp.msbuild": true,
"dotnet-test-explorer.testProjectPath": "**/*.sln", "dotnet-test-explorer.testProjectPath": "**/*tests.csproj",
"dotnet-test-explorer.runInParallel": false, "dotnet-test-explorer.runInParallel": false,
"dotnet-test-explorer.showCodeLens": true, "dotnet-test-explorer.showCodeLens": true,
"dotnet-test-explorer.testArguments": "", "dotnet-test-explorer.testArguments": "",
@ -46,5 +46,7 @@
"database": "isnd", "database": "isnd",
"username": "paul" "username": "paul"
} }
] ],
"omnisharp.disableMSBuildDiagnosticWarning": true,
"omnisharp.enableRoslynAnalyzers": false
} }

41
.vscode/tasks.json vendored
View File

@ -26,6 +26,26 @@
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{
"label": "db-upgrade",
"command": "dotnet",
"type": "process",
"args": [
"ef",
"database",
"update"
],
"problemMatcher": "$msCompile",
"options": {
"cwd": "${workspaceFolder}/src/isnd",
"env": {
"ASPNETCORE_ENV": "Development"
}
}
},
{ {
"label": "buildcli", "label": "buildcli",
"command": "msbuild", "command": "msbuild",
@ -45,8 +65,25 @@
"type": "process", "type": "process",
"args": [ "args": [
"publish", "publish",
"/property:GenerateFullPaths=true", "/p:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary" "/consoleloggerparameters:NoSummary",
"/p:TargetFramework=netcoreapp2.1",
"/p:RuntimeIdentifier=linux-x64",
"/p:PublishDir=${workspaceFolder}/artifacts"
],
"problemMatcher": "$msCompile",
"options": {
"cwd": "${workspaceFolder}"
}
},
{
"label": "monopublish",
"command": "msbuild",
"type": "process",
"args": [
"/t:publish",
"/p:TargetFramework=netcoreapp2.1;PublishDir=${workspaceFolder}/artiffacts;RuntimeIdentifier=linux-x64",
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },

View File

@ -25,7 +25,7 @@ dotnet build /restore -c Release
dotnet publish -c Release dotnet publish -c Release
```` ````
### Déployer le serveur ### Déploiement
````bash ````bash
sudo mkdir -p /srv/www/isnd sudo mkdir -p /srv/www/isnd
@ -44,14 +44,14 @@ sudo systemctl daemon-reload
sudo systemctl start isnd sudo systemctl start isnd
```` ````
* Activer le serveur : * Activation du serveur :
````bash ````bash
sudo systemctl enable isnd sudo systemctl enable isnd
```` ````
### Installer le client ### Installation du client
````bash ````bash
sudo mkdir /usr/local/lib/isn sudo mkdir /usr/local/lib/isn
@ -74,5 +74,52 @@ sudo systemctl start isnd
sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn
sudo chown -R root.root /usr/local/lib/isn sudo chown -R root.root /usr/local/lib/isn
```` ````
## TODO ## TODO
```json
{
"@id": "https://api.nuget.org/v3/registration5-semver1/",
"@type": "RegistrationsBaseUrl",
"comment": "Base URL of Azure storage where NuGet package registration info is stored"
},
{
"@id": "https://api.nuget.org/v3-flatcontainer/",
"@type": "PackageBaseAddress/3.0.0",
"comment": "Base URL of where NuGet packages are stored, in the format https://api.nuget.org/v3-flatcontainer/{id-lower}/{version-lower}/{id-lower}.{version-lower}.nupkg"
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/",
"@type": "RegistrationsBaseUrl/3.0.0-rc",
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by RC clients. This base URL does not include SemVer 2.0.0 packages."
},
{
"@id": "https://api.nuget.org/v3/registration5-semver1/",
"@type": "RegistrationsBaseUrl/3.0.0-beta",
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by Beta clients. This base URL does not include SemVer 2.0.0 packages."
},
{
"@id": "https://www.nuget.org/packages/{id}/{version}?_src=template",
"@type": "PackageDetailsUriTemplate/5.1.0",
"comment": "URI template used by NuGet Client to construct details URL for packages"
},
{
"@id": "https://api.nuget.org/v3/registration5-gz-semver2/",
"@type": "RegistrationsBaseUrl/3.6.0",
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
},
````

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<apikeys>
</apikeys>
<packageSources>
<add key="myIsnDev" value="http://localhost:5000/index.json" protocolVersion="3" />
</packageSources>
</configuration>

View File

@ -0,0 +1,2 @@
nuget install -Verbosity detailed -Source http://localhost:5000/index.json -Prerelease Yavsc.Abstract
nuget locals all -clear

View File

@ -0,0 +1,4 @@
= URL's
<http://localhost:5000/v3.4.0/registration/yavsc.abstract/index.json>

View File

@ -1,11 +1,13 @@
#!/bin/bash #!/bin/bash
set -e set -e
# compiler tout # compiler tout
dotnet publish -c Release dotnet build -c Release
dotnet publish -c Release -f netcoreapp2.1 src/isnd
# MAJ du serveur # MAJ du serveur
sudo systemctl stop isnd sudo systemctl stop isnd
sudo cp -a src/isnd/bin/Release/netcoreapp2.1/publish/* /srv/www/isnd sudo cp -a src/isnd/bin/Release/netcoreapp2.1/publish/* /srv/www/isnd
sudo systemctl start isnd sudo systemctl start isnd
# MAJ du client # MAJ du client
sudo cp -a src/isn/bin/Release/net472/* /usr/local/lib/isn sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn
sudo chmod +x /usr/local/lib/isn/isn.exe sudo chown -R root.root /usr/local/lib/isn

22
omnisharp.json Normal file
View File

@ -0,0 +1,22 @@
{
"dotnet": {
"enabled": false
},
"msbuild": {
"enabled": true
},
"Dnx": {
"enabled": false
},
"Script": {
"enabled": false
},
"fileOptions": {
"systemExcludeSearchPatterns": [
"**/bin/**/*",
"**/obj/**/*",
"**/node_modules/**/*"
],
"userExcludeSearchPatterns": []
}
}

View File

@ -1,21 +1,21 @@
using isn.abst;
namespace isnd.Entities 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 Get = "package"; public const string GetPackage = Constants.PaquetFileEstension;
public const string GetVersion = "version";
public const string Search = "search"; public const string Search = "search";
public const string AutoComplete = "autocomplete"; public const string AutoComplete = "autocomplete";
public const string CatalogLeaf = "catalog-leaf"; public const string CatalogLeaf = "catalog-leaf";
public const string CatalogPackageDetail = "package-detail";
public const string Delete = "delete"; public const string Delete = "delete";
public const string Registration = "registration"; public const string Registration = "registration";
internal const string GetNuspec = Constants.SpecFileEstension;
} }
} }

View File

@ -0,0 +1,9 @@
namespace isn.abst
{
public static class Constants
{
public const string PaquetFileEstension = "nupkg";
public const string SpecFileEstension = "nuspec";
public const string JsonFileEstension = "json";
}
}

View File

@ -4,7 +4,7 @@ using System.Linq;
namespace isnd.Attributes namespace isnd.Attributes
{ {
internal class SafeNameAttribute : ValidationAttribute public class SafeNameAttribute : ValidationAttribute
{ {
public override bool IsValid(object value) public override bool IsValid(object value)
{ {

View File

@ -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> <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<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" />

View File

@ -20,11 +20,11 @@ namespace isn
currentSource = settings.DefaultSource; currentSource = settings.DefaultSource;
} }
} }
static OptionSet storeoptions = new OptionSet { static readonly OptionSet storeoptions = new OptionSet {
{ "s|source=", "use source", val => currentSource = currentSource ?? val }, { "s|source=", "use source", val => currentSource = currentSource ?? val },
{ "h|help", "show this message and exit", h => shouldShowPushHelp = h != null }, { "h|help", "show this message and exit", h => shouldShowPushHelp = h != null },
}; };
private static string _configFileName = private static readonly string _configFileName =
Path.Combine( Path.Combine(
Path.Combine(Environment.GetFolderPath( Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.UserProfile), ".isn"), Environment.SpecialFolder.UserProfile), ".isn"),
@ -32,21 +32,21 @@ namespace isn
; ;
public const string push = "push"; public const string push = "push";
static OptionSet options = new OptionSet { static readonly OptionSet options = new OptionSet {
{ "h|help", "show this message and exit", h => shouldShowHelp = h != null }, { "h|help", "show this message and exit", h => shouldShowHelp = h != null },
}; };
static OptionSet pushoptions = new OptionSet { static readonly OptionSet pushoptions = new OptionSet {
{ "k|api-key=", "use api key", val => apiKey = apiKey ?? val }, { "k|api-key=", "use api key", val => apiKey = apiKey ?? val },
{ "p|store-api-key", "store used api key (=<true|false>)", val => storApiKey = val != null }, { "p|store-api-key", "store used api key (=<true|false>)", val => storApiKey = val != null },
{ "s|source=", "use source", val => currentSource = currentSource ?? val }, { "s|source=", "use source", val => currentSource = currentSource ?? val },
{ "h|help", "show this message and exit", h => shouldShowPushHelp = h != null }, { "h|help", "show this message and exit", h => shouldShowPushHelp = h != null },
}; };
static OptionSet sourceoptions = new OptionSet { static readonly OptionSet sourceoptions = new OptionSet {
{ "h|help", "show this message and exit", h => shouldShowSourceHelp = h != null }, { "h|help", "show this message and exit", h => shouldShowSourceHelp = h != null },
}; };
static OptionSet showOptions = new OptionSet { static readonly OptionSet showOptions = new OptionSet {
{ "h|help", "show this message and exit", h => shouldShowSourceHelp = h != null }, { "h|help", "show this message and exit", h => shouldShowSourceHelp = h != null },
}; };
@ -154,7 +154,7 @@ namespace isn
var pushCmd = new Command(push) var pushCmd = new Command(push)
{ {
Run = async sargs => Run = sargs =>
{ {
var pargs = pushoptions.Parse(sargs); var pargs = pushoptions.Parse(sargs);
if (shouldShowPushHelp) if (shouldShowPushHelp)

View File

@ -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;
}
} }
} }

View File

@ -4,22 +4,22 @@
<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" />
<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" />

View File

@ -6,7 +6,7 @@ using System.Linq;
using isnd.ViewModels; using isnd.ViewModels;
using Unleash; using Unleash;
using System.Reflection; using System.Reflection;
using Microsoft.EntityFrameworkCore;
namespace isnd.Controllers namespace isnd.Controllers
{ {
@ -25,9 +25,10 @@ namespace isnd.Controllers
public IActionResult Index() public IActionResult Index()
{ {
return View(new HomeIndexViewModel{ return View(new HomeIndexViewModel{
PkgCount = _dbContext.Packages.Count(), PkgCount = _dbContext.Packages
.Where(p => p.Versions.Count > 0)
.Count(),
UnleashClient = _unleashĈlient UnleashClient = _unleashĈlient
}); });
} }

View File

@ -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();
@ -47,60 +50,5 @@ namespace isnd
return View("Index", model); return View("Index", model);
} }
// GET: PackageVersion/Details/5
public async Task<IActionResult> Details(string pkgid, string version)
{
if (pkgid == null || version == null)
{
return NotFound();
}
var packageVersion = await _context.PackageVersions
.Include(p => p.Package)
.FirstOrDefaultAsync(m => m.PackageId == pkgid && m.FullString == version);
if (packageVersion == null)
{
return NotFound();
}
return View(packageVersion);
}
[Authorize]
public async Task<IActionResult> Delete(string pkgid, string version, string pkgtype)
{
if (pkgid == null || version == null)
{
return NotFound();
}
var packageVersion = await _context.PackageVersions.Include(p => p.Package)
.FirstOrDefaultAsync(m => m.PackageId == pkgid
&& m.FullString == version && m.Type == pkgtype);
if (packageVersion == null) return NotFound();
if (!User.IsOwner(packageVersion)) return Unauthorized();
var pkg = await _pm.GetPackageAsync(pkgid, version, pkgtype);
return View(pkg);
}
// POST: PackageVersion/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string PackageId, string FullString,
string Type)
{
PackageVersion packageVersion = await _context.PackageVersions
.FirstOrDefaultAsync(m => m.PackageId == PackageId
&& m.FullString == FullString && m.Type == Type);
if (packageVersion == null) return NotFound();
if (!User.IsOwner(packageVersion)) return Unauthorized();
await _pm.DeletePackageAsync(PackageId, FullString, Type);
return RedirectToAction(nameof(Index));
}
} }
} }

View File

@ -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 });

View File

@ -17,26 +17,17 @@ namespace isnd.Controllers
int skip = 0, int skip = 0,
int take = 25) int take = 25)
{ {
CheckParams(take, semVerLevel); if (take > maxTake)
if (ModelState.ErrorCount > 0) return BadRequest(ModelState);
return Ok(packageManager.AutoComplete(id,skip,take,prerelease,packageType));
}
protected void CheckParams(int maxTake)
{
if (maxTake > maxTake)
{ {
ModelState.AddModelError("take", "Maximum exceeded"); ModelState.AddModelError("take", "Maximum exceeded");
} }
}
protected void CheckParams(int take, string semVerLevel)
{
CheckParams(take);
if (semVerLevel != PackageManager.BASE_API_LEVEL) if (semVerLevel != PackageManager.BASE_API_LEVEL)
{ {
ModelState.AddModelError("semVerLevel", PackageManager.BASE_API_LEVEL + " expected"); ModelState.AddModelError("semVerLevel", PackageManager.BASE_API_LEVEL + " expected");
} }
if (ModelState.ErrorCount > 0) return BadRequest(ModelState);
return Ok(packageManager.AutoComplete(id,skip,take,prerelease,packageType));
} }
} }
} }

View File

@ -1,25 +1,22 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using isnd.Data.Catalog;
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 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()
{ {
return Ok(PackageManager.CurrentCatalogIndex); return Ok(PackageManager.CurrentCatalogIndex);
} }
[HttpGet(_pkgRootPrefix + ApiConfig.CatalogPage + "-{id}")] [HttpGet(_pkgRootPrefix + ApiConfig.CatalogPage + "-{id}")]
public IActionResult Index(string id) public IActionResult Index(string id)
{ {
@ -27,35 +24,50 @@ namespace isnd.Controllers
return Ok(PackageManager.CurrentCatalogPages[int.Parse(id)]); return Ok(PackageManager.CurrentCatalogPages[int.Parse(id)]);
} }
[HttpGet(_pkgRootPrefix + ApiConfig.CatalogLeaf + "/{id}/{*lower}")] [HttpGet(_pkgRootPrefix + "{apiVersion}/" + ApiConfig.Registration + "/{id}/{lower}.json")]
public async Task<IActionResult> CatalogLeafAsync(string id, string lower) public IActionResult CatalogRegistration(string apiVersion, string id, string lower)
{ {
string pkgType = ParamHelpers.Optional(ref lower); if (lower.Equals("index", System.StringComparison.OrdinalIgnoreCase))
var pkgVersion = await dbContext.PackageVersions
.Include(v => v.LatestCommit)
.SingleOrDefaultAsync(
v => v.PackageId == id &&
v.FullString == lower &&
v.Type == pkgType
);
if (pkgVersion == null) return NotFound();
var pub = await dbContext.Commits
.Include(c => c.Versions)
.OrderBy(c => c.CommitTimeStamp)
.SingleOrDefaultAsync
(
c => c.Action == PackageAction.PublishPackage
&& c.Versions.Contains(pkgVersion)
);
return Ok(new CatalogLeaf
{ {
CommitId = id, var query = new Data.Catalog.RegistrationPageIndexQuery
Id = pkgVersion.PackageId, {
CommitTimeStamp = pkgVersion.LatestCommit.CommitTimeStamp Query = id,
Prerelease = true
}); };
var index = packageManager.GetPackageRegistrationIndex(query);
if (index == null) return NotFound();
// query.TotalHits = result.Items.Select(i=>i.Items.Length).Aggregate((a,b)=>a+b);
return Ok(index);
}
var leaf = packageManager.SearchById(id,lower,null);
if (leaf.Count()==0) return NotFound(new { id, lower });
return Ok(leaf.First());
} }
[HttpGet(_pkgRootPrefix + ApiConfig.CatalogLeaf + "/{id}/{version}/{lower}/index.json")]
public IActionResult CatalogLeaf(string id, string pversion, string lower)
{
bool askForindex = lower == null;
var pkgvs = this.packageManager.GetCatalogLeaf(id, pversion, lower).ToArray();
if (pkgvs.Count() == 0) return NotFound();
List<string> types = pkgvs.Select(
v => v.Type ?? "Dependency"
).Distinct().ToList();
if (!types.Contains("PackageDelete"))
types.Add("PackageDetails");
var last = pkgvs.Last();
var pub = last.LatestCommit.CommitTimeStamp;
return Ok(new Data.Packages.Catalog.CatalogLeaf
{
CommitId = last.CommitId,
Id = id,
CommitTimeStamp = pub,
Version = last.FullString,
Published = pub,
RefType = types.ToArray()
});
}
} }
} }

View File

@ -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);
} }
} }

View File

@ -3,20 +3,23 @@ using System.IO;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using isnd.Attributes; using isnd.Attributes;
using isnd.Entities; using isnd.Entities;
using isn.abst;
namespace isnd.Controllers namespace isnd.Controllers
{ {
public partial class PackagesController public partial class PackagesController
{ {
// Web get nupkg // Web get the paquet
[HttpGet(_pkgRootPrefix + ApiConfig.Get + "/{id}/{lower}/{idf}-{lowerf}.nupkg")] [HttpGet(_pkgRootPrefix + ApiConfig.GetPackage + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.PaquetFileEstension)]
public IActionResult GetPackage( public IActionResult GetPackage(
[FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower, [FromRoute][SafeName][Required] string lower,
[FromRoute] string idf, [FromRoute] string lowerf) [FromRoute] string idf, [FromRoute] string lowerf)
{ {
var pkgpath = Path.Combine(isndSettings.PackagesRootDir, var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}-{lower}.nupkg" id, lower, $"{id}-{lower}." + Constants.PaquetFileEstension
); );
FileInfo pkgfi = new FileInfo(pkgpath); FileInfo pkgfi = new FileInfo(pkgpath);
@ -29,7 +32,8 @@ namespace isnd.Controllers
} }
// Web get spec // Web get spec
[HttpGet(_pkgRootPrefix + ApiConfig.Get + "/{id}/{lower}/{idf}-{lowerf}.nuspec")] [HttpGet(_pkgRootPrefix + Constants.SpecFileEstension + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.SpecFileEstension)]
public IActionResult GetNuspec( public IActionResult GetNuspec(
[FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower, [FromRoute][SafeName][Required] string lower,
@ -37,7 +41,7 @@ namespace isnd.Controllers
[FromRoute][SafeName][Required] string lowerf) [FromRoute][SafeName][Required] string lowerf)
{ {
var pkgpath = Path.Combine(isndSettings.PackagesRootDir, var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}.nuspec"); id, lower, $"{id}." + Constants.SpecFileEstension);
FileInfo pkgfi = new FileInfo(pkgpath); FileInfo pkgfi = new FileInfo(pkgpath);
if (!pkgfi.Exists) if (!pkgfi.Exists)

View File

@ -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.Get + "/{id}/{lower}/index.json")] [HttpGet(_pkgRootPrefix + ApiConfig.GetVersion + "/{id}/{lower}/" + ApiConfig.IndexDotJson)]
public IActionResult GetVersions( public IActionResult GetVersions(
string id, string id,
string lower, string lower,

View File

@ -15,7 +15,8 @@ using isnd.Data;
using isnd.Helpers; using isnd.Helpers;
using isnd.Entities; using isnd.Entities;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using isnd.Data.Catalog; using isn.abst;
using isnd.Data.Packages;
namespace isnd.Controllers namespace isnd.Controllers
{ {
@ -52,7 +53,7 @@ namespace isnd.Controllers
{ {
string initpath = Path.Combine(Environment.GetEnvironmentVariable("TEMP") ?? string initpath = Path.Combine(Environment.GetEnvironmentVariable("TEMP") ??
Environment.GetEnvironmentVariable("TMP") ?? "/tmp", Environment.GetEnvironmentVariable("TMP") ?? "/tmp",
$"isn-{Guid.NewGuid()}.nupkg"); $"isn-{Guid.NewGuid()}."+Constants.PaquetFileEstension);
using (FileStream fw = new FileStream(initpath, FileMode.Create)) using (FileStream fw = new FileStream(initpath, FileMode.Create))
{ {
@ -63,14 +64,14 @@ namespace isnd.Controllers
{ {
var archive = new ZipArchive(fw); var archive = new ZipArchive(fw);
var nuspec = archive.Entries.FirstOrDefault(e => e.FullName.EndsWith(".nuspec")); var spec = archive.Entries.FirstOrDefault(e => e.FullName.EndsWith("." + Constants.SpecFileEstension));
if (nuspec == null) return BadRequest(new { error = "no nuspec from archive" }); if (spec == null) return BadRequest(new { error = "no " + Constants.SpecFileEstension + " from archive" });
string pkgpath; string pkgpath;
NuGetVersion version; NuGetVersion version;
string pkgid; string pkgid;
string fullpath; string fullpath;
using (var specstr = nuspec.Open()) using (var specstr = spec.Open())
{ {
NuspecCoreReader reader = new NuspecCoreReader(specstr); NuspecCoreReader reader = new NuspecCoreReader(specstr);
@ -82,29 +83,29 @@ namespace isnd.Controllers
string pkgidpath = Path.Combine(isndSettings.PackagesRootDir, string pkgidpath = Path.Combine(isndSettings.PackagesRootDir,
pkgid); pkgid);
pkgpath = Path.Combine(pkgidpath, version.ToFullString()); pkgpath = Path.Combine(pkgidpath, version.ToFullString());
string name = $"{pkgid}-{version}.nupkg"; string name = $"{pkgid}-{version}."+Constants.PaquetFileEstension;
fullpath = Path.Combine(pkgpath, name); fullpath = Path.Combine(pkgpath, name);
var destpkgiddir = new DirectoryInfo(pkgidpath); var destpkgiddir = new DirectoryInfo(pkgidpath);
Package package = dbContext.Packages.SingleOrDefault(p => p.Id == pkgid); Package pkg = dbContext.Packages.SingleOrDefault(p => p.Id == pkgid);
if (package != null) if (pkg != null)
{ {
if (package.OwnerId != apikey.UserId) if (pkg.OwnerId != apikey.UserId)
{ {
return new ForbidResult(); return new ForbidResult();
} }
package.Description = pkgdesc; pkg.Description = pkgdesc;
} }
else else
{ {
package = new Package pkg = new Package
{ {
Id = pkgid, Id = pkgid,
Description = pkgdesc, Description = pkgdesc,
OwnerId = apikey.UserId, OwnerId = apikey.UserId,
LatestVersion = commit LatestVersion = commit,
}; };
dbContext.Packages.Add(package); dbContext.Packages.Add(pkg);
} }
if (!destpkgiddir.Exists) destpkgiddir.Create(); if (!destpkgiddir.Exists) destpkgiddir.Create();
@ -117,7 +118,7 @@ namespace isnd.Controllers
// mais si elle ne l'est pas en base de donnéés, // mais si elle ne l'est pas en base de donnéés,
// on remplace la version sur disque. // on remplace la version sur disque.
var pkgv = dbContext.PackageVersions.Where( var pkgv = dbContext.PackageVersions.Where(
v => v.PackageId == package.Id v => v.PackageId == pkg.Id
); );
if (pkgv !=null && pkgv.Count()==0) if (pkgv !=null && pkgv.Count()==0)
@ -136,21 +137,23 @@ namespace isnd.Controllers
files.Add(name); files.Add(name);
string fullstringversion = version.ToFullString(); string fullstringversion = version.ToFullString();
var pkgvers = dbContext.PackageVersions.Where var pkgvers = dbContext.PackageVersions.Where
(v => v.PackageId == package.Id && v.FullString == fullstringversion); (v => v.PackageId == pkg.Id && v.FullString == fullstringversion);
if (pkgvers.Count() > 0) if (pkgvers.Count() > 0)
{ {
foreach (var v in pkgvers.ToArray()) foreach (var v in pkgvers.ToArray())
dbContext.PackageVersions.Remove(v); dbContext.PackageVersions.Remove(v);
} }
// FIXME default type or null // FIXME default type or null
if (types==null || types.Count==0) if (types==null || types.Count==0)
dbContext.PackageVersions.Add dbContext.PackageVersions.Add
(new PackageVersion{ (new PackageVersion{
Package = package, Package = pkg,
Major = version.Major, Major = version.Major,
Minor = version.Minor, Minor = version.Minor,
Patch = version.Patch, Patch = version.Patch,
Revision = version.Revision,
IsPrerelease = version.IsPrerelease, IsPrerelease = version.IsPrerelease,
FullString = version.ToFullString(), FullString = version.ToFullString(),
Type = null, Type = null,
@ -161,7 +164,7 @@ namespace isnd.Controllers
{ {
var pkgver = new PackageVersion var pkgver = new PackageVersion
{ {
Package = package, Package = pkg,
Major = version.Major, Major = version.Major,
Minor = version.Minor, Minor = version.Minor,
Patch = version.Patch, Patch = version.Patch,
@ -176,7 +179,7 @@ namespace isnd.Controllers
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync();
packageManager.ÛpdateCatalogFor(commit); packageManager.ÛpdateCatalogFor(commit);
logger.LogInformation($"new package : {nuspec.Name}"); logger.LogInformation($"new paquet : {spec.Name}");
} }
} }
using (var shacrypto = System.Security.Cryptography.SHA512.Create()) using (var shacrypto = System.Security.Cryptography.SHA512.Create())
@ -194,12 +197,12 @@ namespace isnd.Controllers
} }
} }
} }
string nuspecfullpath = Path.Combine(pkgpath, pkgid + ".nuspec"); string nuspecfullpath = Path.Combine(pkgpath, pkgid + "." + Constants.SpecFileEstension);
FileInfo nfpi = new FileInfo(nuspecfullpath); FileInfo nfpi = new FileInfo(nuspecfullpath);
if (nfpi.Exists) if (nfpi.Exists)
nfpi.Delete(); nfpi.Delete();
nuspec.ExtractToFile(nuspecfullpath); spec.ExtractToFile(nuspecfullpath);
} }
} }

View File

@ -0,0 +1,10 @@
using isnd.Data.Catalog;
namespace isnd
{
public class RegistrationPageIndexQueryAndResult
{
public RegistrationPageIndexQuery Query { get; set; }
public RegistrationPageIndex Result { get; set; }
}
}

View File

@ -11,7 +11,7 @@ namespace isnd.Controllers
{ {
// GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE} // GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
[HttpGet(_pkgRootPrefix + ApiConfig.Search)] [HttpGet(_pkgRootPrefix + ApiConfig.Search)]
public async Task<IActionResult> Search( public IActionResult Search(
string q, string q,
int skip = 0, int skip = 0,
int take = 25, int take = 25,

View File

@ -1,7 +1,11 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using isnd.Data;
using isnd.Data.Catalog;
using isnd.Helpers;
using isnd.ViewModels; using isnd.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -11,15 +15,12 @@ namespace isnd.Controllers
public partial class PackagesController public partial class PackagesController
{ {
// Web search // Web search
public async Task<IActionResult> Index(PackageIndexViewModel model) public async Task<IActionResult> Index(RegistrationPageIndexQuery model)
{ {
var applicationDbContext = dbContext.Packages.Include(p => p.Versions).Where( return View(new RegistrationPageIndexQueryAndResult{Query = model,
p => ( model.Prerelease || p.Versions.Any(v => !v.IsPrerelease)) Result = packageManager.GetPackageRegistrationIndex(model)});
&& ((model.Query == null) || p.Id.StartsWith(model.Query)));
model.Data = await applicationDbContext.ToArrayAsync();
return View(model);
} }
public async Task<IActionResult> Details(string pkgid) public async Task<IActionResult> Details(string pkgid)
{ {
if (pkgid == null) if (pkgid == null)
@ -50,6 +51,41 @@ namespace isnd.Controllers
} }
const int MAX_PKG_VERSION_LIST = 50; const int MAX_PKG_VERSION_LIST = 50;
[Authorize]
public async Task<IActionResult> Delete(string pkgid, string version, string pkgtype)
{
if (pkgid == null || version == null)
{
return NotFound();
}
// var report = await packageManager.DeletePackageAsync(id, lower, type);
var packageVersion = await dbContext.PackageVersions.Include(p => p.Package)
.FirstOrDefaultAsync(m => m.PackageId == pkgid
&& m.FullString == version && m.Type == pkgtype);
if (packageVersion == null) return NotFound();
if (!User.IsOwner(packageVersion)) return Unauthorized();
var pkg = await packageManager.GetPackageAsync(pkgid, version, pkgtype);
return View(pkg);
}
// POST: PackageVersion/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string PackageId, string FullString,
string Type)
{
PackageVersion packageVersion = await dbContext.PackageVersions
.Include(pv => pv.Package)
.FirstOrDefaultAsync(m => m.PackageId == PackageId
&& m.FullString == FullString && m.Type == Type);
if (packageVersion == null) return NotFound();
if (!User.IsOwner(packageVersion)) return Unauthorized();
await packageManager.DeletePackageAsync(PackageId, FullString, Type);
return RedirectToAction(nameof(Index));
}
} }
} }

View File

@ -6,8 +6,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using isnd.Data; using isnd.Data;
using isnd.Data.ApiKeys; using isnd.Data.ApiKeys;
using isnd.Data.Catalog; using isnd.Data.Packages;
using isnd.Data.Historic;
namespace isnd.Data namespace isnd.Data
{ {

View File

@ -0,0 +1,11 @@
using NuGet.Versioning;
namespace isnd.Data.Catalog
{
public class AlternatePackage
{
public string id { get ; set; }
public VersionRange range { get ; set; }
}
}

View File

@ -0,0 +1,82 @@
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class CatalogEntry
{
/// <summary>
/// The URL to the document used to produce this object
/// </summary>
/// <value></value>
[Key][Required,JsonRequired]
[StringLength(1024)]
[JsonProperty("@id")]
public string Id { get; set; }
/// <summary>
/// Authors
/// </summary>
/// <value>string or array of strings</value>
public string authors { get; set; }
/// <summary>
/// The dependencies of the package, grouped by target framework
/// </summary>
/// <value>array of objects</value>
public DependencyGroup[] dependencyGroups { get; set; }
/// <summary>
/// The deprecation associated with the package
/// </summary>
/// <value></value>
public Deprecation deprecation { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
public string iconUrl { get; set; }
/// <summary>
/// The ID of the package
/// </summary>
/// <value></value>
public string idp { get; set; }
public string licenseUrl { get; set; }
public string licenseExpression { get; set; }
/// <summary>
/// Should be considered as listed if absent
/// </summary>
/// <value></value>
public bool listed { get; set; }
public string minClientVersion { get; set; }
public string projectUrl { get; set; }
/// <summary>
/// A string containing a ISO 8601 timestamp of when the package was published
/// </summary>
/// <value></value>
public string published { get; set; }
public bool requireLicenseAcceptance { get; set; }
public string summary { get; set; }
/// <summary>
/// The tags
/// </summary>
/// <value></value>
public string tags { get; set; }
public string title { get; set; }
/// <summary>
/// The full version string after normalization
/// </summary>
/// <value></value>
[Required,JsonRequired]
public string version { get; set; } // string yes
/// <summary>
/// The security vulnerabilities of the package
/// </summary>
/// <value></value>
public Vulnerabilitie[] vulnerabilities { get; set; }
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class CatalogIndex : IObject
{
[JsonProperty("@id")]
public string Id { get; set ; }
[JsonProperty("items")]
public List<PageRef> Items { get; set; }
[JsonProperty("count")]
public int Count { get => Items?.Count ?? 0; }
public string CommitId { get; set; }
public DateTime CommitTimeStamp { get; set; }
}
}

View File

@ -0,0 +1,6 @@
namespace isnd.Data.Catalog
{
public class DependencyGroup
{
}
}

View File

@ -0,0 +1,14 @@
namespace isnd.Data.Catalog
{
public class Deprecation
{
/*
Legacy The package is no longer maintained
CriticalBugs The package has bugs which make it unsuitable for usage
Other The package is deprecated due to a reason not on this list
*/
public string[] reasons { get; set; } // array of strings yes The reasons why the package was deprecated
public string message { get; set; } // The additional details about this deprecation
public AlternatePackage alternatePackage { get; set; } // object no The alternate package that should be used instead
}
}

View File

@ -1,26 +0,0 @@
using System;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class PageRef : IObject
{
/// <summary>
/// Page Url
/// </summary>
/// <value></value>
[JsonProperty("@id")]
public string Id { get; set; }
/// <summary>
/// Page entry count
/// </summary>
/// <value></value>
[JsonProperty("count")]
public int Count { get; set; }
public string CommitId { get; set; }
public DateTime CommitTimeStamp { get; set; }
}
}

View File

@ -0,0 +1,40 @@
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
/// <summary>
/// Hosts a catalog entry,
/// the atomic content reference
/// </summary>
public class RegistrationLeaf
{
/*
@id string yes
catalogEntry object yes
packageContent string yes
*/
[JsonProperty("@id")]
[Key][Required]
[StringLength(1024)]
/// <summary>
/// The URL to the registration leaf
/// </summary>
/// <value></value>
public string Id { get; set; }
/// <summary>
/// The catalog entry containing the package metadata
/// </summary>
/// <value></value>
[JsonProperty("catalogEntry")]
public CatalogEntry Entry { get; set; }
/// <summary>
/// The URL to the package content (.nupkg)
/// </summary>
/// <value></value>
[JsonProperty("packageContent")]
public string PackageContent { get; set; }
}
}

View File

@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using isnd.Data.Packages;
using Newtonsoft.Json;
using NuGet.Versioning;
namespace isnd.Data.Catalog
{
public class RegistrationPage
{
[JsonProperty("@id")]
[JsonRequired]
public string Id { get; protected set;}
private List<PackageVersion> items;
protected string Bid { get ; private set; }
public string DlBase { get; }
public RegistrationPage (string bid, string dlBase)
{
Bid = bid;
DlBase = dlBase;
this.items = new List<PackageVersion>();
}
public RegistrationPage (string bid, string pkgid, string dlBase, IEnumerable<PackageVersion> items)
{
Bid = bid;
Parent = Bid + "/index.json";
DlBase = dlBase;
this.items = new List<PackageVersion>(items);
SetPackageId(pkgid);
UpdateCompact();
}
protected void SetPackageId(string pkgid)
{
this.Id = Bid + "/" + pkgid + "/index.json";
}
private void UpdateCompact()
{
NuGetVersion upper = new NuGetVersion(0,0,0);
// Assert.True(items.All(p=>p.Id == id));
foreach (var p in items)
{
if (upper < p.NugetVersion) upper = p.NugetVersion;
}
Upper = upper.ToFullString();
NuGetVersion lower = upper;
foreach (var p in items)
{
if (lower > p.NugetVersion) lower = p.NugetVersion;
}
Lower = lower.ToFullString();
}
/// <summary>
/// no The array of registration leaves and their associate metadata
/// </summary>
/// <value></value>
[JsonProperty("items")]
public RegistrationLeaf[] Items { get => items.Select((p) => p.ToLeave(Bid, DlBase)).ToArray(); }
public void AddVersionRange(IEnumerable<PackageVersion> vitems)
{
if (vitems.Count() == 0) return;
items.AddRange(vitems);
UpdateCompact();
}
/// <summary>
/// The highest SemVer 2.0.0 version in the page (inclusive)
/// </summary>
/// <value></value>
[JsonProperty("upper"), JsonRequired]
public string Upper { get; private set; }
/// <summary>
/// The lowest SemVer 2.0.0 version in the page (inclusive)
/// </summary>
/// <value></value>
[JsonProperty("lower"), JsonRequired]
public string Lower { get; private set; }
/// <summary>
/// The URL to the registration index
/// </summary>
/// <value></value>
[JsonProperty("parent")]
public string Parent { get; set; }
[JsonProperty("count")]
public int Count { get; internal set; }
public string CommitId { get; internal set; }
public DateTime CommitTimeStamp { get; internal set; }
}
}

View File

@ -0,0 +1,43 @@
using isnd.Data.Packages;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
namespace isnd.Data.Catalog
{
public class RegistrationPageIndex
{
/// <summary>
/// Page Url
/// </summary>
/// <value></value>
[JsonProperty("@id")]
public string Id { get; protected set; }
public RegistrationPageIndex(string bid, string id)
{
Id = bid + "/" + id + "/index.json";
Items = new List<RegistrationPage>();
}
public RegistrationPageIndex(string bid, string id, string dlBase, IEnumerable<Package> pkgs) : this(bid, id)
{
// leaves;
this.Items = new List<RegistrationPage>
(pkgs.GroupBy(l => l.Id)
.Select(lg => new RegistrationPage
(bid, lg.Key, dlBase, lg.ToArray()
.Select(p => p.Versions).Aggregate
((l, m) => { l.AddRange(m); return l.ToList(); })
)));
}
[JsonProperty("count")]
public int Count { get => Items?.Count ?? 0; }
[JsonProperty("items")]
public List<RegistrationPage> Items { get; set; }
public string CommitId { get; set; }
}
}

View File

@ -0,0 +1,28 @@
using System.Collections.Generic;
using isnd.Data.Packages;
using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class RegistrationPageIndexQuery
{
public RegistrationPageIndexQuery()
{
}
[JsonProperty("query")]
public string Query { get; set; }
[JsonProperty("prerelease")]
public bool Prerelease { get; set; } = true;
[JsonProperty("skip")]
public int Skip { get; set; } = 0;
[JsonProperty("take")]
public int Take { get; set; } = 25;
[JsonProperty("totalHits")]
public int TotalHits { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace isnd.Data.Catalog
{
public class Vulnerabilitie
{
public string advisoryUrl { get; set; } // string yes Location of security advisory for the package
public string severity { get; set; } // string yes Severity of advisory: "0" = Low, "1" = Moderate, "2" = High, "3" = Critical
}
}

View File

@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using isnd.Data.Catalog; using isnd.Data.Packages;
using isnd.Data.Packages.Catalog;
namespace isnd.Data.Historic namespace isnd.Data.Historic
{ {

View File

@ -1,48 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using isnd.Data.Catalog;
using Newtonsoft.Json;
namespace isnd.Data
{
public class PackageVersion
{
[Required]
[ForeignKey("Package")]
[StringLength(1024)]
public string PackageId { get; set; }
[Required]
public int Major { get; set; }
[Required]
public int Minor { get; set; }
[Required]
public int Patch { get; set; }
[StringLength(256)]
[Required][Key]
public string FullString { get; set; }
public bool IsPrerelease { get; set; }
[StringLength(256)]
public string Type { get; set; }
[JsonIgnore]
public virtual Package Package { get; set; }
[Required][JsonIgnore]
[ForeignKey("LatestCommit")]
public long CommitNId { get; set ; }
[NotMapped]
public string CommitId { get => CommitNId.ToString(); }
public virtual Commit LatestCommit{ get; set; }
public string NugetLink => $"/package/{PackageId}/{FullString}/{PackageId}-{FullString}.nupkg";
public string NuspecLink => $"/package/{PackageId}/{FullString}/{PackageId}-{FullString}.nuspec";
}
}

View File

@ -1,14 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using isnd.Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace isnd.Data.Catalog namespace isnd.Data.Packages.Catalog
{ {
public class CatalogLeaf : IObject public class CatalogLeaf : IObject
{ {
[JsonProperty("@type")] [JsonProperty("@type")]
public List<string> RefType { get; set; } public string[] RefType { get; set; }
[JsonProperty("commitId")] [JsonProperty("commitId")]
public string CommitId { get; set; } public string CommitId { get; set; }

View File

@ -1,7 +1,7 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace isnd.Data.Catalog namespace isnd.Interfaces
{ {
public interface IObject public interface IObject
{ {

View File

@ -1,4 +1,4 @@
namespace isnd.Data.Catalog namespace isnd.Data.Packages.Catalog
{ {
public class PackageDetail : CatalogLeaf public class PackageDetail : CatalogLeaf
{ {

View File

@ -1,8 +1,9 @@
using System; using System;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using isnd.Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace isnd.Data.Catalog namespace isnd.Data.Packages.Catalog
{ {
/// <summary> /// <summary>
/// An presence of package in a catalog, /// An presence of package in a catalog,

View File

@ -1,8 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using isnd.Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace isnd.Data.Catalog namespace isnd.Data.Packages.Catalog
{ {
public class Page : IObject public class Page : IObject
{ {

View File

@ -3,8 +3,9 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json; using Newtonsoft.Json;
using isnd.Interfaces;
namespace isnd.Data.Catalog namespace isnd.Data.Packages
{ {
public enum PackageAction public enum PackageAction
{ {

View File

@ -2,10 +2,12 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using isnd.Data.Catalog; using isnd.Data.Catalog;
using isnd.Interfaces;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace isnd.Data namespace isnd.Data.Packages
{ {
public class Package : IObject public class Package : IObject
{ {
@ -30,8 +32,8 @@ namespace isnd.Data
public virtual List<PackageVersion> Versions { get; set; } public virtual List<PackageVersion> Versions { get; set; }
/// <summary> /// <summary>
/// Latest package version put, or post, /// Latest version at put, posted,
/// or { delete when no more active version }. /// or even deletion when no more active version.
/// </summary> /// </summary>
/// <value></value> /// <value></value>
[Required][JsonIgnore] [Required][JsonIgnore]
@ -44,5 +46,28 @@ namespace isnd.Data
public virtual Commit LatestVersion{ get; set; } public virtual Commit LatestVersion{ get; set; }
public DateTime CommitTimeStamp { get; set; } public DateTime CommitTimeStamp { get; set; }
/// <summary>
/// Returns the leaf
/// </summary>
/// <param name="bid">base url tu use for building the id property</param>
/// <returns></returns>
public RegistrationLeaf ToLeave(string bid)
{
if (Versions.Count == 0) throw new Exception("NO VERSION");
var v = Versions.OrderBy(w => w.NugetVersion).First();
RegistrationLeaf leave = new RegistrationLeaf
{
Id = bid + Id + "/" + v.FullString + ".json",
PackageContent = v.NugetLink,
Entry = new CatalogEntry
{
Id = bid + Id + ".json",
idp = Id,
version = v.FullString,
authors = $"{Owner.FullName} <${Owner.Email}>"
}
};
return leave;
}
} }
} }

View File

@ -0,0 +1,83 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using isn.abst;
using isnd.Data.Catalog;
using isnd.Data.Packages;
using isnd.Data.Packages.Catalog;
using Newtonsoft.Json;
using NuGet.Versioning;
namespace isnd.Data
{
public class PackageVersion
{
[Required]
[ForeignKey("Package")]
[StringLength(1024)]
[JsonProperty("id")]
public string PackageId { get; set; }
[Required]
public int Major { get; set; }
[Required]
public int Minor { get; set; }
[Required]
public int Patch { get; set; }
public int Revision { get; set; }
/// <summary>
/// Full version string
/// </summary>
/// <value></value>
[StringLength(256)]
[Required][Key]
public string FullString { get; set; }
public bool IsPrerelease { get; set; }
[StringLength(256)]
public string Type { get; set; }
[JsonIgnore]
public virtual Package Package { get; set; }
[Required][JsonIgnore]
[ForeignKey("LatestCommit")]
public long CommitNId { get; set; }
[NotMapped]
public string CommitId { get => CommitNId.ToString(); }
public virtual Commit LatestCommit {get; set; }
public string NugetLink => $"{Constants.PaquetFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}."
+ Constants.PaquetFileEstension;
public string NuspecLink => $"{Constants.SpecFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}."
+ Constants.SpecFileEstension;
public string SementicVersionString { get => $"{Major}.{Minor}.{Patch}"; }
public NuGetVersion NugetVersion { get => new NuGetVersion(FullString); }
public RegistrationLeaf ToLeave(string bid, string dlbase)
{
string leaveid = bid + "/" + this.PackageId + "/" + FullString + ".json";
return new RegistrationLeaf
{
Id = leaveid,
PackageContent = dlbase + NugetLink,
Entry = new CatalogEntry
{
Id = leaveid,
idp = PackageId,
version = FullString,
authors = $"{this.Package.Owner.FullName} <${Package.Owner.Email}>"
}
};
}
}
}

View File

@ -2,12 +2,11 @@ namespace isnd.Helpers
{ {
public static class PackageIdHelpers public static class PackageIdHelpers
{ {
internal static bool SeparatedByMinusMatch(string id, string q) internal static bool SeparatedByMinusMatch(string id, string q)
{ {
foreach (var part in id.Split('-')) foreach (var part in id.Split('-'))
{ {
if (part.StartsWith(q, System.StringComparison.OrdinalIgnoreCase)) return true; if (part.Equals(q, System.StringComparison.OrdinalIgnoreCase)) return true;
} }
return false; return false;
} }
@ -24,7 +23,7 @@ namespace isnd.Helpers
while (id.Length > i && char.IsLower(id[i])) i++; while (id.Length > i && char.IsLower(id[i])) i++;
if (i == 0) break; if (i == 0) break;
id = id.Substring(i); id = id.Substring(i);
if (id.StartsWith(query, System.StringComparison.OrdinalIgnoreCase)) return true; if (id.Equals(query, System.StringComparison.OrdinalIgnoreCase)) return true;
} }
return false; return false;
} }

View File

@ -1,14 +1,19 @@
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;
} }
} }

View File

@ -2,6 +2,10 @@ namespace isnd.Helpers
{ {
public static class SiteHelpers public static class SiteHelpers
{ {
/// <summary>
/// The Git Sementic version (from GitVersion.MsBuild)[published]
/// </summary>
/// <value></value>
public static string SemVer { public static string SemVer {
get => GitVersionInformation.SemVer; get => GitVersionInformation.SemVer;
} }

View File

@ -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)
{ {

View File

@ -4,6 +4,8 @@ using isn.Abstract;
using isnd.Controllers; 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.Catalog;
using isnd.Services; using isnd.Services;
using isnd.ViewModels; using isnd.ViewModels;
using NuGet.Versioning; using NuGet.Versioning;
@ -13,15 +15,20 @@ 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();
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);
PackageIndexViewModel 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 userid, string pkgId, 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 pkgId, string semver, string pkgType);
IEnumerable<RegistrationLeaf> SearchById(string pkgId, string semver, string pkgType);
RegistrationPageIndex GetCatalogIndex();
RegistrationPageIndex GetPackageRegistrationIndex(RegistrationPageIndexQuery query);
} }
} }

View File

@ -0,0 +1,358 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using isnd.Data;
namespace isndhost.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220926205013_revision")]
partial class revision
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.1.14-servicing-32113")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("CreationDate");
b.Property<string>("Name");
b.Property<string>("UserId")
.IsRequired();
b.Property<int>("ValidityPeriodInDays");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("isnd.Data.ApplicationUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<string>("FullName");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Action");
b.Property<DateTime>("TimeStamp");
b.HasKey("Id");
b.ToTable("Commits");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasMaxLength(1024);
b.Property<long>("CommitNId");
b.Property<DateTime>("CommitTimeStamp");
b.Property<string>("Description")
.HasMaxLength(1024);
b.Property<string>("OwnerId")
.IsRequired();
b.Property<bool>("Public");
b.HasKey("Id");
b.HasIndex("CommitNId");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.Property<string>("FullString")
.ValueGeneratedOnAdd()
.HasMaxLength(256);
b.Property<long>("CommitNId");
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<string>("PackageId")
.IsRequired()
.HasMaxLength(1024);
b.Property<int>("Patch");
b.Property<string>("Type")
.HasMaxLength(256);
b.HasKey("FullString");
b.HasIndex("CommitNId");
b.HasIndex("PackageId");
b.ToTable("PackageVersions");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider");
b.Property<string>("Name");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isnd.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestVersion")
.WithMany()
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany("Versions")
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.Packages.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,17 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class revision : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

View File

@ -0,0 +1,360 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using isnd.Data;
namespace isndhost.Migrations
{
[DbContext(typeof(ApplicationDbContext))]
[Migration("20220926223321_Re_Vision")]
partial class Re_Vision
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.1.14-servicing-32113")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("CreationDate");
b.Property<string>("Name");
b.Property<string>("UserId")
.IsRequired();
b.Property<int>("ValidityPeriodInDays");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("isnd.Data.ApplicationUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<string>("FullName");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Action");
b.Property<DateTime>("TimeStamp");
b.HasKey("Id");
b.ToTable("Commits");
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd()
.HasMaxLength(1024);
b.Property<long>("CommitNId");
b.Property<DateTime>("CommitTimeStamp");
b.Property<string>("Description")
.HasMaxLength(1024);
b.Property<string>("OwnerId")
.IsRequired();
b.Property<bool>("Public");
b.HasKey("Id");
b.HasIndex("CommitNId");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.Property<string>("FullString")
.ValueGeneratedOnAdd()
.HasMaxLength(256);
b.Property<long>("CommitNId");
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<string>("PackageId")
.IsRequired()
.HasMaxLength(1024);
b.Property<int>("Patch");
b.Property<int>("Revision");
b.Property<string>("Type")
.HasMaxLength(256);
b.HasKey("FullString");
b.HasIndex("CommitNId");
b.HasIndex("PackageId");
b.ToTable("PackageVersions");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider");
b.Property<string>("ProviderKey");
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider");
b.Property<string>("Name");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isnd.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestVersion")
.WithMany()
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{
b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany("Versions")
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.Packages.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isnd.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,23 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class Re_Vision : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "Revision",
table: "PackageVersions",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Revision",
table: "PackageVersions");
}
}
}

View File

@ -92,7 +92,7 @@ namespace isndhost.Migrations
b.ToTable("AspNetUsers"); b.ToTable("AspNetUsers");
}); });
modelBuilder.Entity("isnd.Data.Catalog.Commit", b => modelBuilder.Entity("isnd.Data.Packages.Commit", b =>
{ {
b.Property<long>("Id") b.Property<long>("Id")
.ValueGeneratedOnAdd(); .ValueGeneratedOnAdd();
@ -106,7 +106,7 @@ namespace isndhost.Migrations
b.ToTable("Commits"); b.ToTable("Commits");
}); });
modelBuilder.Entity("isnd.Data.Package", b => modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{ {
b.Property<string>("Id") b.Property<string>("Id")
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
@ -153,6 +153,8 @@ namespace isndhost.Migrations
b.Property<int>("Patch"); b.Property<int>("Patch");
b.Property<int>("Revision");
b.Property<string>("Type") b.Property<string>("Type")
.HasMaxLength(256); .HasMaxLength(256);
@ -280,9 +282,9 @@ namespace isndhost.Migrations
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
}); });
modelBuilder.Entity("isnd.Data.Package", b => modelBuilder.Entity("isnd.Data.Packages.Package", b =>
{ {
b.HasOne("isnd.Data.Catalog.Commit", "LatestVersion") b.HasOne("isnd.Data.Packages.Commit", "LatestVersion")
.WithMany() .WithMany()
.HasForeignKey("CommitNId") .HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
@ -295,12 +297,12 @@ namespace isndhost.Migrations
modelBuilder.Entity("isnd.Data.PackageVersion", b => modelBuilder.Entity("isnd.Data.PackageVersion", b =>
{ {
b.HasOne("isnd.Data.Catalog.Commit", "LatestCommit") b.HasOne("isnd.Data.Packages.Commit", "LatestCommit")
.WithMany("Versions") .WithMany("Versions")
.HasForeignKey("CommitNId") .HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.Package", "Package") b.HasOne("isnd.Data.Packages.Package", "Package")
.WithMany("Versions") .WithMany("Versions")
.HasForeignKey("PackageId") .HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade); .OnDelete(DeleteBehavior.Cascade);

View File

@ -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);

View File

@ -6,6 +6,8 @@ using System.Threading.Tasks;
using isn.Abstract; using isn.Abstract;
using isnd.Data; using isnd.Data;
using isnd.Data.Catalog; using isnd.Data.Catalog;
using isnd.Data.Packages;
using isnd.Data.Packages.Catalog;
using isnd.Entities; using isnd.Entities;
using isnd.Helpers; using isnd.Helpers;
using isnd.Interfaces; using isnd.Interfaces;
@ -22,7 +24,7 @@ namespace isnd.Services
public const string BASE_API_LEVEL = "3.5.0"; public const string BASE_API_LEVEL = "3.5.0";
ApplicationDbContext dbContext; ApplicationDbContext dbContext;
public PackageManager(ApplicationDbContext dbContext, public PackageManager(ApplicationDbContext dbContext,
IOptions<IsndSettings> siteConfigOptionsOptions) IOptions<IsndSettings> siteConfigOptionsOptions)
{ {
@ -47,15 +49,15 @@ namespace isnd.Services
Comment = "Package Publish service" Comment = "Package Publish service"
}); });
// under dev, only leash in release mode // under dev, only leash in release mode
if (unleashClient.IsEnabled("pkg-get", false)) if (unleashClient.IsEnabled("pkg-get", true))
res.Add( res.Add(
new Resource new Resource
{ {
Id = extUrl + ApiConfig.Base, Id = extUrl + ApiConfig.GetPackage,
Type = "PackageBaseAddress/" + BASE_API_LEVEL, Type = "PackageBaseAddress/3.0.0",
Comment = "Package Base Address service" Comment = "Package Base Address service"
}); });
if (unleashClient.IsEnabled("pkg-autocomplete", false)) if (unleashClient.IsEnabled("pkg-autocomplete", true))
res.Add( res.Add(
new Resource new Resource
{ {
@ -71,47 +73,55 @@ namespace isnd.Services
Type = "SearchQueryService/" + BASE_API_LEVEL, Type = "SearchQueryService/" + BASE_API_LEVEL,
Comment = "Search Query service" Comment = "Search Query service"
}); });
if (unleashClient.IsEnabled("pkg-catalog", false)) if (unleashClient.IsEnabled("pkg-catalog", true))
res.Add( res.Add(
new Resource new Resource
{ {
Id = extUrl + ApiConfig.Catalog, Id = extUrl + ApiConfig.Catalog,
Type = "Catalog/"+ BASE_API_LEVEL, Type = "Catalog/" + BASE_API_LEVEL,
Comment = "Package Catalog Index" Comment = "Package Catalog Index"
}); });
if (unleashClient.IsEnabled("pkg-registration", false))
res.Add( /* FIXME */
res.Add(
new Resource new Resource
{ {
Id = extUrl + ApiConfig.Registration, Id = extUrl + "v" + BASE_API_LEVEL + "/" + ApiConfig.Registration,
Type = "Catalog/" + BASE_API_LEVEL, Type = "RegistrationsBaseUrl",
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."
}); });
res.Add(
new Resource
{
Id = extUrl + "v3.0.0-beta/" + ApiConfig.Registration,
Type = "RegistrationsBaseUrl/3.0.0-beta",
Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
});
res.Add(
new Resource
{
Id = extUrl + "v3.0.0-rc/" + ApiConfig.Registration,
Type = "RegistrationsBaseUrl/3.0.0-rc",
Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
});
res.Add(new Resource
{
Id = extUrl + "v3.4.0/" + ApiConfig.Registration,
Type = "RegistrationsBaseUrl/3.4.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."
});
res.Add(new Resource
{
Id = extUrl + "v3.6.0/" + ApiConfig.Registration,
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."
});
return res; return res;
} }
public PackageIndexViewModel SearchByName(string query,
int skip, int take, bool prerelease = false,
string packageType = null)
{
var scope = dbContext.Packages
.Include(p => p.Versions)
.Where(
p => (PackageIdHelpers.CamelCaseMatch(p.Id, query) || PackageIdHelpers.SeparatedByMinusMatch(p.Id, query))
&& (prerelease || p.Versions.Any(v => !v.IsPrerelease))
&& (packageType == null || p.Versions.Any(v => v.Type == packageType))
);
var total = scope.Count();
var pkgs = scope.Skip(skip).Take(take).ToArray();
return new PackageIndexViewModel
{
Query = query,
TotalHits = total,
Data = pkgs
};
}
public AutoCompleteResult AutoComplete(string id, public AutoCompleteResult AutoComplete(string id,
int skip, int take, bool prerelease = false, int skip, int take, bool prerelease = false,
string packageType = null) string packageType = null)
@ -146,17 +156,20 @@ namespace isnd.Services
&& (packageType == null || v.Type == packageType) && (packageType == null || v.Type == packageType)
&& (parsedVersion.CompareTo(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0) && (parsedVersion.CompareTo(new SemanticVersion(v.Major, v.Minor, v.Patch)) < 0)
) )
.OrderBy(v => v.FullString) .OrderBy(v => v.NugetVersion)
.Select(v => v.FullString) .Select(v => v.FullString)
.Skip(skip).Take(take).ToArray(); .Skip(skip).Take(take).ToArray();
} }
public static CatalogIndex CurrentCatalogIndex { get; protected set; } public static RegistrationPageIndex CurrentCatalogIndex { get; protected set; }
public static List<Page> CurrentCatalogPages { get; protected set; } public static List<RegistrationPage> CurrentCatalogPages { get; protected set; }
public string CatalogBaseUrl => extUrl;
private IsndSettings isndSettings; private IsndSettings isndSettings;
private string extUrl; private string extUrl;
public virtual CatalogIndex GetCatalogIndex() public virtual RegistrationPageIndex GetCatalogIndex()
{ {
if (CurrentCatalogIndex == null) if (CurrentCatalogIndex == null)
{ {
@ -170,36 +183,29 @@ namespace isnd.Services
int p = 0; int p = 0;
var oldIndex = CurrentCatalogIndex; var oldIndex = CurrentCatalogIndex;
var oldPages = CurrentCatalogPages; var oldPages = CurrentCatalogPages;
string baseid= extUrl + ApiConfig.Catalog; string baseid = extUrl + ApiConfig.Catalog;
string basepageid= extUrl + ApiConfig.CatalogPage; string bidreg = $"{extUrl}v3.4.0/{ApiConfig.Registration}";
CurrentCatalogIndex = new CatalogIndex string basepageid = extUrl + ApiConfig.CatalogPage;
{ CurrentCatalogIndex = new RegistrationPageIndex(baseid,"index");
Id = baseid, CurrentCatalogPages = new List<RegistrationPage>();
Items = new List<PageRef>()
};
CurrentCatalogPages = new List<Page>();
var scope = dbContext.Commits.OrderBy(c => c.TimeStamp); var scope = dbContext.Commits.OrderBy(c => c.TimeStamp);
PageRef pageRef = null; RegistrationPage page = null;
Page page = null;
i = isndSettings.CatalogPageLen; i = isndSettings.CatalogPageLen;
foreach (var commit in scope) foreach (var commit in scope)
{ {
if (i >= this.isndSettings.CatalogPageLen) if (i >= this.isndSettings.CatalogPageLen)
{ {
page = new Page page = new RegistrationPage(basepageid, extUrl)
{ {
Id = basepageid + "-" + p++,
Parent = baseid, Parent = baseid,
CommitId = commit.CommitId, CommitId = commit.CommitId,
CommitTimeStamp = commit.CommitTimeStamp, CommitTimeStamp = commit.CommitTimeStamp
Items = new List<PackageRef>()
}; };
CurrentCatalogPages.Add(page); CurrentCatalogPages.Add(page);
pageRef = new PageRef var pageRef = new RegistrationPage(page.Id, extUrl)
{ {
Id = page.Id,
CommitId = commit.CommitId, CommitId = commit.CommitId,
CommitTimeStamp = commit.CommitTimeStamp CommitTimeStamp = commit.CommitTimeStamp
}; };
@ -207,37 +213,32 @@ namespace isnd.Services
i = 0; i = 0;
} }
var validPkgs = dbContext.Packages var validPkgs = dbContext.Packages
.Include(po => po.Owner)
.Include(pkg => pkg.Versions) .Include(pkg => pkg.Versions)
.Include(pkg => pkg.LatestVersion) .Include(pkg => pkg.LatestVersion)
.Where( .Where(
pkg => pkg.Versions.Count(v => v.CommitId == commit.CommitId) > 0 pkg => pkg.Versions.Count(v => v.CommitId == commit.CommitId) > 0
); ).GroupBy((q) => q.Id);
// pkg.Versions.OrderByDescending(vi => vi.CommitNId).First().FullString // pkg.Versions.OrderByDescending(vi => vi.CommitNId).First().FullString
foreach (var pkg in validPkgs) foreach (var pkgid in validPkgs)
{ {
var v = pkg.Versions. StringBuilder refid = new StringBuilder(bidreg);
Where (cv => cv.CommitId == commit.CommitId) refid.AppendFormat("{0}/",
.OrderByDescending(vc => vc.CommitNId).First(); pkgid.Key);
/* var pkgref = new PackageRef
StringBuilder refid = new StringBuilder(extUrl); {
refid.AppendFormat("{0}/{1}/{2}",ApiConfig.CatalogLeaf, v.PackageId Version = v.FullString,
, v.FullString); LastCommit = v.LatestCommit,
if (v.Type!=null) CommitId = v.LatestCommit.CommitId,
refid.AppendFormat("/{0}",v.Type); CommitTimeStamp = v.LatestCommit.CommitTimeStamp,
RefId = refid.ToString(),
var pkgref = new PackageRef Id = v.PackageId,
{ RefType = v.LatestCommit.Action == PackageAction.PublishPackage
Version = v.FullString, ? "nuget:PackageDetails" :
LastCommit = v.LatestCommit, "nuget:PackageDelete"
CommitId = v.LatestCommit.CommitId, }; */
CommitTimeStamp = v.LatestCommit.CommitTimeStamp, foreach (var pkgv in pkgid)
RefId = refid.ToString(), page.AddVersionRange(pkgv.Versions);
Id = v.PackageId,
RefType = v.LatestCommit.Action == PackageAction.PublishPackage
? "nuget:PackageDetails" :
"nuget:PackageDelete"
};
page.Items.Add(pkgref);
} }
reason = commit; reason = commit;
i++; i++;
@ -256,8 +257,9 @@ namespace isnd.Services
public async Task<PackageDeletionReport> DeletePackageAsync(string pkgid, string version, string type) public async Task<PackageDeletionReport> DeletePackageAsync(string pkgid, string version, string type)
{ {
// TODO package deletion on disk // TODO deletion on disk
var commit = new Commit{ var commit = new Commit
{
Action = PackageAction.DeletePackage, Action = PackageAction.DeletePackage,
TimeStamp = DateTime.Now TimeStamp = DateTime.Now
}; };
@ -269,12 +271,12 @@ namespace isnd.Services
); );
if (pkg == null) if (pkg == null)
{ {
return new PackageDeletionReport{ Deleted = false }; return new PackageDeletionReport { Deleted = false };
} }
dbContext.PackageVersions.Remove(pkg); dbContext.PackageVersions.Remove(pkg);
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync();
ÛpdateCatalogFor(commit); ÛpdateCatalogFor(commit);
return new PackageDeletionReport{ Deleted = true, DeletedVersion = pkg }; return new PackageDeletionReport { Deleted = true, DeletedVersion = pkg };
} }
public async Task<PackageVersion> GetPackageAsync(string pkgid, string version, string type) public async Task<PackageVersion> GetPackageAsync(string pkgid, string version, string type)
@ -285,5 +287,63 @@ namespace isnd.Services
v.Type == type v.Type == type
); );
} }
public IEnumerable<PackageVersion> GetCatalogLeaf(string pkgId, string semver, string pkgType)
{
return dbContext.PackageVersions
.Include(v => v.Package)
.Include(v => v.LatestCommit)
.Where(v => v.PackageId == pkgId
&& (semver == null ||
semver.StartsWith(v.SementicVersionString))
&& (pkgType == null || pkgType == 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 };
}
public IEnumerable<Data.Catalog.RegistrationLeaf> SearchById(string pkgId, string semver, string pkgType)
{
string bid = $"{extUrl}v3.4.0/{ApiConfig.Registration}";
return dbContext.PackageVersions
.Include(v => v.Package)
.Include(v => v.Package.Owner)
.Include(v => v.LatestCommit)
.Where(v => v.PackageId == pkgId && semver.Equals(v.FullString, StringComparison.OrdinalIgnoreCase)
&& (pkgType == null || pkgType == v.Type))
.OrderByDescending(p=> p.CommitId)
.Select(p => p.Package.ToLeave(bid))
;
}
public PackageVersion GetPackage(string pkgId, string semver, string pkgType)
{
return dbContext.PackageVersions
.Include(v => v.Package)
.Include(v => v.LatestCommit)
.Single(v => v.PackageId == pkgId && semver == v.FullString
&& (pkgType == null || pkgType == v.Type));
}
public RegistrationPageIndex GetPackageRegistrationIndex(RegistrationPageIndexQuery query)
{
// RegistrationPageIndexAndQuery
var scope = dbContext.Packages.Include(p => p.Versions).Include(p => p.Owner)
.Where(p => (PackageIdHelpers.CamelCaseMatch(p.Id, query.Query)
|| PackageIdHelpers.SeparatedByMinusMatch(p.Id, query.Query))
&& (query.Prerelease || p.Versions.Any(v => !v.IsPrerelease)));
var total = scope.Count();
var pkgs = scope.Skip(query.Skip).Take(query.Take).ToArray();
string bid = $"{extUrl}v3.4.0/{ApiConfig.Registration}";
return
new RegistrationPageIndex(bid, query.Query, extUrl, pkgs);
}
} }
} }

View File

@ -22,13 +22,14 @@ namespace isnd
{ {
public class Startup public class Startup
{ {
public static string ExternalAddress { get; internal set; }
public Startup(IConfiguration config) public Startup(IConfiguration config)
{ {
Configuration = config; Configuration = config;
} }
public IConfiguration Configuration { get; } public static IConfiguration Configuration { get; private set; }
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
@ -81,25 +82,19 @@ namespace isnd
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<Microsoft.AspNetCore.Hosting.IHostingEnvironment>().CreateUnleahClient(config.Value);
}); });
services.AddAuthentication("Bearer") services.AddAuthentication("Bearer")
.AddJwtBearer("Bearer", options => .AddJwtBearer("Bearer", options =>
{ {
options.Authority = "https://localhost:5001"; options.Authority = ExternalAddress;
options.TokenValidationParameters = new TokenValidationParameters options.TokenValidationParameters = new TokenValidationParameters
{ {
ValidateAudience = false ValidateAudience = false
}; };
}); });
} }
public static IUnleash UnleashClient { get; private set; }
public static string ExternalAddress { get; internal set; }
// 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, Microsoft.AspNetCore.Hosting.IHostingEnvironment env,
@ -117,7 +112,7 @@ namespace isnd
dbContext.Database.Migrate(); dbContext.Database.Migrate();
} }
app.UseHttpsRedirection(); // app.UseHttpsRedirection();
app.UseStatusCodePages().UseStaticFiles().UseAuthentication().UseMvc(routes => app.UseStatusCodePages().UseStaticFiles().UseAuthentication().UseMvc(routes =>
{ {
routes.MapRoute( routes.MapRoute(

View File

@ -0,0 +1,38 @@
using System;
using Newtonsoft.Json;
namespace isnd.ViewModels
{
public class CatalogRegistration
{
[JsonProperty("@id")]
public string Id { get; set; }
/*
"@id": "https://api.nuget.org/v3/registration3/nuget.versioning/4.3.0.json",
"catalogEntry": "https://api.nuget.org/v3/catalog0/data/2017.08.11.18.24.22/nuget.versioning.4.3.0.json",
"listed": true,
"packageContent": "https://api.nuget.org/v3-flatcontainer/nuget.versioning/4.3.0/nuget.versioning.4.3.0.nupkg",
"published": "2017-08-11T18:24:14.36+00:00",
"registration": "https://api.nuget.org/v3/registration3/nuget.versioning/index.json"
*/
[JsonProperty("catalogEntry")]
public string CatalogEntry { get; set; }
[JsonProperty("listed")]
public bool Listed { get; set; } = true;
[JsonProperty("packageContent")]
public string PackageContent { get; set; }
[JsonProperty("published")]
public DateTime CommitTimeStamp { get; set; }
[JsonProperty("registration")]
public string registration { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using isnd.Data;
using Newtonsoft.Json;
namespace isnd.ViewModels
{
public class PackageIndexViewModel
{
[JsonProperty("prerelease")]
public bool Prerelease { get; set; }
[JsonProperty("data")]
public Package[] Data {get; set;}
[JsonProperty("query")]
public string Query { get; set; }
[JsonProperty("totalHits")]
public int TotalHits { get; internal set; }
}
}

View File

@ -1,4 +1,5 @@
using isnd.Data; using isnd.Data;
using isnd.Data.Packages;
namespace isnd.Services namespace isnd.Services
{ {

View File

@ -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>

View File

@ -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)
@ -43,7 +43,7 @@
@foreach (var item in Model.Versions) { @foreach (var item in Model.Versions) {
<tr> <tr>
<td> <td>
@Html.DisplayFor(modelItem => item.Package.Id) @Html.DisplayFor(modelItem => item.PackageId)
<a href="@item.NugetLink"> <a href="@item.NugetLink">
nuget nuget
</a> </a>

View File

@ -38,7 +38,8 @@
<pre><code id="code" >&lt;PackageReference Include="@Model.pkgid" Version="@Model.latest.FullString" /&gt;</code></pre> <pre><code id="code" >&lt;PackageReference Include="@Model.pkgid" Version="@Model.latest.FullString" /&gt;</code></pre>
</div> </div>
<div> <div>
@Html.ActionLink("Edit", "Edit", new { pkgid = Model.pkgid, version = Model.latest.FullString }) | @Html.ActionLink("Edit", "Edit", new { pkgid = Model.pkgid, version = Model.latest.FullString }) |
@Html.ActionLink("Delete", "Delete", new { pkgid = Model.pkgid, version= Model.latest.FullString }) |
<a asp-action="Index">Back to List</a> <a asp-action="Index">Back to List</a>
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
@model PackageIndexViewModel @model isnd.RegistrationPageIndexQueryAndResult
@{ @{
ViewData["Title"] = "Index"; ViewData["Title"] = "Index";
@ -11,9 +11,9 @@
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group"> <div class="form-group">
<label asp-for="Query" class="control-label"></label> <label asp-for="Query.Query" class="control-label"></label>
<input asp-for="Query" class="form-control" /> <input asp-for="Query.Query" class="form-control" />
<label asp-for="TotalHits" class="control-label"></label> <label asp-for="Query.TotalHits" class="control-label"></label>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="submit" value="Find" class="btn btn-default" /> <input type="submit" value="Find" class="btn btn-default" />
@ -25,29 +25,29 @@
<thead> <thead>
<tr> <tr>
<th> <th>
@Html.DisplayNameFor(model => model.Data[0].Id) @Html.DisplayNameFor(model => model.Result.Items[0].Id)
</th> </th>
<th> <th>
@Html.DisplayNameFor(model => model.Data[0].Description) @Html.DisplayNameFor(model => model.Result.Items[0].CommitId)
</th> </th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach (var item in Model.Data) { @foreach (var page in Model.Result.Items) {
@foreach (var item in page.Items) {
<tr> <tr>
<td> <td>
@Html.DisplayFor(modelItem => item.Id) @Html.DisplayFor(modelItem => item.Id)
</td> </td>
<td> <td>
@Html.DisplayFor(modelItem => item.Description) @Html.DisplayFor(modelItem => item.Entry.Description)
</td> </td>
<td> <td>
@Html.ActionLink("Details", "Details", new { pkgid = item.Id }) | @Html.ActionLink("Details", "Details", new { pkgid = item.Id })
@Html.ActionLink("Delete", "Delete", new { pkgid = item.Id })
</td> </td>
</tr> </tr>
} }}
</tbody> </tbody>
</table> </table>

View File

@ -3,15 +3,16 @@
<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" >
</head> </head>
<body> <body>
<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>
@ -24,10 +25,15 @@
<a class="nav-link" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a> <a class="nav-link" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li> </li>
</ul> </ul>
<form class="form-inline my-2 my-lg-0" asp-action="Index" asp-controller="Packages"> <div class="navbar-nav mr-auto">
<input name="Query" id="Query" class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"> <div class="navbar-item">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> <form class="form-inline my-2 my-lg-0" asp-action="Index" asp-controller="Packages">
<input style="margin:.3em;" name="Query" id="Query" class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<input style="margin:.3em;" name="IsPrerelease" id="IsPrerelease" class="form-control mr-sm-2" type="checkbox" checked><label for="IsPrerelease"> <i>Pre-release </i></Label>
<button style="margin:.3em;" class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form> </form>
</div>
</div>
<partial name="_LoginPartial" /> <partial name="_LoginPartial" />
</div> </div>
</div> </div>

View File

@ -1,4 +1,5 @@
@using isnd.Data @using isnd.Data
@using isnd.ViewModels @using isnd.ViewModels
@using isnd.Helpers @using isnd.Helpers
@using isnd.Data.Catalog;
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,39 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<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" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="2.1.6" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="2.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="2.1.2" />
<PackageReference Include="Microsoft.AspNetCore.All" /> <PackageReference Include="Microsoft.AspNetCore.All" />
<PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="NuGet.Packaging.Core" Version="5.9.0" /> <PackageReference Include="NuGet.Packaging.Core" Version="5.6.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.30" />
<PackageReference Include="MailKit" Version="2.11.1" /> <PackageReference Include="MailKit" Version="2.8.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.1" IncludeAssets="All" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" IncludeAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.1" IncludeAssets="All" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.2" IncludeAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" IncludeAssets="All" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.3" IncludeAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.2" />
<PackageReference Include="unleash.client" Version="1.6.1" /> <PackageReference Include="unleash.client" Version="1.6.1" />
<PackageReference Include="GitVersion.MsBuild" Version="5.6.10*"> <PackageReference Include="GitVersion.MsBuild" Version="5.6.10*">
<PrivateAssets>All</PrivateAssets> <PrivateAssets>All</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="4.6.0" />
<PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="../isn.abst/isn.abst.csproj" /> <ProjectReference Include="../isn.abst/isn.abst.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" /> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.2" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.1.0-preview1-final" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.1.0-preview1-final" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -7843,7 +7843,11 @@ a.text-dark:hover, a.text-dark:focus {
border: 1px solid #333; border: 1px solid #333;
box-shadow: 8px 8px 5px #444; box-shadow: 8px 8px 5px #444;
padding: 8px 12px; padding: 8px 12px;
background-image: linear-gradient(180deg, #fff, #ddd 40%, #ccc); } background-image: linear-gradient(180deg, #fff, #ddd 40%, #ccc);
margin: 1em; }
.fa-copy { .fa-copy {
cursor: copy; } cursor: copy; }
.border-top.footer.text-muted {
padding: 1em; }

View File

@ -105,8 +105,14 @@ background-color: black;
box-shadow: 8px 8px 5px #444; box-shadow: 8px 8px 5px #444;
padding: 8px 12px; padding: 8px 12px;
background-image: linear-gradient(180deg, #fff, #ddd 40%, #ccc); background-image: linear-gradient(180deg, #fff, #ddd 40%, #ccc);
margin: 1em;
} }
.fa-copy { .fa-copy {
cursor: copy; cursor: copy;
} }
.border-top.footer.text-muted {
padding: 1em;
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<apikeys>
</apikeys>
<packageSources>
<add key="isn-dev" value="http://localhost:5000/index.json" protocolVersion="3" />
</packageSources>
</configuration>

View File

@ -0,0 +1,2 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

4
test/data/test-isn/isn-test.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
nuget locals all -clear && dotnet nuget locals all --clear && nuget add Yavsc.Abstract -Config NuGet.Config -Source isn-dev

View File

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

View File

@ -0,0 +1 @@
nuget install -NoCache -Verbosity detailed -ConfigFile NuGet.Config Yavsc.Abstract

View File

@ -9,6 +9,8 @@ using Newtonsoft.Json;
using isn.Abstract; using isn.Abstract;
using System.Linq; using System.Linq;
using Xunit; using Xunit;
using isn.abst;
using isnd.Entities;
namespace isn.tests namespace isn.tests
{ {
@ -25,52 +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/index.json"; 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.nupkg" }); var report = Program.PushPkg(new string[] { "/home/paul/Nupkgs/Yavsc.Abstract.1.0.8."
+ 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);
} }
} }

View File

@ -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" />

View File

@ -1,33 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework> <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<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" />
<PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" /> <PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.runner.reporters" Version="2.4.1" /> <PackageReference Include="xunit.runner.reporters" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageToolReference Include="xunit.runner.console" Version="2.4.1" PrivateAssets="All" /> <PackageReference Include="Microsoft.AspNetCore.Antiforgery" Version="2.1.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\isnd\isnd.csproj" /> <ProjectReference Include="..\..\src\isnd\isnd.csproj" />
<ProjectReference Include="..\..\src\isn\isn.csproj" /> <ProjectReference Include="..\..\src\isn\isn.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<MyTestingConfigFiles Include="appsettings.Testing.json" />
</ItemGroup>
<!--
<Target Name="CopyTestConfig" AfterTargets="Build">
<Copy SourceFiles="@(MyTestingConfigFiles)" DestinationFolder="$(OutputPath)" />
</Target>-->
</Project> </Project>