Compare commits

..

215 Commits
main ... net6

Author SHA1 Message Date
Paul Schneider e8eee642c2 code cleanup 1 year ago
Paul Schneider 34d0c3c4fe REORG 2 years ago
Paul Schneider dc30540e40 bump to net7.0 framework 2 years ago
Paul Schneider 6f79be26d8 builds 2 years ago
Paul Schneider ca079e1c47 a descent catalog index /catalog 2 years ago
Paul Schneider 4f040be236 net6.0 2 years ago
Paul Schneider 70f6e411e5 version bump & click fixes 2 years ago
Paul Schneider 3695c17429 xunit web server collection 2 years ago
Paul Schneider 282b0277ae settings 2 years ago
Paul Schneider 18b67bd725 Elle est pas belle la vie ? 2 years ago
Paul Schneider 51dcb39c93 support alias as default source 2 years ago
Paul Schneider a7ea749d2c Nothing concrete . 2 years ago
Paul Schneider 95600facf4 search view fixed 2 years ago
Paul Schneider 58f77a06ea A valid package index page 2 years ago
Paul Schneider 88c8480911 A valid registration page Index 2 years ago
Paul Schneider c147eaf54a by Nuget version 2 years ago
Paul Schneider e49db8e1a1 re_Vision 2 years ago
Paul Schneider 9aac183e2c Merge branch 'broken/ef' 2 years ago
Paul Schneider 037559a0b7 layout 2 years ago
Paul Schneider 9c4d45b97c + Revsion 2 years ago
Paul Schneider 9aa3140a11 WIP 2 years ago
Paul Schneider 7f9344d437 add a vscode task for ef db update 2 years ago
Paul Schneider f46ca00de9 REORG 2 years ago
Paul Schneider fcea41f8c1 Catalog++ 2 years ago
Paul Schneider 58f49af5f0 publish 2 years ago
Paul Schneider fececb327e WIP reg page 2 years ago
Paul Schneider 14206ac477 catalog impl 2 years ago
Paul Schneider fa9a12ad49 WIP Page leaf 2 years ago
Paul Schneider 7f9984b059 WIP page leaf 2 years ago
Paul Schneider 2dcf1a2806 refacts 2 years ago
Paul Schneider a84e1d9750 Corrige la suppression de paquets 2 years ago
Paul Schneider 97eba2390e https redirection 2 years ago
Paul Schneider 6c9f29bc56 MEF 2 years ago
Paul Schneider 2d5438c943 presentation 2 years ago
Paul Schneider 519a4fbd46 Okey 2 years ago
Paul Schneider a11bab759e retour sur la MEF du footer 2 years ago
Paul Schneider d7f0a5db36 Footer layout 2 years ago
Paul Schneider 5d59760a77 version bump 2 years ago
Paul Schneider 3e09afcbfe Errors to Error std output 2 years ago
Paul Schneider 8fa4c04367 naming 2 years ago
Paul Schneider 60e4ca8c54 ex to output 2 years ago
Paul Schneider da92b9dbec er 2 years ago
Paul Schneider 6194e185b9 gitversion tool 2 years ago
Paul Schneider 5c1a49811a Versioning 2 years ago
Paul Schneider 328f6f166a deploy 2 years ago
Paul Schneider 4191513eef Compilation warns 2 years ago
Paul Schneider 217cc49019 Versionning 2 years ago
Paul Schneider a4a1c6e271 WIP NuGet API 3.5.0 2 years ago
Paul Schneider c06f518836 fixing url's 2 years ago
Paul Schneider edc9628b67 testing config 2 years ago
Paul Schneider 4bb43877c7 Build test host using given app config file 2 years ago
Paul Schneider ce8b7bcdb3 Fixes the 500 2 years ago
Paul Schneider 67ec19184b reposted a pkg 2 years ago
Paul Schneider 57609e6ed3 Response status code does not indicate success: 500 (Internal Server Error). 2 years ago
Paul Schneider b46e786ace warn-- 2 years ago
Paul Schneider 423f9c15b3 not working by me. 2 years ago
Paul Schneider 6d21d7370c test 2 years ago
Paul Schneider ee07affbbd ... 2 years ago
Paul Schneider cba0720150 sources set-default 2 years ago
Paul Schneider a2d91e072f ... 2 years ago
Paul Schneider 1befc2e053 ... 2 years ago
Paul Schneider df55836c58 fixes the isn client update 3 years ago
Paul Schneider cd3629a5a0 dark theme, logo, tests 3 years ago
Paul Schneider 51a08dec9a icon 3 years ago
Paul Schneider 386eec262d dark theme 3 years ago
Paul Schneider 45d6c22d1e bad config file path 3 years ago
Paul Schneider 225c8ef588 bad config file name 3 years ago
Paul Schneider 290a3047b5 echo settings file path 3 years ago
Paul Schneider ec70927830 env is Dev 3 years ago
Paul Schneider 9f338ca09f testing app settings for ci 3 years ago
Paul Schneider cfd63fe68d default source apikey 3 years ago
Paul Schneider f33ca22255 uhnit testing from vscode 3 years ago
Paul Schneider e6f4349621 reorg 3 years ago
Paul Schneider 903f5157d2 unleash migrates 3 years ago
Paul Schneider 066c038e4d web ui 3 years ago
Paul Schneider 95aae91156 Refactorisation of deletion 3 years ago
Paul Schneider 6dd76ac1a5 REORG+histo 3 years ago
Paul Schneider 459f8ea422 nodejs ... 3 years ago
Paul Schneider 5607c53329 Fixes the base resource 3 years ago
Paul Schneider 71de903f13 bodies 3 years ago
Paul Schneider a92bee32e1 CQ 3 years ago
Paul Schneider 7a835c5c95 Fixes the versionCommit migration 3 years ago
Paul Schneider f918d26273 catalog updated at push 3 years ago
Paul Schneider 25d545e327 isn as net472 assembly 3 years ago
Paul Schneider 57feb53e82 Fixe l'Url du paquet dans le catalogue 3 years ago
Paul Schneider b7dae240cd Catalog packages 3 years ago
Paul Schneider d8bfdc293d catalog index 3 years ago
Paul Schneider f6fa7a0ec9 unit tests and pkg version commits 3 years ago
Paul Schneider 55e407d951 commit version 3 years ago
Paul Schneider cdb9a26d2c Catalog 3 years ago
Paul Schneider 504f431937 refact 3 years ago
Paul Schneider 7da74b0dfb dep & tags 3 years ago
Paul Schneider 6520d8e4cc dotnet 3 years ago
Paul Schneider 55b74a584a msbuild 3 years ago
Paul Schneider 0ec9889e96 msbuild ci tag 3 years ago
Paul Schneider b17ee8be75 Settings 3 years ago
Paul Schneider f6f3473346 protect 3 years ago
Paul Schneider ae114c68db refacts 3 years ago
Paul Schneider 5f0dfee768 bug on config 3 years ago
Paul Schneider 9ee058e1c8 bootstrap upgrade 3 years ago
Paul Schneider 30d81c06df update git ignore list 3 years ago
Paul Schneider 3845e2c9c4 serve 3 years ago
Paul Schneider 74427cc15e better Display 3 years ago
Paul Schneider 5c188b57fc cleaning 3 years ago
Paul Schneider 74ffc8e83e Prre release buton 3 years ago
Paul Schneider 7f0518ec82 Put it better 3 years ago
Paul Schneider 58750587d0 pkg upd by no db 3 years ago
Paul Schneider bd1c47e7c6 throw 3 years ago
Paul Schneider f7b375ad50 isnapikey 3 years ago
Paul Schneider 558d5fc8ae . 3 years ago
Paul Schneider fff4599ff4 fixes the put 3 years ago
Paul Schneider e356636539 Client installation notes 3 years ago
Paul Schneider 1aef7ce614 upgrade notes 3 years ago
Paul Schneider 82cec8eece Api Key view 3 years ago
Paul Schneider cd7c0be03d Unleash client instance as singleton 3 years ago
Paul Schneider a345992351 isn brand fix 3 years ago
Paul Schneider 5e74b24439 refact & client install notes 3 years ago
Paul Schneider 451d810ade using async methods 3 years ago
Paul Schneider 6f82a0a00f Activer le serveur 3 years ago
Paul Schneider 48ca2df19e async calls 3 years ago
Paul Schneider 355b2d4c7c Unleash client init 3 years ago
Paul Schneider d33a19d35f installation instructions 3 years ago
Paul Schneider 5a783edac2 Pipline status 3 years ago
Paul Schneider 32d25733af ci fix due to refact 3 years ago
Paul Schneider 709e1433bb isntallation steps 3 years ago
Paul Schneider 476d35ae8a refact 3 years ago
Paul Schneider 5de53a3cba rebrand 3 years ago
Paul Schneider ae6abc104a resources 3 years ago
Paul Schneider eba75d0db4 getversions 3 years ago
Paul Schneider aaa49788dc autocomplete 3 years ago
Paul Schneider b8809deaa1 search 3 years ago
Paul Schneider 6fcad7c252 MAJ de la description À l'incrément de version 3 years ago
Paul Schneider 2c31ffb7c4 ignorer une version existante en base mais pas sur le disque 3 years ago
Paul Schneider 58501329ac removes auto devops 3 years ago
Paul Schneider 8c25889e88 not only main 3 years ago
Paul Schneider 90b8913e98 master => main 3 years ago
Paul Schneider c88dccd950 reference some env 3 years ago
Paul Schneider 963ce8579c Update .gitlab-ci.yml 3 years ago
Paul Schneider 1c1964eb2c renames the 'deploy' job 3 years ago
Paul Schneider a5d6e08945 Merge branch 'set-sast-config-1' into 'master'
Set .gitlab-ci.yml to enable or configure SAST

See merge request Paul/nuget-host!1
3 years ago
Paul Schneider 21b51d4cbd Set .gitlab-ci.yml to enable or configure SAST 3 years ago
Paul Schneider 27634c3159 api key settings 3 years ago
Paul Schneider a11c30e782 re-ignore already present 3 years ago
Paul Schneider 5cb35f54d5 ci & admin & auth & cli 3 years ago
Paul Schneider 981f3209e0 ignore code 1 3 years ago
Paul Schneider 3fa1241ea2 cleaning 3 years ago
Paul Schneider c14adcdd80 try++ 3 years ago
Paul Schneider 25069e5aa2 try++ 3 years ago
Paul Schneider b341fdfa4d trying and fix 401 3 years ago
Paul Schneider e88763df09 simplified 3 years ago
Paul Schneider c456a28282 re push 3 years ago
Paul Schneider f7cfeeba8d add source or true 3 years ago
Paul Schneider 7752620bef deploy src/**/*.nupkg 3 years ago
Paul Schneider 4fa03c5a1d link warn & deploy to gitlab 3 years ago
Paul Schneider 61ba3b2bf8 a valid nuget local repo 3 years ago
Paul Schneider 1266dd54db nugetd 3 years ago
Paul Schneider be30ef3c25 gestion des versions :
* dossier des versions = FullString
* Suppressioni de versions
3 years ago
Paul Schneider 41fbe54638 minor change 3 years ago
Paul Schneider d80271dcbf permissions sur le paquet 3 years ago
Paul Schneider 3a59b8304a [{"PkgName":"nuget-cli.1.0.0.nupkg","Executed":true,"OK":true,"AlreadyPresent":false,"Message":"{\"versionId\":\"nuget-host, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\",\"files\":[\"nuget-cli-1.0.0.nupkg\"]}","StatusCode":"OK","StackTrace":null}] 3 years ago
Paul Schneider f6a27fa919 don't use redirection 3 years ago
Paul Schneider e51da7f359 TODO policy on existing zip from fs 3 years ago
Paul Schneider e4511a8aaa owner id 3 years ago
Paul Schneider 9575dd2754 report.OK 3 years ago
Paul Schneider 54a900c361 Merge branch 'master' of gitlab.pschneider.fr:Paul/nuget-host 3 years ago
Paul Schneider efb004ee08 Fixe l'envoi du fichier 3 years ago
Paul Schneider e0a3ec0bd5 Ok 3 years ago
Paul Schneider d7cabaad8b using web request 3 years ago
Paul Schneider 9adad9a327 refact 3 years ago
Paul Schneider 3d3a6cf017 refact 3 years ago
Paul Schneider 2f4ff1e774 return to canonical usage 3 years ago
Paul Schneider 9289b3af91 no more nuget 3 years ago
Paul Schneider 90cfc29492 cli to msbuild 3 years ago
Paul Schneider c83ff84370 Don't merge. 3 years ago
Paul Schneider d117f26c77 seeing some PUT 3 years ago
Paul Schneider c2f38800aa ... 3 years ago
Paul Schneider a8c9b7619f TODO cli output 3 years ago
Paul Schneider 97dec15153 push 3 years ago
Paul Schneider 512495d10b ci test 3 years ago
Paul Schneider 5bbcf9cb29 cli helped 3 years ago
Paul Schneider b6098c28a6 refact 3 years ago
Paul Schneider 36e1137e50 sln 3 years ago
Paul Schneider 3086cc65c4 clean 3 years ago
Paul Schneider 4cec5d0229 launch 3 years ago
Paul Schneider 61dc82df5b artifacts 3 years ago
Paul Schneider db6f514fb5 .... 3 years ago
Paul Schneider cc675844b6 ... 3 years ago
Paul Schneider f95765f541 not user-secret 3 years ago
Paul Schneider e5d3ba36cc testing? 3 years ago
Paul Schneider ffb7cad00a Réussi! - échec : 0, réussite : 2, ignorée(s) : 0, total : 2, durée : 444 ms 3 years ago
Paul Schneider 6a59f776d5 refact 3 years ago
Paul Schneider 93394b3e82 api key unprotected 3 years ago
Paul Schneider d063f10da5 c'est pas ici! 3 years ago
Paul Schneider bb02706773 apikey.creationdate 3 years ago
Paul Schneider 915736c4e2 migrate database 3 years ago
Paul Schneider b550f05c4f typo 3 years ago
Paul Schneider dd4dd9321b ci++ 3 years ago
Paul Schneider a238bd8cbf arts2 3 years ago
Paul Schneider fb822b6aaf yml 3 years ago
Paul Schneider ffd1dca16e artfcts 3 years ago
Paul Schneider 198189ab09 fixes build 3 years ago
Paul Schneider ccbdd155f3 ci 3 years ago
Paul Schneider 445ea24dd2 ngh 3 years ago
Paul Schneider 48df937b7f Add .gitlab-ci.yml 3 years ago
Paul Schneider 10b1fd0748 Add LICENSE 3 years ago
Paul Schneider 15fa91138d version 3 years ago
Paul Schneider dd6d83cf06 ApiKey 3 years ago
Paul Schneider 749eb645d5 refactorisation de la configuration 3 years ago
Paul Schneider 838de379fd Removes IdentityServer4 usage 3 years ago
Paul Schneider dc37c9a9f0 adds aspnet.identity 3 years ago
Paul Schneider a2f26f1e8e base namespace to nuget_host 3 years ago
Paul Schneider 1b2d850522 refact 3 years ago
Paul Schneider ec5bd7ca1f builds 3 years ago
Paul Schneider cede04a33e more references. 3 years ago
Paul Schneider 5b6d74d8ee protecting api 4 years ago
180 changed files with 19251 additions and 8223 deletions

12
.gitignore vendored

@ -6,16 +6,18 @@
/src/isn/.vscode/
/test/isnd.tests/obj/
/test/isnd.tests/bin/
/packages/
bower_components/
/test/isn.tests/bin
/test/isn.tests/obj/
appsettings.Testing.json
appsettings.Development.json
/wwwroot/.sass-cache/
/src/isnd/wwwroot/.sass-cache/
/src/isn.abst/bin
/src/isn.abst/obj
/src/isnd/packages/
/test/data/test-isn/bin/
/test/data/test-isn/obj
.fake
/artifacts/
/.vs/
/.vscode/
appsettings.Development.json
artifacts/

@ -0,0 +1,27 @@
<Properties StartupConfiguration="{468DB0E4-6221-4E01-BEFF-F452865E59C1}|Default">
<MonoDevelop.Ide.Workbench ActiveDocument="src/isnd/isnd.csproj">
<Files>
<File FileName="src/isn/Program.cs" Line="55" Column="48" />
<File FileName="src/isnd/isnd.csproj" Line="15" Column="56" />
</Files>
<Pads>
<Pad Id="ProjectPad">
<State name="__root__">
<Node name="isn" expanded="True">
<Node name="src" expanded="True" selected="True" />
<Node name="test" expanded="True" />
</Node>
</State>
</Pad>
</Pads>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.ItemProperties.src.isnd PreferredExecutionTarget="MonoDevelop.Default" />
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.ItemProperties.test.isnd.tests PreferredExecutionTarget="MonoDevelop.Default" />
<MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints>
<MultiItemStartupConfigurations />
<MonoDevelop.Ide.ItemProperties.src.isn PreferredExecutionTarget="MonoDevelop.Default" />
</Properties>

@ -0,0 +1,52 @@
{
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
// Pointez pour afficher la description des attributs existants.
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
},
{
"name": "push",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/isn/bin/Debug/netcoreapp2.1/isn.dll",
"requireExactSource": false,
"args": [
"push",
"-s", "http://localhost:5000/index.json",
"-k", "CfDJ8PZdCuMAkkdPqlnuLoghOuKBNLoprBqsy64fJqrYnVEOCj-eI7pfoVjHPXHazx_YSUDtnz9ic8olLY6JcZYOE2lVfpThjs8bE73AR4HjDQPhiMOY2NU-lWtCuxhk0K16xqOoFU5pAPLF83-YXJtt02_WMAQWfxVbq5_LpskRcZrk",
"-p",
"/home/paul/Nupkgs/Yavsc.Abstract.1.0.8.nupkg"
],
"cwd": "${workspaceFolder}/src/isn",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "web",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/isnd/bin/Debug/net7.0/isnd.dll",
"args": [],
"cwd": "${workspaceFolder}/src/isnd",
"stopAtEntry": false,
"requireExactSource": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
}
]
}

@ -0,0 +1,52 @@
{
"omnisharp.msbuild": true,
"dotnet-test-explorer.testProjectPath": "**/*tests.csproj",
"dotnet-test-explorer.runInParallel": false,
"dotnet-test-explorer.showCodeLens": true,
"dotnet-test-explorer.testArguments": "",
"nxunitExplorer.modules": [
"test/i*/bin/Debug/*/*.tests.dll"
],
"nxunitExplorer.skippattern": "",
"dotnetCoreExplorer.runEnvVars": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetCoreExplorer.searchpatterns": "test/**/bin/**/*.tests.{dll,exe}",
"sqltools.connections": [
{
"previewLimit": 50,
"server": "localhost",
"port": 5432,
"driver": "PostgreSQL",
"name": "isndev",
"group": "isn",
"database": "dotnetmvc",
"username": "dotnetmvc",
"password": "RvJa=y#b/tfg"
},
{
"previewLimit": 50,
"server": "localhost",
"port": 5432,
"askForPassword": true,
"driver": "PostgreSQL",
"name": "isnd",
"group": "isn",
"database": "webid",
"username": "webid"
},
{
"previewLimit": 50,
"server": "localhost",
"port": 5432,
"askForPassword": true,
"driver": "PostgreSQL",
"name": "isnddev",
"group": "isn",
"database": "isnd",
"username": "paul"
}
],
"omnisharp.disableMSBuildDiagnosticWarning": true,
"omnisharp.enableRoslynAnalyzers": false
}

@ -0,0 +1,8 @@
using System;
namespace {{namespace}}
{
public class {{name}}
{
}
}

@ -0,0 +1,3 @@
export class {{name}} {
}

@ -0,0 +1,9 @@
Imports System
Namespace {{namespace}}
Public Class {{name}}
End Class
End Namespace

@ -0,0 +1,3 @@
export default {{name}} {
}

@ -0,0 +1,8 @@
using System;
namespace {{namespace}}
{
public enum {{name}}
{
}
}

@ -0,0 +1,8 @@
using System;
namespace {{namespace}}
{
public interface {{name}}
{
}
}

@ -0,0 +1,3 @@
export interface {{name}} {
}

@ -0,0 +1,46 @@
{
"templates": [
{
"name": "Class",
"extension": "cs",
"file": "./class.cs-template",
"parameters": "./template-parameters.js"
},
{
"name": "Interface",
"extension": "cs",
"file": "./interface.cs-template",
"parameters": "./template-parameters.js"
},
{
"name": "Enum",
"extension": "cs",
"file": "./enum.cs-template",
"parameters": "./template-parameters.js"
},
{
"name": "Class",
"extension": "ts",
"file": "./class.ts-template",
"parameters": "./template-parameters.js"
},
{
"name": "Interface",
"extension": "ts",
"file": "./interface.ts-template",
"parameters": "./template-parameters.js"
},
{
"name": "Default",
"extension": "ts",
"file": "./default.ts-template",
"parameters": "./template-parameters.js"
},
{
"name": "Class",
"extension": "vb",
"file": "./class.vb-template",
"parameters": "./template-parameters.js"
}
]
}

@ -0,0 +1,17 @@
var path = require("path");
module.exports = function(filename, projectPath, folderPath) {
var namespace = "Unknown";
if (projectPath) {
namespace = path.basename(projectPath, path.extname(projectPath));
if (folderPath) {
namespace += "." + folderPath.replace(path.dirname(projectPath), "").substring(1).replace(/[\\\/]/g, ".");
}
namespace = namespace.replace(/[\\\-]/g, "_");
}
return {
namespace: namespace,
name: path.basename(filename, path.extname(filename))
}
};

63
.vscode/tasks.json vendored

@ -1,6 +1,18 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "restore",
"command": "dotnet",
"type": "process",
"args": [
"restore",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"--ignore-failed-sources"
],
"problemMatcher": "$msCompile"
},
{
"label": "build",
"command": "dotnet",
@ -11,8 +23,7 @@
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"group": "build"
"problemMatcher": "$msCompile"
},
{
"label": "db-upgrade",
@ -29,9 +40,23 @@
"env": {
"ASPNETCORE_ENV": "Development"
}
},
"dependsOn":["build"],
"group": "test"
}
},
{
"label": "buildcli",
"command": "msbuild",
"type": "process",
"args": [
"src/isn",
"/p:Configuration=Debug",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary",
"/restore"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
@ -48,8 +73,24 @@
"problemMatcher": "$msCompile",
"options": {
"cwd": "${workspaceFolder}"
},
"group": "none"
}
},
{
"label": "monopublish",
"command": "msbuild",
"type": "process",
"args": [
"/t:publish",
"/p:TargetFramework=netcoreapp2.1;PublishDir=${workspaceFolder}/artiffacts;RuntimeIdentifier=linux-x64",
],
"problemMatcher": "$msCompile"
},
{
"label": "copyTestConfig",
"command": "dotnet",
"type": "process",
"args": [ "build", "/t:CopyTestConfig" ]
},
{
"label": "test",
@ -57,7 +98,7 @@
"type": "process",
"options": {
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ASPNETCORE_ENVIRONMENT": "Testing"
}
},
"args": [
@ -66,8 +107,7 @@
"--logger:xunit"
],
"problemMatcher": "$msCompile",
"dependsOn": [ "build"],
"group": "test"
"dependsOn": [ "build", "copyTestConfig"]
},
{
"label": "watch",
@ -83,8 +123,7 @@
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"problemMatcher": "$msCompile",
"group": "test"
"problemMatcher": "$msCompile"
}
]
}

