Compare commits
202 Commits
main
...
fixed-page
Author | SHA1 | Date |
---|---|---|
Paul Schneider | 58f77a06ea | 2 years ago |
Paul Schneider | 88c8480911 | 2 years ago |
Paul Schneider | c147eaf54a | 2 years ago |
Paul Schneider | e49db8e1a1 | 2 years ago |
Paul Schneider | 9aac183e2c | 2 years ago |
Paul Schneider | 037559a0b7 | 2 years ago |
Paul Schneider | 9c4d45b97c | 2 years ago |
Paul Schneider | 9aa3140a11 | 2 years ago |
Paul Schneider | 7f9344d437 | 2 years ago |
Paul Schneider | f46ca00de9 | 2 years ago |
Paul Schneider | fcea41f8c1 | 2 years ago |
Paul Schneider | 58f49af5f0 | 2 years ago |
Paul Schneider | fececb327e | 2 years ago |
Paul Schneider | 14206ac477 | 2 years ago |
Paul Schneider | fa9a12ad49 | 2 years ago |
Paul Schneider | 7f9984b059 | 2 years ago |
Paul Schneider | 2dcf1a2806 | 2 years ago |
Paul Schneider | a84e1d9750 | 2 years ago |
Paul Schneider | 97eba2390e | 2 years ago |
Paul Schneider | 6c9f29bc56 | 2 years ago |
Paul Schneider | 2d5438c943 | 2 years ago |
Paul Schneider | 519a4fbd46 | 2 years ago |
Paul Schneider | a11bab759e | 2 years ago |
Paul Schneider | d7f0a5db36 | 2 years ago |
Paul Schneider | 5d59760a77 | 2 years ago |
Paul Schneider | 3e09afcbfe | 2 years ago |
Paul Schneider | 8fa4c04367 | 2 years ago |
Paul Schneider | 60e4ca8c54 | 2 years ago |
Paul Schneider | da92b9dbec | 2 years ago |
Paul Schneider | 6194e185b9 | 2 years ago |
Paul Schneider | 5c1a49811a | 2 years ago |
Paul Schneider | 328f6f166a | 2 years ago |
Paul Schneider | 4191513eef | 2 years ago |
Paul Schneider | 217cc49019 | 2 years ago |
Paul Schneider | a4a1c6e271 | 2 years ago |
Paul Schneider | c06f518836 | 2 years ago |
Paul Schneider | edc9628b67 | 2 years ago |
Paul Schneider | 4bb43877c7 | 2 years ago |
Paul Schneider | ce8b7bcdb3 | 2 years ago |
Paul Schneider | 67ec19184b | 2 years ago |
Paul Schneider | 57609e6ed3 | 2 years ago |
Paul Schneider | b46e786ace | 2 years ago |
Paul Schneider | 423f9c15b3 | 2 years ago |
Paul Schneider | 6d21d7370c | 2 years ago |
Paul Schneider | ee07affbbd | 2 years ago |
Paul Schneider | cba0720150 | 2 years ago |
Paul Schneider | a2d91e072f | 2 years ago |
Paul Schneider | 1befc2e053 | 2 years ago |
Paul Schneider | df55836c58 | 3 years ago |
Paul Schneider | cd3629a5a0 | 3 years ago |
Paul Schneider | 51a08dec9a | 3 years ago |
Paul Schneider | 386eec262d | 3 years ago |
Paul Schneider | 45d6c22d1e | 3 years ago |
Paul Schneider | 225c8ef588 | 3 years ago |
Paul Schneider | 290a3047b5 | 3 years ago |
Paul Schneider | ec70927830 | 3 years ago |
Paul Schneider | 9f338ca09f | 3 years ago |
Paul Schneider | cfd63fe68d | 3 years ago |
Paul Schneider | f33ca22255 | 3 years ago |
Paul Schneider | e6f4349621 | 3 years ago |
Paul Schneider | 903f5157d2 | 3 years ago |
Paul Schneider | 066c038e4d | 3 years ago |
Paul Schneider | 95aae91156 | 3 years ago |
Paul Schneider | 6dd76ac1a5 | 3 years ago |
Paul Schneider | 459f8ea422 | 3 years ago |
Paul Schneider | 5607c53329 | 3 years ago |
Paul Schneider | 71de903f13 | 3 years ago |
Paul Schneider | a92bee32e1 | 3 years ago |
Paul Schneider | 7a835c5c95 | 3 years ago |
Paul Schneider | f918d26273 | 3 years ago |
Paul Schneider | 25d545e327 | 3 years ago |
Paul Schneider | 57feb53e82 | 3 years ago |
Paul Schneider | b7dae240cd | 3 years ago |
Paul Schneider | d8bfdc293d | 3 years ago |
Paul Schneider | f6fa7a0ec9 | 3 years ago |
Paul Schneider | 55e407d951 | 3 years ago |
Paul Schneider | cdb9a26d2c | 3 years ago |
Paul Schneider | 504f431937 | 3 years ago |
Paul Schneider | 7da74b0dfb | 3 years ago |
Paul Schneider | 6520d8e4cc | 3 years ago |
Paul Schneider | 55b74a584a | 3 years ago |
Paul Schneider | 0ec9889e96 | 3 years ago |
Paul Schneider | b17ee8be75 | 3 years ago |
Paul Schneider | f6f3473346 | 3 years ago |
Paul Schneider | ae114c68db | 3 years ago |
Paul Schneider | 5f0dfee768 | 3 years ago |
Paul Schneider | 9ee058e1c8 | 3 years ago |
Paul Schneider | 30d81c06df | 3 years ago |
Paul Schneider | 3845e2c9c4 | 3 years ago |
Paul Schneider | 74427cc15e | 3 years ago |
Paul Schneider | 5c188b57fc | 3 years ago |
Paul Schneider | 74ffc8e83e | 3 years ago |
Paul Schneider | 7f0518ec82 | 3 years ago |
Paul Schneider | 58750587d0 | 3 years ago |
Paul Schneider | bd1c47e7c6 | 3 years ago |
Paul Schneider | f7b375ad50 | 3 years ago |
Paul Schneider | 558d5fc8ae | 3 years ago |
Paul Schneider | fff4599ff4 | 3 years ago |
Paul Schneider | e356636539 | 3 years ago |
Paul Schneider | 1aef7ce614 | 3 years ago |
Paul Schneider | 82cec8eece | 3 years ago |
Paul Schneider | cd7c0be03d | 3 years ago |
Paul Schneider | a345992351 | 3 years ago |
Paul Schneider | 5e74b24439 | 3 years ago |
Paul Schneider | 451d810ade | 3 years ago |
Paul Schneider | 6f82a0a00f | 3 years ago |
Paul Schneider | 48ca2df19e | 3 years ago |
Paul Schneider | 355b2d4c7c | 3 years ago |
Paul Schneider | d33a19d35f | 3 years ago |
Paul Schneider | 5a783edac2 | 3 years ago |
Paul Schneider | 32d25733af | 3 years ago |
Paul Schneider | 709e1433bb | 3 years ago |
Paul Schneider | 476d35ae8a | 3 years ago |
Paul Schneider | 5de53a3cba | 3 years ago |
Paul Schneider | ae6abc104a | 3 years ago |
Paul Schneider | eba75d0db4 | 3 years ago |
Paul Schneider | aaa49788dc | 3 years ago |
Paul Schneider | b8809deaa1 | 3 years ago |
Paul Schneider | 6fcad7c252 | 3 years ago |
Paul Schneider | 2c31ffb7c4 | 3 years ago |
Paul Schneider | 58501329ac | 3 years ago |
Paul Schneider | 8c25889e88 | 3 years ago |
Paul Schneider | 90b8913e98 | 3 years ago |
Paul Schneider | c88dccd950 | 3 years ago |
Paul Schneider | 963ce8579c | 3 years ago |
Paul Schneider | 1c1964eb2c | 3 years ago |
Paul Schneider | a5d6e08945 | 3 years ago |
Paul Schneider | 21b51d4cbd | 3 years ago |
Paul Schneider | 27634c3159 | 3 years ago |
Paul Schneider | a11c30e782 | 3 years ago |
Paul Schneider | 5cb35f54d5 | 3 years ago |
Paul Schneider | 981f3209e0 | 3 years ago |
Paul Schneider | 3fa1241ea2 | 3 years ago |
Paul Schneider | c14adcdd80 | 3 years ago |
Paul Schneider | 25069e5aa2 | 3 years ago |
Paul Schneider | b341fdfa4d | 3 years ago |
Paul Schneider | e88763df09 | 3 years ago |
Paul Schneider | c456a28282 | 3 years ago |
Paul Schneider | f7cfeeba8d | 3 years ago |
Paul Schneider | 7752620bef | 3 years ago |
Paul Schneider | 4fa03c5a1d | 3 years ago |
Paul Schneider | 61ba3b2bf8 | 3 years ago |
Paul Schneider | 1266dd54db | 3 years ago |
Paul Schneider | be30ef3c25 | 3 years ago |
Paul Schneider | 41fbe54638 | 3 years ago |
Paul Schneider | d80271dcbf | 3 years ago |
Paul Schneider | 3a59b8304a | 3 years ago |
Paul Schneider | f6a27fa919 | 3 years ago |
Paul Schneider | e51da7f359 | 3 years ago |
Paul Schneider | e4511a8aaa | 3 years ago |
Paul Schneider | 9575dd2754 | 3 years ago |
Paul Schneider | 54a900c361 | 3 years ago |
Paul Schneider | efb004ee08 | 3 years ago |
Paul Schneider | e0a3ec0bd5 | 3 years ago |
Paul Schneider | d7cabaad8b | 3 years ago |
Paul Schneider | 9adad9a327 | 3 years ago |
Paul Schneider | 3d3a6cf017 | 3 years ago |
Paul Schneider | 2f4ff1e774 | 3 years ago |
Paul Schneider | 9289b3af91 | 3 years ago |
Paul Schneider | 90cfc29492 | 3 years ago |
Paul Schneider | c83ff84370 | 3 years ago |
Paul Schneider | d117f26c77 | 3 years ago |
Paul Schneider | c2f38800aa | 3 years ago |
Paul Schneider | a8c9b7619f | 3 years ago |
Paul Schneider | 97dec15153 | 3 years ago |
Paul Schneider | 512495d10b | 3 years ago |
Paul Schneider | 5bbcf9cb29 | 3 years ago |
Paul Schneider | b6098c28a6 | 3 years ago |
Paul Schneider | 36e1137e50 | 3 years ago |
Paul Schneider | 3086cc65c4 | 3 years ago |
Paul Schneider | 4cec5d0229 | 3 years ago |
Paul Schneider | 61dc82df5b | 3 years ago |
Paul Schneider | db6f514fb5 | 3 years ago |
Paul Schneider | cc675844b6 | 3 years ago |
Paul Schneider | f95765f541 | 3 years ago |
Paul Schneider | e5d3ba36cc | 3 years ago |
Paul Schneider | ffb7cad00a | 3 years ago |
Paul Schneider | 6a59f776d5 | 3 years ago |
Paul Schneider | 93394b3e82 | 3 years ago |
Paul Schneider | d063f10da5 | 3 years ago |
Paul Schneider | bb02706773 | 3 years ago |
Paul Schneider | 915736c4e2 | 3 years ago |
Paul Schneider | b550f05c4f | 3 years ago |
Paul Schneider | dd4dd9321b | 3 years ago |
Paul Schneider | a238bd8cbf | 3 years ago |
Paul Schneider | fb822b6aaf | 3 years ago |
Paul Schneider | ffd1dca16e | 3 years ago |
Paul Schneider | 198189ab09 | 3 years ago |
Paul Schneider | ccbdd155f3 | 3 years ago |
Paul Schneider | 445ea24dd2 | 3 years ago |
Paul Schneider | 48df937b7f | 3 years ago |
Paul Schneider | 10b1fd0748 | 3 years ago |
Paul Schneider | 15fa91138d | 3 years ago |
Paul Schneider | dd6d83cf06 | 3 years ago |
Paul Schneider | 749eb645d5 | 3 years ago |
Paul Schneider | 838de379fd | 3 years ago |
Paul Schneider | dc37c9a9f0 | 3 years ago |
Paul Schneider | a2f26f1e8e | 3 years ago |
Paul Schneider | 1b2d850522 | 3 years ago |
Paul Schneider | ec5bd7ca1f | 3 years ago |
Paul Schneider | cede04a33e | 3 years ago |
Paul Schneider | 5b6d74d8ee | 4 years ago |
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0"?>
|
||||
<project name="Isn" default="clean" basedir=".">
|
||||
<description>The Hello World of build files.</description>
|
||||
<property name="debug" value="true" overwrite="false" />
|
||||
|
||||
<target name="clean" description="remove all generated files">
|
||||
<delete dir="src/isn.abst/bin/" failonerror="false" />
|
||||
<delete dir="src/isn.abst/obj/" failonerror="false" />
|
||||
<delete dir="src/isn/bin/" failonerror="false" />
|
||||
<delete dir="src/isn/obj/" failonerror="false" />
|
||||
<delete dir="src/isnd/bin/" failonerror="false" />
|
||||
<delete dir="src/isnd/obj/" failonerror="false" />
|
||||
<delete dir="test/isn.tests/bin/" failonerror="false" />
|
||||
<delete dir="test/isn.tests/obj/" failonerror="false" />
|
||||
<delete dir="test/isnd.tests/bin/" failonerror="false" />
|
||||
<delete dir="test/isnd.tests/obj/" failonerror="false" />
|
||||
</target>
|
||||
<target name="build" description="build all">
|
||||
<exec program="dotnet" commandline="build" />
|
||||
</target>
|
||||
<target name="test" description="build all">
|
||||
<exec program="dotnet" commandline="test" />
|
||||
</target>
|
||||
</project>
|
@ -1,3 +1,23 @@
|
||||
.sass-cache/
|
||||
/src/isnd/bin/
|
||||
/src/isnd/obj/
|
||||
/src/isn/obj
|
||||
/src/isn/bin
|
||||
/src/isn/.vscode/
|
||||
/test/isnd.tests/obj/
|
||||
/test/isnd.tests/bin/
|
||||
/packages/
|
||||
/bin/
|
||||
/obj/
|
||||
bower_components/
|
||||
/test/isn.tests/bin
|
||||
/test/isn.tests/obj/
|
||||
appsettings.Testing.json
|
||||
appsettings.Development.json
|
||||
/wwwroot/.sass-cache/
|
||||
/src/isnd/wwwroot/.sass-cache/
|
||||
/src/isn.abst/bin
|
||||
/src/isn.abst/obj
|
||||
/src/isnd/packages/
|
||||
/test/data/test-isn/bin/
|
||||
/test/data/test-isn/obj
|
||||
.fake
|
||||
artifacts/
|
||||
|
@ -0,0 +1,66 @@
|
||||
# You can override the included template(s) by including variable overrides
|
||||
# See https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
|
||||
# Note that environment variables can be set in several places
|
||||
# See https://docs.gitlab.com/ee/ci/variables/#priority-of-environment-variables
|
||||
image: busybox:latest
|
||||
before_script:
|
||||
- dotnet restore
|
||||
- dotnet nuget remove source gitlab || true
|
||||
nonreg:
|
||||
tags:
|
||||
- dotnet
|
||||
stage: test
|
||||
environment: Development
|
||||
script:
|
||||
- |
|
||||
echo "setting : $ISND_TESTING_SETTINGS"
|
||||
dotnet build
|
||||
cat $ISND_TESTING_SETTINGS > test/isnd.tests/appsettings.json
|
||||
dotnet test
|
||||
publish:
|
||||
tags:
|
||||
- dotnet
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- nonreg
|
||||
artifacts:
|
||||
paths:
|
||||
- src/isnd/bin/Release/netcoreapp2.1/publish/
|
||||
when: always
|
||||
script:
|
||||
- dotnet publish --configuration Release
|
||||
deploy-to-gitlab:
|
||||
tags:
|
||||
- dotnet
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- nonreg
|
||||
artifacts:
|
||||
paths:
|
||||
- src/*/bin/Release/*.nupkg
|
||||
when: always
|
||||
script:
|
||||
- dotnet pack -c Release
|
||||
- dotnet nuget add source --name gitlab --username gitlab+deploy-token-2 --password
|
||||
$CI_JOB_TOKEN --store-password-in-clear-text "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json"
|
||||
- dotnet nuget push src/*/bin/Release/*.nupkg -s gitlab
|
||||
deploy-to-isn:
|
||||
stage: deploy
|
||||
tags:
|
||||
- dotnet
|
||||
artifacts:
|
||||
paths:
|
||||
- src/*/bin/Release/*.nupkg
|
||||
when: always
|
||||
script:
|
||||
- dotnet pack --configuration Release --no-restore
|
||||
- cd src/isn
|
||||
- find -name "*.nupkg" -exec dotnet run push -s $ISNSOURCE -k $ISNAPIKEY {} \;
|
||||
environment:
|
||||
name: production
|
||||
url: $ISNSOURCE
|
||||
dependencies:
|
||||
- nonreg
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
@ -1,29 +1,48 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
|
||||
// Pointez pour afficher la description des attributs existants.
|
||||
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (web)",
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach"
|
||||
},
|
||||
{
|
||||
"name": "push",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/bin/Debug/netcoreapp2.0/nuget-host.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"program": "${workspaceFolder}/src/isn/bin/Debug/netcoreapp2.1/isn.dll",
|
||||
"requireExactSource": false,
|
||||
"args": [
|
||||
"push", "/home/paul/Nupkgs/Yavsc.Abstract.1.0.8.nupkg"
|
||||
],
|
||||
"cwd": "${workspaceFolder}/src/isn",
|
||||
"stopAtEntry": false,
|
||||
"OS-COMMENT5": "Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser",
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\\\bNow listening on:\\\\s+(https?://\\\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "web",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/src/isnd/bin/Debug/netcoreapp2.1/isnd.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/src/isnd",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false,
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
{
|
||||
"omnisharp.msbuild": true,
|
||||
"dotnet-test-explorer.testProjectPath": "**/*tests.csproj",
|
||||
"dotnet-test-explorer.runInParallel": false,
|
||||
"dotnet-test-explorer.showCodeLens": true,
|
||||
"dotnet-test-explorer.testArguments": "",
|
||||
"nxunitExplorer.modules": [
|
||||
"test/i*/bin/Debug/*/*.tests.dll"
|
||||
],
|
||||
"nxunitExplorer.skippattern": "",
|
||||
"dotnetCoreExplorer.runEnvVars": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Testing"
|
||||
},
|
||||
"dotnetCoreExplorer.searchpatterns": "test/**/bin/**/*.tests.{dll,exe}",
|
||||
"sqltools.connections": [
|
||||
{
|
||||
"previewLimit": 50,
|
||||
"server": "localhost",
|
||||
"port": 5432,
|
||||
"driver": "PostgreSQL",
|
||||
"name": "isndev",
|
||||
"group": "isn",
|
||||
"database": "dotnetmvc",
|
||||
"username": "dotnetmvc",
|
||||
"password": "RvJa=y#b/tfg"
|
||||
},
|
||||
{
|
||||
"previewLimit": 50,
|
||||
"server": "localhost",
|
||||
"port": 5432,
|
||||
"askForPassword": true,
|
||||
"driver": "PostgreSQL",
|
||||
"name": "isnd",
|
||||
"group": "isn",
|
||||
"database": "webid",
|
||||
"username": "webid"
|
||||
},
|
||||
{
|
||||
"previewLimit": 50,
|
||||
"server": "localhost",
|
||||
"port": 5432,
|
||||
"askForPassword": true,
|
||||
"driver": "PostgreSQL",
|
||||
"name": "isnddev",
|
||||
"group": "isn",
|
||||
"database": "isnd",
|
||||
"username": "paul"
|
||||
}
|
||||
],
|
||||
"omnisharp.disableMSBuildDiagnosticWarning": true,
|
||||
"omnisharp.enableRoslynAnalyzers": false
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace {{namespace}}
|
||||
{
|
||||
public class {{name}}
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export class {{name}} {
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
Imports System
|
||||
|
||||
Namespace {{namespace}}
|
||||
|
||||
Public Class {{name}}
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
@ -0,0 +1,3 @@
|
||||
export default {{name}} {
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace {{namespace}}
|
||||
{
|
||||
public enum {{name}}
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
using System;
|
||||
|
||||
namespace {{namespace}}
|
||||
{
|
||||
public interface {{name}}
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
export interface {{name}} {
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
{
|
||||
"templates": [
|
||||
{
|
||||
"name": "Class",
|
||||
"extension": "cs",
|
||||
"file": "./class.cs-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
},
|
||||
{
|
||||
"name": "Interface",
|
||||
"extension": "cs",
|
||||
"file": "./interface.cs-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
},
|
||||
{
|
||||
"name": "Enum",
|
||||
"extension": "cs",
|
||||
"file": "./enum.cs-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
},
|
||||
{
|
||||
"name": "Class",
|
||||
"extension": "ts",
|
||||
"file": "./class.ts-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
},
|
||||
{
|
||||
"name": "Interface",
|
||||
"extension": "ts",
|
||||
"file": "./interface.ts-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
},
|
||||
{
|
||||
"name": "Default",
|
||||
"extension": "ts",
|
||||
"file": "./default.ts-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
},
|
||||
{
|
||||
"name": "Class",
|
||||
"extension": "vb",
|
||||
"file": "./class.vb-template",
|
||||
"parameters": "./template-parameters.js"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
var path = require("path");
|
||||
|
||||
module.exports = function(filename, projectPath, folderPath) {
|
||||
var namespace = "Unknown";
|
||||
if (projectPath) {
|
||||
namespace = path.basename(projectPath, path.extname(projectPath));
|
||||
if (folderPath) {
|
||||
namespace += "." + folderPath.replace(path.dirname(projectPath), "").substring(1).replace(/[\\\/]/g, ".");
|
||||
}
|
||||
namespace = namespace.replace(/[\\\-]/g, "_");
|
||||
}
|
||||
|
||||
return {
|
||||
namespace: namespace,
|
||||
name: path.basename(filename, path.extname(filename))
|
||||
}
|
||||
};
|
@ -1,113 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NuGet.Packaging;
|
||||
|
||||
namespace nuget_host.Controllers
|
||||
{
|
||||
public class PackagesController : Controller
|
||||
{
|
||||
private ILogger<PackagesController> logger;
|
||||
|
||||
public PackagesController(ILoggerFactory loggerFactory)
|
||||
{
|
||||
logger = loggerFactory.CreateLogger<PackagesController>();
|
||||
|
||||
}
|
||||
|
||||
[HttpPut("packages/{*spec}")]
|
||||
public IActionResult Put(string spec)
|
||||
{
|
||||
string path = null;
|
||||
if (string.IsNullOrEmpty(spec))
|
||||
{
|
||||
var clientVersionId = Request.Headers["X-NuGet-Client-Version"];
|
||||
ViewData["nuget client "] = "nuget {clientVersionId}";
|
||||
foreach (var file in Request.Form.Files)
|
||||
{
|
||||
string initpath = "package.nupkg";
|
||||
using (FileStream fw = new FileStream(initpath, FileMode.Create))
|
||||
{
|
||||
file.CopyTo(fw);
|
||||
}
|
||||
|
||||
using (FileStream fw = new FileStream(initpath, FileMode.Open))
|
||||
{
|
||||
var archive = new System.IO.Compression.ZipArchive(fw);
|
||||
foreach (var filename in archive.GetFiles())
|
||||
{
|
||||
if (filename.EndsWith(".nuspec"))
|
||||
{
|
||||
// var entry = archive.GetEntry(filename);
|
||||
var specstr = archive.OpenFile(filename);
|
||||
NuspecReader reader = new NuspecReader(specstr);
|
||||
|
||||
string pkgdesc = reader.GetDescription();
|
||||
string pkgid = reader.GetId();
|
||||
var version = reader.GetVersion();
|
||||
|
||||
|
||||
path = Path.Combine(Startup.SourceDir,
|
||||
Path.Combine(pkgid,
|
||||
Path.Combine(version.ToFullString(),
|
||||
$"{pkgid}-{version}.nupkg")));
|
||||
var source = new FileInfo(initpath);
|
||||
var dest = new FileInfo(path);
|
||||
var destdir = new DirectoryInfo(dest.DirectoryName);
|
||||
if (dest.Exists)
|
||||
return BadRequest(new {error = "existant"});
|
||||
|
||||
if (!destdir.Exists) destdir.Create();
|
||||
source.MoveTo(path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewData["spec"] = spec;
|
||||
// TODO Assert valid sem ver spec
|
||||
var filelst = new DirectoryInfo(Startup.SourceDir);
|
||||
var fi = new FileInfo(spec);
|
||||
var lst = filelst.GetFiles(fi.Name + "*.nupkg");
|
||||
ViewData["lst"] = lst.Select(entry => entry.Name);
|
||||
}
|
||||
return Ok(ViewData);
|
||||
}
|
||||
|
||||
[HttpGet("Packages/{spec}")]
|
||||
public IActionResult Index(string spec)
|
||||
{
|
||||
if (string.IsNullOrEmpty(spec))
|
||||
{
|
||||
ViewData["warn"] = "no spec";
|
||||
/*
|
||||
usr/lib/mono/msbuild/Current/bin/NuGet.targets(128,5): error : Failed to retrieve information about 'Microsoft.VisualStudio.Web.CodeGeneration.Tools' from remote source 'http://localhost:5000/Packages/FindPackagesById()?id='Microsoft.VisualStudio.Web.CodeGeneration.Tools'&semVerLevel=2.0.0'. [/home/paul/workspace/nuget-host/nuget-host.csproj]
|
||||
|
||||
|
||||
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewData["spec"] = spec;
|
||||
// TODO Assert valid sem ver spec
|
||||
var filelst = new DirectoryInfo(Startup.SourceDir);
|
||||
var fi = new FileInfo(spec);
|
||||
var lst = filelst.GetDirectories(spec);
|
||||
ViewData["lst"] = lst.Select(entry => entry.Name);
|
||||
}
|
||||
return Ok(ViewData);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
mode: Mainline
|
||||
branches: {}
|
||||
ignore:
|
||||
sha: []
|
||||
merge-message-formats: {}
|
@ -0,0 +1,14 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
@ -1,11 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace nuget_host.Models
|
||||
{
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
}
|
||||
}
|
@ -1,9 +1,125 @@
|
||||
# Usage
|
||||
# ISN
|
||||
|
||||
[![pipeline status](http://gitlab.pschneider.fr/Paul/nuget-host/badges/main/pipeline.svg)](http://gitlab.pschneider.fr/Paul/nuget-host/-/commits/main)
|
||||
|
||||
## Usage
|
||||
|
||||
````sh
|
||||
|
||||
nuget sources remove -Name dev
|
||||
nuget sources add -Name dev -Source Http://localhost:5000/packages
|
||||
nuget push your-versionned.nupkg -ApiKey 15d0dda1-4028-4896-9f1a-188817da23f4 -Source http://localhost:5000/packages
|
||||
dotnet user-secrets set ConnectionStrings:DefaultConnection "Server=<lame-pgserver>;Port=<lame-pgport>;Database=<lame-dbname>;Username=<lame-dbusername>;Password=<lame-dbpass>;"
|
||||
|
||||
isnd&
|
||||
|
||||
# get an api-key from <http://localhost:5000/ApkKeys>
|
||||
|
||||
isn push -k <lame-api-key> -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
|
||||
````
|
||||
|
||||
## Installation
|
||||
|
||||
Depuis le dossier de la solution, compiler la solution :
|
||||
|
||||
````bash
|
||||
dotnet build /restore -c Release
|
||||
dotnet publish -c Release
|
||||
````
|
||||
|
||||
### Déploiement
|
||||
|
||||
````bash
|
||||
sudo mkdir -p /srv/www/isnd
|
||||
sudo cp -a src/isnd/bin/Release/netcoreapp2.1/publish/* /srv/www/isnd
|
||||
sudo cp contrib/isnd /etc/init.d/isnd
|
||||
sudo chmod +x /etc/init.d/isnd
|
||||
sudo chown -R www-data.www-data /srv/www/isnd
|
||||
sudo systemctl daemon-reload
|
||||
````
|
||||
|
||||
* Créer une base de donées Postgresql,
|
||||
* ajuster un fichier de configuration `/srv/www/isnd/appsettings.Production.json`
|
||||
* Démarrer le serveur :
|
||||
|
||||
````bash
|
||||
sudo systemctl start isnd
|
||||
````
|
||||
|
||||
* Activation du serveur :
|
||||
|
||||
````bash
|
||||
sudo systemctl enable isnd
|
||||
````
|
||||
|
||||
|
||||
### Installation du client
|
||||
|
||||
````bash
|
||||
sudo mkdir /usr/local/lib/isn
|
||||
sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn
|
||||
sudo chown -R root.root /usr/local/lib/isn
|
||||
sudo ln -s /usr/local/lib/isn/isn /usr/local/bin/isn
|
||||
````
|
||||
|
||||
### Mises à jour
|
||||
|
||||
````bash
|
||||
# compiler tout
|
||||
dotnet build -c Release
|
||||
dotnet publish -c Release -f netcoreapp2.1 src/isnd
|
||||
# MAJ du serveur
|
||||
sudo systemctl stop isnd
|
||||
sudo cp -a src/isnd/bin/Release/netcoreapp2.1/publish/* /srv/www/isnd
|
||||
sudo systemctl start isnd
|
||||
# MAJ du client
|
||||
sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn
|
||||
sudo chown -R root.root /usr/local/lib/isn
|
||||
````
|
||||
|
||||
## TODO
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
"@id": "https://api.nuget.org/v3/registration5-semver1/",
|
||||
"@type": "RegistrationsBaseUrl",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored"
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
"@id": "https://api.nuget.org/v3-flatcontainer/",
|
||||
"@type": "PackageBaseAddress/3.0.0",
|
||||
"comment": "Base URL of where NuGet packages are stored, in the format https://api.nuget.org/v3-flatcontainer/{id-lower}/{version-lower}/{id-lower}.{version-lower}.nupkg"
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
"@id": "https://api.nuget.org/v3/registration5-semver1/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-rc",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by RC clients. This base URL does not include SemVer 2.0.0 packages."
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
"@id": "https://api.nuget.org/v3/registration5-semver1/",
|
||||
"@type": "RegistrationsBaseUrl/3.0.0-beta",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored used by Beta clients. This base URL does not include SemVer 2.0.0 packages."
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
"@id": "https://www.nuget.org/packages/{id}/{version}?_src=template",
|
||||
"@type": "PackageDetailsUriTemplate/5.1.0",
|
||||
"comment": "URI template used by NuGet Client to construct details URL for packages"
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
"@id": "https://api.nuget.org/v3/registration5-gz-semver2/",
|
||||
"@type": "RegistrationsBaseUrl/3.6.0",
|
||||
"comment": "Base URL of Azure storage where NuGet package registration info is stored in GZIP format. This base URL includes SemVer 2.0.0 packages."
|
||||
|
||||
},
|
||||
|
||||
````
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="1"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="2"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="3"></li>
|
||||
</ol>
|
||||
<div class="carousel-inner" role="listbox">
|
||||
<div class="item active">
|
||||
<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how to build ASP.NET apps that can run anywhere.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
There are powerful new features in Visual Studio for building modern web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Bring in libraries from NuGet and npm, and automate tasks using Grunt or Gulp.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<h2>Application uses</h2>
|
||||
<ul>
|
||||
<li>Sample pages using ASP.NET Core MVC</li>
|
||||
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>How to</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Overview</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Run & Deploy</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
@ -1,22 +0,0 @@
|
||||
@model ErrorViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
|
||||
</p>
|
@ -1,71 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - nuget_host</title>
|
||||
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
||||
</environment>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">nuget_host</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
|
||||
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
|
||||
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© 2018 - nuget_host</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<environment include="Development">
|
||||
<script src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
|
||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
||||
asp-fallback-test="window.jQuery"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
|
||||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
|
||||
</script>
|
||||
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
@ -1,3 +0,0 @@
|
||||
@using nuget_host
|
||||
@using nuget_host.Models
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
/usr/bin/mono /usr/local/lib/isn/isn.exe $*
|
@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
### BEGIN INIT INFO
|
||||
# Provides: isnd
|
||||
# Required-Start: $local_fs $network $named $time $syslog $postgresql
|
||||
# Required-Stop: $local_fs $network $named $time $syslog $postgresql
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Description: Script to run asp.net 5 application in background
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Ivan Derevianko aka druss <drussilla7@gmail.com>
|
||||
# Modified by: Paul Schneider <redienhcs.luap@gmail.com>
|
||||
|
||||
. /lib/init/vars.sh
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
NAME=isnd
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
TMP_SAVE_runlevel_VAR=$runlevel
|
||||
unset runlevel
|
||||
|
||||
running() {
|
||||
if [ -f $PIDFILE ]
|
||||
then
|
||||
PID=$(cat $PIDFILE)
|
||||
if kill -0 $PID 2>/dev/null
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
export WWW_USER=www-data
|
||||
export ROOT=/srv/www/${NAME}
|
||||
export DESC="$NAME"
|
||||
export PIDFILE=/var/run/kestrel-${NAME}.pid
|
||||
export LOGDIR=/var/log
|
||||
export DOTNET_CLI_HOME=$ROOT
|
||||
export ASPDOTNETCORE_ENVIRONMENT=Production
|
||||
export ASPDOTNETCORE_LOGLEVEL=Information
|
||||
status() {
|
||||
if running;
|
||||
then
|
||||
echo "Service running $DESC ($NAME; pid: $PID)"
|
||||
else
|
||||
echo "Service stopped $DESC ($NAME)"
|
||||
fi
|
||||
echo WWW_USER: $WWW_USER ROOT:$ROOT DESC: $DESC NAME: $NAME PIDFILE: $PIDFILE LOGDIR=$LOGDIR
|
||||
}
|
||||
|
||||
|
||||
start() {
|
||||
if running; then
|
||||
echo "Service already running $DESC" "$NAME"
|
||||
log_end_msg 0
|
||||
else
|
||||
cd $ROOT
|
||||
log_daemon_msg "Starting service $NAME for user $WWW_USER"
|
||||
if ! start-stop-daemon -SbmCv -u $WWW_USER -p $PIDFILE -d $ROOT -g www-data -x /usr/bin/dotnet isnd.dll run > "${LOGDIR}/kestrel-${NAME}.log"
|
||||
then
|
||||
log_daemon_msg "Could not start $NAME : $?, see ${LOGDIR}/kestrel-${NAME}.log"
|
||||
log_end_msg 2
|
||||
else
|
||||
log_daemon_msg "Service $DESC started ($NAME), logs: ${LOGDIR}/kestrel-${NAME}.log"
|
||||
log_end_msg 0
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
stop() {
|
||||
if running
|
||||
then
|
||||
log_daemon_msg "Stopping service $NAME"
|
||||
start-stop-daemon -K -p "$PIDFILE"
|
||||
log_daemon_msg "$DESC stopped"
|
||||
log_end_msg 0
|
||||
else
|
||||
log_daemon_msg "$DESC Service not running"
|
||||
log_end_msg 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
esac
|
||||
|
||||
export runlevel=$TMP_SAVE_runlevel_VAR
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<apikeys>
|
||||
</apikeys>
|
||||
<packageSources>
|
||||
<add key="myIsnDev" value="http://localhost:5000/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>
|
@ -0,0 +1,2 @@
|
||||
nuget install -Verbosity detailed -Source http://localhost:5000/index.json -Prerelease Yavsc.Abstract
|
||||
nuget locals all -clear
|
@ -0,0 +1,4 @@
|
||||
= URL's
|
||||
|
||||
<http://localhost:5000/v3.4.0/registration/yavsc.abstract/index.json>
|
||||
|
@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# compiler tout
|
||||
dotnet build -c Release
|
||||
dotnet publish -c Release -f netcoreapp2.1 src/isnd
|
||||
# MAJ du serveur
|
||||
sudo systemctl stop isnd
|
||||
sudo cp -a src/isnd/bin/Release/netcoreapp2.1/publish/* /srv/www/isnd
|
||||
sudo systemctl start isnd
|
||||
# MAJ du client
|
||||
sudo cp -a src/isn/bin/Release/netcoreapp2.1/* /usr/local/lib/isn
|
||||
sudo chown -R root.root /usr/local/lib/isn
|
@ -0,0 +1,30 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"codecov.tool": {
|
||||
"version": "1.13.0",
|
||||
"commands": [
|
||||
"codecov"
|
||||
]
|
||||
},
|
||||
"gitversion.tool": {
|
||||
"version": "5.10.1",
|
||||
"commands": [
|
||||
"dotnet-gitversion"
|
||||
]
|
||||
},
|
||||
"gitreleasemanager.tool": {
|
||||
"version": "0.13.0",
|
||||
"commands": [
|
||||
"dotnet-gitreleasemanager"
|
||||
]
|
||||
},
|
||||
"Wyam2.Tool": {
|
||||
"version": "3.0.0-rc3",
|
||||
"commands": [
|
||||
"wyam2"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
{
|
||||
"dotnet": {
|
||||
"enabled": false
|
||||
},
|
||||
"msbuild": {
|
||||
"enabled": true
|
||||
},
|
||||
"Dnx": {
|
||||
"enabled": false
|
||||
},
|
||||
"Script": {
|
||||
"enabled": false
|
||||
},
|
||||
"fileOptions": {
|
||||
"systemExcludeSearchPatterns": [
|
||||
"**/bin/**/*",
|
||||
"**/obj/**/*",
|
||||
"**/node_modules/**/*"
|
||||
],
|
||||
"userExcludeSearchPatterns": []
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using isn.abst;
|
||||
|
||||
namespace isnd.Entities
|
||||
{
|
||||
public static class ApiConfig
|
||||
{
|
||||
public const string Publish = "put";
|
||||
public const string Index = "index";
|
||||
public const string IndexDotJson = Index + ".json";
|
||||
public const string Catalog = "catalog";
|
||||
public const string CatalogPage = "catalog-page";
|
||||
public const string GetPackage = Constants.PaquetFileEstension;
|
||||
public const string GetVersion = "version";
|
||||
public const string Search = "search";
|
||||
public const string AutoComplete = "autocomplete";
|
||||
public const string CatalogLeaf = "catalog-leaf";
|
||||
public const string Delete = "delete";
|
||||
public const string Registration = "registration";
|
||||
internal const string GetNuspec = Constants.SpecFileEstension;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn.Abstract
|
||||
{
|
||||
public class ApiIndexViewModel
|
||||
{
|
||||
[JsonProperty("version")]
|
||||
public string Version { get; set; }
|
||||
|
||||
[JsonProperty("resources")]
|
||||
public Resource[] Resources { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace isn.abst
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const string PaquetFileEstension = "nupkg";
|
||||
public const string SpecFileEstension = "nuspec";
|
||||
public const string JsonFileEstension = "json";
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn.Abstract
|
||||
{
|
||||
public class Resource
|
||||
{
|
||||
[JsonProperty("@id")]
|
||||
public string Id {get; set; }
|
||||
|
||||
[JsonProperty("@type")]
|
||||
public string Type {get; set; }
|
||||
|
||||
[JsonProperty("comment")]
|
||||
public string Comment {get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
|
||||
namespace isnd.Attributes
|
||||
{
|
||||
public class SafeNameAttribute : ValidationAttribute
|
||||
{
|
||||
public override bool IsValid(object value)
|
||||
{
|
||||
if (!(value is string))
|
||||
return false;
|
||||
string str = value as string;
|
||||
if (str.Length>126) return false;
|
||||
if (str.Any(c => !char.IsLetterOrDigit(c)
|
||||
&& !"-_.".Contains(c))) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
namespace isn
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
internal const string ClientVersion = "isn v1.0";
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public interface IDataProtector
|
||||
{
|
||||
string Protect(string data);
|
||||
string UnProtect(string data);
|
||||
}
|
||||
|
||||
public class DefaultDataProtector : IDataProtector
|
||||
{
|
||||
private byte delta = 145;
|
||||
|
||||
public DefaultDataProtector()
|
||||
{
|
||||
|
||||
}
|
||||
public string Protect(string data)
|
||||
{
|
||||
List<Byte> protd = new List<byte>();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (byte c in Encoding.UTF8.GetBytes(data))
|
||||
{
|
||||
protd.Add((byte) (c ^ delta));
|
||||
}
|
||||
return System.Convert.ToBase64String(protd.ToArray());
|
||||
}
|
||||
|
||||
public string UnProtect(string data)
|
||||
{
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<byte> unps = new List<byte>();
|
||||
|
||||
foreach (byte c in System.Convert.FromBase64CharArray(data.ToCharArray(),0,data.Length))
|
||||
{
|
||||
unps.Add((byte) (c ^ delta));
|
||||
}
|
||||
return Encoding.UTF8.GetString(unps.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace isn
|
||||
{
|
||||
public class IsnSourceSettings
|
||||
{
|
||||
internal string Source { get; set; }
|
||||
|
||||
internal string[] Keys { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace isn
|
||||
{
|
||||
public class IsndErrorMessage
|
||||
{
|
||||
public int ecode { get; set; }
|
||||
public string msg { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public class SourceSettings
|
||||
{
|
||||
public string ApiKey { get; set; }
|
||||
public string Alias { get; set; }
|
||||
}
|
||||
|
||||
public class Settings
|
||||
{
|
||||
public string DataProtectionTitle {get; set; }
|
||||
public Dictionary<string, SourceSettings> Sources { get; set; }
|
||||
|
||||
public bool AutoUpdateApiKey { get; set; } = false;
|
||||
public string DefaultSource { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using isn.Abstract;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public static class SourceHelpers
|
||||
{
|
||||
public static ApiIndexViewModel GetServerResources(string url)
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
ApiIndexViewModel result = null;
|
||||
// var json = await client.GetStringAsync(new System.Uri(url));
|
||||
|
||||
Task.Run(async ()=> {
|
||||
var response = await client.GetStringAsync(url);
|
||||
result = JsonConvert.DeserializeObject<ApiIndexViewModel>(response);
|
||||
}).Wait();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public static class UploadFilesToServerUsingHttpClient
|
||||
{
|
||||
public static PushReport UploadFilesToServer(this HttpClient client, Uri uri, FileInfo fi,
|
||||
string apikey)
|
||||
{
|
||||
return UploadFilesToServerAsync(client, uri, fi, apikey).Result;
|
||||
}
|
||||
|
||||
public static async Task<PushReport> UploadFilesToServerAsync(this HttpClient client, Uri uri, FileInfo fi,
|
||||
string apikey)
|
||||
{
|
||||
|
||||
client.DefaultRequestHeaders.Add("X-NuGet-Client-Version", Constants.ClientVersion);
|
||||
client.DefaultRequestHeaders.Add("X-NuGet-ApiKey", apikey);
|
||||
|
||||
using (var multipartFormDataContent = new MultipartFormDataContent())
|
||||
{
|
||||
/* var values = new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("Id", Guid.NewGuid().ToString()),
|
||||
new KeyValuePair<string, string>("Key", "awesome"),
|
||||
new KeyValuePair<string, string>("From", "khalid@home.com")
|
||||
//other values
|
||||
};foreach (var keyValuePair in values)
|
||||
{
|
||||
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
|
||||
String.Format("\"{0}\"", keyValuePair.Key));
|
||||
} */
|
||||
multipartFormDataContent.Add(new ByteArrayContent(File.ReadAllBytes(fi.FullName)),
|
||||
'"' + "File" + '"',
|
||||
'"' + fi.Name + '"');
|
||||
|
||||
var result = await client.PutAsync(uri, multipartFormDataContent);
|
||||
|
||||
if (result.IsSuccessStatusCode)
|
||||
{
|
||||
string report = await result.Content.ReadAsStringAsync();
|
||||
Console.WriteLine(report);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
string ereport = await result.Content.ReadAsStringAsync();
|
||||
Console.WriteLine(ereport);
|
||||
}
|
||||
return new PushReport();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
|
||||
public class UploadFilesToServerUsingWebRequest
|
||||
{
|
||||
public void UploadFilesToServer(PushReport report, Uri uri, FileInfo fi,
|
||||
string apikey)
|
||||
{
|
||||
// string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
|
||||
const int TXLEN = 0x1000;
|
||||
/// the form-data file upload, properly formatted
|
||||
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
|
||||
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
// "X-NuGet-ApiKey
|
||||
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
|
||||
string fileheader = string.Format(fileheaderTemplate, "file", fi.Name, "application/octet-stream");
|
||||
byte[] fileheaderbytes = Encoding.ASCII.GetBytes(fileheader);
|
||||
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
|
||||
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
|
||||
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create(uri);
|
||||
|
||||
httpWebRequest.Method = "PUT";
|
||||
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||
httpWebRequest.AllowAutoRedirect = false;
|
||||
httpWebRequest.Headers.Add("X-NuGet-Client-Version", Constants.ClientVersion);
|
||||
httpWebRequest.Headers.Add("X-NuGet-ApiKey", apikey);
|
||||
httpWebRequest.ContentLength = boundarybytes.Length +
|
||||
fileheaderbytes.Length + fi.Length + endBoundaryBytes.Length;
|
||||
|
||||
|
||||
httpWebRequest.BeginGetRequestStream(async (result) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
|
||||
|
||||
using (Stream requestStream = request.EndGetRequestStream(result))
|
||||
{
|
||||
await WriteToStream(requestStream, boundarybytes, boundarybytes.Length);
|
||||
await WriteToStream(requestStream, fileheaderbytes, fileheaderbytes.Length);
|
||||
using (var fss = fi.OpenRead())
|
||||
{
|
||||
byte[] buffer = new byte[TXLEN];
|
||||
var form_bytes_read = fss.Read(buffer, 0, TXLEN);
|
||||
while (form_bytes_read > 0)
|
||||
{
|
||||
await WriteToStream(requestStream, buffer, form_bytes_read);
|
||||
form_bytes_read = fss.Read(buffer, 0, TXLEN);
|
||||
}
|
||||
}
|
||||
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
|
||||
requestStream.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception rex)
|
||||
{
|
||||
report.Executed = false;
|
||||
report.StackTrace = rex.StackTrace;
|
||||
report.Message = rex.Message;
|
||||
Console.Error.WriteLine("Stack trace:");
|
||||
Console.Error.WriteLine(rex.StackTrace);
|
||||
WebResponse eresp = httpWebRequest.GetResponse();
|
||||
if (!CheckResponse(eresp, report))
|
||||
throw new Exception("Invalid server response type");
|
||||
|
||||
}
|
||||
}, httpWebRequest);
|
||||
|
||||
WebResponse resp = httpWebRequest.GetResponse();
|
||||
if (!CheckResponse(resp, report)) throw new Exception("Invalid server response type");
|
||||
if (Program.Settings.AutoUpdateApiKey)
|
||||
Program.EnsureKeyStored();
|
||||
|
||||
}
|
||||
|
||||
static bool CheckResponse(WebResponse resp, PushReport report)
|
||||
{
|
||||
Stream stream = resp.GetResponseStream();
|
||||
StreamReader re = new StreamReader(stream);
|
||||
if (resp is HttpWebResponse)
|
||||
{
|
||||
if (resp.ContentType == "text/json")
|
||||
{
|
||||
String json = re.ReadToEnd();
|
||||
report.Message = json;
|
||||
var hrep = resp as HttpWebResponse;
|
||||
report.StatusCode = hrep.StatusCode.ToString();
|
||||
report.OK = hrep.StatusCode == HttpStatusCode.Accepted
|
||||
|| hrep.StatusCode == HttpStatusCode.OK;
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates HTTP POST request & uploads database to server. Author : Farhan Ghumra
|
||||
/// </summary>
|
||||
internal async Task UploadFilesToServerAsync(PushReport report, Uri uri, FileInfo fi,
|
||||
string apikey)
|
||||
{
|
||||
// string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
|
||||
const int TXLEN = 0x1000;
|
||||
/// the form-data file upload, properly formatted
|
||||
string fileheaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\";\r\nContent-Type: {2}\r\n\r\n";
|
||||
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
// "X-NuGet-ApiKey
|
||||
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
|
||||
string fileheader = string.Format(fileheaderTemplate, "file", fi.Name, "application/octet-stream");
|
||||
byte[] fileheaderbytes = Encoding.ASCII.GetBytes(fileheader);
|
||||
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
|
||||
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
|
||||
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
|
||||
|
||||
httpWebRequest.Method = "PUT";
|
||||
httpWebRequest.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||
httpWebRequest.AllowAutoRedirect = false;
|
||||
httpWebRequest.Headers.Add("X-NuGet-Client-Version", Constants.ClientVersion);
|
||||
httpWebRequest.Headers.Add("X-NuGet-ApiKey", apikey);
|
||||
httpWebRequest.ContentLength = boundarybytes.Length +
|
||||
fileheaderbytes.Length + fi.Length + endBoundaryBytes.Length;
|
||||
|
||||
|
||||
httpWebRequest.BeginGetRequestStream(async (result) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
|
||||
|
||||
using (Stream requestStream = request.EndGetRequestStream(result))
|
||||
{
|
||||
await WriteToStream(requestStream, boundarybytes, boundarybytes.Length);
|
||||
await WriteToStream(requestStream, fileheaderbytes, fileheaderbytes.Length);
|
||||
using (var fss = fi.OpenRead())
|
||||
{
|
||||
byte[] buffer = new byte[TXLEN];
|
||||
var form_bytes_read = fss.Read(buffer, 0, TXLEN);
|
||||
while (form_bytes_read > 0)
|
||||
{
|
||||
await WriteToStream(requestStream, buffer, form_bytes_read);
|
||||
form_bytes_read = fss.Read(buffer, 0, TXLEN);
|
||||
}
|
||||
}
|
||||
requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
|
||||
requestStream.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception rex)
|
||||
{
|
||||
report.Message = rex.Message;
|
||||
Console.Error.WriteLine(rex.Message);
|
||||
Console.Error.WriteLine("Stack trace:");
|
||||
Console.Error.WriteLine(rex.StackTrace);
|
||||
throw;
|
||||
}
|
||||
}, httpWebRequest);
|
||||
|
||||
WebResponse resp = await httpWebRequest.GetResponseAsync();
|
||||
|
||||
Stream stream = resp.GetResponseStream();
|
||||
StreamReader re = new StreamReader(stream);
|
||||
if (resp is HttpWebResponse)
|
||||
{
|
||||
String json = await re.ReadToEndAsync();
|
||||
report.Message = json;
|
||||
var hrep = resp as HttpWebResponse;
|
||||
report.StatusCode = hrep.StatusCode.ToString();
|
||||
report.OK = hrep.StatusCode == HttpStatusCode.Accepted
|
||||
|| hrep.StatusCode == HttpStatusCode.OK;
|
||||
}
|
||||
else throw new Exception("Invalid server response type");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes byte array to stream. Author : Farhan Ghumra
|
||||
/// </summary>
|
||||
private static async Task WriteToStream(Stream s, byte[] bytes, int len)
|
||||
{
|
||||
await s.WriteAsync(bytes, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public class PushCommand
|
||||
{
|
||||
static public PushReport Run(string pkg, string source)
|
||||
{
|
||||
if (source == null) source = Program.Settings.DefaultSource;
|
||||
if (source == null) throw new InvalidOperationException("source is null");
|
||||
string apikey = Program.Protector.UnProtect(Program.Settings.Sources[source].ApiKey);
|
||||
var resources = SourceHelpers.GetServerResources(source);
|
||||
if (resources.Resources == null)
|
||||
throw new InvalidOperationException("source gave no resource");
|
||||
if (!resources.Resources.Any(res => res.Type == "PackagePublish/2.0.0"))
|
||||
throw new InvalidOperationException("Source won't serve the expected push command");
|
||||
var pubRes = resources.Resources.First(res => res.Type == "PackagePublish/2.0.0");
|
||||
FileInfo fi = new FileInfo(pkg);
|
||||
if (!fi.Exists)
|
||||
{
|
||||
var report = new PushReport
|
||||
{
|
||||
PkgName = fi.Name,
|
||||
Message = "Le fichier n'existe pas"
|
||||
};
|
||||
return report;
|
||||
}
|
||||
using (var client = new HttpClient())
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Connecting to "+ pubRes.Id);
|
||||
return client.UploadFilesToServer(new Uri(pubRes.Id), fi, apikey);
|
||||
}
|
||||
catch (HttpRequestException hrex)
|
||||
{
|
||||
var report = new PushReport
|
||||
{
|
||||
PkgName = fi.Name,
|
||||
Message = "HttpRequest: " + hrex.Message,
|
||||
StackTrace = hrex.StackTrace,
|
||||
StatusCode = hrex.HResult.ToString()
|
||||
};
|
||||
Console.Error.WriteLine(hrex.Message);
|
||||
return report;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var report = new PushReport
|
||||
{
|
||||
PkgName = fi.Name,
|
||||
Message = ex.Message,
|
||||
StackTrace = ex.StackTrace
|
||||
};
|
||||
Console.Error.WriteLine(ex.Message);
|
||||
return report;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace isn
|
||||
{
|
||||
|
||||
partial class Program
|
||||
{
|
||||
public static List<PushReport> PushPkg(IEnumerable<string> pkgs)
|
||||
{
|
||||
List<PushReport> pushReports = new List<PushReport>();
|
||||
|
||||
foreach (string pkg in pkgs)
|
||||
{
|
||||
var report = PushCommand.Run(pkg, currentSource);
|
||||
|
||||
pushReports.Add(report);
|
||||
}
|
||||
if (storApiKey)
|
||||
{
|
||||
EnsureKeyStored();
|
||||
}
|
||||
return pushReports;
|
||||
}
|
||||
|
||||
private static object Add(IEnumerable<string> str)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace isn
|
||||
{
|
||||
|
||||
partial class Program
|
||||
{
|
||||
|
||||
private static void StoreApiKey(IEnumerable<string> storeArgs)
|
||||
{
|
||||
var args = storeoptions.Parse(storeArgs);
|
||||
if (shouldShowPushHelp)
|
||||
{
|
||||
// output the options
|
||||
Console.Error.WriteLine("Push Options:");
|
||||
storeoptions.WriteOptionDescriptions(Console.Out);
|
||||
}
|
||||
else
|
||||
{
|
||||
apiKey = args[0];
|
||||
EnsureKeyStored();
|
||||
}
|
||||
}
|
||||
|
||||
public static void EnsureKeyStored()
|
||||
{
|
||||
if (currentSource == null)
|
||||
{
|
||||
if (Settings.DefaultSource == null)
|
||||
return;
|
||||
currentSource = Settings.DefaultSource;
|
||||
}
|
||||
|
||||
if (Settings.Sources.ContainsKey(currentSource))
|
||||
{
|
||||
if (apiKey == null)
|
||||
{
|
||||
// Une suppression
|
||||
Settings.Sources.Remove(currentSource);
|
||||
if (Settings.DefaultSource == currentSource) Settings.DefaultSource = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Une mise À jour
|
||||
string ptd = Protector.Protect(apiKey);
|
||||
Settings.Sources[currentSource].ApiKey = ptd;
|
||||
if (Settings.DefaultSource == null) Settings.DefaultSource = currentSource;
|
||||
}
|
||||
}
|
||||
else if (apiKey != null)
|
||||
{
|
||||
// une addition
|
||||
string ptd = Protector.Protect(apiKey);
|
||||
Settings.Sources.Add(currentSource, new SourceSettings { ApiKey = ptd });
|
||||
}
|
||||
SaveConfig();
|
||||
}
|
||||
public static void SaveConfig()
|
||||
{
|
||||
FileInfo cfgSettingIf = new FileInfo(_configFileName);
|
||||
if (!cfgSettingIf.Directory.Exists) cfgSettingIf.Directory.Create();
|
||||
File.WriteAllText(
|
||||
cfgSettingIf.FullName,
|
||||
JsonConvert.SerializeObject(
|
||||
Settings,
|
||||
Formatting.Indented
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
||||
namespace isn
|
||||
{
|
||||
|
||||
partial class Program
|
||||
{
|
||||
|
||||
private static void ShowConfig()
|
||||
{
|
||||
Console.WriteLine(JsonConvert.SerializeObject(Settings, Formatting.Indented));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
|
||||
partial class Program
|
||||
{
|
||||
private static void SourceAdd(IEnumerable<string> str)
|
||||
{
|
||||
foreach (string arg in str)
|
||||
{
|
||||
if (Settings.Sources.ContainsKey(arg))
|
||||
{
|
||||
SourceSettings setting = Settings.Sources[arg];
|
||||
throw new InvalidOperationException
|
||||
(setting.Alias);
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
partial class Program
|
||||
{
|
||||
private static void SourceList(IEnumerable<string> sargs)
|
||||
{
|
||||
IEnumerable<string> spec = sargs.Count()>0 ? sargs : Settings.Sources.Keys;
|
||||
foreach (string arg in spec)
|
||||
{
|
||||
SourceSettings setting = Settings.Sources[arg];
|
||||
Console.WriteLine(JsonConvert.SerializeObject(setting));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
|
||||
partial class Program
|
||||
{
|
||||
private static void SetDefaultSource(string arg)
|
||||
{
|
||||
SourceSettings settings =
|
||||
Settings.Sources.ContainsKey(arg) ?
|
||||
Settings.Sources[arg] :
|
||||
Settings.Sources.Values.FirstOrDefault((s)=> s.Alias == arg) ;
|
||||
if (settings==null) throw new InvalidOperationException(arg);
|
||||
Settings.DefaultSource = arg;
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using System.Net;
|
||||
|
||||
namespace isn
|
||||
{
|
||||
public class PushReport
|
||||
{
|
||||
public string PkgName { get; set; }
|
||||
public bool Executed { get; internal set; }
|
||||
public bool OK { get; internal set; }
|
||||
public bool AlreadyPresent { get; internal set; }
|
||||
public string Message { get; internal set; }
|
||||
public string StatusCode { get; internal set; }
|
||||
public string StackTrace { get; internal set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace isnd.Authorization
|
||||
{
|
||||
internal class ValidApiKeyRequirement : IAuthorizationRequirement
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
namespace isnd.Authorization
|
||||
{
|
||||
internal class ValidApiKeyRequirementHandler : AuthorizationHandler<ValidApiKeyRequirement>
|
||||
{
|
||||
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidApiKeyRequirement requirement)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
namespace isnd
|
||||
{
|
||||
public static class IsndConstants
|
||||
{
|
||||
public const string AdministratorRoleName = "Admin";
|
||||
public const string RequireAdminPolicyName = "RequireAdministratorRole";
|
||||
public const string RequireValidApiKey = "RequireValideApiKey";
|
||||
}
|
||||
}
|
@ -0,0 +1,258 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using isnd.Data;
|
||||
using isnd.Data.Roles;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class AccountController : Controller
|
||||
{
|
||||
private readonly IAuthenticationSchemeProvider _schemeProvider;
|
||||
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly AdminStartupList _startupAdminList;
|
||||
|
||||
public AccountController(
|
||||
IAuthenticationSchemeProvider schemeProvider,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
IOptions<AdminStartupList> startupAdminListConfig )
|
||||
{
|
||||
_schemeProvider = schemeProvider;
|
||||
_signInManager = signInManager;
|
||||
_userManager = userManager;
|
||||
_startupAdminList = startupAdminListConfig.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entry point into the login workflow
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Login(string returnUrl)
|
||||
{
|
||||
// build a model so we know what to show on the login page
|
||||
var vm = await BuildLoginViewModelAsync(returnUrl);
|
||||
|
||||
if (vm.IsExternalLoginOnly)
|
||||
{
|
||||
// we only have one option for logging in and it's an external provider
|
||||
return RedirectToAction("Challenge", "External", new { scheme = vm.ExternalLoginScheme, returnUrl });
|
||||
}
|
||||
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle postback from username/password login
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Login(LoginInputModel model, string button)
|
||||
{
|
||||
|
||||
// the user clicked the "cancel" button
|
||||
if (button != "login")
|
||||
{
|
||||
|
||||
// since we don't have a valid context, then we just go back to the home page
|
||||
return Redirect("~/");
|
||||
}
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
// validate username/password
|
||||
var user = await _userManager.FindByNameAsync(model.Username);
|
||||
var signResult = await _signInManager.CheckPasswordSignInAsync(user, model.Password, true);
|
||||
|
||||
if (signResult.Succeeded)
|
||||
{
|
||||
|
||||
// only set explicit expiration here if user chooses "remember me".
|
||||
// otherwise we rely upon expiration configured in cookie middleware.
|
||||
AuthenticationProperties props = null;
|
||||
if (AccountOptions.AllowRememberLogin && model.RememberLogin)
|
||||
{
|
||||
props = new AuthenticationProperties
|
||||
{
|
||||
IsPersistent = true,
|
||||
ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
|
||||
};
|
||||
};
|
||||
|
||||
await _signInManager.SignInAsync(user, model.RememberLogin && AccountOptions.AllowRememberLogin);
|
||||
if (Url.IsLocalUrl(model.ReturnUrl))
|
||||
{
|
||||
return Redirect(model.ReturnUrl);
|
||||
}
|
||||
else if (string.IsNullOrEmpty(model.ReturnUrl))
|
||||
{
|
||||
return Redirect("~/");
|
||||
}
|
||||
else
|
||||
{
|
||||
// user might have clicked on a malicious link - should be logged
|
||||
throw new Exception("invalid return URL");
|
||||
}
|
||||
}
|
||||
|
||||
ModelState.AddModelError(string.Empty, AccountOptions.InvalidCredentialsErrorMessage);
|
||||
}
|
||||
|
||||
// something went wrong, show form with error
|
||||
var vm = await BuildLoginViewModelAsync(model);
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Show logout page
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Logout(string logoutId)
|
||||
{
|
||||
// build a model so the logout page knows what to display
|
||||
var vm = BuildLogoutViewModel(logoutId);
|
||||
|
||||
if (vm.ShowLogoutPrompt == false)
|
||||
{
|
||||
// if the request for logout was properly authenticated from IdentityServer, then
|
||||
// we don't need to show the prompt and can just log the user out directly.
|
||||
return await Logout(vm);
|
||||
}
|
||||
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle logout page postback
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Logout(LogoutInputModel model)
|
||||
{
|
||||
// build a model so the logged out page knows what to display
|
||||
var vm = BuildLoggedOutViewModel(model.LogoutId);
|
||||
|
||||
if (User?.Identity.IsAuthenticated == true)
|
||||
{
|
||||
// delete local authentication cookie
|
||||
await HttpContext.SignOutAsync();
|
||||
}
|
||||
|
||||
// check if we need to trigger sign-out at an upstream identity provider
|
||||
if (vm.TriggerExternalSignout)
|
||||
{
|
||||
// build a return URL so the upstream provider will redirect back
|
||||
// to us after the user has logged out. this allows us to then
|
||||
// complete our single sign-out processing.
|
||||
string url = Url.Action("Logout", new { logoutId = vm.LogoutId });
|
||||
|
||||
// this triggers a redirect to the external provider for sign-out
|
||||
return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
|
||||
}
|
||||
|
||||
return View("LoggedOut", vm);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult AccessDenied()
|
||||
{
|
||||
return new BadRequestObjectResult(403);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************/
|
||||
/* helper APIs for the AccountController */
|
||||
/*****************************************/
|
||||
private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)
|
||||
{
|
||||
|
||||
|
||||
var schemes = await _schemeProvider.GetAllSchemesAsync();
|
||||
|
||||
var providers = schemes
|
||||
.Where(x => x.DisplayName != null)
|
||||
.Select(x => new ExternalProvider
|
||||
{
|
||||
DisplayName = x.DisplayName ?? x.Name,
|
||||
AuthenticationScheme = x.Name
|
||||
}).ToList();
|
||||
|
||||
var allowLocal = true;
|
||||
|
||||
|
||||
return new LoginViewModel
|
||||
{
|
||||
AllowRememberLogin = AccountOptions.AllowRememberLogin,
|
||||
EnableLocalLogin = allowLocal && AccountOptions.AllowLocalLogin,
|
||||
ReturnUrl = returnUrl,
|
||||
ExternalProviders = providers.ToArray()
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<LoginViewModel> BuildLoginViewModelAsync(LoginInputModel model)
|
||||
{
|
||||
var vm = await BuildLoginViewModelAsync(model.ReturnUrl);
|
||||
vm.Username = model.Username;
|
||||
vm.RememberLogin = model.RememberLogin;
|
||||
return vm;
|
||||
}
|
||||
|
||||
private LogoutViewModel BuildLogoutViewModel(string logoutId)
|
||||
{
|
||||
var vm = new LogoutViewModel { LogoutId = logoutId, ShowLogoutPrompt = AccountOptions.ShowLogoutPrompt };
|
||||
|
||||
if (User?.Identity.IsAuthenticated != true)
|
||||
{
|
||||
// if the user is not authenticated, then just show logged out page
|
||||
vm.ShowLogoutPrompt = false;
|
||||
return vm;
|
||||
}
|
||||
|
||||
// show the logout prompt. this prevents attacks where the user
|
||||
// is automatically signed out by another malicious web page.
|
||||
return vm;
|
||||
}
|
||||
|
||||
private LoggedOutViewModel BuildLoggedOutViewModel(string logoutId)
|
||||
{
|
||||
var vm = new LoggedOutViewModel
|
||||
{
|
||||
AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,
|
||||
LogoutId = logoutId
|
||||
};
|
||||
return vm;
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public async Task<IActionResult> GetAdminrole()
|
||||
{
|
||||
string username = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
if (_startupAdminList.Users.Contains(username))
|
||||
{
|
||||
var user = await _userManager.FindByNameAsync(username);
|
||||
var roles = await _userManager.GetRolesAsync(user);
|
||||
if (!roles.Contains(IsndConstants.AdministratorRoleName))
|
||||
{
|
||||
await _userManager.AddToRoleAsync(user, IsndConstants.AdministratorRoleName);
|
||||
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
return BadRequest();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using isnd.Data;
|
||||
using isnd.Entities;
|
||||
using isnd.Data.ApiKeys;
|
||||
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
[Authorize]
|
||||
public class ApiKeysController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext dbContext;
|
||||
private readonly IsndSettings isndSettings;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
|
||||
private readonly IDataProtector protector;
|
||||
public ApiKeysController(ApplicationDbContext dbContext,
|
||||
IOptions<IsndSettings> isndSettingsOptions,
|
||||
IDataProtectionProvider provider,
|
||||
UserManager<ApplicationUser> userManager)
|
||||
{
|
||||
this.dbContext = dbContext;
|
||||
this.isndSettings = isndSettingsOptions.Value;
|
||||
protector = provider.CreateProtector(isndSettings.ProtectionTitle);
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Index()
|
||||
{
|
||||
List<ApiKey> index = await GetUserKeys().ToListAsync();
|
||||
IndexModel model = new IndexModel { ApiKey = index };
|
||||
ViewData["Title"] = "Index";
|
||||
return View("Index", model);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Create()
|
||||
{
|
||||
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var user = await _userManager.FindByIdAsync(userId);
|
||||
ViewBag.UserId = new SelectList(new List<ApplicationUser> { user });
|
||||
return View(new CreateModel{ });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Create(CreateModel model)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
IQueryable<ApiKey> userKeys = GetUserKeys();
|
||||
if (userKeys.Count() >= isndSettings.MaxUserKeyCount)
|
||||
{
|
||||
ModelState.AddModelError(null, "Maximum key count reached");
|
||||
return View();
|
||||
}
|
||||
ApiKey newKey = new ApiKey { UserId = userid, Name = model.Name,
|
||||
CreationDate = DateTime.Now };
|
||||
_ = dbContext.ApiKeys.Add(newKey);
|
||||
_ = await dbContext.SaveChangesAsync();
|
||||
return View("Details", new DetailModel { Name = newKey.Name,
|
||||
ProtectedValue = protector.Protect(newKey.Id),
|
||||
ApiKey = newKey });
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Delete(string id)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
|
||||
return View(new DeleteModel { ApiKey = key });
|
||||
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Delete(DeleteModel model)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = dbContext.ApiKeys.FirstOrDefault(k => k.Id == model.ApiKey.Id && k.UserId == userid);
|
||||
if (key == null)
|
||||
{
|
||||
ModelState.AddModelError(null, "Key not found");
|
||||
return View();
|
||||
}
|
||||
_ = dbContext.ApiKeys.Remove(key);
|
||||
_ = await dbContext.SaveChangesAsync();
|
||||
return View("Index", new IndexModel { ApiKey = GetUserKeys().ToList() } );
|
||||
}
|
||||
|
||||
public async Task<ActionResult> Details(string id)
|
||||
{
|
||||
string userid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
ApiKey key = await dbContext.ApiKeys.FirstOrDefaultAsync(k => k.Id == id && k.UserId == userid);
|
||||
if (key == null)
|
||||
{
|
||||
ModelState.AddModelError(null, "Key not found");
|
||||
return View();
|
||||
}
|
||||
return View("Details", new DetailModel { ApiKey = key, Name = key.Name, ProtectedValue = protector.Protect(key.Id)});
|
||||
|
||||
}
|
||||
|
||||
public async Task<ActionResult> Edit(string id)
|
||||
{
|
||||
|
||||
EditModel edit = new EditModel();
|
||||
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
|
||||
var user = await _userManager.FindByIdAsync(userId);
|
||||
|
||||
edit.ApiKey = await GetUserKeys().SingleOrDefaultAsync(k =>
|
||||
k.UserId == userId && k.Id == id);
|
||||
ViewBag.UserId = new SelectList(new List<ApplicationUser> { user });
|
||||
|
||||
return View(edit);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Edit(EditModel model)
|
||||
{
|
||||
string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
|
||||
var apiKey = await dbContext.ApiKeys.SingleOrDefaultAsync(k => k.UserId == userId && k.Id == model.ApiKey.Id);
|
||||
apiKey.Name = model.ApiKey.Name;
|
||||
apiKey.ValidityPeriodInDays = model.ApiKey.ValidityPeriodInDays;
|
||||
await dbContext.SaveChangesAsync();
|
||||
return View("Details", new DetailModel { ApiKey = apiKey });
|
||||
}
|
||||
|
||||
public IQueryable<ApiKey> GetUserKeys()
|
||||
{
|
||||
return dbContext.ApiKeys.Include(k => k.User).Where(k => k.User.UserName == User.Identity.Name);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using isnd.Data;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
|
||||
// TODO Web hook CI
|
||||
public class NewUpdateController : Controller
|
||||
{
|
||||
[Authorize(Policy = IsndConstants.RequireAdminPolicyName)]
|
||||
public IActionResult NewRelease(NewReleaseInfo version)
|
||||
{
|
||||
throw new NotImplementedException("web hook");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using isnd.Data;
|
||||
using isnd.ViewModels;
|
||||
using isnd.Helpers;
|
||||
using isnd.Interfaces;
|
||||
|
||||
namespace isnd
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class PackageVersionController : Controller
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
private readonly IPackageManager _pm;
|
||||
|
||||
public PackageVersionController(ApplicationDbContext context,
|
||||
IPackageManager pm)
|
||||
{
|
||||
_context = context;
|
||||
_pm = pm;
|
||||
}
|
||||
|
||||
// GET: PackageVersion
|
||||
public async Task<IActionResult> Index(PackageVersionIndexViewModel model)
|
||||
{
|
||||
var applicationDbContext = _context.PackageVersions.Include(p => p.Package)
|
||||
.Include(p => p.Package.Owner)
|
||||
.Include(p => p.Package.Versions)
|
||||
.Where(
|
||||
p => (model.Prerelease || !p.IsPrerelease)
|
||||
&& ((model.PackageId == null) || p.PackageId.StartsWith(model.PackageId)));
|
||||
model.Versions = await applicationDbContext.ToArrayAsync();
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public async Task<IActionResult> Mines(PackageVersionIndexViewModel model)
|
||||
{
|
||||
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var applicationDbContext = _context.PackageVersions
|
||||
.Include(p => p.Package).Where(
|
||||
p => (string.IsNullOrEmpty(model.PackageId) || p.PackageId.StartsWith(model.PackageId))
|
||||
&& p.Package.OwnerId == userId);
|
||||
|
||||
model.Versions = await applicationDbContext.ToArrayAsync();
|
||||
|
||||
return View("Index", model);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NuGet.Versioning;
|
||||
using isnd.Data;
|
||||
using isnd.Entities;
|
||||
using Unleash;
|
||||
using isnd.Services;
|
||||
using isnd.ViewModels;
|
||||
using System.Threading.Tasks;
|
||||
using isnd.Interfaces;
|
||||
using isn.Abstract;
|
||||
using isn.abst;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
public partial class PackagesController : Controller
|
||||
{
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.IndexDotJson)]
|
||||
public IActionResult ApiIndex()
|
||||
{
|
||||
return Ok(new ApiIndexViewModel{ Version = PackageManager.BASE_API_LEVEL, Resources = resources });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
using isnd.Services;
|
||||
using isnd.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
public partial class PackagesController
|
||||
{
|
||||
|
||||
// GET /autocomplete?id=isn.protocol&prerelease=true
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.AutoComplete)]
|
||||
public IActionResult AutoComplete(
|
||||
string id,
|
||||
string semVerLevel,
|
||||
bool prerelease = false,
|
||||
string packageType = null,
|
||||
int skip = 0,
|
||||
int take = 25)
|
||||
{
|
||||
if (take > maxTake)
|
||||
{
|
||||
ModelState.AddModelError("take", "Maximum exceeded");
|
||||
}
|
||||
if (semVerLevel != PackageManager.BASE_API_LEVEL)
|
||||
{
|
||||
ModelState.AddModelError("semVerLevel", PackageManager.BASE_API_LEVEL + " expected");
|
||||
}
|
||||
if (ModelState.ErrorCount > 0) return BadRequest(ModelState);
|
||||
|
||||
return Ok(packageManager.AutoComplete(id,skip,take,prerelease,packageType));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using isnd.Services;
|
||||
using isnd.Entities;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using NuGet.Versioning;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
public partial class PackagesController
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.Catalog)]
|
||||
public IActionResult CatalogIndex()
|
||||
{
|
||||
return Ok(PackageManager.CurrentCatalogIndex);
|
||||
}
|
||||
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.CatalogPage + "-{id}")]
|
||||
public IActionResult Index(string id)
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/nuget/api/catalog-resource#versioning
|
||||
return Ok(PackageManager.CurrentCatalogPages[int.Parse(id)]);
|
||||
}
|
||||
|
||||
[HttpGet(_pkgRootPrefix + "{apiVersion}/" + ApiConfig.Registration + "/{id}/{lower}.json")]
|
||||
public IActionResult CatalogRegistration(string apiVersion, string id, string lower)
|
||||
{
|
||||
if (lower.Equals("index", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var query = new Data.Catalog.RegistrationPageIndexQuery
|
||||
{
|
||||
Query = id,
|
||||
Prerelease = true
|
||||
};
|
||||
var index = packageManager.GetPackageRegistrationIndex(query);
|
||||
if (index == null) return NotFound();
|
||||
// query.TotalHits = result.Items.Select(i=>i.Items.Length).Aggregate((a,b)=>a+b);
|
||||
return Ok(index);
|
||||
}
|
||||
var leaf = packageManager.SearchById(id,lower,null);
|
||||
if (leaf.Count()==0) return NotFound(new { id, lower });
|
||||
return Ok(leaf.First());
|
||||
}
|
||||
|
||||
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.CatalogLeaf + "/{id}/{version}/{lower}/index.json")]
|
||||
public IActionResult CatalogLeaf(string id, string pversion, string lower)
|
||||
{
|
||||
|
||||
bool askForindex = lower == null;
|
||||
var pkgvs = this.packageManager.GetCatalogLeaf(id, pversion, lower).ToArray();
|
||||
if (pkgvs.Count() == 0) return NotFound();
|
||||
List<string> types = pkgvs.Select(
|
||||
v => v.Type ?? "Dependency"
|
||||
).Distinct().ToList();
|
||||
if (!types.Contains("PackageDelete"))
|
||||
types.Add("PackageDetails");
|
||||
var last = pkgvs.Last();
|
||||
var pub = last.LatestCommit.CommitTimeStamp;
|
||||
return Ok(new Data.Packages.Catalog.CatalogLeaf
|
||||
{
|
||||
CommitId = last.CommitId,
|
||||
Id = id,
|
||||
CommitTimeStamp = pub,
|
||||
Version = last.FullString,
|
||||
Published = pub,
|
||||
RefType = types.ToArray()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
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;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public partial class PackagesController : Controller
|
||||
{
|
||||
const int maxTake = 100;
|
||||
private readonly Resource[] resources;
|
||||
private readonly ILogger<PackagesController> logger;
|
||||
private readonly IDataProtector protector;
|
||||
|
||||
private readonly IsndSettings isndSettings;
|
||||
readonly ApplicationDbContext dbContext;
|
||||
private readonly IPackageManager packageManager;
|
||||
private readonly IUnleash unleashĈlient;
|
||||
const string _pkgRootPrefix = "~/";
|
||||
|
||||
public PackagesController(
|
||||
ILoggerFactory loggerFactory,
|
||||
IDataProtectionProvider provider,
|
||||
IOptions<IsndSettings> isndOptions,
|
||||
IUnleash unleashĈlient,
|
||||
ApplicationDbContext dbContext,
|
||||
IPackageManager pm)
|
||||
{
|
||||
logger = loggerFactory.CreateLogger<PackagesController>();
|
||||
isndSettings = isndOptions.Value;
|
||||
protector = provider.CreateProtector(isndSettings.ProtectionTitle);
|
||||
this.dbContext = dbContext;
|
||||
packageManager = pm;
|
||||
this.unleashĈlient = unleashĈlient;
|
||||
resources = packageManager.GetResources(unleashĈlient).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using isnd.Helpers;
|
||||
using isnd.Entities;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using isnd.Attributes;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
public partial class PackagesController
|
||||
{
|
||||
[HttpDelete(_pkgRootPrefix + ApiConfig.Delete + "/{id}/{lower?}/{type?}")]
|
||||
public async Task<IActionResult> ApiDelete(
|
||||
[FromRoute][SafeName][Required] string id,
|
||||
[FromRoute][SafeName][Required] string lower,
|
||||
[FromRoute] string type)
|
||||
{
|
||||
var uid = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
var report = await packageManager.UserAskForPackageDeletionAsync(uid, id, lower, type);
|
||||
return Ok(report);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using isnd.Attributes;
|
||||
using isnd.Entities;
|
||||
using isn.abst;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
|
||||
public partial class PackagesController
|
||||
{
|
||||
// Web get the paquet
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.GetPackage + "/{id}/{lower}/{idf}-{lowerf}."
|
||||
+ Constants.PaquetFileEstension)]
|
||||
public IActionResult GetPackage(
|
||||
[FromRoute][SafeName][Required] string id,
|
||||
[FromRoute][SafeName][Required] string lower,
|
||||
[FromRoute] string idf, [FromRoute] string lowerf)
|
||||
{
|
||||
var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
|
||||
id, lower, $"{id}-{lower}." + Constants.PaquetFileEstension
|
||||
);
|
||||
|
||||
FileInfo pkgfi = new FileInfo(pkgpath);
|
||||
|
||||
if (!pkgfi.Exists)
|
||||
{
|
||||
return BadRequest("!pkgfi.Exists");
|
||||
}
|
||||
return File(pkgfi.OpenRead(), "application/zip; charset=binary");
|
||||
}
|
||||
|
||||
// Web get spec
|
||||
[HttpGet(_pkgRootPrefix + Constants.SpecFileEstension + "/{id}/{lower}/{idf}-{lowerf}."
|
||||
+ Constants.SpecFileEstension)]
|
||||
public IActionResult GetNuspec(
|
||||
[FromRoute][SafeName][Required] string id,
|
||||
[FromRoute][SafeName][Required] string lower,
|
||||
[FromRoute][SafeName][Required] string idf,
|
||||
[FromRoute][SafeName][Required] string lowerf)
|
||||
{
|
||||
var pkgpath = Path.Combine(isndSettings.PackagesRootDir,
|
||||
id, lower, $"{id}." + Constants.SpecFileEstension);
|
||||
|
||||
FileInfo pkgfi = new FileInfo(pkgpath);
|
||||
if (!pkgfi.Exists)
|
||||
{
|
||||
return BadRequest("!pkgfi.Exists");
|
||||
}
|
||||
|
||||
return File(pkgfi.OpenRead(), "text/xml; charset=utf-8");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NuGet.Versioning;
|
||||
using isnd.Entities;
|
||||
using isn.abst;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
public partial class PackagesController
|
||||
{
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.GetVersion + "/{id}/{lower}/" + ApiConfig.IndexDotJson)]
|
||||
public IActionResult GetVersions(
|
||||
string id,
|
||||
string lower,
|
||||
bool prerelease = false,
|
||||
string packageType = null,
|
||||
int skip = 0,
|
||||
int take = 25)
|
||||
{
|
||||
if (take > maxTake)
|
||||
{
|
||||
ModelState.AddModelError("take", "Maximum exceeded");
|
||||
}
|
||||
// NugetVersion
|
||||
if (!NuGetVersion.TryParse(lower, out NuGetVersion parsedVersion))
|
||||
{
|
||||
ModelState.AddModelError("lower", "invalid version string");
|
||||
}
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
return Ok(new
|
||||
{
|
||||
versions = packageManager.GetVersions(
|
||||
id, parsedVersion, prerelease, packageType, skip, take)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,220 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NuGet.Packaging.Core;
|
||||
using NuGet.Versioning;
|
||||
using isnd.Data;
|
||||
using isnd.Helpers;
|
||||
using isnd.Entities;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using isn.abst;
|
||||
using isnd.Data.Packages;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
|
||||
public partial class PackagesController
|
||||
{
|
||||
|
||||
[HttpPut(_pkgRootPrefix + ApiConfig.Publish)]
|
||||
public async Task<IActionResult> Put()
|
||||
{
|
||||
try
|
||||
{
|
||||
var clientVersionId = Request.Headers["X-NuGet-Client-Version"];
|
||||
string apiKey = Request.Headers["X-NuGet-ApiKey"][0];
|
||||
ViewData["versionId"] = typeof(PackagesController).Assembly.FullName;
|
||||
var files = new List<string>();
|
||||
ViewData["files"] = files;
|
||||
|
||||
var clearkey = protector.Unprotect(apiKey);
|
||||
var apikey = dbContext.ApiKeys.SingleOrDefault(k => k.Id == clearkey);
|
||||
if (apikey == null)
|
||||
{
|
||||
logger.LogError("403 : no api-key");
|
||||
return Unauthorized();
|
||||
}
|
||||
Commit commit = new Commit
|
||||
{
|
||||
Action = PackageAction.PublishPackage,
|
||||
TimeStamp = DateTime.Now
|
||||
};
|
||||
dbContext.Commits.Add(commit);
|
||||
|
||||
foreach (IFormFile file in Request.Form.Files)
|
||||
{
|
||||
string initpath = Path.Combine(Environment.GetEnvironmentVariable("TEMP") ??
|
||||
Environment.GetEnvironmentVariable("TMP") ?? "/tmp",
|
||||
$"isn-{Guid.NewGuid()}."+Constants.PaquetFileEstension);
|
||||
|
||||
using (FileStream fw = new FileStream(initpath, FileMode.Create))
|
||||
{
|
||||
file.CopyTo(fw);
|
||||
}
|
||||
|
||||
using (FileStream fw = new FileStream(initpath, FileMode.Open))
|
||||
{
|
||||
var archive = new ZipArchive(fw);
|
||||
|
||||
var spec = archive.Entries.FirstOrDefault(e => e.FullName.EndsWith("." + Constants.SpecFileEstension));
|
||||
if (spec == null) return BadRequest(new { error = "no " + Constants.SpecFileEstension + " from archive" });
|
||||
string pkgpath;
|
||||
NuGetVersion version;
|
||||
string pkgid;
|
||||
string fullpath;
|
||||
|
||||
using (var specstr = spec.Open())
|
||||
{
|
||||
NuspecCoreReader reader = new NuspecCoreReader(specstr);
|
||||
|
||||
string pkgdesc = reader.GetDescription();
|
||||
var types = reader.GetPackageTypes();
|
||||
pkgid = reader.GetId();
|
||||
version = reader.GetVersion();
|
||||
|
||||
string pkgidpath = Path.Combine(isndSettings.PackagesRootDir,
|
||||
pkgid);
|
||||
pkgpath = Path.Combine(pkgidpath, version.ToFullString());
|
||||
string name = $"{pkgid}-{version}."+Constants.PaquetFileEstension;
|
||||
fullpath = Path.Combine(pkgpath, name);
|
||||
|
||||
var destpkgiddir = new DirectoryInfo(pkgidpath);
|
||||
Package pkg = dbContext.Packages.SingleOrDefault(p => p.Id == pkgid);
|
||||
if (pkg != null)
|
||||
{
|
||||
if (pkg.OwnerId != apikey.UserId)
|
||||
{
|
||||
return new ForbidResult();
|
||||
}
|
||||
pkg.Description = pkgdesc;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkg = new Package
|
||||
{
|
||||
Id = pkgid,
|
||||
Description = pkgdesc,
|
||||
OwnerId = apikey.UserId,
|
||||
LatestVersion = commit,
|
||||
};
|
||||
dbContext.Packages.Add(pkg);
|
||||
}
|
||||
if (!destpkgiddir.Exists) destpkgiddir.Create();
|
||||
|
||||
var source = new FileInfo(initpath);
|
||||
var dest = new FileInfo(fullpath);
|
||||
var destdir = new DirectoryInfo(dest.DirectoryName);
|
||||
if (dest.Exists)
|
||||
{
|
||||
// La version existe sur le disque,
|
||||
// mais si elle ne l'est pas en base de donnéés,
|
||||
// on remplace la version sur disque.
|
||||
var pkgv = dbContext.PackageVersions.Where(
|
||||
v => v.PackageId == pkg.Id
|
||||
);
|
||||
|
||||
if (pkgv !=null && pkgv.Count()==0)
|
||||
{
|
||||
dest.Delete();
|
||||
}
|
||||
else {
|
||||
logger.LogWarning("400 : pkgversion:existant");
|
||||
ModelState.AddModelError("pkgversion", "existant" );
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
}
|
||||
{
|
||||
if (!destdir.Exists) destdir.Create();
|
||||
source.MoveTo(fullpath);
|
||||
files.Add(name);
|
||||
string fullstringversion = version.ToFullString();
|
||||
var pkgvers = dbContext.PackageVersions.Where
|
||||
(v => v.PackageId == pkg.Id && v.FullString == fullstringversion);
|
||||
if (pkgvers.Count() > 0)
|
||||
{
|
||||
foreach (var v in pkgvers.ToArray())
|
||||
dbContext.PackageVersions.Remove(v);
|
||||
}
|
||||
|
||||
// FIXME default type or null
|
||||
if (types==null || types.Count==0)
|
||||
dbContext.PackageVersions.Add
|
||||
(new PackageVersion{
|
||||
|
||||
Package = pkg,
|
||||
Major = version.Major,
|
||||
Minor = version.Minor,
|
||||
Patch = version.Patch,
|
||||
Revision = version.Revision,
|
||||
IsPrerelease = version.IsPrerelease,
|
||||
FullString = version.ToFullString(),
|
||||
Type = null,
|
||||
LatestCommit = commit
|
||||
});
|
||||
else
|
||||
foreach (var type in types)
|
||||
{
|
||||
var pkgver = new PackageVersion
|
||||
{
|
||||
Package = pkg,
|
||||
Major = version.Major,
|
||||
Minor = version.Minor,
|
||||
Patch = version.Patch,
|
||||
IsPrerelease = version.IsPrerelease,
|
||||
FullString = version.ToFullString(),
|
||||
Type = type.Name,
|
||||
LatestCommit = commit
|
||||
};
|
||||
dbContext.PackageVersions.Add(pkgver);
|
||||
}
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
packageManager.ÛpdateCatalogFor(commit);
|
||||
|
||||
logger.LogInformation($"new paquet : {spec.Name}");
|
||||
}
|
||||
}
|
||||
using (var shacrypto = System.Security.Cryptography.SHA512.Create())
|
||||
{
|
||||
using (var stream = System.IO.File.OpenRead(fullpath))
|
||||
{
|
||||
var hash = shacrypto.ComputeHash(stream);
|
||||
var shafullname = fullpath + ".sha512";
|
||||
var hashtext = Convert.ToBase64String(hash);
|
||||
var hashtextbytes = Encoding.ASCII.GetBytes(hashtext);
|
||||
|
||||
using (var shafile = System.IO.File.OpenWrite(shafullname))
|
||||
{
|
||||
shafile.Write(hashtextbytes, 0, hashtextbytes.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
string nuspecfullpath = Path.Combine(pkgpath, pkgid + "." + Constants.SpecFileEstension);
|
||||
FileInfo nfpi = new FileInfo(nuspecfullpath);
|
||||
|
||||
if (nfpi.Exists)
|
||||
nfpi.Delete();
|
||||
spec.ExtractToFile(nuspecfullpath);
|
||||
}
|
||||
|
||||
}
|
||||
return Ok(ViewData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex.Message);
|
||||
logger.LogError("Stack Trace: " + ex.StackTrace);
|
||||
return new ObjectResult(new { ViewData, ex.Message })
|
||||
{ StatusCode = 500 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using isnd.Data.Catalog;
|
||||
|
||||
namespace isnd
|
||||
{
|
||||
public class RegistrationPageIndexQueryAndResult
|
||||
{
|
||||
public RegistrationPageIndexQuery Query { get; set; }
|
||||
public RegistrationPageIndex Result { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using isnd.Entities;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
|
||||
public partial class PackagesController
|
||||
{
|
||||
// GET {@id}?q={QUERY}&skip={SKIP}&take={TAKE}&prerelease={PRERELEASE}&semVerLevel={SEMVERLEVEL}&packageType={PACKAGETYPE}
|
||||
[HttpGet(_pkgRootPrefix + ApiConfig.Search)]
|
||||
public IActionResult Search(
|
||||
string q,
|
||||
int skip = 0,
|
||||
int take = 25,
|
||||
bool prerelease = false,
|
||||
string semVerLevel = null,
|
||||
string packageType = null
|
||||
)
|
||||
{
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using isnd.Data;
|
||||
using isnd.Data.Catalog;
|
||||
using isnd.Helpers;
|
||||
using isnd.ViewModels;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace isnd.Controllers
|
||||
{
|
||||
|
||||
public partial class PackagesController
|
||||
{
|
||||
// Web search
|
||||
public async Task<IActionResult> Index(RegistrationPageIndexQuery model)
|
||||
{
|
||||
return View(new RegistrationPageIndexQueryAndResult{Query = model,
|
||||
Result = packageManager.GetPackageRegistrationIndex(model)});
|
||||
}
|
||||
|
||||
public async Task<IActionResult> Details(string pkgid)
|
||||
{
|
||||
if (pkgid == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
var packageVersion = dbContext.PackageVersions
|
||||
.Include(p => p.Package)
|
||||
.Where(m => m.PackageId == pkgid)
|
||||
.OrderByDescending(p => p)
|
||||
;
|
||||
|
||||
if (packageVersion == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
bool results = await packageVersion.AnyAsync();
|
||||
var latest = await packageVersion.FirstAsync();
|
||||
|
||||
return View("Details", new PackageDetailViewModel
|
||||
{
|
||||
latest = latest,
|
||||
pkgid = pkgid,
|
||||
totalHits = packageVersion.Count(),
|
||||
data = packageVersion.Take(MAX_PKG_VERSION_LIST).ToArray()
|
||||
});
|
||||
|
||||
}
|
||||
const int MAX_PKG_VERSION_LIST = 50;
|
||||
|
||||
[Authorize]
|
||||
public async Task<IActionResult> Delete(string pkgid, string version, string pkgtype)
|
||||
{
|
||||
if (pkgid == null || version == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
// var report = await packageManager.DeletePackageAsync(id, lower, type);
|
||||
|
||||
var packageVersion = await dbContext.PackageVersions.Include(p => p.Package)
|
||||
.FirstOrDefaultAsync(m => m.PackageId == pkgid
|
||||
&& m.FullString == version && m.Type == pkgtype);
|
||||
if (packageVersion == null) return NotFound();
|
||||
if (!User.IsOwner(packageVersion)) return Unauthorized();
|
||||
var pkg = await packageManager.GetPackageAsync(pkgid, version, pkgtype);
|
||||
return View(pkg);
|
||||
}
|
||||
|
||||
// POST: PackageVersion/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DeleteConfirmed(string PackageId, string FullString,
|
||||
string Type)
|
||||
{
|
||||
PackageVersion packageVersion = await dbContext.PackageVersions
|
||||
.Include(pv => pv.Package)
|
||||
.FirstOrDefaultAsync(m => m.PackageId == PackageId
|
||||
&& m.FullString == FullString && m.Type == Type);
|
||||
if (packageVersion == null) return NotFound();
|
||||
if (!User.IsOwner(packageVersion)) return Unauthorized();
|
||||
|
||||
await packageManager.DeletePackageAsync(PackageId, FullString, Type);
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace isnd.Data
|
||||
{
|
||||
public class LoggedOutViewModel
|
||||
{
|
||||
public string PostLogoutRedirectUri { get; set; }
|
||||
public string ClientName { get; set; }
|
||||
public string SignOutIframeUrl { get; set; }
|
||||
|
||||
public bool AutomaticRedirectAfterSignOut { get; set; }
|
||||
|
||||
public string LogoutId { get; set; }
|
||||
public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;
|
||||
public string ExternalAuthenticationScheme { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace isnd.Data
|
||||
{
|
||||
public class LoginInputModel
|
||||
{
|
||||
[Required]
|
||||
public string Username { get; set; }
|
||||
[Required]
|
||||
public string Password { get; set; }
|
||||
public bool RememberLogin { get; set; }
|
||||
public string ReturnUrl { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace isnd.Data
|
||||
{
|
||||
public class LoginViewModel : LoginInputModel
|
||||
{
|
||||
public bool AllowRememberLogin { get; set; } = true;
|
||||
public bool EnableLocalLogin { get; set; } = true;
|
||||
|
||||
public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();
|
||||
public IEnumerable<ExternalProvider> VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName));
|
||||
|
||||
public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1;
|
||||
public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace isnd.Data
|
||||
{
|
||||
public class LogoutViewModel : LogoutInputModel
|
||||
{
|
||||
public bool ShowLogoutPrompt { get; set; } = true;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
|
||||
namespace isnd.Data
|
||||
{
|
||||
public class RedirectViewModel
|
||||
{
|
||||
public string RedirectUrl { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class ApiKey
|
||||
{
|
||||
[Required][Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[Required][ForeignKey("User")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public int ValidityPeriodInDays{ get; set; }
|
||||
|
||||
public DateTime CreationDate { get; set; }
|
||||
|
||||
public bool IsValid => CreationDate.AddDays(ValidityPeriodInDays) > DateTime.Now;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class ApiKeyViewModel
|
||||
{
|
||||
[Display(Name = "Key Name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
|
||||
[Display(Name = "Key Value")]
|
||||
public string ProtectedValue { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class CreateModel
|
||||
{
|
||||
|
||||
[Required][StringLength(255)]
|
||||
[Display(Name = "Key Name")]
|
||||
public string Name { get; set; }
|
||||
public string UserId { get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class DeleteModel
|
||||
{
|
||||
public ApiKey ApiKey { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class DetailModel : ApiKeyViewModel
|
||||
{
|
||||
public ApiKey ApiKey { get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class EditModel
|
||||
{
|
||||
public EditModel()
|
||||
{
|
||||
if (ApiKey==null) ApiKey = new ApiKey();
|
||||
}
|
||||
|
||||
public ApiKey ApiKey { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace isnd.Data.ApiKeys
|
||||
{
|
||||
public class IndexModel
|
||||
{
|
||||
public List<ApiKey> ApiKey { get; set; }
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue