diff --git a/.gitignore b/.gitignore index 2c6c27e..68dafe9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,24 @@ .sass-cache/ -bin/ -obj/ +/src/isnd/bin/ +/src/isnd/obj/ +/src/isn/obj +/src/isn/bin +/src/isn/.vscode/ +/test/isnd.tests/obj/ +/test/isnd.tests/bin/ +/packages/ bower_components/ -appsettings.*.json +/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/ diff --git a/Directory.Build.props b/Directory.Build.props deleted file mode 100644 index ff02831..0000000 --- a/Directory.Build.props +++ /dev/null @@ -1,11 +0,0 @@ - - - net10.0 - true - WTFPL - 1.0.8 - true - 85fd766d-5d23-4476-aed1-463b2942e86a - WTFPL - - \ No newline at end of file diff --git a/GitVersion.yml b/GitVersion.yml new file mode 100644 index 0000000..122fa7e --- /dev/null +++ b/GitVersion.yml @@ -0,0 +1,5 @@ +mode: Mainline +branches: {} +ignore: + sha: [] +merge-message-formats: {} diff --git a/README.md b/README.md index b4f0003..0e34410 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ isnd& # get an api-key from -isn push -k -s http://localhost:5000/api/v3/index.json your-lame-versionned.nupkg +isn push -k -s http://localhost:5000/index.json your-lame-versionned.nupkg wget http://localhost:5000/package/index.json?q=your&prerelease=true&semVerLevel=2.0.0 ```` @@ -55,8 +55,8 @@ sudo systemctl enable isnd ````bash sudo mkdir /usr/local/lib/isn -sudo cp -a src/isn/bin/Release/net10.0/* /usr/local/lib/isn -sudo chown -R root:root /usr/local/lib/isn +sudo cp -a src/isn/bin/Release/net6.0/* /usr/local/lib/isn +sudo chown -R root.root /usr/local/lib/isn sudo ln -s /usr/local/lib/isn/isn /usr/local/bin/isn ```` @@ -66,15 +66,12 @@ sudo ln -s /usr/local/lib/isn/isn /usr/local/bin/isn set -e # compiler tout dotnet build -c Release -# publier -dotnet publish -c Release src/isnd -dotnet publish -c Release src/isn - +dotnet publish -c Release -f net7.0 src/isnd # MAJ du serveur sudo systemctl stop isnd -sudo cp -a src/isnd/bin/Release/net10.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/net10.0/* /usr/local/lib/isn -sudo chown -R root:root /usr/local/lib/isn +sudo cp -a src/isn/bin/Release/net7.0/* /usr/local/lib/isn +sudo chown -R root.root /usr/local/lib/isn ```` diff --git a/contrib/testinstnuget/call.lines b/contrib/testinstnuget/call.lines index e69de29..c6abc1a 100644 --- a/contrib/testinstnuget/call.lines +++ b/contrib/testinstnuget/call.lines @@ -0,0 +1,2 @@ +nuget install -Verbosity detailed -Source http://localhost:5000/index.json -Prerelease Yavsc.Abstract +nuget locals all -clear diff --git a/contrib/testinstnuget/urls.adoc b/contrib/testinstnuget/urls.adoc new file mode 100644 index 0000000..5c81113 --- /dev/null +++ b/contrib/testinstnuget/urls.adoc @@ -0,0 +1,4 @@ += URL's + + + diff --git a/contrib/upgrade-isn-isnd.sh b/contrib/upgrade-isn-isnd.sh index 457348b..8a93152 100755 --- a/contrib/upgrade-isn-isnd.sh +++ b/contrib/upgrade-isn-isnd.sh @@ -3,14 +3,11 @@ set -e # compiler tout dotnet build -c Release -dotnet publish -c Release src/isnd -dotnet publish -c Release src/isn +dotnet publish -c Release -f netcoreapp2.1 src/isnd # MAJ du serveur sudo systemctl stop isnd -sudo cp -a src/isnd/bin/Release/net10.0/publish/* /srv/www/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/net10.0/* /usr/local/lib/isn -sudo chown -R root:root /usr/local/lib/isn - - +sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn +sudo chown -R root.root /usr/local/lib/isn diff --git a/isn.sln b/isn.sln index 41f4f70..1e20c9f 100644 --- a/isn.sln +++ b/isn.sln @@ -1,101 +1,101 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.6.30114.105 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{3C312E42-9A47-4BED-8265-A405FCA6AFFF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isnd.tests", "test\isnd.tests\isnd.tests.csproj", "{9D758F00-17FF-433D-B088-F9C2D97C9BD1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E8A2DF68-847A-4D88-B002-64FB666F696C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isnd", "src\isnd\isnd.csproj", "{468DB0E4-6221-4E01-BEFF-F452865E59C1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isn", "src\isn\isn.csproj", "{910E800A-59AE-46C4-B7C7-879986179246}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isn.tests", "test\isn.tests\isn.tests.csproj", "{305F640E-11BA-44F9-95E0-C6882E9CD151}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isn.abstract", "src\isn.abstract\isn.abstract.csproj", "{F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x64.ActiveCfg = Debug|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x64.Build.0 = Debug|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x86.ActiveCfg = Debug|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x86.Build.0 = Debug|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|Any CPU.Build.0 = Release|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x64.ActiveCfg = Release|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x64.Build.0 = Release|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x86.ActiveCfg = Release|Any CPU - {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x86.Build.0 = Release|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x64.ActiveCfg = Debug|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x64.Build.0 = Debug|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x86.ActiveCfg = Debug|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x86.Build.0 = Debug|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|Any CPU.Build.0 = Release|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x64.ActiveCfg = Release|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x64.Build.0 = Release|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x86.ActiveCfg = Release|Any CPU - {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x86.Build.0 = Release|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Debug|Any CPU.Build.0 = Debug|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x64.ActiveCfg = Debug|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x64.Build.0 = Debug|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x86.ActiveCfg = Debug|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x86.Build.0 = Debug|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Release|Any CPU.ActiveCfg = Release|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Release|Any CPU.Build.0 = Release|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Release|x64.ActiveCfg = Release|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Release|x64.Build.0 = Release|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Release|x86.ActiveCfg = Release|Any CPU - {910E800A-59AE-46C4-B7C7-879986179246}.Release|x86.Build.0 = Release|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|Any CPU.Build.0 = Debug|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x64.ActiveCfg = Debug|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x64.Build.0 = Debug|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x86.ActiveCfg = Debug|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x86.Build.0 = Debug|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|Any CPU.ActiveCfg = Release|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|Any CPU.Build.0 = Release|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x64.ActiveCfg = Release|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x64.Build.0 = Release|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x86.ActiveCfg = Release|Any CPU - {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x86.Build.0 = Release|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Debug|x64.ActiveCfg = Debug|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Debug|x64.Build.0 = Debug|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Debug|x86.ActiveCfg = Debug|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Debug|x86.Build.0 = Debug|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Release|Any CPU.Build.0 = Release|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Release|x64.ActiveCfg = Release|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Release|x64.Build.0 = Release|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Release|x86.ActiveCfg = Release|Any CPU - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {9D758F00-17FF-433D-B088-F9C2D97C9BD1} = {3C312E42-9A47-4BED-8265-A405FCA6AFFF} - {468DB0E4-6221-4E01-BEFF-F452865E59C1} = {E8A2DF68-847A-4D88-B002-64FB666F696C} - {910E800A-59AE-46C4-B7C7-879986179246} = {E8A2DF68-847A-4D88-B002-64FB666F696C} - {305F640E-11BA-44F9-95E0-C6882E9CD151} = {3C312E42-9A47-4BED-8265-A405FCA6AFFF} - {F0671F01-ADD7-47A6-8A29-1AAC8565DBE2} = {E8A2DF68-847A-4D88-B002-64FB666F696C} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.6.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{3C312E42-9A47-4BED-8265-A405FCA6AFFF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isnd.tests", "test\isnd.tests\isnd.tests.csproj", "{9D758F00-17FF-433D-B088-F9C2D97C9BD1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E8A2DF68-847A-4D88-B002-64FB666F696C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isnd", "src\isnd\isnd.csproj", "{468DB0E4-6221-4E01-BEFF-F452865E59C1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isn", "src\isn\isn.csproj", "{910E800A-59AE-46C4-B7C7-879986179246}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isn.tests", "test\isn.tests\isn.tests.csproj", "{305F640E-11BA-44F9-95E0-C6882E9CD151}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "isn.abst", "src\isn.abst\isn.abst.csproj", "{4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x64.Build.0 = Debug|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Debug|x86.Build.0 = Debug|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|Any CPU.Build.0 = Release|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x64.ActiveCfg = Release|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x64.Build.0 = Release|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x86.ActiveCfg = Release|Any CPU + {9D758F00-17FF-433D-B088-F9C2D97C9BD1}.Release|x86.Build.0 = Release|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x64.ActiveCfg = Debug|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x64.Build.0 = Debug|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x86.ActiveCfg = Debug|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Debug|x86.Build.0 = Debug|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|Any CPU.Build.0 = Release|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x64.ActiveCfg = Release|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x64.Build.0 = Release|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x86.ActiveCfg = Release|Any CPU + {468DB0E4-6221-4E01-BEFF-F452865E59C1}.Release|x86.Build.0 = Release|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Debug|Any CPU.Build.0 = Debug|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x64.ActiveCfg = Debug|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x64.Build.0 = Debug|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x86.ActiveCfg = Debug|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Debug|x86.Build.0 = Debug|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Release|Any CPU.ActiveCfg = Release|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Release|Any CPU.Build.0 = Release|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Release|x64.ActiveCfg = Release|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Release|x64.Build.0 = Release|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Release|x86.ActiveCfg = Release|Any CPU + {910E800A-59AE-46C4-B7C7-879986179246}.Release|x86.Build.0 = Release|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|Any CPU.Build.0 = Debug|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x64.ActiveCfg = Debug|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x64.Build.0 = Debug|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x86.ActiveCfg = Debug|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Debug|x86.Build.0 = Debug|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|Any CPU.ActiveCfg = Release|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|Any CPU.Build.0 = Release|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x64.ActiveCfg = Release|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x64.Build.0 = Release|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x86.ActiveCfg = Release|Any CPU + {305F640E-11BA-44F9-95E0-C6882E9CD151}.Release|x86.Build.0 = Release|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Debug|x64.ActiveCfg = Debug|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Debug|x64.Build.0 = Debug|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Debug|x86.ActiveCfg = Debug|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Debug|x86.Build.0 = Debug|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Release|Any CPU.Build.0 = Release|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Release|x64.ActiveCfg = Release|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Release|x64.Build.0 = Release|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Release|x86.ActiveCfg = Release|Any CPU + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {9D758F00-17FF-433D-B088-F9C2D97C9BD1} = {3C312E42-9A47-4BED-8265-A405FCA6AFFF} + {468DB0E4-6221-4E01-BEFF-F452865E59C1} = {E8A2DF68-847A-4D88-B002-64FB666F696C} + {910E800A-59AE-46C4-B7C7-879986179246} = {E8A2DF68-847A-4D88-B002-64FB666F696C} + {305F640E-11BA-44F9-95E0-C6882E9CD151} = {3C312E42-9A47-4BED-8265-A405FCA6AFFF} + {4EFA7D3E-8B31-4BF7-96D1-B9F2867735C7} = {E8A2DF68-847A-4D88-B002-64FB666F696C} + EndGlobalSection +EndGlobal diff --git a/src/Directory.Build.props b/src/Directory.Build.props deleted file mode 100644 index ff02831..0000000 --- a/src/Directory.Build.props +++ /dev/null @@ -1,11 +0,0 @@ - - - net10.0 - true - WTFPL - 1.0.8 - true - 85fd766d-5d23-4476-aed1-463b2942e86a - WTFPL - - \ No newline at end of file diff --git a/src/isn.abstract/ApiConfig.cs b/src/isn.abst/ApiConfig.cs similarity index 89% rename from src/isn.abstract/ApiConfig.cs rename to src/isn.abst/ApiConfig.cs index 907b0e6..42d9633 100644 --- a/src/isn.abstract/ApiConfig.cs +++ b/src/isn.abst/ApiConfig.cs @@ -1,6 +1,4 @@ - - -using Isn.Abstract; +using isn.abst; namespace isnd.Entities { @@ -18,5 +16,6 @@ namespace isnd.Entities public const string CatalogLeaf = "catalog-leaf"; public const string Delete = "delete"; public const string Registration = "registration"; + internal const string GetNuspec = Constants.SpecFileEstension; } -} +} \ No newline at end of file diff --git a/src/isn.abstract/ApiIndexViewModel.cs b/src/isn.abst/ApiIndexViewModel.cs similarity index 91% rename from src/isn.abstract/ApiIndexViewModel.cs rename to src/isn.abst/ApiIndexViewModel.cs index 7034ae9..a8e9709 100644 --- a/src/isn.abstract/ApiIndexViewModel.cs +++ b/src/isn.abst/ApiIndexViewModel.cs @@ -1,7 +1,7 @@ using isnd.Data.Catalog; using Newtonsoft.Json; -namespace Isn.Abstract +namespace isn.Abstract { public class ApiIndexViewModel : HappyIdOwner { diff --git a/src/isn.abstract/Constants.cs b/src/isn.abst/Constants.cs similarity index 62% rename from src/isn.abstract/Constants.cs rename to src/isn.abst/Constants.cs index 1a12cc5..59ab714 100644 --- a/src/isn.abstract/Constants.cs +++ b/src/isn.abst/Constants.cs @@ -1,14 +1,10 @@ -namespace Isn.Abstract +namespace isn.abst { public static class Constants { public const string PaquetFileEstension = "nupkg"; public const string SpecFileEstension = "nuspec"; public const string JsonFileEstension = "json"; - - /** - * The prefix for API routes. - */ - public const string APIPrefix = "api/v3/"; + public const string PackageRootServerPrefix = "~/pkgs/"; } } \ No newline at end of file diff --git a/src/isn.abstract/HappyIdOwner.cs b/src/isn.abst/HappyIdOwner.cs similarity index 100% rename from src/isn.abstract/HappyIdOwner.cs rename to src/isn.abst/HappyIdOwner.cs diff --git a/src/isn.abstract/Resource.cs b/src/isn.abst/Resource.cs similarity index 90% rename from src/isn.abstract/Resource.cs rename to src/isn.abst/Resource.cs index da21eff..ab069a5 100644 --- a/src/isn.abstract/Resource.cs +++ b/src/isn.abst/Resource.cs @@ -1,7 +1,7 @@ using isnd.Data.Catalog; using Newtonsoft.Json; -namespace Isn.Abstract +namespace isn.Abstract { public class Resource : HappyIdOwner { diff --git a/src/isn.abstract/SafeNameAttribute.cs b/src/isn.abst/SafeNameAttribute.cs similarity index 100% rename from src/isn.abstract/SafeNameAttribute.cs rename to src/isn.abst/SafeNameAttribute.cs diff --git a/src/isn.abst/isn.abst.csproj b/src/isn.abst/isn.abst.csproj new file mode 100644 index 0000000..411e36d --- /dev/null +++ b/src/isn.abst/isn.abst.csproj @@ -0,0 +1,15 @@ + + + 1.0.1 + 1.0.7 + net7.0 + NETSDK1138 + 1.0.7.0 + 1.0.7.0 + 1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327 + + + + + + \ No newline at end of file diff --git a/src/isn.abstract/isn.abstract.csproj b/src/isn.abstract/isn.abstract.csproj deleted file mode 100644 index 8fdeb35..0000000 --- a/src/isn.abstract/isn.abstract.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - true - 1.0.0.0 - 1.0.0.0 - 1.0.0+Branch.main.Sha.654065d7fef34ba4ed2fb3bca5bc91de9ad16e85 - 1.0.0 - - - - - - \ No newline at end of file diff --git a/src/isn/Constants.cs b/src/isn/Constants.cs index 3bb3423..e68c94c 100644 --- a/src/isn/Constants.cs +++ b/src/isn/Constants.cs @@ -1,4 +1,4 @@ -namespace Isn +namespace isn { internal static class Constants { diff --git a/src/isn/IDataProtector.cs b/src/isn/IDataProtector.cs index e0904ac..d91ea23 100644 --- a/src/isn/IDataProtector.cs +++ b/src/isn/IDataProtector.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Text; -namespace Isn +namespace isn { public interface IDataProtector { diff --git a/src/isn/IsnSourceSettings.cs b/src/isn/IsnSourceSettings.cs index 1390359..bc2491c 100644 --- a/src/isn/IsnSourceSettings.cs +++ b/src/isn/IsnSourceSettings.cs @@ -1,4 +1,4 @@ -namespace Isn +namespace isn { public class IsnSourceSettings { diff --git a/src/isn/IsndErrorMessage.cs b/src/isn/IsndErrorMessage.cs index bdd61d7..fa6b062 100644 --- a/src/isn/IsndErrorMessage.cs +++ b/src/isn/IsndErrorMessage.cs @@ -1,4 +1,4 @@ -namespace Isn +namespace isn { public class IsndErrorMessage { diff --git a/src/isn/Program.cs b/src/isn/Program.cs index 5abbbb3..8a543a6 100644 --- a/src/isn/Program.cs +++ b/src/isn/Program.cs @@ -5,14 +5,14 @@ using System.Linq; using Mono.Options; using Newtonsoft.Json; -namespace Isn +namespace isn { public partial class Program { public static void LoadConfig() { - FileInfo cfgSettingIf = new FileInfo(ConfigFileName); + FileInfo cfgSettingIf = new FileInfo(_configFileName); if (cfgSettingIf.Exists) { var json = File.ReadAllText(cfgSettingIf.FullName); @@ -29,13 +29,12 @@ namespace Isn { "h|help", "show this message and exit", h => shouldShowPushHelp = h != null }, }; - private static string ConfigDirectory => - Environment.GetEnvironmentVariable("ISN_CONFIG_DIR") - ?? Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - ".isn"); - - private static string ConfigFileName => Path.Combine(ConfigDirectory, "config.json"); + private static readonly string _configFileName = + Path.Combine( + Path.Combine(Environment.GetFolderPath( + Environment.SpecialFolder.UserProfile), ".isn"), + "config.json") + ; public const string push = "push"; static readonly OptionSet options = new OptionSet { diff --git a/src/isn/Settings.cs b/src/isn/Settings.cs index 9c4c1c8..2bd0def 100644 --- a/src/isn/Settings.cs +++ b/src/isn/Settings.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; -namespace Isn +namespace isn { public class SourceSettings { diff --git a/src/isn/SourceHelpers.cs b/src/isn/SourceHelpers.cs index 8b1ba21..ba8762b 100644 --- a/src/isn/SourceHelpers.cs +++ b/src/isn/SourceHelpers.cs @@ -4,9 +4,9 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; -using Isn.Abstract; +using isn.Abstract; -namespace Isn +namespace isn { public static class SourceHelpers { diff --git a/src/isn/UploadFilesToServerUsingHttpClient.cs b/src/isn/UploadFilesToServerUsingHttpClient.cs index de5c33b..ce51297 100644 --- a/src/isn/UploadFilesToServerUsingHttpClient.cs +++ b/src/isn/UploadFilesToServerUsingHttpClient.cs @@ -5,7 +5,7 @@ using System.Net; using System.Net.Http; using System.Threading.Tasks; -namespace Isn +namespace isn { public static class UploadFilesToServerUsingHttpClient { diff --git a/src/isn/UploadFilesToServerUsingWebRequest.cs b/src/isn/UploadFilesToServerUsingWebRequest.cs index cd2aad8..21ead1a 100644 --- a/src/isn/UploadFilesToServerUsingWebRequest.cs +++ b/src/isn/UploadFilesToServerUsingWebRequest.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; -namespace Isn +namespace isn { public class UploadFilesToServerUsingWebRequest diff --git a/src/isn/commands/PushCommand.cs b/src/isn/commands/PushCommand.cs index 6820814..bf4e08a 100644 --- a/src/isn/commands/PushCommand.cs +++ b/src/isn/commands/PushCommand.cs @@ -6,7 +6,7 @@ using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; -namespace Isn +namespace isn { public static class PushCommand { @@ -18,8 +18,6 @@ namespace Isn source = Program.Settings.Sources.First(s=>s.Value.Alias==source).Key; if (source==null) throw new InvalidOperationException("source is invalid"); - var resolvedApiKey = string.IsNullOrWhiteSpace(apikey) ? ResolveSourceApiKey(source) : apikey; - var resources = SourceHelpers.GetServerResources(source); if (resources.Resources == null) throw new InvalidOperationException("source gave no resource"); @@ -40,7 +38,7 @@ namespace Isn try { Console.WriteLine("Connecting to "+ pubRes.Id); - return client.UploadFilesToServer(new Uri(pubRes.Id), fi, resolvedApiKey); + return client.UploadFilesToServer(new Uri(pubRes.Id), fi, apikey); } catch (HttpRequestException hrex) { @@ -66,25 +64,5 @@ namespace Isn return report; } } - - private static string ResolveSourceApiKey(string source) - { - if (string.IsNullOrWhiteSpace(source)) - { - return null; - } - - if (Program.Settings.Sources.Values.Any(s => s.Alias == source)) - { - source = Program.Settings.Sources.First(s => s.Value.Alias == source).Key; - } - - if (Program.Settings.Sources.TryGetValue(source, out var sourceSettings)) - { - return sourceSettings.GetClearApiKey(); - } - - return null; - } } } \ No newline at end of file diff --git a/src/isn/commands/push.cs b/src/isn/commands/push.cs index e00e307..58daf08 100644 --- a/src/isn/commands/push.cs +++ b/src/isn/commands/push.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using Newtonsoft.Json; -namespace Isn +namespace isn { partial class Program diff --git a/src/isn/commands/set-api-key.cs b/src/isn/commands/set-api-key.cs index 7da6021..7b2f018 100644 --- a/src/isn/commands/set-api-key.cs +++ b/src/isn/commands/set-api-key.cs @@ -4,7 +4,7 @@ using System.IO; using Newtonsoft.Json; -namespace Isn +namespace isn { partial class Program @@ -61,7 +61,7 @@ namespace Isn } public static void SaveConfig() { - FileInfo cfgSettingIf = new FileInfo(ConfigFileName); + FileInfo cfgSettingIf = new FileInfo(_configFileName); if (!cfgSettingIf.Directory.Exists) cfgSettingIf.Directory.Create(); File.WriteAllText( cfgSettingIf.FullName, diff --git a/src/isn/commands/show.config.cs b/src/isn/commands/show.config.cs index b1d8cd8..ff00e36 100644 --- a/src/isn/commands/show.config.cs +++ b/src/isn/commands/show.config.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace Isn +namespace isn { partial class Program diff --git a/src/isn/commands/sources.add.cs b/src/isn/commands/sources.add.cs index b01fe91..90d2aed 100644 --- a/src/isn/commands/sources.add.cs +++ b/src/isn/commands/sources.add.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; -namespace Isn +namespace isn { partial class Program diff --git a/src/isn/commands/sources.list.cs b/src/isn/commands/sources.list.cs index 79a8c7f..6a1239a 100644 --- a/src/isn/commands/sources.list.cs +++ b/src/isn/commands/sources.list.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -namespace Isn +namespace isn { partial class Program { diff --git a/src/isn/commands/sources.set-default.cs b/src/isn/commands/sources.set-default.cs index a30a1c1..8a691b3 100644 --- a/src/isn/commands/sources.set-default.cs +++ b/src/isn/commands/sources.set-default.cs @@ -1,7 +1,7 @@ using System; using System.Linq; -namespace Isn +namespace isn { partial class Program diff --git a/src/isn/isn.csproj b/src/isn/isn.csproj index a99ff29..a61ef49 100644 --- a/src/isn/isn.csproj +++ b/src/isn/isn.csproj @@ -1,24 +1,25 @@  Exe + net7.0 nuget_cli + 45b74c62-05bc-4603-95b4-3e80ae2fdf50 + 1.0.7 + 1.0.1 true + WTFPL true NETSDK1138 - 1.0.0.0 - 1.0.0.0 - 1.0.0+Branch.main.Sha.654065d7fef34ba4ed2fb3bca5bc91de9ad16e85 - 1.0.0 + 1.0.7.0 + 1.0.7.0 + 1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327 - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - + + + + + + \ No newline at end of file diff --git a/src/isn/model/PushReport.cs b/src/isn/model/PushReport.cs index 61f54bd..d8e082e 100644 --- a/src/isn/model/PushReport.cs +++ b/src/isn/model/PushReport.cs @@ -1,7 +1,7 @@ using System.Net; using System.Text; -namespace Isn +namespace isn { public class PushReport { diff --git a/src/isnd/Controllers/AccountController.cs b/src/isnd/Controllers/AccountController.cs index 9774f30..e367166 100644 --- a/src/isnd/Controllers/AccountController.cs +++ b/src/isnd/Controllers/AccountController.cs @@ -29,22 +29,14 @@ namespace isnd.Controllers IAuthenticationSchemeProvider schemeProvider, SignInManager signInManager, UserManager userManager, - IOptions startupAdminListConfig, - RoleManager roleManager - ) + IOptions startupAdminListConfig ) { _schemeProvider = schemeProvider; _signInManager = signInManager; _userManager = userManager; _startupAdminList = startupAdminListConfig.Value; - var roles = roleManager.Roles.ToList(); - if (!roles.Any(r => r.Name == IsndConstants.AdministratorRoleName)) - { - var role = new IdentityRole(IsndConstants.AdministratorRoleName); - roleManager.CreateAsync(role).GetAwaiter().GetResult(); - } } - + /// /// Entry point into the login workflow /// @@ -248,10 +240,10 @@ namespace isnd.Controllers [Authorize] public async Task GetAdminrole() { - string userEmail = User.FindFirstValue(ClaimTypes.Email); - if (_startupAdminList.Users.Contains(userEmail)) + string username = User.FindFirstValue(ClaimTypes.NameIdentifier); + if (_startupAdminList.Users.Contains(username)) { - var user = await _userManager.FindByEmailAsync(userEmail); + var user = await _userManager.FindByNameAsync(username); var roles = await _userManager.GetRolesAsync(user); if (!roles.Contains(IsndConstants.AdministratorRoleName)) { diff --git a/src/isnd/Controllers/ApiKeysController.cs b/src/isnd/Controllers/ApiKeysController.cs index fc5c278..bbc2d21 100644 --- a/src/isnd/Controllers/ApiKeysController.cs +++ b/src/isnd/Controllers/ApiKeysController.cs @@ -65,7 +65,7 @@ namespace isnd.Controllers return View(); } ApiKey newKey = new ApiKey { UserId = userid, Name = model.Name, - CreationDate = DateTime.UtcNow }; + CreationDate = DateTime.Now }; _ = dbContext.ApiKeys.Add(newKey); _ = await dbContext.SaveChangesAsync(); return View("Details", new DetailModel { Name = newKey.Name, diff --git a/src/isnd/Controllers/HomeController.cs b/src/isnd/Controllers/HomeController.cs index 399d228..45512c1 100644 --- a/src/isnd/Controllers/HomeController.cs +++ b/src/isnd/Controllers/HomeController.cs @@ -1,9 +1,12 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; using isnd.Data; using System.Linq; using isnd.ViewModels; +using Unleash; using System.Reflection; -using Isn.Abstract; +using Microsoft.EntityFrameworkCore; namespace isnd.Controllers { @@ -13,33 +16,31 @@ namespace isnd.Controllers public class HomeController : Controller { private readonly ApplicationDbContext _dbContext; + private readonly IUnleash _unleashĈlient; /// /// Home controller ctor /// /// + /// public HomeController( - ApplicationDbContext dbContext) + ApplicationDbContext dbContext, + IUnleash unleashĈlient) { _dbContext = dbContext; + _unleashĈlient = unleashĈlient; } - - /** - * Index - */ + public IActionResult Index() { - return View(new HomeIndexViewModel - { + return View(new HomeIndexViewModel{ PkgCount = _dbContext.Packages .Where(p => p.Versions.Count > 0) - .Count() - }); + .Count(), + UnleashClient = _unleashĈlient + }); } - /** - * About - */ public IActionResult About() { ViewData["Message"] = "Your application description page."; @@ -47,24 +48,18 @@ namespace isnd.Controllers return View(); } - /** - * Contact - */ public IActionResult Contact() { ViewData["Message"] = "Your contact page."; - var ass = typeof(Resource).GetType().Assembly; + var ass = typeof(isn.Abstract.Resource).GetType().Assembly; var attrs = ass.GetCustomAttributes(true); // ass.GetCustomAttributes(true); - System.Reflection.AssemblyFileVersionAttribute v = (AssemblyFileVersionAttribute) + System.Reflection.AssemblyFileVersionAttribute v = (AssemblyFileVersionAttribute) GetType().Assembly.GetCustomAttribute(typeof(AssemblyFileVersionAttribute)); return View(); } - /** - * Privacy - */ public IActionResult Privacy() { ViewData["Message"] = "Your Privacy page."; @@ -72,9 +67,6 @@ namespace isnd.Controllers return View(ViewData); } - /** - * Error - */ public IActionResult Error() { return View(); diff --git a/src/isnd/Controllers/Packages/ApiIndex.cs b/src/isnd/Controllers/Packages/ApiIndex.cs index 1a1e435..56930cf 100644 --- a/src/isnd/Controllers/Packages/ApiIndex.cs +++ b/src/isnd/Controllers/Packages/ApiIndex.cs @@ -1,9 +1,12 @@ using Microsoft.AspNetCore.Mvc; -using isnd.Services; -using isnd.Interfaces; -using System.Linq; using isnd.Entities; -using Isn.Abstract; +using isnd.Services; +using isn.Abstract; +using isn.abst; +using isnd.Interfaces; +using Unleash; +using System.Linq; + namespace isnd.Controllers { @@ -19,17 +22,18 @@ namespace isnd.Controllers /// Api Controller Constructor /// /// - public ApiController(IPackageManager pm) + /// + public ApiController(IPackageManager pm, IUnleash unleashĈlient) { packageManager = pm; - resources = packageManager.GetResources().ToArray(); + resources = packageManager.GetResources(unleashĈlient).ToArray(); } /// /// API index /// /// - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.IndexDotJson)] + [HttpGet(Constants.PackageRootServerPrefix + ApiConfig.IndexDotJson)] public IActionResult ApiIndex() { return Ok(new ApiIndexViewModel(packageManager.CatalogBaseUrl + ApiConfig.IndexDotJson){ Version = PackageManager.BASE_API_LEVEL, Resources = resources }); diff --git a/src/isnd/Controllers/Packages/PackagesController.AutoComplete.cs b/src/isnd/Controllers/Packages/PackagesController.AutoComplete.cs index b3d5711..6f1fbf6 100644 --- a/src/isnd/Controllers/Packages/PackagesController.AutoComplete.cs +++ b/src/isnd/Controllers/Packages/PackagesController.AutoComplete.cs @@ -1,7 +1,7 @@ using isnd.Services; using isnd.Entities; using Microsoft.AspNetCore.Mvc; -using Isn.Abstract; +using isn.abst; namespace isnd.Controllers { @@ -9,7 +9,7 @@ namespace isnd.Controllers { // GET /autocomplete?id=isn.protocol&prerelease=true - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.AutoComplete)] + [HttpGet(Constants.PackageRootServerPrefix + ApiConfig.AutoComplete)] public IActionResult AutoComplete( string id, string semVerLevel, diff --git a/src/isnd/Controllers/Packages/PackagesController.Catalog.cs b/src/isnd/Controllers/Packages/PackagesController.Catalog.cs index d5a2357..950291d 100644 --- a/src/isnd/Controllers/Packages/PackagesController.Catalog.cs +++ b/src/isnd/Controllers/Packages/PackagesController.Catalog.cs @@ -1,7 +1,14 @@ +using System.Data.Common; +using System.Linq; using System.Threading.Tasks; +using isnd.Services; using isnd.Entities; using Microsoft.AspNetCore.Mvc; -using Isn.Abstract; +using System.Collections.Generic; +using NuGet.Versioning; +using isnd.Data.Packages.Catalog; +using isnd.Data.Catalog; +using isn.abst; namespace isnd.Controllers { @@ -9,14 +16,14 @@ namespace isnd.Controllers { // https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.Catalog)] + [HttpGet(Constants.PackageRootServerPrefix + ApiConfig.Catalog)] public async Task CatalogIndex() { return Ok(await packageManager.GetCatalogIndexAsync()); } - [HttpGet("~/" + Constants.APIPrefix + "{apiVersion}/" + ApiConfig.Registration + "/{id}/{lower}.json")] + [HttpGet(Constants.PackageRootServerPrefix + "{apiVersion}/" + ApiConfig.Registration + "/{id}/{lower}.json")] public async Task CatalogRegistration(string apiVersion, string id, string lower) { if (lower.Equals("index", System.StringComparison.InvariantCultureIgnoreCase)) diff --git a/src/isnd/Controllers/Packages/PackagesController.Delete.cs b/src/isnd/Controllers/Packages/PackagesController.Delete.cs index bccefb4..74c193e 100644 --- a/src/isnd/Controllers/Packages/PackagesController.Delete.cs +++ b/src/isnd/Controllers/Packages/PackagesController.Delete.cs @@ -5,13 +5,13 @@ using isnd.Entities; using System.ComponentModel.DataAnnotations; using isnd.Attributes; using System.Security.Claims; -using Isn.Abstract; +using isn.abst; namespace isnd.Controllers { public partial class PackagesController { - [HttpDelete("~/" + Constants.APIPrefix + ApiConfig.Delete + "/{id}/{lower?}/{type?}")] + [HttpDelete(Constants.PackageRootServerPrefix + ApiConfig.Delete + "/{id}/{lower?}/{type?}")] public async Task ApiDelete( [FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string lower, diff --git a/src/isnd/Controllers/Packages/PackagesController.GetPackage.cs b/src/isnd/Controllers/Packages/PackagesController.GetPackage.cs index 182184a..b044ae7 100644 --- a/src/isnd/Controllers/Packages/PackagesController.GetPackage.cs +++ b/src/isnd/Controllers/Packages/PackagesController.GetPackage.cs @@ -1,38 +1,22 @@ using System.ComponentModel.DataAnnotations; using System.IO; -using System.Linq; using Microsoft.AspNetCore.Mvc; -using Isn.Abstract; -using isnd.Entities; using isnd.Attributes; +using isnd.Entities; +using isn.abst; namespace isnd.Controllers { public partial class PackagesController { - // NuGet v3 flat-container versions index. - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.GetPackage + "/{id}/" + ApiConfig.IndexDotJson)] - public IActionResult GetPackageVersionsById( - [FromRoute][SafeName][Required] string id) - { - var versions = dbContext.PackageVersions - .Where(v => v.PackageId.ToLower() == id.ToLower()) - .Select(v => v.FullString) - .Distinct() - .OrderBy(v => v) - .ToArray(); - - return Ok(new { versions }); - } - - // NuGet v3 flat-container package download by filename, e.g. id.version.nupkg. - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.GetPackage + "/{id}/{lower}/{filename}." + // Web get the paquet + [HttpGet(Constants.PackageRootServerPrefix + ApiConfig.GetPackage + "/{id}/{lower}/{idf}-{lowerf}." + Constants.PaquetFileEstension)] - public IActionResult GetPackageByFilename( - [FromRoute][SafeName][Required] string id, + public IActionResult GetPackage( + [FromRoute][SafeName][Required] string id, [FromRoute][SafeName][Required] string lower, - [FromRoute][SafeName][Required] string filename) + [FromRoute] string idf, [FromRoute] string lowerf) { var pkgpath = Path.Combine(isndSettings.PackagesRootDir, id, lower, $"{id}-{lower}." + Constants.PaquetFileEstension @@ -48,9 +32,7 @@ namespace isnd.Controllers } // Web get spec - [HttpGet("~/" + Constants.APIPrefix + Constants.SpecFileEstension + "/{id}/{lower}/{idf}.{lowerf}." - + Constants.SpecFileEstension)] - [HttpGet("~/" + Constants.APIPrefix + Constants.SpecFileEstension + "/{id}/{lower}/{idf}-{lowerf}." + [HttpGet(Constants.PackageRootServerPrefix + Constants.SpecFileEstension + "/{id}/{lower}/{idf}-{lowerf}." + Constants.SpecFileEstension)] public IActionResult GetNuspec( [FromRoute][SafeName][Required] string id, diff --git a/src/isnd/Controllers/Packages/PackagesController.GetVersions.cs b/src/isnd/Controllers/Packages/PackagesController.GetVersions.cs index 55cfad9..5cdda12 100644 --- a/src/isnd/Controllers/Packages/PackagesController.GetVersions.cs +++ b/src/isnd/Controllers/Packages/PackagesController.GetVersions.cs @@ -1,13 +1,13 @@ using Microsoft.AspNetCore.Mvc; using NuGet.Versioning; using isnd.Entities; -using Isn.Abstract; +using isn.abst; namespace isnd.Controllers { public partial class PackagesController { - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.GetVersion + "/{id}/{lower}/" + ApiConfig.IndexDotJson)] + [HttpGet(Constants.PackageRootServerPrefix + ApiConfig.GetVersion + "/{id}/{lower}/" + ApiConfig.IndexDotJson)] public IActionResult GetVersions( string id, string lower, diff --git a/src/isnd/Controllers/Packages/PackagesController.Put.cs b/src/isnd/Controllers/Packages/PackagesController.Put.cs index 12335ce..f1570e8 100644 --- a/src/isnd/Controllers/Packages/PackagesController.Put.cs +++ b/src/isnd/Controllers/Packages/PackagesController.Put.cs @@ -15,7 +15,7 @@ using isnd.Data; using isnd.Helpers; using isnd.Entities; using Microsoft.AspNetCore.Http; -using Isn.Abstract; +using isn.abst; using isnd.Data.Packages; using Microsoft.AspNetCore.Authorization; @@ -25,18 +25,18 @@ namespace isnd.Controllers public partial class PackagesController { // TODO [Authorize(Policy = IsndConstants.RequireValidApiKey)] - [HttpPut("~/" + Constants.APIPrefix + ApiConfig.Publish)] + [HttpPut(Constants.PackageRootServerPrefix + ApiConfig.Publish)] public async Task Put() { try { var clientVersionId = Request.Headers["X-NuGet-Client-Version"]; - string apiKey = Request.Headers["X-NuGet-ApiKey"].FirstOrDefault() ?? string.Empty; + string apiKey = Request.Headers["X-NuGet-ApiKey"][0]; ViewData["versionId"] = typeof(PackagesController).Assembly.FullName; var files = new List(); ViewData["files"] = files; - var clearkey = ApiKeyProtector.TryUnprotectKey(protector, apiKey); + var clearkey = protector.Unprotect(apiKey); var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey); if (apikey == null) { @@ -46,7 +46,7 @@ namespace isnd.Controllers Commit commit = new Commit { Action = PackageAction.PublishPackage, - TimeStamp = DateTime.UtcNow + TimeStamp = DateTime.Now }; dbContext.Commits.Add(commit); @@ -145,7 +145,7 @@ namespace isnd.Controllers dbContext.PackageVersions.Remove(v); } - // Default package type must be non-null for composite key consistency. + // FIXME default type or null if (types==null || types.Count==0) dbContext.PackageVersions.Add (new PackageVersion{ @@ -157,7 +157,7 @@ namespace isnd.Controllers Revision = version.Revision, IsPrerelease = version.IsPrerelease, FullString = version.ToFullString(), - Type = string.Empty, + Type = null, LatestCommit = commit }); else @@ -171,14 +171,14 @@ namespace isnd.Controllers Patch = version.Patch, IsPrerelease = version.IsPrerelease, FullString = version.ToFullString(), - Type = type.Name ?? string.Empty, + Type = type.Name, LatestCommit = commit }; dbContext.PackageVersions.Add(pkgver); } await dbContext.SaveChangesAsync(); - packageManager.UpdateCatalogForAsync(commit); + packageManager.ÛpdateCatalogForAsync(commit); logger.LogInformation($"new paquet : {spec.Name}"); } diff --git a/src/isnd/Controllers/Packages/PackagesController.Search.cs b/src/isnd/Controllers/Packages/PackagesController.Search.cs index 61c19d1..8a67c63 100644 --- a/src/isnd/Controllers/Packages/PackagesController.Search.cs +++ b/src/isnd/Controllers/Packages/PackagesController.Search.cs @@ -3,7 +3,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using isnd.Entities; -using Isn.Abstract; +using isn.abst; namespace isnd.Controllers { @@ -11,7 +11,7 @@ namespace isnd.Controllers public partial class PackagesController { // GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE} - [HttpGet("~/" + Constants.APIPrefix + ApiConfig.Search)] + [HttpGet(Constants.PackageRootServerPrefix + ApiConfig.Search)] public IActionResult Search( string q, int skip = 0, diff --git a/src/isnd/Controllers/Packages/PackagesController.WebViews.cs b/src/isnd/Controllers/Packages/PackagesController.WebViews.cs index 6432261..eb6c477 100644 --- a/src/isnd/Controllers/Packages/PackagesController.WebViews.cs +++ b/src/isnd/Controllers/Packages/PackagesController.WebViews.cs @@ -60,7 +60,6 @@ namespace isnd.Controllers { return NotFound(); } - pkgtype ??= string.Empty; // var report = await packageManager.DeletePackageAsync(id, lower, type); var packageVersion = await dbContext.PackageVersions.Include(p => p.Package) @@ -78,7 +77,6 @@ namespace isnd.Controllers public async Task DeleteConfirmed(string PackageId, string FullString, string Type) { - Type ??= string.Empty; PackageVersion packageVersion = await dbContext.PackageVersions .Include(pv => pv.Package) .FirstOrDefaultAsync(m => m.PackageId == PackageId diff --git a/src/isnd/Controllers/Packages/PackagesController.cs b/src/isnd/Controllers/Packages/PackagesController.cs index c890314..ddf9e69 100644 --- a/src/isnd/Controllers/Packages/PackagesController.cs +++ b/src/isnd/Controllers/Packages/PackagesController.cs @@ -1,13 +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.Abstract; namespace isnd.Controllers { @@ -22,15 +30,13 @@ namespace isnd.Controllers private readonly IsndSettings isndSettings; readonly ApplicationDbContext dbContext; private readonly IPackageManager packageManager; - - /** - * PackagesController - */ + private readonly IUnleash unleashĈlient; public PackagesController( ILoggerFactory loggerFactory, IDataProtectionProvider provider, IOptions isndOptions, + IUnleash unleashĈlient, ApplicationDbContext dbContext, IPackageManager pm) { @@ -39,7 +45,8 @@ namespace isnd.Controllers protector = provider.CreateProtector(isndSettings.ProtectionTitle); this.dbContext = dbContext; packageManager = pm; - resources = packageManager.GetResources().ToArray(); + this.unleashĈlient = unleashĈlient; + resources = packageManager.GetResources(unleashĈlient).ToArray(); } } } diff --git a/src/isnd/Data/ApiKeys/ApiKey.cs b/src/isnd/Data/ApiKeys/ApiKey.cs index f891693..517e93a 100644 --- a/src/isnd/Data/ApiKeys/ApiKey.cs +++ b/src/isnd/Data/ApiKeys/ApiKey.cs @@ -20,6 +20,6 @@ namespace isnd.Data.ApiKeys public DateTime CreationDate { get; set; } - public bool IsValid => CreationDate.AddDays(ValidityPeriodInDays) > DateTime.UtcNow; + public bool IsValid => CreationDate.AddDays(ValidityPeriodInDays) > DateTime.Now; } } \ No newline at end of file diff --git a/src/isnd/Data/ApplicationDbContext.cs b/src/isnd/Data/ApplicationDbContext.cs index c965f22..d01c0b6 100644 --- a/src/isnd/Data/ApplicationDbContext.cs +++ b/src/isnd/Data/ApplicationDbContext.cs @@ -22,19 +22,6 @@ namespace isnd.Data public ApplicationDbContext(DbContextOptions options) : base(options) { } - protected override void OnModelCreating(ModelBuilder builder) - { - base.OnModelCreating(builder); - - builder.Entity(entity => - { - entity.HasKey(v => new { v.PackageId, v.FullString, v.Type }); - entity.Property(v => v.Type) - .IsRequired() - .HasDefaultValue(string.Empty); - }); - } - /// /// User API keys /// diff --git a/src/isnd/Data/Packages/PackageVersion.cs b/src/isnd/Data/Packages/PackageVersion.cs index 83047ee..9120d93 100644 --- a/src/isnd/Data/Packages/PackageVersion.cs +++ b/src/isnd/Data/Packages/PackageVersion.cs @@ -1,7 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using Isn.Abstract; +using isn.abst; using isnd.Data.Catalog; using isnd.Data.Packages; using isnd.Data.Packages.Catalog; @@ -38,6 +38,7 @@ namespace isnd.Data /// [StringLength(256)] [Required] + [Key] public string FullString { get; set; } public bool IsPrerelease { get; set; } @@ -57,9 +58,9 @@ namespace isnd.Data public string CommitId { get => CommitNId.ToString(); } public virtual Commit LatestCommit { get; set; } - public string NugetLink => $"{Constants.APIPrefix}{Constants.PaquetFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}." + public string NugetLink => $"{Constants.PaquetFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}." + Constants.PaquetFileEstension; - public string NuspecLink => $"{Constants.APIPrefix}{Constants.SpecFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}." + public string NuspecLink => $"{Constants.SpecFileEstension}/{PackageId}/{FullString}/{PackageId}-{FullString}." + Constants.SpecFileEstension; public string SementicVersionString { get => $"{Major}.{Minor}.{Patch}"; } diff --git a/src/isnd/Entities/SmtpSettings.cs b/src/isnd/Entities/SmtpSettings.cs index 3d2ae1d..5a4a861 100644 --- a/src/isnd/Entities/SmtpSettings.cs +++ b/src/isnd/Entities/SmtpSettings.cs @@ -2,30 +2,11 @@ namespace isnd.Entities { public class SmtpSettings { - /** - * The SMTP server host. - */ - public string Host {get; set;} - - /** - * The SMTP server port. - */ + public string Server {get; set;} public int Port {get; set;} - /** - * The name of the sender. - */ public string SenderName {get; set;} - /** - * The email address of the sender. - */ - public string SenderEmail {get; set;} - /** - * The username for SMTP authentication. - */ + public string SenderEMail {get; set;} public string UserName {get; set;} - /** - * The password for SMTP authentication. - */ public string Password {get; set;} } } \ No newline at end of file diff --git a/src/isnd/Helpers/ApiKeyProtector.cs b/src/isnd/Helpers/ApiKeyProtector.cs deleted file mode 100644 index 98f5e72..0000000 --- a/src/isnd/Helpers/ApiKeyProtector.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Security.Cryptography; -using System.Text; -using Microsoft.AspNetCore.DataProtection; - -namespace isnd.Helpers -{ - public static class ApiKeyProtector - { - private const byte LegacyDelta = 145; - - public static string TryUnprotectKey(IDataProtector protector, string protectedValue) - { - if (string.IsNullOrWhiteSpace(protectedValue)) - { - return protectedValue; - } - - if (TryUnprotect(protector, protectedValue, out var unprotected)) - { - return unprotected; - } - - if (TryUnprotectLegacy(protectedValue, out unprotected)) - { - return unprotected; - } - - return protectedValue; - } - - private static bool TryUnprotect(IDataProtector protector, string protectedValue, out string unprotected) - { - try - { - unprotected = protector.Unprotect(protectedValue); - return true; - } - catch (CryptographicException) - { - unprotected = null; - return false; - } - catch (FormatException) - { - unprotected = null; - return false; - } - } - - private static bool TryUnprotectLegacy(string protectedValue, out string unprotected) - { - try - { - unprotected = UnprotectLegacy(protectedValue); - return true; - } - catch (FormatException) - { - unprotected = null; - return false; - } - } - - public static string UnprotectLegacy(string protectedValue) - { - if (string.IsNullOrWhiteSpace(protectedValue)) - { - return protectedValue; - } - - var bytes = Convert.FromBase64String(protectedValue); - var unprotectedBytes = new byte[bytes.Length]; - for (var index = 0; index < bytes.Length; index++) - { - unprotectedBytes[index] = (byte)(bytes[index] ^ LegacyDelta); - } - - return Encoding.UTF8.GetString(unprotectedBytes); - } - } -} diff --git a/src/isnd/Helpers/PackageVersionHelpers.cs b/src/isnd/Helpers/PackageVersionHelpers.cs index a60d283..49f41d6 100644 --- a/src/isnd/Helpers/PackageVersionHelpers.cs +++ b/src/isnd/Helpers/PackageVersionHelpers.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; -using Isn.Abstract; +using isn.abst; using isnd.Data; using isnd.Data.Catalog; using isnd.Entities; diff --git a/src/isnd/Helpers/UnleashHelpers.cs b/src/isnd/Helpers/UnleashHelpers.cs new file mode 100644 index 0000000..d107bff --- /dev/null +++ b/src/isnd/Helpers/UnleashHelpers.cs @@ -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 + { + { "Authorization", unleashClientSettings.ClientApiKey } + } + }; + + UnleashClientFactory unleashClientFactory = new UnleashClientFactory(); + return unleashClientFactory.CreateClient(unleashSettings); + } + } +} \ No newline at end of file diff --git a/src/isnd/Interfaces/IPackageManager.cs b/src/isnd/Interfaces/IPackageManager.cs index 9dd8ffc..8e5c2b2 100644 --- a/src/isnd/Interfaces/IPackageManager.cs +++ b/src/isnd/Interfaces/IPackageManager.cs @@ -1,76 +1,35 @@ using System.Collections.Generic; using System.Threading.Tasks; -using Isn.Abstract; +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 { - /** - * IPackageManager - */ public interface IPackageManager { - /** - * CatalogBaseUrl - */ string CatalogBaseUrl { get; } - /** - * AutoComplete generation - */ AutoCompleteResult AutoComplete(string pkgid, int skip, int take, bool prerelease = false, string packageType = null); - /** - * GetVersions - */ string[] GetVersions(string pkgid, NuGetVersion parsedVersion, bool prerelease = false, string packageType = null, int skip = 0, int take = 25); - /** - * GetResources - */ - IEnumerable GetResources(); - /** - * UpdateCatalogForAsync - */ - Task UpdateCatalogForAsync(Commit commit); - /** - * DeletePackageAsync - */ + IEnumerable GetResources(IUnleash unleashĈlient); + Task ÛpdateCatalogForAsync(Commit commit); Task DeletePackageAsync(string pkgid, string version, string type); - - /** - * UserAskForPackageDeletionAsync - */ Task UserAskForPackageDeletionAsync(string userid, string pkgId, string lower, string type); - - /** - * GetPackageAsync - */ Task GetPackageAsync(string pkgid, string version, string type); - - /** - * GetCatalogEntryAsync - */ Task GetCatalogEntryAsync(string pkgId, string version, string pkgType); - /** - * SearchCatalogEntriesById - */ IEnumerable SearchCatalogEntriesById(string pkgId, string semver, string pkgType); - /** - * GetCatalogIndexAsync - */ Task GetCatalogIndexAsync(); - /** - * GetPackageRegistrationIndexAsync - */ Task GetPackageRegistrationIndexAsync(RegistrationPageIndexQuery query); -/** - * SearchPackageAsync - */ + Task SearchPackageAsync(RegistrationPageIndexQuery query); } diff --git a/src/isnd/Migrations/20260705174847_net10.Designer.cs b/src/isnd/Migrations/20260705174847_net10.Designer.cs deleted file mode 100644 index 75e320c..0000000 --- a/src/isnd/Migrations/20260705174847_net10.Designer.cs +++ /dev/null @@ -1,458 +0,0 @@ -// -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; - -#nullable disable - -namespace isndhost.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20260705174847_net10")] - partial class net10 - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.9") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.Property("ValidityPeriodInDays") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ApiKeys"); - }); - - modelBuilder.Entity("isnd.Data.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("AccessFailedCount") - .HasColumnType("integer"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("PasswordHash") - .HasColumnType("text"); - - b.Property("PhoneNumber") - .HasColumnType("text"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property("SecurityStamp") - .HasColumnType("text"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("isnd.Data.PackageVersion", b => - { - b.Property("FullString") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("CommitNId") - .HasColumnType("bigint"); - - b.Property("IsPrerelease") - .HasColumnType("boolean"); - - b.Property("Major") - .HasColumnType("integer"); - - b.Property("Minor") - .HasColumnType("integer"); - - b.Property("PackageId") - .IsRequired() - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("Patch") - .HasColumnType("integer"); - - b.Property("Revision") - .HasColumnType("integer"); - - b.Property("Type") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("FullString"); - - b.HasIndex("CommitNId"); - - b.HasIndex("PackageId"); - - b.ToTable("PackageVersions"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Commit", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Action") - .HasColumnType("integer"); - - b.Property("TimeStamp") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.ToTable("Commits"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Package", b => - { - b.Property("Id") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("CommitNId") - .HasColumnType("bigint"); - - b.Property("CommitTimeStamp") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("OwnerId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.HasIndex("CommitNId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Packages"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b => - { - b.HasOne("isnd.Data.ApplicationUser", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("isnd.Data.PackageVersion", b => - { - b.HasOne("isnd.Data.Packages.Commit", "LatestCommit") - .WithMany("Versions") - .HasForeignKey("CommitNId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.Packages.Package", "Package") - .WithMany("Versions") - .HasForeignKey("PackageId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("LatestCommit"); - - b.Navigation("Package"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Package", b => - { - b.HasOne("isnd.Data.Packages.Commit", "LatestVersion") - .WithMany() - .HasForeignKey("CommitNId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.ApplicationUser", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("LatestVersion"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Commit", b => - { - b.Navigation("Versions"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Package", b => - { - b.Navigation("Versions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/isnd/Migrations/20260705174847_net10.cs b/src/isnd/Migrations/20260705174847_net10.cs deleted file mode 100644 index 56789db..0000000 --- a/src/isnd/Migrations/20260705174847_net10.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace isndhost.Migrations -{ - /// - public partial class net10 : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Id", - table: "Commits", - type: "bigint", - nullable: false, - oldClrType: typeof(long), - oldType: "bigint") - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); - - migrationBuilder.AlterColumn( - name: "Id", - table: "AspNetUserClaims", - type: "integer", - nullable: false, - oldClrType: typeof(int), - oldType: "integer") - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); - - migrationBuilder.AlterColumn( - name: "Id", - table: "AspNetRoleClaims", - type: "integer", - nullable: false, - oldClrType: typeof(int), - oldType: "integer") - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "Id", - table: "Commits", - type: "bigint", - nullable: false, - oldClrType: typeof(long), - oldType: "bigint") - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - migrationBuilder.AlterColumn( - name: "Id", - table: "AspNetUserClaims", - type: "integer", - nullable: false, - oldClrType: typeof(int), - oldType: "integer") - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - migrationBuilder.AlterColumn( - name: "Id", - table: "AspNetRoleClaims", - type: "integer", - nullable: false, - oldClrType: typeof(int), - oldType: "integer") - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - } - } -} diff --git a/src/isnd/Migrations/20260705211205_pkgver_composite_identity_fix.Designer.cs b/src/isnd/Migrations/20260705211205_pkgver_composite_identity_fix.Designer.cs deleted file mode 100644 index 77ef305..0000000 --- a/src/isnd/Migrations/20260705211205_pkgver_composite_identity_fix.Designer.cs +++ /dev/null @@ -1,457 +0,0 @@ -// -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; - -#nullable disable - -namespace isndhost.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20260705211205_pkgver_composite_identity_fix")] - partial class pkgver_composite_identity_fix - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.9") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.Property("ValidityPeriodInDays") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("ApiKeys"); - }); - - modelBuilder.Entity("isnd.Data.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("AccessFailedCount") - .HasColumnType("integer"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property("FullName") - .HasColumnType("text"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("PasswordHash") - .HasColumnType("text"); - - b.Property("PhoneNumber") - .HasColumnType("text"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property("SecurityStamp") - .HasColumnType("text"); - - b.Property("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("isnd.Data.PackageVersion", b => - { - b.Property("PackageId") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("FullString") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("Type") - .ValueGeneratedOnAdd() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasDefaultValue(""); - - b.Property("CommitNId") - .HasColumnType("bigint"); - - b.Property("IsPrerelease") - .HasColumnType("boolean"); - - b.Property("Major") - .HasColumnType("integer"); - - b.Property("Minor") - .HasColumnType("integer"); - - b.Property("Patch") - .HasColumnType("integer"); - - b.Property("Revision") - .HasColumnType("integer"); - - b.HasKey("PackageId", "FullString", "Type"); - - b.HasIndex("CommitNId"); - - b.ToTable("PackageVersions"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Commit", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Action") - .HasColumnType("integer"); - - b.Property("TimeStamp") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.ToTable("Commits"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Package", b => - { - b.Property("Id") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("CommitNId") - .HasColumnType("bigint"); - - b.Property("CommitTimeStamp") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("OwnerId") - .IsRequired() - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.HasIndex("CommitNId"); - - b.HasIndex("OwnerId"); - - b.ToTable("Packages"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b => - { - b.HasOne("isnd.Data.ApplicationUser", "User") - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("isnd.Data.PackageVersion", b => - { - b.HasOne("isnd.Data.Packages.Commit", "LatestCommit") - .WithMany("Versions") - .HasForeignKey("CommitNId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.Packages.Package", "Package") - .WithMany("Versions") - .HasForeignKey("PackageId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("LatestCommit"); - - b.Navigation("Package"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Package", b => - { - b.HasOne("isnd.Data.Packages.Commit", "LatestVersion") - .WithMany() - .HasForeignKey("CommitNId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.ApplicationUser", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("LatestVersion"); - - b.Navigation("Owner"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Commit", b => - { - b.Navigation("Versions"); - }); - - modelBuilder.Entity("isnd.Data.Packages.Package", b => - { - b.Navigation("Versions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/isnd/Migrations/20260705211205_pkgver_composite_identity_fix.cs b/src/isnd/Migrations/20260705211205_pkgver_composite_identity_fix.cs deleted file mode 100644 index f61688a..0000000 --- a/src/isnd/Migrations/20260705211205_pkgver_composite_identity_fix.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace isndhost.Migrations -{ - /// - public partial class pkgver_composite_identity_fix : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropPrimaryKey( - name: "PK_PackageVersions", - table: "PackageVersions"); - - migrationBuilder.DropIndex( - name: "IX_PackageVersions_PackageId", - table: "PackageVersions"); - - migrationBuilder.Sql("UPDATE \"PackageVersions\" SET \"Type\" = '' WHERE \"Type\" IS NULL;"); - - migrationBuilder.AlterColumn( - name: "Type", - table: "PackageVersions", - type: "character varying(256)", - maxLength: 256, - nullable: false, - defaultValue: "", - oldClrType: typeof(string), - oldType: "character varying(256)", - oldMaxLength: 256, - 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.AlterColumn( - name: "Type", - table: "PackageVersions", - type: "character varying(256)", - maxLength: 256, - nullable: true, - oldClrType: typeof(string), - oldType: "character varying(256)", - oldMaxLength: 256, - oldDefaultValue: ""); - - migrationBuilder.Sql("UPDATE \"PackageVersions\" SET \"Type\" = NULL WHERE \"Type\" = '';"); - - migrationBuilder.AddPrimaryKey( - name: "PK_PackageVersions", - table: "PackageVersions", - column: "FullString"); - - migrationBuilder.CreateIndex( - name: "IX_PackageVersions_PackageId", - table: "PackageVersions", - column: "PackageId"); - } - } -} diff --git a/src/isnd/Migrations/ApplicationDbContextModelSnapshot.cs b/src/isnd/Migrations/ApplicationDbContextModelSnapshot.cs index 917c397..7d8c883 100644 --- a/src/isnd/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/src/isnd/Migrations/ApplicationDbContextModelSnapshot.cs @@ -6,8 +6,6 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using isnd.Data; -#nullable disable - namespace isndhost.Migrations { [DbContext(typeof(ApplicationDbContext))] @@ -17,161 +15,23 @@ namespace isndhost.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "10.0.9") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) + .HasAnnotation("ProductVersion", "2.1.14-servicing-32113") .HasAnnotation("Relational:MaxIdentifierLength", 63); - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b => { b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); + .ValueGeneratedOnAdd(); - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); + b.Property("CreationDate"); - b.Property("Name") - .HasColumnType("text"); + b.Property("Name"); b.Property("UserId") - .IsRequired() - .HasColumnType("text"); + .IsRequired(); - b.Property("ValidityPeriodInDays") - .HasColumnType("integer"); + b.Property("ValidityPeriodInDays"); b.HasKey("Id"); @@ -183,124 +43,63 @@ namespace isndhost.Migrations modelBuilder.Entity("isnd.Data.ApplicationUser", b => { b.Property("Id") - .HasColumnType("text"); + .ValueGeneratedOnAdd(); - b.Property("AccessFailedCount") - .HasColumnType("integer"); + b.Property("AccessFailedCount"); b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); + .IsConcurrencyToken(); b.Property("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); + .HasMaxLength(256); - b.Property("EmailConfirmed") - .HasColumnType("boolean"); + b.Property("EmailConfirmed"); - b.Property("FullName") - .HasColumnType("text"); + b.Property("FullName"); - b.Property("LockoutEnabled") - .HasColumnType("boolean"); + b.Property("LockoutEnabled"); - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); + b.Property("LockoutEnd"); b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); + .HasMaxLength(256); b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); + .HasMaxLength(256); - b.Property("PasswordHash") - .HasColumnType("text"); + b.Property("PasswordHash"); - b.Property("PhoneNumber") - .HasColumnType("text"); + b.Property("PhoneNumber"); - b.Property("PhoneNumberConfirmed") - .HasColumnType("boolean"); + b.Property("PhoneNumberConfirmed"); - b.Property("SecurityStamp") - .HasColumnType("text"); + b.Property("SecurityStamp"); - b.Property("TwoFactorEnabled") - .HasColumnType("boolean"); + b.Property("TwoFactorEnabled"); b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); + .HasMaxLength(256); b.HasKey("Id"); b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); + .HasName("EmailIndex"); b.HasIndex("NormalizedUserName") .IsUnique() - .HasDatabaseName("UserNameIndex"); + .HasName("UserNameIndex"); - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("isnd.Data.PackageVersion", b => - { - b.Property("PackageId") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); - - b.Property("FullString") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("Type") - .ValueGeneratedOnAdd() - .HasMaxLength(256) - .HasColumnType("character varying(256)") - .HasDefaultValue(""); - - b.Property("CommitNId") - .HasColumnType("bigint"); - - b.Property("IsPrerelease") - .HasColumnType("boolean"); - - b.Property("Major") - .HasColumnType("integer"); - - b.Property("Minor") - .HasColumnType("integer"); - - b.Property("Patch") - .HasColumnType("integer"); - - b.Property("Revision") - .HasColumnType("integer"); - - b.HasKey("PackageId", "FullString", "Type"); - - b.HasIndex("CommitNId"); - - b.ToTable("PackageVersions"); + b.ToTable("AspNetUsers"); }); modelBuilder.Entity("isnd.Data.Packages.Commit", b => { b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); + .ValueGeneratedOnAdd(); - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + b.Property("Action"); - b.Property("Action") - .HasColumnType("integer"); - - b.Property("TimeStamp") - .HasColumnType("timestamp with time zone"); + b.Property("TimeStamp"); b.HasKey("Id"); @@ -310,25 +109,20 @@ namespace isndhost.Migrations modelBuilder.Entity("isnd.Data.Packages.Package", b => { b.Property("Id") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); + .ValueGeneratedOnAdd() + .HasMaxLength(1024); - b.Property("CommitNId") - .HasColumnType("bigint"); + b.Property("CommitNId"); - b.Property("CommitTimeStamp") - .HasColumnType("timestamp with time zone"); + b.Property("CommitTimeStamp"); b.Property("Description") - .HasMaxLength(1024) - .HasColumnType("character varying(1024)"); + .HasMaxLength(1024); b.Property("OwnerId") - .IsRequired() - .HasColumnType("text"); + .IsRequired(); - b.Property("Public") - .HasColumnType("boolean"); + b.Property("Public"); b.HasKey("Id"); @@ -339,55 +133,145 @@ namespace isndhost.Migrations b.ToTable("Packages"); }); + modelBuilder.Entity("isnd.Data.PackageVersion", b => + { + b.Property("FullString") + .ValueGeneratedOnAdd() + .HasMaxLength(256); + + b.Property("CommitNId"); + + b.Property("IsPrerelease"); + + b.Property("Major"); + + b.Property("Minor"); + + b.Property("PackageId") + .IsRequired() + .HasMaxLength(1024); + + b.Property("Patch"); + + b.Property("Revision"); + + b.Property("Type") + .HasMaxLength(256); + + b.HasKey("FullString"); + + b.HasIndex("CommitNId"); + + b.HasIndex("PackageId"); + + b.ToTable("PackageVersions"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken(); + + b.Property("Name") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("RoleId") .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ClaimType"); + + b.Property("ClaimValue"); + + b.Property("UserId") .IsRequired(); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) + b.Property("LoginProvider"); + + b.Property("ProviderKey"); + + b.Property("ProviderDisplayName"); + + b.Property("UserId") .IsRequired(); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + b.Property("UserId"); - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + b.Property("RoleId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("isnd.Data.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + b.Property("UserId"); + + b.Property("LoginProvider"); + + b.Property("Name"); + + b.Property("Value"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); }); modelBuilder.Entity("isnd.Data.ApiKeys.ApiKey", b => @@ -395,29 +279,7 @@ namespace isndhost.Migrations b.HasOne("isnd.Data.ApplicationUser", "User") .WithMany() .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("User"); - }); - - modelBuilder.Entity("isnd.Data.PackageVersion", b => - { - b.HasOne("isnd.Data.Packages.Commit", "LatestCommit") - .WithMany("Versions") - .HasForeignKey("CommitNId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("isnd.Data.Packages.Package", "Package") - .WithMany("Versions") - .HasForeignKey("PackageId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("LatestCommit"); - - b.Navigation("Package"); + .OnDelete(DeleteBehavior.Cascade); }); modelBuilder.Entity("isnd.Data.Packages.Package", b => @@ -425,28 +287,70 @@ namespace isndhost.Migrations b.HasOne("isnd.Data.Packages.Commit", "LatestVersion") .WithMany() .HasForeignKey("CommitNId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .OnDelete(DeleteBehavior.Cascade); b.HasOne("isnd.Data.ApplicationUser", "Owner") .WithMany() .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("LatestVersion"); - - b.Navigation("Owner"); + .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("isnd.Data.Packages.Commit", b => + modelBuilder.Entity("isnd.Data.PackageVersion", b => { - b.Navigation("Versions"); + b.HasOne("isnd.Data.Packages.Commit", "LatestCommit") + .WithMany("Versions") + .HasForeignKey("CommitNId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("isnd.Data.Packages.Package", "Package") + .WithMany("Versions") + .HasForeignKey("PackageId") + .OnDelete(DeleteBehavior.Cascade); }); - modelBuilder.Entity("isnd.Data.Packages.Package", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.Navigation("Versions"); + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("isnd.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("isnd.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", 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", b => + { + b.HasOne("isnd.Data.ApplicationUser") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); }); #pragma warning restore 612, 618 } diff --git a/src/isnd/Services/EmailSender.cs b/src/isnd/Services/EmailSender.cs index 7f3d1fd..31b85e7 100644 --- a/src/isnd/Services/EmailSender.cs +++ b/src/isnd/Services/EmailSender.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.Extensions.Options; using Microsoft.AspNetCore.Hosting; using MailKit.Net.Smtp; -using MailKit.Security; using MimeKit; using System; @@ -37,26 +36,14 @@ namespace isnd.Services { try { var message = new MimeMessage(); - message.From.Add(new MailboxAddress(Options.SenderName, Options.SenderEmail)); - message.To.Add(new MailboxAddress(name ?? email, email)); + message.From.Add(new MailboxAddress(Options.SenderName, Options.SenderEMail)); + message.To.Add(new MailboxAddress(name??email, email)); message.Body = new TextPart("html") { Text = body }; using (var client = new SmtpClient()) { - client.ServerCertificateValidationCallback = (s,c,h,e) => true; - if (Options.Port > 0) - { - await client.ConnectAsync(Options.Host, Options.Port, SecureSocketOptions.Auto); - } - else - { - await client.ConnectAsync(Options.Host); - } - - if (!string.IsNullOrWhiteSpace(Options.UserName)) - { - await client.AuthenticateAsync(Options.UserName, Options.Password); - } - + client.ServerCertificateValidationCallback = (s,c,h,e)=>true; + await client.ConnectAsync(Options.Server); + await client.AuthenticateAsync(Options.UserName, Options.Password); await client.SendAsync(message); await client.DisconnectAsync(true); } diff --git a/src/isnd/Services/PackageManager.cs b/src/isnd/Services/PackageManager.cs index 0ba1c04..2dc301e 100644 --- a/src/isnd/Services/PackageManager.cs +++ b/src/isnd/Services/PackageManager.cs @@ -1,45 +1,39 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; -using Isn.Abstract; +using isn.Abstract; using isnd.Data; using isnd.Data.Catalog; using isnd.Data.Packages; +using isnd.Data.Packages.Catalog; using isnd.Entities; +using isnd.Helpers; using isnd.Interfaces; using isnd.ViewModels; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using NuGet.Versioning; +using Unleash; namespace isnd.Services { public class PackageManager : IPackageManager { public const string BASE_API_LEVEL = "3.0.0"; - private static string NormalizePackageType(string packageType) => packageType ?? string.Empty; ApplicationDbContext dbContext; - /** - * Constructor for the PackageManager class. - * @param dbContext The database context. - * @param siteConfigOptionsOptions The options for the IsndSettings configuration. - */ public PackageManager(ApplicationDbContext dbContext, IOptions siteConfigOptionsOptions) { this.dbContext = dbContext; isndSettings = siteConfigOptionsOptions.Value; - extUrl = isndSettings.ExternalUrl + "/" +Constants.APIPrefix; + extUrl = isndSettings.ExternalUrl + "/"; } - /** - * GetResources - */ - - public IEnumerable GetResources() + public IEnumerable GetResources(IUnleash unleashClient) { var res = new List @@ -50,8 +44,7 @@ namespace isnd.Services }, // under dev, only leash in release mode - // NuGet clients expect a trailing slash on PackageBaseAddress to resolve relative paths. - new Resource(extUrl + ApiConfig.GetPackage + "/", "PackageBaseAddress/3.0.0") + new Resource(extUrl + ApiConfig.GetPackage, "PackageBaseAddress/3.0.0") { Comment = @"Package Base Address service - Base URL of where NuGet packages are stored, in the format https:///nupkg/{id-lower}/{version-lower}/{id-lower}.{version-lower}.nupkg" }, @@ -69,15 +62,39 @@ namespace isnd.Services Comment = "Base URL of storage where isn package registration info is stored. This base URL includes SemVer 2.0.0 packages." } }; + /* new Resource(extUrl + ApiConfig.Catalog, "Catalog/" + BASE_API_LEVEL) + { + Comment = "Package Catalog Index" + },*/ + + /* res.Add( + ); res.Add( + new Resource(extUrl + "v3.0.0/" + ApiConfig.Registration, "RegistrationsBaseUrl") + { + + Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages." + }); + + res.Add( + new Resource(extUrl + "v3.0.0-beta/" + ApiConfig.Registration, "RegistrationsBaseUrl/3.0.0-beta") + { + Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages." + }); + res.Add( + new Resource(extUrl + "v3.0.0-rc/" + ApiConfig.Registration,"RegistrationsBaseUrl/3.0.0-rc") + { + Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages." + }); + res.Add(new Resource(extUrl + "v3.4.0/" + ApiConfig.Registration,"RegistrationsBaseUrl/3.4.0") + { + Comment = "Base URL of storage where isn package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages." + }); + + res.Add(); */ return res; } - /** - * AutoComplete generation - */ - - public AutoCompleteResult AutoComplete(string id, int skip, int take, bool prerelease = false, string packageType = null) @@ -118,24 +135,18 @@ namespace isnd.Services } - /** - * CatalogBaseUrl - */ + public string CatalogBaseUrl => extUrl; private IsndSettings isndSettings; private string extUrl; - /** - * GetCatalogIndexAsync - */ - public virtual async Task GetCatalogIndexAsync() { - return await UpdateCatalogForAsync(null); + return await ÛpdateCatalogForAsync(null); } - public async Task UpdateCatalogForAsync(Commit reason = null) + public async Task ÛpdateCatalogForAsync(Commit reason = null) { int i = 0; @@ -192,12 +203,11 @@ namespace isnd.Services public async Task DeletePackageAsync(string pkgid, string version, string type) { - type = NormalizePackageType(type); // TODO deletion on disk var commit = new Commit { Action = PackageAction.DeletePackage, - TimeStamp = DateTime.UtcNow + TimeStamp = DateTime.Now }; dbContext.Commits.Add(commit); var pkg = await dbContext.PackageVersions.SingleOrDefaultAsync( @@ -211,13 +221,12 @@ namespace isnd.Services } dbContext.PackageVersions.Remove(pkg); await dbContext.SaveChangesAsync(); - await UpdateCatalogForAsync(commit); + await ÛpdateCatalogForAsync(commit); return new PackageDeletionReport { Deleted = true, DeletedVersion = pkg }; } public async Task GetPackageAsync(string pkgid, string version, string type) { - type = NormalizePackageType(type); return await dbContext.PackageVersions.SingleOrDefaultAsync( v => v.PackageId == pkgid && v.FullString == version && @@ -238,7 +247,6 @@ namespace isnd.Services public async Task UserAskForPackageDeletionAsync(string uid, string id, string lower, string type) { - type = NormalizePackageType(type); PackageVersion packageVersion = await dbContext.PackageVersions .Include(pv => pv.Package) .FirstOrDefaultAsync(m => m.PackageId == id diff --git a/src/isnd/Startup.cs b/src/isnd/Startup.cs index 2238cf1..93be266 100644 --- a/src/isnd/Startup.cs +++ b/src/isnd/Startup.cs @@ -1,4 +1,5 @@ - +using System.Linq; +using System.Collections.Generic; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; @@ -14,46 +15,41 @@ using isnd.Entities; using isnd.Authorization; using isnd.Data.Roles; using Microsoft.AspNetCore.Authorization; +using Unleash; using Microsoft.Extensions.Options; using isnd.Helpers; using Microsoft.IdentityModel.Tokens; using System; +using Microsoft.OpenApi.Models; using System.IO; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using System.Text.Json; +using System.Text.Json.Serialization; +using isnd.Data.Catalog; +using Newtonsoft.Json; using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.OpenApi; namespace isnd { -/** - * Startup class for configuring services and the app's request pipeline. - */ public class Startup { - /** - * Constructor for the Startup class. - * @param config The configuration object. - */ public Startup(IConfiguration config) { Configuration = config; } - /** - * The configuration object. - */ public static IConfiguration Configuration { get; private set; } - /** - * This method gets called by the runtime. Use this method to add services to the container. - * @param services The service collection. - */ + // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var smtpSettingsconf = Configuration.GetSection("Smtp"); var isndSettingsconf = Configuration.GetSection("Isn"); - var adminStartupListConf = Configuration.GetSection("AdminStartupList"); + var adminStartupListConf = Configuration.GetSection("AdminList"); + var unleashConf = Configuration.GetSection("Unleash"); services.Configure(options => { @@ -61,26 +57,14 @@ namespace isnd ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); - var connectionString = Configuration.GetConnectionString("DefaultConnection"); - var useInMemoryDatabase = Configuration.GetValue("UseInMemoryDatabase") || - string.IsNullOrWhiteSpace(connectionString) || - connectionString.Contains("<", StringComparison.Ordinal); - services.Configure(smtpSettingsconf) .Configure(isndSettingsconf) .Configure(adminStartupListConf) + .Configure(unleashConf) .Configure(o => o.Path = "~/migrate") .AddDbContext(options => - { - if (useInMemoryDatabase) - { - options.UseInMemoryDatabase("isnd-tests"); - } - else - { - options.UseNpgsql(connectionString); - } - }) + options.UseNpgsql( + Configuration.GetConnectionString("DefaultConnection"))) .AddIdentity() .AddRoles() .AddEntityFrameworkStores() @@ -105,7 +89,20 @@ namespace isnd .AddTransient() .AddTransient() .AddSingleton() - .AddAuthentication("Bearer") + .AddSingleton(s => + { + var config = s.GetRequiredService>(); + if (config.Value == null) + throw new System.Exception("No unleash client settings"); + if (config.Value.ApiUrl == null) + throw new System.Exception("No unleash client ApiUrl"); + if (config.Value.ClientApiKey == null) + throw new System.Exception("No unleash client ClientApiKey"); + return s.GetRequiredService().CreateUnleahClient(config.Value); + }); + + + services.AddAuthentication("Bearer") .AddJwtBearer("Bearer", options => { options.Authority = isndSettingsconf.GetValue("ExternalUrl"); @@ -144,13 +141,7 @@ namespace isnd }); } - /** - * This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - * @param app The application builder. - * @param env The web host environment. - * @param dbContext The application database context. - * @param isnSettingsOption The isnd settings options. - */ + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationDbContext dbContext, diff --git a/src/isnd/ViewModels/HomeIndexViewModel.cs b/src/isnd/ViewModels/HomeIndexViewModel.cs index 1beadca..3dac63c 100644 --- a/src/isnd/ViewModels/HomeIndexViewModel.cs +++ b/src/isnd/ViewModels/HomeIndexViewModel.cs @@ -1,8 +1,11 @@ +using Unleash; + namespace isnd.ViewModels { public class HomeIndexViewModel { public int PkgCount { get; set; } + public IUnleash UnleashClient; } } \ No newline at end of file diff --git a/src/isnd/Views/Home/Features.cshtml b/src/isnd/Views/Home/Features.cshtml index ab2d034..e38c6a9 100644 --- a/src/isnd/Views/Home/Features.cshtml +++ b/src/isnd/Views/Home/Features.cshtml @@ -3,8 +3,15 @@ foreach (string leashed in new string[] { "pkg-push", "pkg-get", "pkg-autocomplete","pkg-search","pkg-catalog"}) { - + if (Model.UnleashClient.IsEnabled(leashed)) + { + //do some magic +