@ -1,46 +0,0 @@
CONFIGURATION=Debug
TARGETFV=net7.0
all: build-isn build-isnd
build-%: src/%
dotnet build -p:Configuration=$(CONFIGURATION) $^
pack-%: src/%
dotnet pack $^
watch:
dotnet watch --project=src/isnd
test-push:
isn push src/isn/bin/Debug/isn.*.nupkg
clean-%: src/%
rm -rf $^/bin $^/obj
packs: pack-isn pack-isnd pack-isn.abst
clean: clean-isnd clean-isn clean-isn.abst
TARGETFRAMEWORK=net8.0
server-update:
dotnet build -c Release src/isnd
dotnet publish -c Release -f $(TARGETFRAMEWORK) src/isnd
sudo systemctl stop isnd
sudo cp -a src/isnd/bin/Release/$(TARGETFRAMEWORK)/publish/* /srv/www/isnd
sudo systemctl start isnd
client-update:
dotnet build -c Release src/isn
# MAJ du client
sudo cp -a src/isn/bin/Release/$(TARGETFRAMEWORK)/* /usr/local/lib/isn
sudo chown -R root:root /usr/local/lib/isn
src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg:
dotnet pack src/isn.abst -c Release
push-test: src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg
isn push -s "http://localhost:3002/v3/index.json" src/isn.abst/bin/Release/isn.abst.1.0.24.nupkg

@ -1,6 +1,11 @@
# ISN
En cours de developement, le détail du paquet n'est toujours pas fourni en API.
FIXME
````log
NU1301: Failed to retrieve information about 'xxx' from remote source 'https://isn.pschneider.fr/nupkg/xxx/index.json'.
````
## Usage
@ -18,41 +23,26 @@ wget http://localhost:5000/package/index.json?q=your&prerelease=true&semVerLevel
## Installation
### Compilation
Dans le dossier de la solution, compiler la solution :
Depuis le dossier de la solution, compiler la solution :
````bash
dotnet build /restore -c Release
dotnet publish -c Release src/isnd
dotnet publish -c Release
````
### Déploiement du serveur
La livraison initiale, aujourd'hui :
### Déploiement
````bash
sudo mkdir -p /srv/www/isnd
sudo cp -a src/isnd/bin/Release/net8.0/publish/* /srv/www/isnd
sudo cp contrib/isnd.service /etc/systemd/system
chown -R isn:isn /srv/www/isnd/
sudo cp -a src/isnd/bin/Release/net6.0/publish/* /srv/www/isnd
sudo cp contrib/isnd /etc/init.d/isnd
sudo chmod +x /etc/init.d/isnd
sudo chown -R www-data.www-data /srv/www/isnd
sudo systemctl daemon-reload
````
Une base de donées Postgresql est requise, avec, pour faire simple,
son utilisateur, et le droit de créer des tables (ce dernier droit pourrait expirer, mais gare aux mises à jour).
Il faudra éditer la configuration pour indiquer :
* dans /etc/systemd/system/isnd.service , la connextion à une base de donnée Postresgql, sous la forme :
`"Server=<pgserver>;Port=<pgport>;Database=<dbname>;Username=<dbusername>;Password=<dbpass>;"`
* dans /srv/www/isnd/appsettings.Production.json, la connection au serveur de messagerie,
* l'URL externe du ou des sites à propulser, et à utiliser dans la description de service,
* et les autres détails.
Pour faire ceci, vous pourrez éditer une copie du fichier `appsettings.json` vers `appsettings.Production.json`,
pour renseigner toutes les valeurs spécifiées.
* Créer une base de donées Postgresql,
* ajuster un fichier de configuration `/srv/www/isnd/appsettings.Production.json`
* Démarrer le serveur :
````bash
@ -65,6 +55,7 @@ sudo systemctl start isnd
sudo systemctl enable isnd
````
### Installation du client
````bash
@ -76,25 +67,16 @@ sudo ln -s /usr/local/lib/isn/isn /usr/local/bin/isn
### Mises à jour
Dans le détail, la séquence serait du style :
````bash
set -e
# compiler tout
dotnet build -c Release
dotnet publish -c Release -f net8.0 src/isnd
dotnet publish -c Release -f net7.0 src/isnd
# MAJ du serveur
sudo systemctl stop isnd
sudo cp -a src/isnd/bin/Release/net8.0/publish/* /srv/www/isnd
sudo cp -a src/isnd/bin/Release/net7.0/publish/* /srv/www/isnd
sudo systemctl start isnd
# MAJ du client
sudo cp -a src/isn/bin/Release/net8.0/* /usr/local/lib/isn
sudo chown -R root:root /usr/local/lib/isn
````
On pourra cibler "client-update" ou "server-update", à la construction :
````bash
make server-update
make client-update
sudo cp -a src/isn/bin/Release/net7.0/* /usr/local/lib/isn
sudo chown -R root.root /usr/local/lib/isn
````

@ -0,0 +1,3 @@
#!/bin/bash
/usr/bin/mono /usr/local/lib/isn/isn.exe $*

@ -0,0 +1,110 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: isnd
# Required-Start: $local_fs $network $named $time $syslog $postgresql
# Required-Stop: $local_fs $network $named $time $syslog $postgresql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Script to run asp.net 5 application in background
### END INIT INFO
# Author: Ivan Derevianko aka druss <drussilla7@gmail.com>
# Modified by: Paul Schneider <redienhcs.luap@gmail.com>
. /lib/init/vars.sh
. /lib/lsb/init-functions
NAME=isnd
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
TMP_SAVE_runlevel_VAR=$runlevel
unset runlevel
running() {
if [ -f $PIDFILE ]
then
PID=$(cat $PIDFILE)
if kill -0 $PID 2>/dev/null
then
return 0
fi
fi
return 1
}
export WWW_USER=www-data
export ROOT=/srv/www/${NAME}
export DESC="$NAME"
export PIDFILE=/var/run/kestrel-${NAME}.pid
export LOGDIR=/var/log
export DOTNET_CLI_HOME=$ROOT
export ASPDOTNETCORE_ENVIRONMENT=Production
export ASPDOTNETCORE_LOGLEVEL=Information
status() {
if running;
then
echo "Service running $DESC ($NAME; pid: $PID)"
else
echo "Service stopped $DESC ($NAME)"
fi
echo WWW_USER: $WWW_USER ROOT:$ROOT DESC: $DESC NAME: $NAME PIDFILE: $PIDFILE LOGDIR=$LOGDIR
}
start() {
if running; then
echo "Service already running $DESC" "$NAME"
log_end_msg 0
else
cd $ROOT
log_daemon_msg "Starting service $NAME for user $WWW_USER"
if ! start-stop-daemon -SbmCv -u $WWW_USER -p $PIDFILE -d $ROOT -g www-data -x /usr/bin/dotnet isnd.dll run > "${LOGDIR}/kestrel-${NAME}.log"
then
log_daemon_msg "Could not start $NAME : $?, see ${LOGDIR}/kestrel-${NAME}.log"
log_end_msg 2
else
log_daemon_msg "Service $DESC started ($NAME), logs: ${LOGDIR}/kestrel-${NAME}.log"
log_end_msg 0
fi
fi
}
stop() {
if running
then
log_daemon_msg "Stopping service $NAME"
start-stop-daemon -K -p "$PIDFILE"
log_daemon_msg "$DESC stopped"
log_end_msg 0
else
log_daemon_msg "$DESC Service not running"
log_end_msg 1
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|restart}"
esac
export runlevel=$TMP_SAVE_runlevel_VAR

@ -1,28 +0,0 @@
[Unit]
Description=isnd - a Nuget package repository daemon
After=syslog.target
After=network.target
Wants=postgresql.service
After=postgresql.service
[Service]
RestartSec=5s
Type=simple
User=isn
Group=isn
WorkingDirectory=/srv/www/isnd/
ExecStart=/srv/www/isnd/isnd
Restart=always
Environment="HOME=/srv/www/isnd"
Environment="ASPNETCORE_ENVIRONMENT=Production"
Environment="ASPNETCORE_ConnectionStrings__DefaultConnection=Server=localhost;Port=5432;Database=isnd;Username=paul;Password=RvJa=y#b/tfg;"
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=isnd
[Install]
WantedBy=multi-user.target

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

@ -1,41 +1,30 @@
{
"version": 1,
"isRoot": true,
"tools": {
"codecov.tool": {
"version": "1.13.0",
"commands": [
"codecov"
],
"rollForward": false
},
"gitversion.tool": {
"version": "5.10.1",
"commands": [
"dotnet-gitversion"
],
"rollForward": false
},
"gitreleasemanager.tool": {
"version": "0.13.0",
"commands": [
"dotnet-gitreleasemanager"
],
"rollForward": false
},
"Wyam2.Tool": {
"version": "3.0.0-rc3",
"commands": [
"wyam2"
],
"rollForward": false
},
"dotnet-ef": {
"version": "8.0.7",
"commands": [
"dotnet-ef"
],
"rollForward": false
"version": 1,
"isRoot": true,
"tools": {
"codecov.tool": {
"version": "1.13.0",
"commands": [
"codecov"
]
},
"gitversion.tool": {
"version": "5.10.1",
"commands": [
"dotnet-gitversion"
]
},
"gitreleasemanager.tool": {
"version": "0.13.0",
"commands": [
"dotnet-gitreleasemanager"
]
},
"Wyam2.Tool": {
"version": "3.0.0-rc3",
"commands": [
"wyam2"
]
}
}
}
}
}

@ -1,12 +0,0 @@
drop table "AspNetRoleClaims" ;
drop table "AspNetUserRoles" ;
drop table "AspNetRoles" ;
drop table "AspNetUserClaims" ;
drop table "AspNetUserTokens" ;
drop table "PackageVersions" ;
drop table "Packages" ;
drop table "Commits" ;
drop table "ApiKeys" ;
drop table "AspNetUserLogins" ;
drop table "AspNetUsers" ;
drop table "__EFMigrationsHistory" ;

@ -1,9 +1,9 @@
{
"dotnet": {
"enabled": true
"enabled": false
},
"msbuild": {
"enabled": false
"enabled": true
},
"Dnx": {
"enabled": false

@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace isn
{
public class APIKO
{
public string Context { get; set; }
public Dictionary<string, string[]> Errors { get; set; }
}
}

@ -1,23 +1,21 @@
using System;
using isn.abst;
namespace isnd.Entities
{
public static class ApiConfig
{
public const string Index = "/index.json";
public const string Catalog = "/catalog";
public const string Package = "/package";
public const string Search = "/search";
public const string AutoComplete = "/autocomplete";
public const string Registration = "/registration";
public const string Nuspec = "/nuspec";
public const string Content = "/content";
public const string Nuget = "/nuget";
[Obsolete("use the V3 search")]
public const string V2Find = "/v2/FindPackagesById()"; // /FindPackagesById()??$filter=IsLatestVersion&$orderby=Version desc&$top=1&id='isn.abst'
public const string Publish = "put";
public const string Index = "index";
public const string IndexDotJson = Index + ".json";
public const string Catalog = "catalog";
public const string CatalogPage = "catalog-page";
public const string GetPackage = Constants.PaquetFileEstension;
public const string GetVersion = "version";
public const string Search = "search";
public const string AutoComplete = "autocomplete";
public const string CatalogLeaf = "catalog-leaf";
public const string Delete = "delete";
public const string Registration = "registration";
internal const string GetNuspec = Constants.SpecFileEstension;
}
}

@ -3,12 +3,15 @@ using Newtonsoft.Json;
namespace isn.Abstract
{
public class ApiIndexViewModel : Permalink
public class ApiIndexViewModel : HappyIdOwner
{
public ApiIndexViewModel(string id) : base(id, "ApiIndex")
public ApiIndexViewModel(string id) : base(id)
{
}
[JsonProperty("@id")]
public string Id { get => GetId(); }
[JsonProperty("version")]
public string Version { get; set; }

@ -2,8 +2,9 @@ namespace isn.abst
{
public static class Constants
{
public const string PacketFileExtension = "nupkg";
public const string SpecFileExtension = "nuspec";
public const string ApiVersionPrefix = "/v3";
public const string PaquetFileEstension = "nupkg";
public const string SpecFileEstension = "nuspec";
public const string JsonFileEstension = "json";
public const string PackageRootServerPrefix = "~/pkgs/";
}
}

@ -2,28 +2,15 @@ using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public abstract class Permalink
public class HappyIdOwner
{
public Permalink(string id)
public HappyIdOwner(string id)
{
Type = GetType().Name;
this.id = id;
}
public Permalink(string id, string type)
{
Type = type;
this.id = id;
}
[JsonProperty("@type")]
public virtual string Type { get; set; }
[JsonProperty("@id")]
public string Id { get => id; }
protected string id;
private string id;
public string GetId() { return id; }
@ -33,7 +20,7 @@ namespace isnd.Data.Catalog
{
if (GetType().IsAssignableFrom(obj.GetType()))
{
var rpobj = (Permalink) obj;
var rpobj = (HappyIdOwner) obj;
return this.id == rpobj.id;
}
}

@ -3,13 +3,19 @@ using Newtonsoft.Json;
namespace isn.Abstract
{
public class Resource : Permalink
public class Resource : HappyIdOwner
{
public Resource(string id, string typename) : base(id)
{
Type = typename;
Id = id;
}
[JsonProperty("@id")]
public string Id {get; set; }
[JsonProperty("@type")]
public string Type {get; set; }
[JsonProperty("comment")]
public string Comment {get; set; }

@ -2,13 +2,14 @@
<PropertyGroup>
<PackageVersion>1.0.1</PackageVersion>
<Version>1.0.7</Version>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net7.0</TargetFrameworks>
<NoWarn>NETSDK1138</NoWarn>
<AssemblyVersion>1.0.7.0</AssemblyVersion>
<FileVersion>1.0.7.0</FileVersion>
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.1" />
<Reference Include="System.ComponentModel.DataAnnotations" Version="4.0.0.0"/>
</ItemGroup>
</Project>

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace isn
{
public interface IDataProtector
{
string Protect(string data);
string UnProtect(string data);
}
public class DefaultDataProtector : IDataProtector
{
private byte delta = 145;
public DefaultDataProtector()
{
}
public string Protect(string data)
{
List<Byte> protd = new List<byte>();
StringBuilder sb = new StringBuilder();
foreach (byte c in Encoding.UTF8.GetBytes(data))
{
protd.Add((byte) (c ^ delta));
}
return System.Convert.ToBase64String(protd.ToArray());
}
public string UnProtect(string data)
{
if (data==null) return null;
StringBuilder sb = new StringBuilder();
List<byte> unps = new List<byte>();
foreach (byte c in System.Convert.FromBase64CharArray(data.ToCharArray(),0,data.Length))
{
unps.Add((byte) (c ^ delta));
}
return Encoding.UTF8.GetString(unps.ToArray());
}
}
}

@ -0,0 +1,9 @@
namespace isn
{
public class IsnSourceSettings
{
internal string Source { get; set; }
internal string[] Keys { get; set; }
}
}

@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Mono.Options;
using Newtonsoft.Json;
@ -18,18 +16,16 @@ namespace isn
if (cfgSettingIf.Exists)
{
var json = File.ReadAllText(cfgSettingIf.FullName);
Settings = JsonConvert.DeserializeObject<Settings>(json);
CurrentSource = Settings.DefaultSourceKey;
}
if (Settings==null)
{
Settings= Settings.Create();
settings = JsonConvert.DeserializeObject<Settings>(json);
if (settings.DefaultSourceKey == null)
{
Settings.DefaultSourceKey = settings.Sources.Keys.FirstOrDefault();
}
CurrentSource = settings.DefaultSourceKey;
}
rsa = RSA.Create(Settings.RSAParameters);
}
static readonly OptionSet storeoptions = new OptionSet {
{ "s|source=", "use source", val => Settings.CurrentSourceKey ??= val },
{ "s|source=", "use source", val => CurrentSource = CurrentSource ?? val },
{ "h|help", "show this message and exit", h => shouldShowPushHelp = h != null },
};
@ -46,9 +42,12 @@ namespace isn
{ "v|version", "show soft version info and exit", h => shouldShowVersion = h != null }
};
static string apiKey;
static readonly OptionSet pushoptions = new OptionSet {
{ "k|api-key=", "use api key", val => Settings.CurrentSource.SetApiKey(rsa, val)},
{ "s|source=", "use source", val => Settings.CurrentSourceKey = val },
{ "k|api-key=", "use api key", val => apiKey = apiKey ?? val },
{ "p|store-api-key", "store used api key", val => storApiKey = val != null },
{ "s|source=", "use source", val => CurrentSource = CurrentSource ?? val },
{ "h|help", "show this message and exit", h => shouldShowPushHelp = h != null },
};
static readonly OptionSet sourceoptions = new OptionSet {
@ -63,21 +62,33 @@ namespace isn
private static bool shouldShowVersion;
private static bool shouldShowSourceHelp;
private static bool shouldShowPushHelp;
public static RSA rsa;
private static string currentSource = null;
private static bool storApiKey = false;
static Settings settings = null;
public static Settings Settings
{
get; set;
get
{
if (settings == null)
LoadConfig();
if (settings == null)
{
settings = new Settings
{
DataProtectionTitle = "isn",
Sources = new Dictionary<string, SourceSettings>()
};
}
return settings;
}
}
public static string CurrentSource { get => Settings.CurrentSourceKey; set => Settings.CurrentSourceKey = value; }
public static string CurrentSource { get => currentSource; set => currentSource = value; }
static int Main(string[] args)
{
LoadConfig();
var commandSet = new CommandSet("isn");
var srclst = new Command("list")
{
@ -168,16 +179,13 @@ namespace isn
}
};
var setapikey = new Command("store-api-key", "Store this API key")
var setapikey = new Command("set-api-key")
{
Run = sargs => StoreApiKey(sargs)
};
setapikey.Options = pushoptions;
commandSet.Add(setapikey);
commandSet.Add(pushCmd);
commandSet.Add(setapikey);
commandSet.Add(srcCmd);
commandSet.Add(showCommand);
@ -208,7 +216,9 @@ namespace isn
{
Console.WriteLine("isn version " + GitVersionInformation.AssemblySemFileVer);
}
return commandSet.Run(args);
}
}
}

@ -1,63 +1,35 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json;
using System.Linq;
namespace isn
{
public class SourceSettings
{
public string ApiKey { get; set; }
public string Alias { get; set; }
/// <summary>
/// Protected API Key
/// </summary>
/// <value></value>
public string ProtectedApiKey { get; set; }
/// <summary>
/// Key alias
/// </summary>
/// <value></value>
public string Url { get; set; }
public SourceSettings()
public string GetClearApiKey()
{
return Protector.UnProtect(ApiKey);
}
public string GetClearApiKey(RSA rsa)
{
var decrypted = rsa.Decrypt(System.Convert.FromBase64String(ProtectedApiKey), RSAEncryptionPadding.Pkcs1);
return Encoding.Default.GetString(decrypted);
}
public void SetApiKey(RSA rsa, string key)
public void SetApiKey(string key)
{
var ciphered =rsa.Encrypt(Encoding.Default.GetBytes(key), RSAEncryptionPadding.Pkcs1);
ProtectedApiKey = System.Convert.ToBase64String(ciphered);
ApiKey = Protector.Protect(key);
}
public static IDataProtector Protector { get; set; } = new DefaultDataProtector();
}
public class Settings
{
private Settings()
{
}
public static Settings Create()
{
var rsaParams = CreateCipheringParameters();
return new Settings {
RSAParameters = rsaParams,
Sources = new Dictionary<string, SourceSettings>()
};
}
public RSAParameters RSAParameters { get; set; }
public string DataProtectionTitle { get; set; }
public Dictionary<string, SourceSettings> Sources { get; set; }
public bool AutoUpdateApiKey { get; set; } = false;
private string defSourceKey;
/// <summary>
@ -69,24 +41,15 @@ namespace isn
get => defSourceKey;
set
{
if (!Sources.ContainsKey(value))
{
Sources[value]=new SourceSettings
{
Alias = defSourceKey
};
}
defSourceKey = value;
}
}
[JsonIgnore, NotMapped]
public string CurrentSourceKey {get; set;}
private static RSAParameters CreateCipheringParameters()
{
var provider = new RSACryptoServiceProvider(2048);
return provider.ExportParameters(true);
}
[JsonIgnore, NotMapped]
public SourceSettings CurrentSource
{
get => this.Sources[CurrentSourceKey];
}
}
}

@ -17,21 +17,8 @@ namespace isn
// var json = await client.GetStringAsync(new System.Uri(url));
Task.Run(async ()=> {
try {
var response = await client.GetStringAsync(url);
result = JsonConvert.DeserializeObject<ApiIndexViewModel>(response);
} catch (HttpRequestException ex)
{
if (ex.StatusCode==HttpStatusCode.NotFound)
{
Console.Error.WriteLine("Not found ... server's down ?");
}
else
{
Console.Error.WriteLine($"{ex.StatusCode} : {ex.Message}");
}
}
}).Wait();
return result;

@ -4,7 +4,6 @@ using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace isn
{
@ -25,19 +24,35 @@ namespace isn
using (var multipartFormDataContent = new MultipartFormDataContent())
{
/* var values = new[]
{
new KeyValuePair<string, string>("Id", Guid.NewGuid().ToString()),
new KeyValuePair<string, string>("Key", "awesome"),
new KeyValuePair<string, string>("From", "khalid@home.com")
//other values
};foreach (var keyValuePair in values)
{
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
} */
multipartFormDataContent.Add(new ByteArrayContent(File.ReadAllBytes(fi.FullName)),
'"' + "File" + '"',
'"' + fi.Name + '"');
var result = await client.PutAsync(uri, multipartFormDataContent);
if (result.IsSuccessStatusCode) return
new PushReport() {
KO = JsonConvert.DeserializeObject<APIKO>(await result.Content.ReadAsStringAsync())
};
if (result.IsSuccessStatusCode)
{
string report = await result.Content.ReadAsStringAsync();
Console.WriteLine(report);
}
else
return new PushReport() {
OK = true
};
{
string ereport = await result.Content.ReadAsStringAsync();
Console.WriteLine(ereport);
}
return new PushReport();
}
}
}