@leashed

+ } + else + { //do old boring stuff

No @leashed (disabled)

} + } } \ No newline at end of file diff --git a/src/isnd/appsettings.json b/src/isnd/appsettings.json index 06ba611..61e4a9b 100644 --- a/src/isnd/appsettings.json +++ b/src/isnd/appsettings.json @@ -16,11 +16,16 @@ }, "AllowedHosts": "*", "Smtp": { - "Host": "", + "Server": "", "Port": 25, "SenderName": "", "SenderEmail": "" }, + "Unleash": + { + "ClientApiKey": "lame-unleash-client-api-key", + "ApiUrl": "http://localhost:4242/api/" + }, "Logging": { "LogLevel": { "Default": "Warning" diff --git a/src/isnd/isnd.csproj b/src/isnd/isnd.csproj index 9b04000..c3c424c 100644 --- a/src/isnd/isnd.csproj +++ b/src/isnd/isnd.csproj @@ -1,42 +1,48 @@  + net7.0 + 85fd766d-5d23-4476-aed1-463b2942e86a true - 1.0.0.0 - 1.0.0.0 - 1.0.0+Branch.main.Sha.654065d7fef34ba4ed2fb3bca5bc91de9ad16e85 - 1.0.0 + WTFPL + NETSDK1138,CS1591,MSB3243 + 1.0.7.0 + 1.0.7.0 + 1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327 + 1.0.7 + true + - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all + + + + + + + + + + + + + + + All - - - + + + + - - - - - - - - - - - - - + - diff --git a/test/data/nuget-artifacts/dummy.nuget.1.0.0.nupkg b/test/data/nuget-artifacts/dummy.nuget.1.0.0.nupkg deleted file mode 100644 index 070a94b..0000000 Binary files a/test/data/nuget-artifacts/dummy.nuget.1.0.0.nupkg and /dev/null differ diff --git a/test/data/nuget-artifacts/dummy.nuget.1.0.0/dummy.nuget.nuspec b/test/data/nuget-artifacts/dummy.nuget.1.0.0/dummy.nuget.nuspec deleted file mode 100644 index feb3a4a..0000000 --- a/test/data/nuget-artifacts/dummy.nuget.1.0.0/dummy.nuget.nuspec +++ /dev/null @@ -1,9 +0,0 @@ - - - - dummy.nuget - 1.0.0 - isnd.tests - Dummy test package used by integration tests. - - diff --git a/test/data/test-isn/ANuGet.Config b/test/data/test-isn/ANuGet.Config new file mode 100644 index 0000000..072ade1 --- /dev/null +++ b/test/data/test-isn/ANuGet.Config @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/test/data/test-isn/test-isn.csproj b/test/data/test-isn/test-isn.csproj index 51e4d77..9836c56 100644 --- a/test/data/test-isn/test-isn.csproj +++ b/test/data/test-isn/test-isn.csproj @@ -1,13 +1,13 @@  Exe - net10.0 + net7.0 test_isn enable enable - 1.0.0.0 - 1.0.0.0 - 1.0.0+Branch.main.Sha.654065d7fef34ba4ed2fb3bca5bc91de9ad16e85 - 1.0.0 + 1.0.7.0 + 1.0.7.0 + 1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327 + 1.0.7 \ No newline at end of file diff --git a/test/data/test-isn/testcmd b/test/data/test-isn/testcmd new file mode 100644 index 0000000..2127221 --- /dev/null +++ b/test/data/test-isn/testcmd @@ -0,0 +1 @@ +nuget install -NoCache -Verbosity detailed -ConfigFile ANuGet.Config Yavsc.Abstract diff --git a/test/isn.tests/PushTest.cs b/test/isn.tests/PushTest.cs index bc985ed..6e0f264 100644 --- a/test/isn.tests/PushTest.cs +++ b/test/isn.tests/PushTest.cs @@ -1,190 +1,29 @@ using System; -using System.Collections.Generic; +using System.Data; using System.IO; -using System.Linq; -using System.Net; +using System.Xml; using System.Net.Http; -using System.Net.Sockets; -using System.Text; + using System.Threading.Tasks; using Newtonsoft.Json; +using isn.Abstract; +using System.Linq; using Xunit; -using Isn.Abstract; +using isn.abst; +using isnd.Entities; -namespace Isn.tests +namespace isn.tests { - public sealed class LocalSourceFixture : IDisposable + public class Tests { - private readonly HttpListener listener; - private readonly Task listenerTask; - private readonly string configDirectory; - private readonly string originalConfigDirectory; - - public string LastApiKeyHeader { get; private set; } - - public LocalSourceFixture() - { - var port = GetFreePort(); - var prefix = $"http://127.0.0.1:{port}/"+Constants.APIPrefix; - listener = new HttpListener(); - listener.Prefixes.Add(prefix); - listener.Start(); - - listenerTask = Task.Run(async () => - { - while (listener.IsListening) - { - HttpListenerContext context; - try - { - context = await listener.GetContextAsync(); - } - catch (HttpListenerException) - { - break; - } - catch (ObjectDisposedException) - { - break; - } - - if (context.Request.HttpMethod == "PUT") - { - LastApiKeyHeader = context.Request.Headers["X-NuGet-ApiKey"]; - } - - var indexJson = JsonConvert.SerializeObject(new ApiIndexViewModel(prefix + "index.json") - { - Version = "3.0.0", - Resources = new[] - { - new Resource(prefix + "put", "PackagePublish/2.0.0") - { - Comment = "test publish endpoint" - } - } - }); - var payload = Encoding.UTF8.GetBytes(indexJson); - context.Response.ContentType = "application/json"; - context.Response.ContentLength64 = payload.Length; - await context.Response.OutputStream.WriteAsync(payload, 0, payload.Length); - context.Response.Close(); - } - }); - - configDirectory = Path.Combine(Path.GetTempPath(), $"isn-tests-{Guid.NewGuid():N}"); - Directory.CreateDirectory(configDirectory); - originalConfigDirectory = Environment.GetEnvironmentVariable("ISN_CONFIG_DIR"); - Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", configDirectory); - - SourceUrl = prefix + "index.json"; - ConfigureIsnSettings(SourceUrl); - Program.LoadConfig(); - } - - public string SourceUrl { get; } - - public void Dispose() - { - listener.Close(); - if (listenerTask != null) - { - try - { - listenerTask.GetAwaiter().GetResult(); - } - catch (Exception) - { - } - } - - Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", originalConfigDirectory); - if (Directory.Exists(configDirectory)) - { - Directory.Delete(configDirectory, recursive: true); - } - } - - private static int GetFreePort() - { - var listener = new TcpListener(IPAddress.Loopback, 0); - listener.Start(); - var port = ((IPEndPoint)listener.LocalEndpoint).Port; - listener.Stop(); - return port; - } - - private void ConfigureIsnSettings(string sourceUrl) - { - var configPath = Path.Combine(configDirectory, "config.json"); - var settings = new Settings - { - DataProtectionTitle = "isn", - Sources = new Dictionary - { - [sourceUrl] = new SourceSettings { Alias = "test" } - }, - DefaultSourceKey = sourceUrl - }; - - File.WriteAllText(configPath, JsonConvert.SerializeObject(settings, Formatting.Indented)); - } - } - - public class Tests : IClassFixture - { - private readonly LocalSourceFixture fixture; - - public Tests(LocalSourceFixture fixture) - { - this.fixture = fixture; - } - - [Fact] - public void SupportsIsolatedConfigDirectoryOverride() - { - var tempDir = Path.Combine(Path.GetTempPath(), $"isn-test-{Guid.NewGuid():N}"); - Directory.CreateDirectory(tempDir); - var originalConfigDir = Environment.GetEnvironmentVariable("ISN_CONFIG_DIR"); - var configFile = Path.Combine(tempDir, "config.json"); - var expectedSource = "https://example.test/index.json"; - var settings = new Settings - { - DataProtectionTitle = "isn", - Sources = new Dictionary - { - [expectedSource] = new SourceSettings { Alias = "override" } - }, - DefaultSourceKey = expectedSource - }; - - try - { - Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", tempDir); - File.WriteAllText(configFile, JsonConvert.SerializeObject(settings, Formatting.Indented)); - - Program.LoadConfig(); - - Assert.Equal(expectedSource, Program.Settings.DefaultSourceKey); - Assert.True(Program.Settings.Sources.ContainsKey(expectedSource)); - } - finally - { - Environment.SetEnvironmentVariable("ISN_CONFIG_DIR", originalConfigDir); - if (Directory.Exists(tempDir)) - { - Directory.Delete(tempDir, recursive: true); - } - } - } [Fact] public void HaveADefaultDataProtector() { - var pass = "a lame and big pass"; - IDataProtector protector = new DefaultDataProtector(); - var protectedpass = protector.Protect(pass); - var unprotectedpass = protector.UnProtect(protectedpass); + string pass = "a lame and big pass"; + isn.IDataProtector _protector = new isn.DefaultDataProtector(); + string protectedpass = _protector.Protect(pass); + string unprotectedpass = _protector.UnProtect(protectedpass); Console.WriteLine(protectedpass); Assert.Equal(pass, unprotectedpass); Assert.True(protectedpass != null); @@ -194,76 +33,33 @@ namespace Isn.tests [Fact] public async Task TestHttpClient() { - using var client = new HttpClient(); - var response = await client.GetAsync(fixture.SourceUrl); + string url = "https://isn.pschneider.fr/" + ApiConfig.IndexDotJson; + HttpClient client = new HttpClient(); + // var json = await client.GetStringAsync(new System.Uri(url)); + var response = await client.GetAsync(url); var json = await response.Content.ReadAsStringAsync(); var vm = JsonConvert.DeserializeObject(json); Console.WriteLine(JsonConvert.SerializeObject(vm)); Assert.NotNull(vm); Assert.NotNull(vm.Resources); } - [Fact] public void TestPush() { Program.LoadConfig(); - var report = Program.PushPkg(new[] { GetDummyPackagePath() }); - Assert.NotNull(report); - Assert.Single(report); - } - - [Fact] - public void PushUsesStoredApiKeyFromConfigWhenNoExplicitApiKeyIsProvided() - { - Program.LoadConfig(); - var clearApiKey = "stored-api-key"; - Program.Settings.Sources[fixture.SourceUrl].SetApiKey(clearApiKey); - Program.SaveConfig(); - Program.LoadConfig(); - - var report = Program.PushPkg(new[] { GetDummyPackagePath() }); - - Assert.NotNull(report); - Assert.Single(report); - Assert.Equal(clearApiKey, fixture.LastApiKeyHeader); + var report = Program.PushPkg(new string[] { "/home/paul/Nupkgs/Yavsc.Abstract.1.0.8." + + Constants.PaquetFileEstension }); } [Fact] public void GetServerResourcesUsingHttpClientAsyncTest() { - var model = SourceHelpers.GetServerResources(fixture.SourceUrl); + var model = SourceHelpers.GetServerResources("Https://isn.pschneider.fr/index.json"); Console.WriteLine(JsonConvert.SerializeObject(model)); Assert.NotNull(model.Resources); - var pub = model.Resources.FirstOrDefault(r => r.Type.StartsWith("PackagePublish/")); + var pub = model.Resources.FirstOrDefault((r) => r.Type.StartsWith("PackagePublish/")); Assert.True(pub != null); } - private static string GetDummyPackagePath() - { - var localOutputDummy = Path.Combine(AppContext.BaseDirectory, "dummy.nupkg"); - if (File.Exists(localOutputDummy)) - { - return localOutputDummy; - } - - var dir = new DirectoryInfo(AppContext.BaseDirectory); - while (dir != null) - { - if (File.Exists(Path.Combine(dir.FullName, "isn.sln"))) - { - var sharedArtifact = Path.Combine(dir.FullName, "test", "data", "nuget-artifacts", "dummy.nuget.1.0.0.nupkg"); - if (File.Exists(sharedArtifact)) - { - return sharedArtifact; - } - - break; - } - - dir = dir.Parent; - } - - throw new FileNotFoundException("Unable to locate a dummy NuGet package for push tests."); - } } } \ No newline at end of file diff --git a/test/isn.tests/isn.tests.csproj b/test/isn.tests/isn.tests.csproj index 9371392..faae98f 100644 --- a/test/isn.tests/isn.tests.csproj +++ b/test/isn.tests/isn.tests.csproj @@ -1,18 +1,20 @@  + net7.0 false - 1.0.0.0 - 1.0.0.0 - 1.0.0+Branch.main.Sha.654065d7fef34ba4ed2fb3bca5bc91de9ad16e85 - 1.0.0 + NETSDK1138 + 1.0.7.0 + 1.0.7.0 + 1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327 + 1.0.7 - - + + - - - + + + diff --git a/test/isnd.tests/UnitTestWebHost.cs b/test/isnd.tests/UnitTestWebHost.cs index 126372a..99ac24e 100644 --- a/test/isnd.tests/UnitTestWebHost.cs +++ b/test/isnd.tests/UnitTestWebHost.cs @@ -1,40 +1,28 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Security.Cryptography; using System.Threading; -using System.Threading.Tasks; -using System.Xml.Linq; -using Isn.Abstract; +using System; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore; +using Xunit; using isnd.Data; -using isnd.Data.ApiKeys; -using isnd.Helpers; -using isnd.tests; -using Microsoft.AspNetCore.DataProtection; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using NuGet.Common; -using NuGet.Configuration; +using System.Diagnostics; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.Extensions.Configuration; +using isnd.tests; using NuGet.Protocol; +using NuGet.Configuration; +using System.Threading.Tasks; using NuGet.Protocol.Core.Types; -using NuGet.Versioning; -using Xunit; namespace isnd.host.tests -{ +{ [Collection("Web server collection")] public class UnitTestWebHost : IClassFixture { - private const string DummyPackageId = "dummy.nuget"; - private const string DummyPackageVersion = "1.0.0"; - private const string DummyArtifactRelativePath = "test/data/nuget-artifacts/dummy.nuget.1.0.0.nupkg"; - - private readonly WebServerFixture server; - + WebServerFixture server; public UnitTestWebHost(WebServerFixture server) { this.server = server; @@ -43,324 +31,83 @@ namespace isnd.host.tests [Fact] public void TestHaveTestDbContextAndMigrate() { - using var serviceScope = server.Host.Services.CreateScope(); - var services = serviceScope.ServiceProvider; - var myDependency = services.GetRequiredService(); - if (myDependency.Database.ProviderName?.Contains("InMemory", StringComparison.OrdinalIgnoreCase) == true) - { - myDependency.Database.EnsureCreated(); - } - else + using (var serviceScope = server.Host.Services.CreateScope()) { + var services = serviceScope.ServiceProvider; + var myDependency = services.GetRequiredService(); myDependency.Database.Migrate(); } } [Fact] - public void LegacyApiKeyProtectorCanUnprotectValuesFromOlderClients() + void TestDropUser() { - const string clearValue = "legacy-api-key"; - var legacyProtectedValue = new Isn.DefaultDataProtector().Protect(clearValue); - - var unprotected = ApiKeyProtector.TryUnprotectKey(new ThrowingProtector(), legacyProtectedValue); - - Assert.Equal(clearValue, unprotected); - } - - [Fact] - public void ApiKeyProtectorReturnsRawValueWhenInputIsNotProtected() - { - const string rawApiKey = "CfDJ8AstXUEkxpJBrmoENwy__WNPxqcOwAuxyYgiU3Mebns5yxAT3VrC5vTuWTRSGZBFB7IGUyFkUYsp2nhRy64NqeUzLgOwEcU4FPOf-yaAtPeTMeStRd60bRh2ZYyQkQ3hrhW-lwpCLwYtNOnOyX2jayuzByF-4QfHIEhg6lbWenzf"; - - var result = ApiKeyProtector.TryUnprotectKey(new ThrowingProtector(), rawApiKey); - - Assert.Equal(rawApiKey, result); - } - - [Fact] - public void TestDropUser() - { - using var serviceScope = server.Host.Services.CreateScope(); - var services = serviceScope.ServiceProvider; - var dbContext = services.GetRequiredService(); - var paul = dbContext.Users.FirstOrDefaultAsync(u => u.Email == "paul@pschneider.fr").Result; - if (paul != null) + + using (var serviceScope = server.Host.Services.CreateScope()) { - dbContext.Users.Remove(paul); - dbContext.SaveChanges(); + var services = serviceScope.ServiceProvider; + var dbContext = services.GetRequiredService(); + var paul = dbContext.Users.FirstOrDefaultAsync(u => u.Email == "paul@pschneider.fr").Result; + if (paul!=null) + { + dbContext.Users.Remove(paul); + dbContext.SaveChanges(); + } } } + [Fact] public void NugetInstallsTest() { - var pkgSourceUrl = GetServerBaseUrl() + "/" + Constants.APIPrefix + "index.json"; - using var client = new HttpClient(); - var response = client.GetAsync(pkgSourceUrl).GetAwaiter().GetResult(); - var body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); - - Assert.True(response.IsSuccessStatusCode, $"Expected {pkgSourceUrl} to be reachable but got {(int)response.StatusCode} {response.ReasonPhrase}"); - Assert.False(string.IsNullOrWhiteSpace(body)); - Assert.Contains("PackagePublish/2.0.0", body, StringComparison.OrdinalIgnoreCase); - Assert.Contains("RegistrationsBaseUrl/Versioned", body, StringComparison.OrdinalIgnoreCase); - } - - [Fact] - public void DummyNugetArtifactShouldBeAReadablePackage() - { - var packagePath = GetDummyArtifactPath(); - Assert.True(File.Exists(packagePath), $"Missing dummy artifact at {packagePath}"); - - var fileInfo = new FileInfo(packagePath); - Assert.True(fileInfo.Length > 0, "Dummy artifact is empty."); - - using var stream = File.OpenRead(packagePath); - using var archive = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: false); - var nuspecEntry = archive.GetEntry("dummy.nuget.nuspec"); - Assert.NotNull(nuspecEntry); - - using var nuspecStream = nuspecEntry.Open(); - var nuspec = XDocument.Load(nuspecStream); - XNamespace ns = "http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"; - var id = nuspec.Root?.Element(ns + "metadata")?.Element(ns + "id")?.Value; - var version = nuspec.Root?.Element(ns + "metadata")?.Element(ns + "version")?.Value; - - Assert.Equal(DummyPackageId, id); - Assert.Equal(DummyPackageVersion, version); - } - - [Fact] - public async Task PushDummyPackageAndDiscoverItThroughNuGetEndpoints() - { - var apiKeyValue = $"dummy-key-{Guid.NewGuid():N}"; - var packagePath = GetDummyArtifactPath(); - Assert.True(File.Exists(packagePath), $"Missing dummy artifact at {packagePath}"); - using (var serviceScope = server.Host.Services.CreateScope()) - { - var dbContext = serviceScope.ServiceProvider.GetRequiredService(); - var userId = $"dummy-user-{Guid.NewGuid():N}"; - - await ResetDummyPackageStateAsync(serviceScope.ServiceProvider, dbContext); - - dbContext.Users.Add(new ApplicationUser - { - Id = userId, - UserName = userId, - NormalizedUserName = userId.ToUpperInvariant(), - Email = $"{userId}@tests.local", - NormalizedEmail = $"{userId}@tests.local".ToUpperInvariant(), - EmailConfirmed = true - }); - - dbContext.ApiKeys.Add(new ApiKey - { - Id = apiKeyValue, - UserId = userId, - Name = "dummy-key", - CreationDate = DateTime.UtcNow, - ValidityPeriodInDays = 30 - }); - - await dbContext.SaveChangesAsync(); + { var isnSettings = serviceScope.ServiceProvider.GetService>().Value; + string pkgSourceUrl = isnSettings.ExternalUrl + "/index.json"; + ProcessStartInfo psi = new ProcessStartInfo("nuget"); + psi.ArgumentList.Add("install"); + psi.ArgumentList.Add("gitversion"); + psi.ArgumentList.Add("-PreRelease"); + psi.ArgumentList.Add("-Source"); + psi.ArgumentList.Add(pkgSourceUrl); + Process p = Process.Start(psi); + p.WaitForExit(); + Assert.True(p.ExitCode == 0, "nuget install failed!"); } - - await PushPackageAsync(packagePath, apiKeyValue); - await AssertRegistrationContainsPushedVersionAsync(DummyPackageId, DummyPackageVersion); - await AssertAutocompleteContainsPushedVersionAsync(DummyPackageId, DummyPackageVersion); - } - - [Fact] - public async Task NuGetV3ProtocolCanDownloadDummyPackage() - { - var apiKeyValue = $"dummy-key-{Guid.NewGuid():N}"; - var packagePath = GetDummyArtifactPath(); - Assert.True(File.Exists(packagePath), $"Missing dummy artifact at {packagePath}"); - - using (var serviceScope = server.Host.Services.CreateScope()) - { - var dbContext = serviceScope.ServiceProvider.GetRequiredService(); - var userId = $"dummy-user-{Guid.NewGuid():N}"; - - await ResetDummyPackageStateAsync(serviceScope.ServiceProvider, dbContext); - - dbContext.Users.Add(new ApplicationUser - { - Id = userId, - UserName = userId, - NormalizedUserName = userId.ToUpperInvariant(), - Email = $"{userId}@tests.local", - NormalizedEmail = $"{userId}@tests.local".ToUpperInvariant(), - EmailConfirmed = true - }); - - dbContext.ApiKeys.Add(new ApiKey - { - Id = apiKeyValue, - UserId = userId, - Name = "dummy-key", - CreationDate = DateTime.UtcNow, - ValidityPeriodInDays = 30 - }); - - await dbContext.SaveChangesAsync(); - } - - await PushPackageAsync(packagePath, apiKeyValue); - - var indexUrl = GetServerBaseUrl() + "/" + Constants.APIPrefix + "index.json"; - var repository = Repository.Factory.GetCoreV3(indexUrl); - var findPackageById = await repository.GetResourceAsync(); - Assert.NotNull(findPackageById); - - await using var nupkgStream = new MemoryStream(); - using var cache = new SourceCacheContext(); - var copied = await findPackageById.CopyNupkgToStreamAsync( - DummyPackageId, - NuGetVersion.Parse(DummyPackageVersion), - nupkgStream, - cache, - NullLogger.Instance, - CancellationToken.None); - - Assert.True(copied, "NuGet v3 client could not download the package from the feed."); - Assert.True(nupkgStream.Length > 0, "Downloaded package stream is empty."); } [Fact] public void TestRegistrationV3Resource() { - using var serviceScope = server.Host.Services.CreateScope(); - var isnSettings = serviceScope.ServiceProvider.GetService>().Value; - string pkgSourceUrl = isnSettings.ExternalUrl + "/pkgs/index.json"; - var throttle = new NullThrottle(); + using (var serviceScope = server.Host.Services.CreateScope()) + { var isnSettings = serviceScope.ServiceProvider.GetService>().Value; + string pkgSourceUrl = isnSettings.ExternalUrl + "/index.json"; + NullThrottle throttle = new NullThrottle(); - var packageSource = new PackageSource(pkgSourceUrl); - var client = new HttpSource(packageSource, PkgSourceMessageHandler, throttle); - _ = new RegistrationResourceV3(client, new Uri(isnSettings.ExternalUrl + "/v3.4.0//registration")); + PackageSource packageSource = new PackageSource(pkgSourceUrl); + HttpSource client = new HttpSource(packageSource, PkgSourceMessageHandler, throttle); + NuGet.Protocol.RegistrationResourceV3 res = new NuGet.Protocol.RegistrationResourceV3(client , + new Uri(isnSettings.ExternalUrl + "/v3.4.0//registration")); + } } - + [Fact] public void TrueTestRegistrationV3Resource() { - using var serviceScope = server.Host.Services.CreateScope(); - var isnSettings = serviceScope.ServiceProvider.GetService>().Value; - string pkgSourceUrl = isnSettings.ExternalUrl + "/pkgs/index.json"; + using (var serviceScope = server.Host.Services.CreateScope()) + { + var isnSettings = serviceScope.ServiceProvider.GetService>().Value; + string pkgSourceUrl = isnSettings.ExternalUrl + "/index.json"; var prov = new RegistrationResourceV3Provider(); var source = new PackageSource(pkgSourceUrl); - var repo = new SourceRepository(source, new INuGetResourceProvider[] { prov }); + var repo = new SourceRepository(source, new INuGetResourceProvider[]{ prov }); prov.TryCreate(repo, CancellationToken.None); + + } } private Task PkgSourceMessageHandler() { throw new NotImplementedException(); } - - private string GetServerBaseUrl() - { - var address = server.Addresses.FirstOrDefault(); - Assert.False(string.IsNullOrWhiteSpace(address), "No listening address was captured from WebServerFixture."); - return address.TrimEnd('/'); - } - - private string GetDummyArtifactPath() - { - var root = FindRepoRoot(); - return Path.Combine(root, DummyArtifactRelativePath); - } - - private static string FindRepoRoot() - { - var dir = new DirectoryInfo(AppContext.BaseDirectory); - while (dir != null) - { - if (File.Exists(Path.Combine(dir.FullName, "isn.sln"))) - { - return dir.FullName; - } - - dir = dir.Parent; - } - - throw new DirectoryNotFoundException("Could not locate repository root from AppContext.BaseDirectory."); - } - - private static async Task ResetDummyPackageStateAsync(IServiceProvider serviceProvider, ApplicationDbContext dbContext) - { - var settings = serviceProvider.GetRequiredService>().Value; - var versions = dbContext.PackageVersions.Where(v => v.PackageId == DummyPackageId); - var packages = dbContext.Packages.Where(p => p.Id == DummyPackageId); - - dbContext.PackageVersions.RemoveRange(versions); - dbContext.Packages.RemoveRange(packages); - await dbContext.SaveChangesAsync(); - - var packageRootDir = settings.PackagesRootDir; - if (!Path.IsPathRooted(packageRootDir)) - { - packageRootDir = Path.Combine(FindRepoRoot(), packageRootDir); - } - - var packageOnDiskPath = Path.Combine(packageRootDir, DummyPackageId); - if (Directory.Exists(packageOnDiskPath)) - { - Directory.Delete(packageOnDiskPath, recursive: true); - } - } - - private async Task PushPackageAsync(string packagePath, string apiKey) - { - using var client = new HttpClient { BaseAddress = new Uri(GetServerBaseUrl()) }; - using var request = new HttpRequestMessage(HttpMethod.Put, $"/{Constants.APIPrefix}{isnd.Entities.ApiConfig.Publish}"); - using var multipart = new MultipartFormDataContent(); - await using var packageStream = File.OpenRead(packagePath); - using var packageContent = new StreamContent(packageStream); - - packageContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); - multipart.Add(packageContent, "package", Path.GetFileName(packagePath)); - request.Content = multipart; - request.Headers.Add("X-NuGet-ApiKey", apiKey); - request.Headers.Add("X-NuGet-Client-Version", "6.11.1"); - - var response = await client.SendAsync(request); - var responseBody = await response.Content.ReadAsStringAsync(); - Assert.True(response.IsSuccessStatusCode, - $"Expected push to succeed but got {(int)response.StatusCode} {response.ReasonPhrase}. Body: {responseBody}"); - } - - private async Task AssertRegistrationContainsPushedVersionAsync(string packageId, string packageVersion) - { - using var client = new HttpClient { BaseAddress = new Uri(GetServerBaseUrl()) }; - var lowerId = packageId.ToLowerInvariant(); - var route = $"/{Constants.APIPrefix}v3.4.0/{isnd.Entities.ApiConfig.Registration}/{lowerId}/index.json"; - var response = await client.GetAsync(route); - var body = await response.Content.ReadAsStringAsync(); - - Assert.True(response.IsSuccessStatusCode, - $"Expected registration endpoint to succeed but got {(int)response.StatusCode} {response.ReasonPhrase}. Body: {body}"); - Assert.Contains(packageVersion, body, StringComparison.OrdinalIgnoreCase); - } - - private async Task AssertAutocompleteContainsPushedVersionAsync(string packageId, string packageVersion) - { - using var client = new HttpClient { BaseAddress = new Uri(GetServerBaseUrl()) }; - var route = $"/{Constants.APIPrefix}{isnd.Entities.ApiConfig.AutoComplete}?id={packageId}&semVerLevel=3.0.0&prerelease=true"; - var response = await client.GetAsync(route); - var body = await response.Content.ReadAsStringAsync(); - - Assert.True(response.IsSuccessStatusCode, - $"Expected autocomplete endpoint to succeed but got {(int)response.StatusCode} {response.ReasonPhrase}. Body: {body}"); - Assert.Contains(packageVersion, body, StringComparison.OrdinalIgnoreCase); - } - - private sealed class ThrowingProtector : IDataProtector - { - public byte[] Protect(byte[] plaintext) => throw new CryptographicException("unexpected protect call"); - - public byte[] Unprotect(byte[] protectedData) => throw new CryptographicException("unexpected unprotect call"); - - public IDataProtector CreateProtector(string purpose) => this; - } } } diff --git a/test/isnd.tests/WebServerFixture.cs b/test/isnd.tests/WebServerFixture.cs index b634ccc..b45be22 100644 --- a/test/isnd.tests/WebServerFixture.cs +++ b/test/isnd.tests/WebServerFixture.cs @@ -38,8 +38,8 @@ namespace isnd.tests .UseStartup(typeof(Startup)) .ConfigureAppConfiguration((builderContext, config) => { - config.AddJsonFile("appsettings.json", optional: false); - config.AddJsonFile("appsettings.Development.json", optional: true); + config.AddJsonFile("appsettings.json", false); + config.AddJsonFile("appsettings.Development.json", false); }); Host = webhostBuilder.Build(); diff --git a/test/isnd.tests/isnd.tests.csproj b/test/isnd.tests/isnd.tests.csproj index 657cd31..f3572a8 100644 --- a/test/isnd.tests/isnd.tests.csproj +++ b/test/isnd.tests/isnd.tests.csproj @@ -1,12 +1,13 @@  + net7.0 false d7144e46-4e63-4391-ba86-64b61f6e7be4 NETSDK1138 - 1.0.0.0 - 1.0.0.0 - 1.0.0+Branch.main.Sha.654065d7fef34ba4ed2fb3bca5bc91de9ad16e85 - 1.0.0 + 1.0.7.0 + 1.0.7.0 + 1.0.7+Branch.main.Sha.3695c1742965d93eba0ad851656cfaa3e44ba327 + 1.0.7 diff --git a/test/isnd.tests/wwwroot/favicon.ico b/test/isnd.tests/wwwroot/favicon.ico new file mode 100644 index 0000000..e69de29