@ -0,0 +1,195 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace isn
{
public class UploadFilesToServerUsingWebRequest
{
public void UploadFilesToServer(PushReport report, Uri uri, FileInfo fi,
string apikey)
{
// string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
const int TXLEN = 0x1000;
/// the form-data file upload, properly formatted
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// "X-NuGet-ApiKey
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
string fileheader = string.Format(fileheaderTemplate, "file", fi.Name, "application/octet-stream");
byte[] fileheaderbytes = Encoding.ASCII.GetBytes(fileheader);
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(uri);
httpWebRequest.Method = "PUT";
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.AllowAutoRedirect = false;
httpWebRequest.Headers.Add("X-NuGet-Client-Version", Constants.ClientVersion);
httpWebRequest.Headers.Add("X-NuGet-ApiKey", apikey);
httpWebRequest.ContentLength = boundarybytes.Length +
fileheaderbytes.Length + fi.Length + endBoundaryBytes.Length;
httpWebRequest.BeginGetRequestStream(async (result) =>
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream requestStream = request.EndGetRequestStream(result))
{
await WriteToStream(requestStream, boundarybytes, boundarybytes.Length);
await WriteToStream(requestStream, fileheaderbytes, fileheaderbytes.Length);
using (var fss = fi.OpenRead())
{
byte[] buffer = new byte[TXLEN];
var form_bytes_read = fss.Read(buffer, 0, TXLEN);
while (form_bytes_read > 0)
{
await WriteToStream(requestStream, buffer, form_bytes_read);
form_bytes_read = fss.Read(buffer, 0, TXLEN);
}
}
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
requestStream.Close();
}
}
catch (Exception rex)
{
report.Executed = false;
report.StackTrace = rex.StackTrace;
report.Message = rex.Message;
Console.Error.WriteLine("Stack trace:");
Console.Error.WriteLine(rex.StackTrace);
WebResponse eresp = httpWebRequest.GetResponse();
if (!CheckResponse(eresp, report))
throw new Exception("Invalid server response type");
}
}, httpWebRequest);
WebResponse resp = httpWebRequest.GetResponse();
if (!CheckResponse(resp, report)) throw new Exception("Invalid server response type");
if (Program.Settings.AutoUpdateApiKey)
Program.EnsureKeyStored();
}
static bool CheckResponse(WebResponse resp, PushReport report)
{
Stream stream = resp.GetResponseStream();
StreamReader re = new StreamReader(stream);
if (resp is HttpWebResponse)
{
if (resp.ContentType == "text/json")
{
String json = re.ReadToEnd();
report.Message = json;
var hrep = resp as HttpWebResponse;
report.StatusCode = hrep.StatusCode.ToString();
report.OK = hrep.StatusCode == HttpStatusCode.Accepted
|| hrep.StatusCode == HttpStatusCode.OK;
return true;
}
}
return false;
}
/// <summary>
/// Creates HTTP POST request &amp; uploads database to server. Author : Farhan Ghumra
/// </summary>
internal async Task UploadFilesToServerAsync(PushReport report, Uri uri, FileInfo fi,
string apikey)
{
// string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
const int TXLEN = 0x1000;
/// the form-data file upload, properly formatted
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// "X-NuGet-ApiKey
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
string fileheader = string.Format(fileheaderTemplate, "file", fi.Name, "application/octet-stream");
byte[] fileheaderbytes = Encoding.ASCII.GetBytes(fileheader);
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
httpWebRequest.Method = "PUT";
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
httpWebRequest.AllowAutoRedirect = false;
httpWebRequest.Headers.Add("X-NuGet-Client-Version", Constants.ClientVersion);
httpWebRequest.Headers.Add("X-NuGet-ApiKey", apikey);
httpWebRequest.ContentLength = boundarybytes.Length +
fileheaderbytes.Length + fi.Length + endBoundaryBytes.Length;
httpWebRequest.BeginGetRequestStream(async (result) =>
{
try
{
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
using (Stream requestStream = request.EndGetRequestStream(result))
{
await WriteToStream(requestStream, boundarybytes, boundarybytes.Length);
await WriteToStream(requestStream, fileheaderbytes, fileheaderbytes.Length);
using (var fss = fi.OpenRead())
{
byte[] buffer = new byte[TXLEN];
var form_bytes_read = fss.Read(buffer, 0, TXLEN);
while (form_bytes_read > 0)
{
await WriteToStream(requestStream, buffer, form_bytes_read);
form_bytes_read = fss.Read(buffer, 0, TXLEN);
}
}
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
requestStream.Close();
}
}
catch (Exception rex)
{
report.Message = rex.Message;
Console.Error.WriteLine(rex.Message);
Console.Error.WriteLine("Stack trace:");
Console.Error.WriteLine(rex.StackTrace);
throw;
}
}, httpWebRequest);
WebResponse resp = await httpWebRequest.GetResponseAsync();
Stream stream = resp.GetResponseStream();
StreamReader re = new StreamReader(stream);
if (resp is HttpWebResponse)
{
String json = await re.ReadToEndAsync();
report.Message = json;
var hrep = resp as HttpWebResponse;
report.StatusCode = hrep.StatusCode.ToString();
report.OK = hrep.StatusCode == HttpStatusCode.Accepted
|| hrep.StatusCode == HttpStatusCode.OK;
}
else throw new Exception("Invalid server response type");
}
/// <summary>
/// Writes byte array to stream. Author : Farhan Ghumra
/// </summary>
private static async Task WriteToStream(Stream s, byte[] bytes, int len)
{
await s.WriteAsync(bytes, 0, len);
}
}
}

@ -8,20 +8,17 @@ using Newtonsoft.Json;
namespace isn
{
public class PushCommand
public static class PushCommand
{
Settings settings;
public PushCommand(Settings settings)
{
this.settings = settings;
}
public PushReport Run(string pkg, string source, string apiKey)
static public PushReport Run(string pkg, string source, string apikey)
{
if (source == null) source = Program.Settings.DefaultSourceKey;
if (source == null) throw new InvalidOperationException("source is null");
if (Program.Settings.Sources.Values.Any(s=>s.Alias==source))
source = Program.Settings.Sources.First(s=>s.Value.Alias==source).Key;
if (source==null) throw new InvalidOperationException("source is invalid");
var resources = SourceHelpers.GetServerResources(source);
if (resources == null) return null;
if (resources.Resources == null)
throw new InvalidOperationException("source gave no resource");
if (!resources.Resources.Any(res => res.Type == "PackagePublish/2.0.0"))
@ -33,30 +30,26 @@ namespace isn
var report = new PushReport
{
PkgName = fi.Name,
Message = "The package does not exist : " + fi.FullName
Message = "Le fichier n'existe pas"
};
return report;
}
using (var client = new HttpClient(
new HttpClientHandler
{
AllowAutoRedirect = false
}
))
using (var client = new HttpClient())
try
{
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, settings.Sources[source].GetClearApiKey(Program.rsa));
Console.WriteLine("Connecting to "+ pubRes.Id);
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, apikey);
}
catch (HttpRequestException httpEx)
catch (HttpRequestException hrex)
{
var report = new PushReport
{
PkgName = fi.Name,
Message = "HttpRequest: " + httpEx.Message,
StackTrace = httpEx.StackTrace,
StatusCode = httpEx.HResult.ToString()
Message = "HttpRequest: " + hrex.Message,
StackTrace = hrex.StackTrace,
StatusCode = hrex.HResult.ToString()
};
Console.Error.WriteLine(httpEx.Message);
Console.Error.WriteLine(hrex.Message);
return report;
}
catch (Exception ex)

@ -12,15 +12,17 @@ namespace isn
public static List<PushReport> PushPkg(IEnumerable<string> pkgs)
{
List<PushReport> pushReports = new List<PushReport>();
var cmd = new PushCommand(Settings);
if (Settings.CurrentSource == null) throw new InvalidOperationException("source is null");
var source = Settings.CurrentSource;
foreach (string pkg in pkgs)
{
var report = cmd.Run(pkg, source.Url, source.GetClearApiKey(rsa));
var report = PushCommand.Run(pkg, CurrentSource, apiKey);
Console.WriteLine(report.ToDoc());
pushReports.Add(report);
}
if (storApiKey)
{
EnsureKeyStored();
}
return pushReports;
}

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace isn
{
partial class Program
{
private static void StoreApiKey(IEnumerable<string> storeArgs)
{
var args = storeoptions.Parse(storeArgs);
if (shouldShowPushHelp)
{
// output the options
Console.Error.WriteLine("Push Options:");
storeoptions.WriteOptionDescriptions(Console.Out);
}
else
{
apiKey = args[0];
EnsureKeyStored();
}
}
public static void EnsureKeyStored()
{
if (CurrentSource == null)
{
if (Settings.DefaultSourceKey == null)
return;
CurrentSource = Settings.DefaultSourceKey;
}
if (Settings.Sources.ContainsKey(CurrentSource))
{
if (apiKey == null)
{
// Une suppression
Settings.Sources.Remove(CurrentSource);
if (Settings.DefaultSourceKey == CurrentSource) Settings.DefaultSourceKey = null;
}
else
{
// Une mise À jour
Settings.Sources[CurrentSource].SetApiKey(apiKey);
if (Settings.DefaultSourceKey == null) Settings.DefaultSourceKey = CurrentSource;
}
}
else if (apiKey != null)
{
// une addition
var setting = new SourceSettings ();
setting.SetApiKey(apiKey);
Settings.Sources.Add(CurrentSource, setting);
}
SaveConfig();
}
public static void SaveConfig()
{
FileInfo cfgSettingIf = new FileInfo(_configFileName);
if (!cfgSettingIf.Directory.Exists) cfgSettingIf.Directory.Create();
File.WriteAllText(
cfgSettingIf.FullName,
JsonConvert.SerializeObject(
Settings,
Formatting.Indented
));
}
}
}

@ -16,7 +16,7 @@ namespace isn
{
SourceSettings setting = Settings.Sources[arg];
throw new InvalidOperationException
(setting.Url);
(setting.Alias);
}
throw new NotImplementedException();
}

@ -11,7 +11,7 @@ namespace isn
SourceSettings settings =
Settings.Sources.ContainsKey(arg) ?
Settings.Sources[arg] :
Settings.Sources.Values.FirstOrDefault((s)=> s.Url == arg) ;
Settings.Sources.Values.FirstOrDefault((s)=> s.Alias == arg) ;
if (settings==null) throw new InvalidOperationException(arg);
Settings.DefaultSourceKey = arg;
SaveConfig();

@ -1,46 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace isn
{
partial class Program
{
private static void StoreApiKey(IEnumerable<string> storeArgs)
{
var args = storeoptions.Parse(storeArgs);
if (args.Count != 1)
{
Console.Error.WriteLine("StoreApiKey command takes only one argument, the key.");
shouldShowPushHelp=true;
}
if (shouldShowPushHelp)
{
// output the options
Console.Error.WriteLine("StoreApiKey Options:");
storeoptions.WriteOptionDescriptions(Console.Out);
}
else
{
Settings.Sources[Settings.CurrentSourceKey].SetApiKey(Program.rsa, args[0]);
SaveConfig();
}
}
public static void SaveConfig()
{
FileInfo cfgSettingIf = new FileInfo(_configFileName);
if (!cfgSettingIf.Directory.Exists) cfgSettingIf.Directory.Create();
File.WriteAllText(
cfgSettingIf.FullName,
JsonConvert.SerializeObject(
Settings,
Formatting.Indented
));
Console.WriteLine("config saved .");
}
}
}

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks>net7.0</TargetFrameworks>
<RootNamespace>nuget_cli</RootNamespace>
<UserSecretsId>45b74c62-05bc-4603-95b4-3e80ae2fdf50</UserSecretsId>
<Version>1.0.7</Version>
@ -15,11 +15,11 @@
<InformationalVersion>1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327</InformationalVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="8.0.0" />
<PackageReference Include="Mono.Options" Version="5.3.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="unleash.client" Version="4.1.6" />
<PackageReference Include="GitVersion.MsBuild" Version="5.12.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="unleash.client" Version="1.6.1" />
<Reference Include="System.Net.Http" Version="4.0.0" />
<PackageReference Include="GitVersion.MsBuild" Version="5.6.10*" />
<ProjectReference Include="../isn.abst/isn.abst.csproj" />
</ItemGroup>
</Project>

@ -1,41 +1,29 @@
using System.Threading.Tasks.Dataflow;
using System.Net;
using System.Text;
using Newtonsoft.Json;
namespace isn
{
public class PushReport
{
public PushReport()
{
}
public string PkgName { get; set; }
public bool Executed { get; set; }
public bool OK { get; set; }
public bool AlreadyPresent { get; set; }
public string Message { get; set; }
public string StatusCode { get; set; }
public string StackTrace { get; set; }
public APIKO KO { get; set; }
public bool Executed { get; internal set; }
public bool OK { get; internal set; }
public bool AlreadyPresent { get; internal set; }
public string Message { get; internal set; }
public string StatusCode { get; internal set; }
public string StackTrace { get; internal set; }
public string ToDoc()
{
StringBuilder sb = new StringBuilder($"= push {PkgName}\n\n");
StringBuilder sb = new StringBuilder($"= Pushing {PkgName}\n\n");
if (Executed) sb.AppendLine("* Executed");
if (OK) sb.AppendLine("* OK");
if (!string.IsNullOrWhiteSpace(Message))
sb.AppendLine("* Message :" + Message);
sb.AppendLine(Message);
if (!string.IsNullOrWhiteSpace(StatusCode))
sb.AppendLine($"* Status Code : ");
if (!string.IsNullOrWhiteSpace(StackTrace))
sb.AppendLine($"* StackTrace : " + StackTrace);
if (KO!=null)
sb.AppendLine($"* KO : " + KO.Context);
sb.AppendLine($"* StackTrace : ");
return sb.ToString();
}
}

@ -13,7 +13,6 @@ using Microsoft.Extensions.Options;
using isnd.Data;
using isnd.Entities;
using isnd.Data.ApiKeys;
using isnd.Interfaces;
namespace isnd.Controllers
@ -24,20 +23,17 @@ namespace isnd.Controllers
private readonly ApplicationDbContext dbContext;
private readonly IsndSettings isndSettings;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IApiKeyProvider apiKeyProvider;
private readonly IDataProtector protector;
public ApiKeysController(ApplicationDbContext dbContext,
IOptions<IsndSettings> isndSettingsOptions,
IDataProtectionProvider provider,
UserManager<ApplicationUser> userManager,
IApiKeyProvider apiKeyProvider
)
UserManager<ApplicationUser> userManager)
{
this.dbContext = dbContext;
this.isndSettings = isndSettingsOptions.Value;
protector = provider.CreateProtector(isndSettings.ProtectionTitle);
_userManager = userManager;
this.apiKeyProvider = apiKeyProvider;
}
[HttpGet]
@ -61,17 +57,17 @@ namespace isnd.Controllers
[HttpPost]
public async Task<ActionResult> Create(CreateModel model)
{
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
IQueryable<ApiKey> userKeys = apiKeyProvider.GetUserKeys(User.Identity.Name);
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
IQueryable<ApiKey> userKeys = GetUserKeys();
if (userKeys.Count() >= isndSettings.MaxUserKeyCount)
{
ModelState.AddModelError(null, "Maximum key count reached");
return View();
}
model.UserId = userId;
ApiKey newKey = await apiKeyProvider.CreateApiKeyAsync(model);
ApiKey newKey = new ApiKey { UserId = userid, Name = model.Name,
CreationDate = DateTime.Now };
_ = dbContext.ApiKeys.Add(newKey);
_ = await dbContext.SaveChangesAsync();
return View("Details", new DetailModel { Name = newKey.Name,
ProtectedValue = protector.Protect(newKey.Id),
ApiKey = newKey });
@ -83,6 +79,7 @@ namespace isnd.Controllers
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
return View(new DeleteModel { ApiKey = key });
}
[HttpPost]
@ -106,7 +103,7 @@ namespace isnd.Controllers
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
if (key == null)
{
ModelState.AddModelError("id", "Key not found");
ModelState.AddModelError(null, "Key not found");
return View();
}
return View("Details", new DetailModel { ApiKey = key, Name = key.Name, ProtectedValue = protector.Protect(key.Id)});

@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
using isnd.Data;
using System.Linq;
using isnd.ViewModels;
using Unleash;
using System.Reflection;
using Microsoft.EntityFrameworkCore;
@ -15,14 +16,19 @@ namespace isnd.Controllers
public class HomeController : Controller
{
private readonly ApplicationDbContext _dbContext;
private readonly IUnleash _unleashĈlient;
/// <summary>
/// Home controller ctor
/// </summary>
/// <param name="dbContext"></param>
/// <param name="unleashĈlient"></param>
public HomeController(
ApplicationDbContext dbContext)
ApplicationDbContext dbContext,
IUnleash unleashĈlient)
{
_dbContext = dbContext;
_unleashĈlient = unleashĈlient;
}
public IActionResult Index()
@ -30,7 +36,9 @@ namespace isnd.Controllers
return View(new HomeIndexViewModel{
PkgCount = _dbContext.Packages
.Where(p => p.Versions.Count > 0)
.Count()});
.Count(),
UnleashClient = _unleashĈlient
});
}
public IActionResult About()
@ -59,9 +67,9 @@ namespace isnd.Controllers
return View(ViewData);
}
public IActionResult Error(string id)
public IActionResult Error()
{
return View("Error", id);
return View();
}
}
}

@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using isnd.Entities;
using isnd.Services;
using isn.Abstract;
using isn.abst;
using isnd.Interfaces;
using Unleash;
using System.Linq;
using isnd.Entities;
namespace isnd.Controllers
{
@ -20,20 +22,21 @@ namespace isnd.Controllers
/// Api Controller Constructor
/// </summary>
/// <param name="pm"></param>
public ApiController(IPackageManager pm)
/// <param name="unleashĈlient"></param>
public ApiController(IPackageManager pm, IUnleash unleashĈlient)
{
packageManager = pm;
resources = packageManager.GetResources().ToArray();
resources = packageManager.GetResources(unleashĈlient).ToArray();
}
/// <summary>
/// API index
/// </summary>
/// <returns></returns>
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Index)]
[HttpGet(Constants.PackageRootServerPrefix + ApiConfig.IndexDotJson)]
public IActionResult ApiIndex()
{
return Ok(new ApiIndexViewModel(packageManager.CatalogBaseUrl){ Version = PackageManager.BASE_API_LEVEL, Resources = resources });
return Ok(new ApiIndexViewModel(packageManager.CatalogBaseUrl + ApiConfig.IndexDotJson){ Version = PackageManager.BASE_API_LEVEL, Resources = resources });
}
}

@ -9,7 +9,7 @@ namespace isnd.Controllers
{
// GET /autocomplete?id=isn.protocol&prerelease=true
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.AutoComplete)]
[HttpGet(Constants.PackageRootServerPrefix + ApiConfig.AutoComplete)]
public IActionResult AutoComplete(
string id,
string semVerLevel,

@ -1,6 +1,13 @@
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
using isnd.Services;
using isnd.Entities;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using NuGet.Versioning;
using isnd.Data.Packages.Catalog;
using isnd.Data.Catalog;
using isn.abst;
namespace isnd.Controllers
@ -9,34 +16,34 @@ namespace isnd.Controllers
{
// https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Catalog)]
[HttpGet(Constants.PackageRootServerPrefix + ApiConfig.Catalog)]
public async Task<IActionResult> CatalogIndex()
{
return Ok(await packageManager.GetCatalogIndexAsync());
}
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Content + "/{id}/{version}.json")]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Registration + "/{id}/{version}.json")]
public async Task<IActionResult> CatalogRegistration(string id, string version)
[HttpGet(Constants.PackageRootServerPrefix + "{apiVersion}/" + ApiConfig.Registration + "/{id}/{lower}.json")]
public async Task<IActionResult> CatalogRegistration(string apiVersion, string id, string lower)
{
if ("index" == version)
if (lower.Equals("index", System.StringComparison.InvariantCultureIgnoreCase))
{
var query = new Data.Catalog.PackageRegistrationQuery
var query = new Data.Catalog.RegistrationPageIndexQuery
{
Query = id,
Prerelease = true
};
var index = await packageManager.GetPackageRegistrationIndexAsync(query);
if (index == null) return NotFound();
// query.TotalHits = result.Items.Select(i=>i.Items.Length).Aggregate((a,b)=>a+b);
return Ok(index);
}
// return a Package
var leaf = await packageManager.GetCatalogEntryAsync(id, version, null);
var leaf = await packageManager.GetCatalogEntryAsync(id, lower, null);
if (null == leaf) return NotFound(new { id, version });
if (null == leaf) return NotFound(new { id, lower });
return Ok(leaf);
}
}
}

@ -11,7 +11,7 @@ namespace isnd.Controllers
{
public partial class PackagesController
{
[HttpDelete("~" + Constants.ApiVersionPrefix + ApiConfig.Package + "/{id}/{lower?}/{type?}")]
[HttpDelete(Constants.PackageRootServerPrefix + ApiConfig.Delete + "/{id}/{lower?}/{type?}")]
public async Task<IActionResult> ApiDelete(
[FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower,

@ -7,51 +7,49 @@ using isn.abst;
namespace isnd.Controllers
{
public partial class PackagesController
{
// Web get the paquet
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Nuget + "/{id}/{lower}/{idf}-{lowerFromName}."
+ Constants.PacketFileExtension)]
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Content + "/{id}/{lower}/{idf}-{lowerFromName}."
+ Constants.PacketFileExtension)]
[HttpGet(Constants.PackageRootServerPrefix + ApiConfig.GetPackage + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.PaquetFileEstension)]
public IActionResult GetPackage(
[FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower,
[FromRoute] string idf, [FromRoute] string lowerFromName)
[FromRoute] string idf, [FromRoute] string lowerf)
{
var pkgPath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}-{lower}." + Constants.PacketFileExtension
var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}-{lower}." + Constants.PaquetFileEstension
);
FileInfo pkgFileInfo = new FileInfo(pkgPath);
FileInfo pkgfi = new FileInfo(pkgpath);
if (!pkgFileInfo.Exists)
if (!pkgfi.Exists)
{
return BadRequest("!pkgFileInfo.Exists");
return BadRequest("!pkgfi.Exists");
}
return File(pkgFileInfo.OpenRead(), "application/zip; charset=binary");
return File(pkgfi.OpenRead(), "application/zip; charset=binary");
}
// Web get spec
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Nuspec + "/{id}/{lower}/{idf}-{lowerFromName}."
+ Constants.SpecFileExtension)]
[HttpGet(Constants.PackageRootServerPrefix + Constants.SpecFileEstension + "/{id}/{lower}/{idf}-{lowerf}."
+ Constants.SpecFileEstension)]
public IActionResult GetNuspec(
[FromRoute][SafeName][Required] string id,
[FromRoute][SafeName][Required] string lower,
[FromRoute][SafeName][Required] string idf,
[FromRoute][SafeName][Required] string lowerFromName)
[FromRoute][SafeName][Required] string lowerf)
{
var pkgPath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}." + Constants.SpecFileExtension);
var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
id, lower, $"{id}." + Constants.SpecFileEstension);
FileInfo pkgFileInfo = new FileInfo(pkgPath);
if (!pkgFileInfo.Exists)
FileInfo pkgfi = new FileInfo(pkgpath);
if (!pkgfi.Exists)
{
return BadRequest("!pkgFileInfo.Exists");
return BadRequest("!pkgfi.Exists");
}
return File(pkgFileInfo.OpenRead(), "text/xml; charset=utf-8");
return File(pkgfi.OpenRead(), "text/xml; charset=utf-8");
}
}
}

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

@ -1,21 +1,31 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using NuGet.Packaging.Core;
using NuGet.Versioning;
using isnd.Data;
using isnd.Helpers;
using isnd.Entities;
using Microsoft.AspNetCore.Http;
using isn.abst;
using isnd.Data.Packages;
using Microsoft.AspNetCore.Authorization;
namespace isnd.Controllers
{
public partial class PackagesController
{
// TODO [Authorize(Policy = IsndConstants.RequireValidApiKey)]
[HttpPut("~" + Constants.ApiVersionPrefix + ApiConfig.Package)]
// TODO [Authorize(Policy = IsndConstants.RequireValidApiKey)]
[HttpPut(Constants.PackageRootServerPrefix + ApiConfig.Publish)]
public async Task<IActionResult> Put()
{
try
@ -26,29 +36,186 @@ namespace isnd.Controllers
var files = new List<string>();
ViewData["files"] = files;
var clearKey = protector.Unprotect(apiKey);
var dbApiKey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearKey);
if (dbApiKey == null)
var clearkey = protector.Unprotect(apiKey);
var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey);
if (apikey == null)
{
logger.LogError("403 : no api-key");
return Unauthorized();
}
Commit commit = new Commit
{
Action = PackageAction.PublishPackage,
TimeStamp = DateTime.Now
};
dbContext.Commits.Add(commit);
foreach (IFormFile file in Request.Form.Files)
{
var version = await packageManager.PutPackageAsync(file.OpenReadStream(), dbApiKey.UserId);
logger.LogInformation($"new package : {version.PackageId} {version.NugetLink}");
string initpath = Path.Combine(Environment.GetEnvironmentVariable("TEMP") ??
Environment.GetEnvironmentVariable("TMP") ?? "/tmp",
$"isn-{Guid.NewGuid()}."+Constants.PaquetFileEstension);
using (FileStream fw = new FileStream(initpath, FileMode.Create))
{
file.CopyTo(fw);
}
using (FileStream fw = new FileStream(initpath, FileMode.Open))
{
var archive = new ZipArchive(fw);
var spec = archive.Entries.FirstOrDefault(e => e.FullName.EndsWith("." + Constants.SpecFileEstension));
if (spec == null) return BadRequest(new { error = "no " + Constants.SpecFileEstension + " from archive" });
string pkgpath;
NuGetVersion version;
string pkgid;
string fullpath;
using (var specstr = spec.Open())
{
NuspecCoreReader reader = new NuspecCoreReader(specstr);
string pkgdesc = reader.GetDescription();
var types = reader.GetPackageTypes();
pkgid = reader.GetId();
version = reader.GetVersion();
string pkgidpath = Path.Combine(isndSettings.PackagesRootDir,
pkgid);
pkgpath = Path.Combine(pkgidpath, version.ToFullString());
string name = $"{pkgid}-{version}."+Constants.PaquetFileEstension;
fullpath = Path.Combine(pkgpath, name);
var destpkgiddir = new DirectoryInfo(pkgidpath);
Package pkg = dbContext.Packages.SingleOrDefault(p => p.Id == pkgid);
if (pkg != null)
{
if (pkg.OwnerId != apikey.UserId)
{
return new ForbidResult();
}
pkg.Description = pkgdesc;
}
else
{
pkg = new Package
{
Id = pkgid,
Description = pkgdesc,
OwnerId = apikey.UserId,
LatestVersion = commit,
};
dbContext.Packages.Add(pkg);
}
if (!destpkgiddir.Exists) destpkgiddir.Create();
var source = new FileInfo(initpath);
var dest = new FileInfo(fullpath);
var destdir = new DirectoryInfo(dest.DirectoryName);
if (dest.Exists)
{
// La version existe sur le disque,
// mais si elle ne l'est pas en base de donnéés,
// on remplace la version sur disque.
var pkgv = dbContext.PackageVersions.Where(
v => v.PackageId == pkg.Id
);
if (pkgv !=null && pkgv.Count()==0)
{
dest.Delete();
}
else {
logger.LogWarning("400 : pkgversion:existant");
ModelState.AddModelError("pkgversion", "existant" );
return BadRequest(ModelState);
}
}
{
if (!destdir.Exists) destdir.Create();
source.MoveTo(fullpath);
files.Add(name);
string fullstringversion = version.ToFullString();
var pkgvers = dbContext.PackageVersions.Where
(v => v.PackageId == pkg.Id && v.FullString == fullstringversion);
if (pkgvers.Count() > 0)
{
foreach (var v in pkgvers.ToArray())
dbContext.PackageVersions.Remove(v);
}
// FIXME default type or null
if (types==null || types.Count==0)
dbContext.PackageVersions.Add
(new PackageVersion{
Package = pkg,
Major = version.Major,
Minor = version.Minor,
Patch = version.Patch,
Revision = version.Revision,
IsPrerelease = version.IsPrerelease,
FullString = version.ToFullString(),
Type = null,
LatestCommit = commit
});
else
foreach (var type in types)
{
var pkgver = new PackageVersion
{
Package = pkg,
Major = version.Major,
Minor = version.Minor,
Patch = version.Patch,
IsPrerelease = version.IsPrerelease,
FullString = version.ToFullString(),
Type = type.Name,
LatestCommit = commit
};
dbContext.PackageVersions.Add(pkgver);
}
await dbContext.SaveChangesAsync();
packageManager.ÛpdateCatalogForAsync(commit);
logger.LogInformation($"new paquet : {spec.Name}");
}
}
using (var shacrypto = System.Security.Cryptography.SHA512.Create())
{
using (var stream = System.IO.File.OpenRead(fullpath))
{
var hash = shacrypto.ComputeHash(stream);
var shafullname = fullpath + ".sha512";
var hashtext = Convert.ToBase64String(hash);
var hashtextbytes = Encoding.ASCII.GetBytes(hashtext);
using (var shafile = System.IO.File.OpenWrite(shafullname))
{
shafile.Write(hashtextbytes, 0, hashtextbytes.Length);
}
}
}
string nuspecfullpath = Path.Combine(pkgpath, pkgid + "." + Constants.SpecFileEstension);
FileInfo nfpi = new FileInfo(nuspecfullpath);
if (nfpi.Exists)
nfpi.Delete();
spec.ExtractToFile(nuspecfullpath);
}
}
return Ok();
return Ok(ViewData);
}
catch (Exception ex)
{
var message = $"PUT exception : {ex.Message} ({ex.GetType().Name})";
logger.LogError(message);
logger.LogError("Stack Trace : " + ex.StackTrace);
return new ObjectResult(new { ViewData, message })
logger.LogError(ex.Message);
logger.LogError("Stack Trace: " + ex.StackTrace);
return new ObjectResult(new { ViewData, ex.Message })
{ StatusCode = 500 };
}
}
}
}

@ -1,37 +1,28 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using isnd.Entities;
using isn.abst;
using System.Threading.Tasks;
using isnd.Data.Catalog;
namespace isnd.Controllers
{
// TODO /search GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
public partial class PackagesController
{
// Web get the paquet
[HttpGet("~" + Constants.ApiVersionPrefix + ApiConfig.Search)]
[HttpHead("~" + Constants.ApiVersionPrefix + ApiConfig.Search)]
[HttpHead("~" + ApiConfig.V2Find)]
public async Task<IActionResult> Search(
string q=null,
int skip=0,
int take=25,
bool prerelease=false,
string semVerLevel = "2.0.0",
string packageType = "Dependency")
// GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
[HttpGet(Constants.PackageRootServerPrefix + ApiConfig.Search)]
public IActionResult Search(
string q,
int skip = 0,
int take = 25,
bool prerelease = false,
string semVerLevel = null,
string packageType = null
)
{
PackageRegistrationQuery query = new PackageRegistrationQuery
{
Prerelease= prerelease,
Query = q,
Skip = skip,
Take = take
};
var result = await packageManager.SearchPackageAsync(query);
return Ok(result);
throw new NotImplementedException();
}
}
}

@ -1,15 +1,11 @@
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using isn.abst;
using isnd.Data;
using isnd.Data.Catalog;
using isnd.Entities;
using isnd.Helpers;
using isnd.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
@ -19,39 +15,22 @@ namespace isnd.Controllers
public partial class PackagesController
{
// Web search
public async Task<IActionResult> Index(PackageRegistrationQuery model)
public async Task<IActionResult> Index(RegistrationPageIndexQuery model)
{
var pkgs = await packageManager.SearchPackageAsync(model);
var result = new RegistrationPageIndexQueryAndResult
{
Source = packageManager.CatalogBaseUrl+ApiConfig.Index,
Query = model
};
List<PackageRegistration> registrations = new List<PackageRegistration>();
foreach (var pk in pkgs.data.GroupBy(x => x.PackageId))
{
registrations.Add(new PackageRegistration(apiBase, pk.Key, pkgs.GetResults().Single(p=>p.Id == pk.Key).Versions));
}
return View(new RegistrationPageIndexQueryAndResult
{
Source = packageManager.CatalogBaseUrl+ApiConfig.Index,
Query = model,
Result = registrations.ToArray()
});
return View(new RegistrationPageIndexQueryAndResult{Query = model,
Result = await packageManager.SearchPackageAsync(model)});
}
public async Task<IActionResult> Details(PackageDetailViewModel model)
public async Task<IActionResult> Details(string pkgid)
{
if (model.pkgid == null)
if (pkgid == null)
{
return NotFound();
}
var packageVersion = dbContext.PackageVersions
.Include(p=>p.LatestCommit)
.Include(p => p.Package)
.Where(m => m.PackageId == model.pkgid)
.Where(m => m.PackageId == pkgid)
.OrderByDescending(p => p)
;
@ -60,25 +39,32 @@ namespace isnd.Controllers
return NotFound();
}
bool results = await packageVersion.AnyAsync();
model.latest = await packageVersion.FirstAsync();
model.totalHits = packageVersion.Count();
model.data = packageVersion.Take(MAX_PKG_VERSION_LIST).ToArray();
var latest = await packageVersion.FirstAsync();
return View("Details", new PackageDetailViewModel
{
ExternalUrl = isndSettings.ExternalUrl,
latest = latest,
pkgid = pkgid,
totalHits = packageVersion.Count(),
data = packageVersion.Take(MAX_PKG_VERSION_LIST).ToArray()
});
return View("Details", model);
}
const int MAX_PKG_VERSION_LIST = 50;
[Authorize, HttpGet]
[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
&& (pkgtype!=null && m.Type == pkgtype || m.Type != "Delete" ));
.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);
@ -86,19 +72,19 @@ namespace isnd.Controllers
}
// POST: PackageVersion/Delete/5
[HttpPost]
[ValidateAntiForgeryToken][Authorize]
public async Task<IActionResult> DeleteConfirmed(string pkgid, string version,
string type)
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(string PackageId, string FullString,
string Type)
{
var packageVersion = await dbContext.PackageVersions
PackageVersion packageVersion = await dbContext.PackageVersions
.Include(pv => pv.Package)
.Where(m => m.PackageId == pkgid
&& m.FullString == version && (type==null || m.Type == type))
.ToArrayAsync();
if (packageVersion.Length==0) return NotFound();
if (!User.IsOwner(packageVersion.First())) return Unauthorized();
await packageManager.DeletePackageAsync(pkgid, version, type);
.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));
}
}

@ -1,14 +1,21 @@
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NuGet.Versioning;
using isnd.Data;
using isnd.Entities;
using Unleash;
using isnd.Services;
using isnd.ViewModels;
using System.Threading.Tasks;
using isnd.Interfaces;
using isn.Abstract;
using isn.abst;
namespace isnd.Controllers
{
@ -17,18 +24,19 @@ namespace isnd.Controllers
{
const int maxTake = 100;
private readonly Resource[] resources;
private readonly string apiBase;
private readonly ILogger<PackagesController> logger;
private readonly IDataProtector protector;
private readonly IsndSettings isndSettings;
readonly ApplicationDbContext dbContext;
private readonly IPackageManager packageManager;
private readonly IUnleash unleashĈlient;
public PackagesController(
ILoggerFactory loggerFactory,
IDataProtectionProvider provider,
IOptions<IsndSettings> isndOptions,
IUnleash unleashĈlient,
ApplicationDbContext dbContext,
IPackageManager pm)
{
@ -37,10 +45,8 @@ namespace isnd.Controllers
protector = provider.CreateProtector(isndSettings.ProtectionTitle);
this.dbContext = dbContext;
packageManager = pm;
resources = packageManager.GetResources().ToArray();
this.apiBase = isndSettings.ExternalUrl + Constants.ApiVersionPrefix;
this.unleashĈlient = unleashĈlient;
resources = packageManager.GetResources(unleashĈlient).ToArray();
}
}
}

@ -18,7 +18,7 @@ namespace isnd.Data.ApiKeys
public int ValidityPeriodInDays{ get; set; }
public DateTimeOffset CreationDate { get; set; }
public DateTime CreationDate { get; set; }
public bool IsValid => CreationDate.AddDays(ValidityPeriodInDays) > DateTime.Now;
}

@ -9,8 +9,6 @@ namespace isnd.Data.ApiKeys
[Display(Name = "Key Name")]
public string Name { get; set; }
public string UserId { get; set; }
public int ValidityPeriodInDays { get; set; }
}
}

@ -1,9 +1,12 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using isnd.Data;
using isnd.Data.ApiKeys;
using isnd.Data.Packages;
using Microsoft.VisualStudio.Web.CodeGenerators.Mvc.Templates.BlazorIdentity.Pages;
using Microsoft.DotNet.Scaffolding.Shared.ProjectModel;
namespace isnd.Data
{
@ -19,20 +22,6 @@ namespace isnd.Data
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
_ = builder.Entity<PackageVersion>()
.HasKey( v => new { v.PackageId, v.FullString } );
_ = builder.Entity<PackageVersion>()
.HasOne(v => v.Package).WithMany(p => p.Versions).HasForeignKey(x => x.PackageId);
_ = builder.Entity<PackageDependencyGroup>().HasOne(g=>g.PackageVersion)
.WithMany(v => v.DependencyGroups).HasForeignKey(x => new { x.PackageId, x.PackageVersionFullString } );
}
/// <summary>
/// User API keys
/// </summary>
@ -44,7 +33,7 @@ namespace isnd.Data
/// </summary>
/// <value></value>
public DbSet<Package> Packages { get; set; }
/// <summary>
/// Package Versions
/// </summary>
@ -56,8 +45,5 @@ namespace isnd.Data
/// </summary>
/// <value></value>
public DbSet<Commit> Commits { get; set; }
public DbSet<Dependency> Dependencies { get; set; }
public DbSet<PackageDependencyGroup> PackageDependencyGroups { get; set; }
}
}

@ -5,8 +5,6 @@ namespace isnd.Data
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
[PersonalData]
public string FullName { get; set; }
}
}

@ -0,0 +1,119 @@
using System.Net.Sockets;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using isnd.Data.Packages;
using NuGet.Versioning;
using System.Collections.Generic;
using System;
using isnd.Interfaces;
namespace isnd.Data.Catalog
{
public class CatalogEntry : HappyIdOwner , IObject// , IPackageDetails
{
/// <summary>
/// Creates a catalog entry
/// </summary>
/// <param name="id">package details url</param>
/// <returns></returns>
public CatalogEntry(string id): base(id)
{
}
/// <summary>
/// The ID of the package
/// </summary>
/// <value></value>
[JsonProperty("id")]
public string Id { get; set; }
/// <summary>
/// The Package details url
/// </summary>
/// <returns></returns>
[JsonProperty("@id")]
public string refid { get => GetId(); }
[JsonProperty("@type")]
public string[] RefType { get; protected set; } = new string[] { "PackageDetail" };
[JsonProperty("commitId")]
public string CommitId { get; set; }
[JsonProperty("commitTimeStamp")]
public DateTime CommitTimeStamp { 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; }
public string language { 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; }
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 security vulnerabilities of the package
/// </summary>
/// <value></value>
public Vulnerabilitie[] vulnerabilities { get; set; }
public string packageContent { get; set; }
/// <summary>
/// A string containing a ISO 8601 timestamp of when the package was published
/// </summary>
/// <value></value>
[JsonProperty("published")]
public DateTime Published { get; set; }
/// <summary>
/// The full version string after normalization
/// </summary>
/// <value></value>
[Required,JsonRequired]
[JsonProperty("version")]
public string Version { get; set; }
}
}

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

@ -1,237 +0,0 @@
using System.ComponentModel;
using System.Net.Sockets;
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using isnd.Data.Packages;
using NuGet.Versioning;
using System.Collections.Generic;
using System;
using isnd.Interfaces;
using NuGet.Protocol.Core.Types;
using NuGet.Protocol;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using System.Threading.Tasks;
using isnd.Entities;
namespace isnd.Data.Catalog
{
public class PackageDetails : Permalink, IObject, IPackageSearchMetadata
{
/// <summary>
/// Creates a catalog entry
/// </summary>
/// <param name="pkg">package id</param>
/// <param name="apiBase">api Base</param>
/// <returns></returns>
public PackageDetails(PackageVersion pkg, string apiBase): base( apiBase + ApiConfig.Registration + "/" + pkg.PackageId + "/" + pkg.FullString + ".json")
{
Title = PackageId = pkg.Package.Id;
Version = pkg.FullString;
Authors = $"{pkg.Package.Owner.FullName} <${pkg.Package.Owner.Email}>";
packageContent = apiBase + pkg.NugetLink;
CommitId = pkg.CommitId;
Published = CommitTimeStamp = pkg.LatestCommit.CommitTimeStamp;
IsListed = !pkg.IsDeleted && pkg.Package.Public;
if (pkg.DependencyGroups!=null)
{
DependencySets = pkg.DependencyGroups.ToDepSetInfo();
}
PackageDetailsUrl = new Uri(this.id);
// TODO Licence Project Urls, Summary, Title, Owners, etc ...
}
[JsonProperty("@type")]
public string[] RefType { get; protected set; } = new string[] { "PackageDetails" };
/// <summary>
///
/// </summary>
/// <param name="apiBase"></param>
/// <param name="pkgId"></param>
/// <param name="pkgVersionString"></param>
/// <param name="commitId"></param>
/// <param name="commitTimeStamp"></param>
/// <param name="authors"></param>
/// <param name="deprecation"></param>
/// <param name="description"></param>
/// <param name="iconUrl"></param>
/// <param name="language"></param>
/// <param name="licenseUrl"></param>
/// <param name="licenseExpression"></param>
/// <param name="minClientVersion"></param>
/// <param name="projectUrl"></param>
/// <param name="requireLicenseAcceptance"></param>
/// <param name="summary"></param>
/// <param name="tags"></param>
/// <param name="title"></param>
/// <param name="packageContent"></param>
/// <param name="version"></param>
/// <param name="identity"></param>
/// <param name="readmeUrl"></param>
/// <param name="reportAbuseUrl"></param>
/// <param name="packageDetailsUrl"></param>
/// <param name="owners"></param>
/// <param name="isListed"></param>
/// <param name="prefixReserved"></param>
/// <param name="licenseMetadata"></param>
public PackageDetails(string apiBase, string pkgId, string pkgVersionString, string commitId, DateTimeOffset commitTimeStamp, string authors, Deprecation deprecation, string description, Uri iconUrl, string language, Uri licenseUrl, string licenseExpression, string minClientVersion, Uri projectUrl, bool requireLicenseAcceptance, string summary, string tags, string title, string packageContent, string version, PackageIdentity identity, Uri readmeUrl, Uri reportAbuseUrl, Uri packageDetailsUrl, string owners, bool isListed, bool prefixReserved, LicenseMetadata licenseMetadata)
: base( apiBase + ApiConfig.Registration + "/" + pkgId + "/" + pkgVersionString + ".json")
{
this.CommitId = commitId;
this.CommitTimeStamp = commitTimeStamp;
this.Authors = authors;
this.deprecation = deprecation;
this.Description = description;
this.IconUrl = iconUrl;
this.language = language;
this.LicenseUrl = licenseUrl;
this.licenseExpression = licenseExpression;
this.minClientVersion = minClientVersion;
this.ProjectUrl = projectUrl;
this.RequireLicenseAcceptance = requireLicenseAcceptance;
this.Summary = summary;
this.Tags = tags;
this.Title = title;
this.packageContent = packageContent;
this.Version = version;
this.Identity = identity;
this.ReadmeUrl = readmeUrl;
this.ReportAbuseUrl = reportAbuseUrl;
this.PackageDetailsUrl = packageDetailsUrl;
this.Owners = owners;
this.IsListed = isListed;
this.PrefixReserved = prefixReserved;
this.LicenseMetadata = licenseMetadata;
}
[JsonProperty("commitId")]
public string CommitId { get; set; }
[JsonProperty("commitTimeStamp")]
public DateTimeOffset CommitTimeStamp { get; set; }
/// <summary>
/// Authors
/// </summary>
/// <value>string or array of strings</value>
[JsonProperty("authors")]
public string Authors { get; set; }
/// <summary>
/// The deprecation associated with the package
/// </summary>
/// <value></value>
public Deprecation deprecation { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("iconUrl")]
public Uri IconUrl { get; set; }
public string language { get; set; }
[JsonProperty("licenseUrl")]
public Uri LicenseUrl { get; set; }
public string licenseExpression { get; set; }
public string minClientVersion { get; set; }
[JsonProperty("projectUrl")]
public Uri ProjectUrl { get; set; }
[JsonProperty("requireLicenseAcceptance")]
public bool RequireLicenseAcceptance { get; set; }
[JsonProperty("summary")]
public string Summary { get; set; }
/// <summary>
/// The tags
/// </summary>
/// <value></value>
[JsonProperty("tags")]
public string Tags { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
/// <summary>
/// The security vulnerabilities of the package
/// </summary>
/// <value></value>
public IEnumerable<PackageVulnerabilityMetadata> Vulnerabilities { get; }
public string packageContent { get; set; }
/// <summary>
/// A string containing a ISO 8601 timestamp of when the package was published
/// </summary>
/// <value></value>
[JsonProperty("published")]
public DateTimeOffset? Published { get; set; }
/// <summary>
/// The full version string after normalization
/// </summary>
/// <value></value>
[Required,JsonRequired]
[JsonProperty("version")]
public string Version { get; set; }
[Required,JsonRequired]
[JsonProperty("id")]
public string PackageId { get; set; }
public long? DownloadCount { get; set; }
public PackageIdentity Identity{ get; set; }
public Uri ReadmeUrl { get; set; }
public Uri ReportAbuseUrl { get; set; }
public Uri PackageDetailsUrl { get; set; }
public string Owners { get; set; }
[JsonProperty("isListed")]
public bool IsListed { get; set; }
public bool PrefixReserved { get; set; }
public LicenseMetadata LicenseMetadata { get; set; }
public IEnumerable<PackageDependencyGroupInfo> DependencySets {get; set;}
IEnumerable<NuGet.Packaging.PackageDependencyGroup> IPackageSearchMetadata.DependencySets => throw new NotImplementedException();
public Task<PackageDeprecationMetadata> GetDeprecationMetadataAsync()
{
throw new NotImplementedException();
}
public Task<IEnumerable<VersionInfo>> GetVersionsAsync()
{
throw new NotImplementedException();
}
}
public class PackageDependencyGroupInfo
{
private PackageDependencyGroup group;
public PackageDependencyGroupInfo(PackageDependencyGroup group)
{
this.group = group;
}
}
}

@ -1,33 +0,0 @@
using isnd.Data.Packages;
using isnd.Entities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace isnd.Data.Catalog
{
public class PackageRegistration : Permalink
{
public PackageRegistration(string url) : base(url)
{
Items = new List<RegistrationPage>();
}
public PackageRegistration(string apiBase, string pkgId, IEnumerable<PackageVersion> versions) : base($"{apiBase}{ApiConfig.Registration}/{pkgId}/index.json")
{
Items = new List<RegistrationPage>
{
new RegistrationPage(pkgId, apiBase, versions)
};
}
[JsonProperty("count")]
public int Count { get => Items.Count; }
[JsonProperty("items")]
public List<RegistrationPage> Items { get; set; }
}
}

@ -1,7 +1,5 @@
using System.ComponentModel.DataAnnotations;
using isnd.Entities;
using Newtonsoft.Json;
using isn.abst;
namespace isnd.Data.Catalog
{
@ -11,16 +9,6 @@ namespace isnd.Data.Catalog
/// </summary>
public class RegistrationLeaf
{
public RegistrationLeaf(string apiBase, string pkgId, string fullVersionString, PackageDetails entry)
{
this.registration = apiBase + ApiConfig.Registration + "/" + pkgId + "/" + fullVersionString + ".json";
Id = registration;
this.PackageContent = apiBase + ApiConfig.Nuget + "/" + pkgId + "/" + fullVersionString
+ "/" + pkgId + "-" + fullVersionString + "." + Constants.PacketFileExtension;
Entry = entry;
}
/*
@id string yes
catalogEntry object yes
@ -40,7 +28,7 @@ namespace isnd.Data.Catalog
/// </summary>
/// <value></value>
[JsonProperty("catalogEntry")]
public PackageDetails Entry { get; set; }
public CatalogEntry Entry { get; set; }
/// <summary>
/// The URL to the package content (.nupkg)
@ -48,7 +36,5 @@ namespace isnd.Data.Catalog
/// <value></value>
[JsonProperty("packageContent")]
public string PackageContent { get; set; }
public string registration { get; set; }
}
}

@ -7,23 +7,26 @@ using NuGet.Versioning;
namespace isnd.Data.Catalog
{
public class RegistrationPage : Permalink
public class RegistrationPage : HappyIdOwner
{
[JsonProperty("@id")]
public string Id { get => GetId(); }
private readonly string pkgid;
private readonly List<RegistrationLeaf> items;
private readonly List<PackageVersion> items;
private readonly string apiBase;
protected string Bid { get ; private set; }
protected string ExternalUrl { get; }
public RegistrationPage (string pkgid, string apiBase) : base(apiBase + $"/registration/{pkgid}/index.json")
public RegistrationPage (string bid, string pkgid, string extUrl) : base(bid + "/" + pkgid + "/index.json")
{
Parent = apiBase + $"/registration/{pkgid}/index.json";
this.items = new List<RegistrationLeaf>();
Bid = bid;
Parent = Bid + $"/{pkgid}/index.json";
ExternalUrl = extUrl;
this.items = new List<PackageVersion>();
this.pkgid = pkgid;
this.apiBase = apiBase;
}
public RegistrationPage(string pkgid, string apiBase, IEnumerable<PackageVersion> versions) : this(pkgid, apiBase)
public RegistrationPage(string bid, string pkgid, string extUrl, List<PackageVersion> versions) : this(bid, pkgid, extUrl)
{
AddVersionRange(versions);
}
@ -39,14 +42,13 @@ namespace isnd.Data.Catalog
/// <value></value>
[JsonProperty("items")]
public RegistrationLeaf[] Items { get => items.ToArray(); }
public CatalogEntry[] Items { get => items.Select((p) => p.ToLeave(Bid, ExternalUrl)).ToArray(); }
public void AddVersionRange(IEnumerable<PackageVersion> vitems)
{
if (vitems.Count() == 0) return;
NuGetVersion upper = null;
NuGetVersion lower = null;
PackageVersion latest = null;
if (Lower!=null) lower = new NuGetVersion(Lower);
if (Upper!=null) upper = new NuGetVersion(Upper);
@ -54,9 +56,7 @@ namespace isnd.Data.Catalog
long commitMax = 0;
foreach (var p in vitems)
{
if (p.LatestCommit==null) continue;
var pkg = p.ToPackage(apiBase);
if (items.Contains(pkg)) continue;
if (items.Contains(p)) continue;
if (upper == null) upper = p.NugetVersion;
else if ( upper < p.NugetVersion) upper = p.NugetVersion;
@ -64,14 +64,12 @@ namespace isnd.Data.Catalog
if (lower == null) lower = p.NugetVersion;
else if (lower > p.NugetVersion) lower = p.NugetVersion;
if (p.CommitNId > commitMax)
{
latest = p;
}
items.Add(pkg);
if (p.CommitNId > commitMax) commitMax = p.CommitNId;
items.Add(p);
}
Upper = upper?.ToFullString() ?? lower?.ToFullString();
Lower = lower?.ToFullString() ?? upper?.ToFullString();
Upper = upper.ToFullString();
Lower = lower.ToFullString();
CommitId = commitMax.ToString();
}
/// <summary>
@ -96,5 +94,7 @@ namespace isnd.Data.Catalog
[JsonProperty("count")]
public int Count { get => items.Count; }
public string CommitId { get; internal set; }
public DateTime CommitTimeStamp { get; internal set; }
}
}

@ -0,0 +1,53 @@
using isnd.Data.Packages;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace isnd.Data.Catalog
{
public class RegistrationPageIndex : HappyIdOwner
{
public RegistrationPageIndex(string url) : base(url)
{
Items = new List<RegistrationPage>();
}
public RegistrationPageIndex(string bid, string id, string extUrl, IEnumerable<Package> pkgs) : base(bid + $"/{id}/index.json")
{
Items = new List<RegistrationPage>();
long cnid = 0;
var pkgsGroups = pkgs.GroupBy(l => l.Id);
// Pour tous les groupes par Id
foreach (var gsp in pkgsGroups)
{
var pkgsbi = gsp.ToArray();
List<PackageVersion> versions = new List<PackageVersion>();
foreach(var l in pkgsbi.Select(p => p.Versions))
{
versions.AddRange(l);
foreach (var pv in l)
{
if (pv.CommitNId> cnid)
{
cnid = pv.CommitNId;
}
}
}
Items.Add(new RegistrationPage(bid, gsp.Key, extUrl, versions));
}
CommitId = cnid.ToString();
}
[JsonProperty("count")]
public int Count { get => Items.Count; }
[JsonProperty("items")]
public List<RegistrationPage> Items { get; set; }
public string CommitId { get; set; }
public DateTime CommitTimeStamp { get; internal set; }
}
}

@ -4,9 +4,9 @@ using Newtonsoft.Json;
namespace isnd.Data.Catalog
{
public class PackageRegistrationQuery
public class RegistrationPageIndexQuery
{
public PackageRegistrationQuery()
public RegistrationPageIndexQuery()
{
}

@ -13,6 +13,6 @@ namespace isnd.Interfaces
string CommitId { get; }
[JsonProperty("commitTimeStamp")]
DateTimeOffset CommitTimeStamp { get; }
DateTime CommitTimeStamp { get; }
}
}

@ -1,12 +0,0 @@
using System;
using isnd.Interfaces;
namespace isnd.Data.Packages.Catalog
{
public class PackageEntry : IObject
{
public string CommitId => throw new NotImplementedException();
public DateTimeOffset CommitTimeStamp => throw new NotImplementedException();
}
}

@ -10,9 +10,10 @@ namespace isnd.Data.Packages.Catalog
/// for availability, or deletion,
///
/// </summary>
public class PackageDetails : IObject
public class PackageRef : IObject
{
[JsonProperty("@id")]
public string RefId { get; set; }
@ -46,7 +47,6 @@ namespace isnd.Data.Packages.Catalog
public virtual Commit LastCommit { get; set; }
[JsonProperty("commitTimeStamp")]
public DateTimeOffset CommitTimeStamp { get; set; }
public DateTime CommitTimeStamp { get; set; }
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using isnd.Interfaces;
using Newtonsoft.Json;
namespace isnd.Data.Packages.Catalog
{
public class Page : IObject
{
[JsonProperty("@id")]
public string Id { get; set; }
[JsonProperty("parent")]
public string Parent { get; set; }
[JsonProperty("items")]
public virtual List<PackageRef> Items { get; set; }
public string CommitId { get; set; }
public DateTime CommitTimeStamp { get; set; }
}
}

@ -21,7 +21,7 @@ namespace isnd.Data.Packages
public long Id { get; set; }
[Required][JsonIgnore]
public DateTimeOffset TimeStamp{ get; set; }
public DateTime TimeStamp{ get; set; }
[Required]
public PackageAction Action { get; set; }
@ -30,7 +30,7 @@ namespace isnd.Data.Packages
public string CommitId { get => Id.ToString(); }
[NotMapped]
public DateTimeOffset CommitTimeStamp { get => TimeStamp; }
public DateTime CommitTimeStamp { get => TimeStamp; }
[ForeignKey("CommitNId")]

@ -1,39 +0,0 @@
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using System.ComponentModel.DataAnnotations.Schema;
using isnd.Data.Packages;
namespace isnd.Data
{
public class Dependency
{
[JsonIgnore]
[Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get;set;}
/// <summary>
/// Dependency Package Identifier
/// </summary>
/// <value></value>
[JsonProperty("id")]
public string PackageId { get;set;}
/// <summary>
/// Dependency Group Id
/// </summary>
/// <value></value>
[Required]
[ForeignKey("Group")]
[JsonIgnore]
public string DependencyGroupId { set ; get ; }
[JsonIgnore]
public virtual PackageDependencyGroup Group{ get; set; }
// TODO Version Range
[JsonProperty("range")]
public string Version { get; set; }
}
}

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
namespace isnd.Data.Packages
{
public interface IPackage
{
string Id { get; set; }
string OwnerId { get; set; }
string Description { get; set; }
bool Public { get; set; }
ApplicationUser Owner { get; set; }
List<PackageVersion> Versions { get; set; }
long CommitNId { get; set; }
string CommitId { get; }
Commit LatestCommit { get; set; }
DateTimeOffset CommitTimeStamp { get; set; }
}
}

@ -3,13 +3,27 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using isnd.Data.Catalog;
using isnd.Interfaces;
using Newtonsoft.Json;
namespace isnd.Data.Packages
{
public interface IPackage
{
string Id { get; set; }
string OwnerId { get; set; }
string Description { get; set; }
bool Public { get; set; }
ApplicationUser Owner { get; set; }
List<PackageVersion> Versions { get; set; }
long CommitNId { get; set; }
string CommitId { get; }
Commit LatestVersion { get; set; }
DateTime CommitTimeStamp { get; set; }
}
public class Package
public class Package : IObject, IPackage
{
[Key]
[Required]
@ -38,19 +52,15 @@ namespace isnd.Data.Packages
/// </summary>
/// <value></value>
[Required]
[JsonIgnore]
[ForeignKey("LatestCommit")]
[JsonIgnore]
public long CommitNId { get; set; }
[NotMapped]
public string CommitId { get => CommitNId.ToString(); }
public virtual Commit LatestCommit { get; set; }
[ForeignKey("CommitNId")]
internal string GetLatestVersion()
{
return Versions.Max(v => v.NugetVersion)?.ToFullString();
}
public virtual Commit LatestVersion { get; set; }
public DateTime CommitTimeStamp { get; set; }
}
}

@ -1,51 +0,0 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using isnd.Data.Catalog;
using Microsoft.DotNet.Scaffolding.Shared.ProjectModel;
using Microsoft.Identity.Client;
using Newtonsoft.Json;
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
using NuGet.Versioning;
namespace isnd.Data
{
static class Helpers
{
public static PackageDependencyGroupInfo[] ToDepSetInfo(this IEnumerable<PackageDependencyGroup> groups)
{
return groups.Select(group => new PackageDependencyGroupInfo(group)).ToArray();
}
}
public class PackageDependencyGroup
{
[JsonIgnore]
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string Id { get ; set;}
[Required]
[JsonProperty("id")]
public string PackageId { get ; set;}
[Required]
[JsonIgnore]
public string PackageVersionFullString { get ; set;}
[JsonProperty("targetFramework")]
[Required]
public string TargetFramework { get; set; }
[JsonIgnore]
[ForeignKey("DependencyGroupId")]
public virtual List<Dependency> Dependencies { get; set; }
[JsonIgnore]
public virtual PackageVersion PackageVersion { get; set; }
}
}

@ -1,4 +1,3 @@
using System.Security.Principal;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
@ -6,20 +5,14 @@ using isn.abst;
using isnd.Data.Catalog;
using isnd.Data.Packages;
using isnd.Data.Packages.Catalog;
using isnd.Entities;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NuGet.Versioning;
using System;
using NuGet.Packaging;
using System.Collections.Generic;
using Package = isnd.Data.Packages.Package;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace isnd.Data
{
[PrimaryKey("PackageId", "FullString")]
public class PackageVersion
public class PackageVersion
{
[Required]
[ForeignKey("Package")]
@ -45,6 +38,7 @@ namespace isnd.Data
/// <value></value>
[StringLength(256)]
[Required]
[Key]
public string FullString { get; set; }
public bool IsPrerelease { get; set; }
@ -52,7 +46,7 @@ namespace isnd.Data
public string Type { get; set; }
[JsonIgnore]
public virtual Packages.Package Package { get; set; }
public virtual Package Package { get; set; }
[Required]
[JsonIgnore]
@ -64,21 +58,23 @@ namespace isnd.Data
public string CommitId { get => CommitNId.ToString(); }
public virtual Commit LatestCommit { get; set; }
public virtual List<PackageDependencyGroup> DependencyGroups { get; set; }
public string NugetLink => $"{ApiConfig.Nuget}/{PackageId}/{FullString}/{PackageId}-{FullString}."
+ Constants.PacketFileExtension;
public string NuspecLink => $"{ApiConfig.Nuspec}/{PackageId}/{FullString}/{PackageId}-{FullString}."
+ Constants.SpecFileExtension;
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 Catalog.RegistrationLeaf ToPackage(string apiBase)
public CatalogEntry ToLeave(string bid, string extUrl)
{
return new Catalog.RegistrationLeaf(apiBase, this.PackageId , FullString, new Catalog.PackageDetails(this, apiBase));
return new CatalogEntry(bid + "/" + this.PackageId + "/" + FullString + ".json")
{
Id = PackageId,
Version = FullString,
authors = $"{this.Package.Owner.FullName} <${Package.Owner.Email}>",
packageContent = extUrl + this.NugetLink
};
}
public bool IsDeleted => LatestCommit?.Action == PackageAction.DeletePackage;
}
}

@ -0,0 +1,8 @@
namespace isnd.Entities
{
public class UnleashClientSettings
{
public string ClientApiKey { get; set; }
public string ApiUrl { get; set; }
}
}

@ -1,23 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using isn;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace isnd.Helpers
{
public static class ApiHelpers
{
static public APIKO CreateAPIKO(this Controller controller, string context)
{
Dictionary<string,string[]> errors = new();
foreach (var elt in controller.ModelState)
{
errors[elt.Key] = elt.Value.Errors.Select( e => e.ErrorMessage).ToArray();
}
return new APIKO{ Context = context, Errors = errors };
}
}
}

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using isnd.Entities;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Unleash;
using Unleash.ClientFactory;
namespace isnd.Helpers
{
public static class UnleashHelpers
{
public static IUnleash CreateUnleahClient(this IHostingEnvironment env,
UnleashClientSettings unleashClientSettings)
{
var unleashSettings = new UnleashSettings
{
UnleashApi = new Uri(unleashClientSettings.ApiUrl),
AppName = "isnd",
Environment = env.EnvironmentName,
CustomHttpHeaders = new Dictionary<string, string>
{
{ "Authorization", unleashClientSettings.ClientApiKey }
}
};
UnleashClientFactory unleashClientFactory = new UnleashClientFactory();
return unleashClientFactory.CreateClient(unleashSettings);
}
}
}

@ -1,13 +0,0 @@
using System.Linq;
using System.Threading.Tasks;
using isnd.Data.ApiKeys;
namespace isnd.Interfaces
{
public interface IApiKeyProvider
{
Task<ApiKey> CreateApiKeyAsync(CreateModel model);
IQueryable<ApiKey> GetUserKeys(string identityName);
}
}

@ -1,36 +1,36 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using isn.Abstract;
using isnd.Controllers;
using isnd.Data;
using isnd.Data.Catalog;
using isnd.Data.Packages;
using isnd.Data.Packages.Catalog;
using isnd.Services;
using isnd.ViewModels;
using NuGet.Versioning;
using Unleash;
namespace isnd.Interfaces
{
public interface IPackageManager
{
string CatalogBaseUrl { get; }
AutoCompleteResult AutoComplete(string pkgid, int skip=0, int take=25, bool prerelease = false, string packageType = null);
AutoCompleteResult AutoComplete(string pkgid, int skip, int take, bool prerelease = false, string packageType = null);
string[] GetVersions(string pkgid, NuGetVersion parsedVersion, bool prerelease = false, string packageType = null, int skip = 0, int take = 25);
IEnumerable<Resource> GetResources();
Task<PackageRegistration> UpdateCatalogForAsync(Commit commit);
IEnumerable<Resource> GetResources(IUnleash unleashĈlient);
Task<RegistrationPageIndex> ÛpdateCatalogForAsync(Commit commit);
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<Data.Catalog.RegistrationLeaf> GetCatalogEntryAsync(string pkgId, string version, string pkgType);
IEnumerable<Data.Catalog.RegistrationLeaf> SearchCatalogEntriesById(string pkgId, string semver, string pkgType, bool preRelease);
Task<CatalogEntry> GetCatalogEntryAsync(string pkgId, string version, string pkgType);
IEnumerable<CatalogEntry> SearchCatalogEntriesById(string pkgId, string semver, string pkgType);
Task<PackageRegistration> GetCatalogIndexAsync();
Task<PackageRegistration> GetPackageRegistrationIndexAsync(PackageRegistrationQuery query);
Task<RegistrationPageIndex> GetCatalogIndexAsync();
Task<RegistrationPageIndex> GetPackageRegistrationIndexAsync(RegistrationPageIndexQuery query);
Task<PackageSearchResult> SearchPackageAsync(PackageRegistrationQuery query);
Task<PackageVersion> PutPackageAsync(Stream packageStream, string ownerId);
Task<RegistrationPageIndex> SearchPackageAsync(RegistrationPageIndexQuery query);
}
}

@ -0,0 +1,230 @@
// <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("20210424155323_init")]
partial class init
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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("isn.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("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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isn.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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,219 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace isndhost.Migrations
{
public partial class init : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
FullName = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
RoleId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
UserId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(nullable: false),
ProviderKey = table.Column<string>(nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
LoginProvider = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: false),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

@ -0,0 +1,253 @@
// <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("20210502153508_api-keys")]
partial class apikeys
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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("isn.Data.ApiKey", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("ApiKeys");
});
modelBuilder.Entity("isn.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("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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isn.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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.ApiKey", b =>
{
b.HasOne("isn.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class apikeys : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ApiKeys",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_ApiKeys", x => x.Id);
table.ForeignKey(
name: "FK_ApiKeys_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_ApiKeys_UserId",
table: "ApiKeys",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "ApiKeys");
}
}
}

@ -0,0 +1,259 @@
// <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("20210508012908_ApkiKey.CreationDate")]
partial class ApkiKeyCreationDate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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("isn.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("isn.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("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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isn.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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isn.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,43 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class ApkiKeyCreationDate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "CreationDate",
table: "ApiKeys",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<string>(
name: "Name",
table: "ApiKeys",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "ValidityPeriodInDays",
table: "ApiKeys",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CreationDate",
table: "ApiKeys");
migrationBuilder.DropColumn(
name: "Name",
table: "ApiKeys");
migrationBuilder.DropColumn(
name: "ValidityPeriodInDays",
table: "ApiKeys");
}
}
}

@ -0,0 +1,316 @@
// <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("20210516060430_packages")]
partial class packages
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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("isn.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("isn.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("isn.Data.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Description");
b.Property<string>("OwnerId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("isn.Data.PackageVersion", b =>
{
b.Property<string>("FullString")
.ValueGeneratedOnAdd()
.HasMaxLength(32);
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<string>("PackageId")
.IsRequired();
b.Property<int>("Patch");
b.HasKey("FullString");
b.HasIndex("PackageId");
b.ToTable("PackageVersions");
});
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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isn.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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isn.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.Package", b =>
{
b.HasOne("isn.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.PackageVersion", b =>
{
b.HasOne("isn.Data.Package", "Package")
.WithMany()
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,70 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class packages : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Packages",
columns: table => new
{
Id = table.Column<string>(nullable: false),
OwnerId = table.Column<string>(nullable: false),
Description = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Packages", x => x.Id);
table.ForeignKey(
name: "FK_Packages_AspNetUsers_OwnerId",
column: x => x.OwnerId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "PackageVersions",
columns: table => new
{
FullString = table.Column<string>(maxLength: 32, nullable: false),
PackageId = table.Column<string>(nullable: false),
Major = table.Column<int>(nullable: false),
Minor = table.Column<int>(nullable: false),
Patch = table.Column<int>(nullable: false),
IsPrerelease = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PackageVersions", x => x.FullString);
table.ForeignKey(
name: "FK_PackageVersions_Packages_PackageId",
column: x => x.PackageId,
principalTable: "Packages",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Packages_OwnerId",
table: "Packages",
column: "OwnerId");
migrationBuilder.CreateIndex(
name: "IX_PackageVersions_PackageId",
table: "PackageVersions",
column: "PackageId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "PackageVersions");
migrationBuilder.DropTable(
name: "Packages");
}
}
}

@ -0,0 +1,312 @@
// <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("20210522194803_packageVersionKey")]
partial class packageVersionKey
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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("isn.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("isn.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("isn.Data.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Description");
b.Property<string>("OwnerId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("isn.Data.PackageVersion", b =>
{
b.Property<string>("PackageId");
b.Property<string>("FullString")
.HasMaxLength(256);
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<int>("Patch");
b.HasKey("PackageId", "FullString");
b.ToTable("PackageVersions");
});
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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isn.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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isn.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.Package", b =>
{
b.HasOne("isn.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.PackageVersion", b =>
{
b.HasOne("isn.Data.Package", "Package")
.WithMany()
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -1,14 +1,9 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace isnd.Migrations
namespace isndhost.Migrations
{
/// <inheritdoc />
public partial class pkgversions : Migration
public partial class packageVersionKey : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
@ -19,9 +14,13 @@ namespace isnd.Migrations
name: "IX_PackageVersions_PackageId",
table: "PackageVersions");
migrationBuilder.DropColumn(
name: "CommitTimeStamp",
table: "Packages");
migrationBuilder.AlterColumn<string>(
name: "FullString",
table: "PackageVersions",
maxLength: 256,
nullable: false,
oldClrType: typeof(string),
oldMaxLength: 32);
migrationBuilder.AddPrimaryKey(
name: "PK_PackageVersions",
@ -29,19 +28,19 @@ namespace isnd.Migrations
columns: new[] { "PackageId", "FullString" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions");
migrationBuilder.AddColumn<DateTimeOffset>(
name: "CommitTimeStamp",
table: "Packages",
type: "timestamp with time zone",
migrationBuilder.AlterColumn<string>(
name: "FullString",
table: "PackageVersions",
maxLength: 32,
nullable: false,
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)));
oldClrType: typeof(string),
oldMaxLength: 256);
migrationBuilder.AddPrimaryKey(
name: "PK_PackageVersions",

@ -0,0 +1,316 @@
// <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("20210621214109_version-types")]
partial class versiontypes
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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("isn.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("isn.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("isn.Data.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Description")
.HasMaxLength(1024);
b.Property<string>("OwnerId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("OwnerId");
b.ToTable("Packages");
});
modelBuilder.Entity("isn.Data.PackageVersion", b =>
{
b.Property<string>("PackageId");
b.Property<string>("FullString")
.HasMaxLength(256);
b.Property<string>("Type")
.HasMaxLength(256);
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<int>("Patch");
b.HasKey("PackageId", "FullString", "Type");
b.ToTable("PackageVersions");
});
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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("isn.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("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("isn.Data.ApplicationUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isn.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.Package", b =>
{
b.HasOne("isn.Data.ApplicationUser", "Owner")
.WithMany()
.HasForeignKey("OwnerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isn.Data.PackageVersion", b =>
{
b.HasOne("isn.Data.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,58 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class versiontypes : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions");
migrationBuilder.AddColumn<string>(
name: "Type",
table: "PackageVersions",
maxLength: 256,
nullable: false,
defaultValue: "");
migrationBuilder.AlterColumn<string>(
name: "Description",
table: "Packages",
maxLength: 1024,
nullable: true,
oldClrType: typeof(string),
oldNullable: true);
migrationBuilder.AddPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions",
columns: new[] { "PackageId", "FullString", "Type" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions");
migrationBuilder.DropColumn(
name: "Type",
table: "PackageVersions");
migrationBuilder.AlterColumn<string>(
name: "Description",
table: "Packages",
nullable: true,
oldClrType: typeof(string),
oldMaxLength: 1024,
oldNullable: true);
migrationBuilder.AddPrimaryKey(
name: "PK_PackageVersions",
table: "PackageVersions",
columns: new[] { "PackageId", "FullString" });
}
}
}

@ -0,0 +1,346 @@
// <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("20210828142245_versionCommit")]
partial class versionCommit
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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.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.Catalog.Commit", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Action");
b.Property<string>("PackageVersionId")
.IsRequired();
b.Property<DateTime>("TimeStamp");
b.HasKey("Id");
b.ToTable("Commits");
});
modelBuilder.Entity("isnd.Data.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
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>("PackageId");
b.Property<string>("FullString")
.HasMaxLength(256);
b.Property<string>("Type")
.HasMaxLength(256);
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<int>("Patch");
b.HasKey("PackageId", "FullString", "Type");
b.ToTable("PackageVersions");
});
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);
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isnd.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isnd.Data.Package", b =>
{
b.HasOne("isnd.Data.Catalog.Commit", "LatestCommit")
.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.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,92 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace isndhost.Migrations
{
public partial class versionCommit : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<long>(
name: "CommitNId",
table: "Packages",
nullable: false,
defaultValue: 0L);
migrationBuilder.AddColumn<DateTime>(
name: "CommitTimeStamp",
table: "Packages",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.AddColumn<bool>(
name: "Public",
table: "Packages",
nullable: false,
defaultValue: false);
migrationBuilder.CreateTable(
name: "Commits",
columns: table => new
{
Id = table.Column<long>(nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
TimeStamp = table.Column<DateTime>(nullable: false),
Action = table.Column<int>(nullable: false),
PackageVersionId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Commits", x => x.Id);
});
migrationBuilder.Sql(
@"delete from ""PackageVersions"""
);
migrationBuilder.Sql(
@"delete from ""Packages"";"
);
migrationBuilder.CreateIndex(
name: "IX_Packages_CommitNId",
table: "Packages",
column: "CommitNId");
migrationBuilder.AddForeignKey(
name: "FK_Packages_Commits_CommitNId",
table: "Packages",
column: "CommitNId",
principalTable: "Commits",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Packages_Commits_CommitNId",
table: "Packages");
migrationBuilder.DropTable(
name: "Commits");
migrationBuilder.DropIndex(
name: "IX_Packages_CommitNId",
table: "Packages");
migrationBuilder.DropColumn(
name: "CommitNId",
table: "Packages");
migrationBuilder.DropColumn(
name: "CommitTimeStamp",
table: "Packages");
migrationBuilder.DropColumn(
name: "Public",
table: "Packages");
}
}
}

@ -0,0 +1,355 @@
// <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("20210828150712_pkgVersionCommit")]
partial class pkgVersionCommit
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
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.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.Catalog.Commit", b =>
{
b.Property<long>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("Action");
b.Property<string>("PackageVersionId")
.IsRequired();
b.Property<DateTime>("TimeStamp");
b.HasKey("Id");
b.ToTable("Commits");
});
modelBuilder.Entity("isnd.Data.Package", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
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>("PackageId");
b.Property<string>("FullString")
.HasMaxLength(256);
b.Property<string>("Type")
.HasMaxLength(256);
b.Property<long>("CommitNId");
b.Property<bool>("IsPrerelease");
b.Property<int>("Major");
b.Property<int>("Minor");
b.Property<int>("Patch");
b.HasKey("PackageId", "FullString", "Type");
b.HasIndex("CommitNId");
b.ToTable("PackageVersions");
});
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);
});
modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b =>
{
b.HasOne("isnd.Data.ApplicationUser", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("isnd.Data.Package", b =>
{
b.HasOne("isnd.Data.Catalog.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.Catalog.Commit", "LatestCommit")
.WithMany()
.HasForeignKey("CommitNId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("isnd.Data.Package", "Package")
.WithMany("Versions")
.HasForeignKey("PackageId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace isndhost.Migrations
{
public partial class pkgVersionCommit : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<long>(
name: "CommitNId",
table: "PackageVersions",
nullable: false,
defaultValue: 0L);
migrationBuilder.CreateIndex(
name: "IX_PackageVersions_CommitNId",
table: "PackageVersions",
column: "CommitNId");
migrationBuilder.AddForeignKey(
name: "FK_PackageVersions_Commits_CommitNId",
table: "PackageVersions",
column: "CommitNId",
principalTable: "Commits",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_PackageVersions_Commits_CommitNId",
table: "PackageVersions");
migrationBuilder.DropIndex(
name: "IX_PackageVersions_CommitNId",
table: "PackageVersions");
migrationBuilder.DropColumn(
name: "CommitNId",
table: "PackageVersions");
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…