diff --git a/.github/workflows/check-dependencies.yml b/.github/workflows/check-dependencies.yml
index 3862920ff..9dee36876 100644
--- a/.github/workflows/check-dependencies.yml
+++ b/.github/workflows/check-dependencies.yml
@@ -33,7 +33,7 @@ jobs:
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v1.7.2
with:
- dotnet-version: '5.0.103'
+ dotnet-version: '5.0.200'
# Run update depencies script
- name: Update dependencies
run: ./update-dependencies.ps1
diff --git a/.github/workflows/maintain-2.0.0.yml b/.github/workflows/maintain-2.0.0.yml
deleted file mode 100644
index 6bc5f5910..000000000
--- a/.github/workflows/maintain-2.0.0.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-# Update all depencies each days if needed
-
-name: Release 2.0 Dependencies
-
-# Controls when the action will run.
-on:
- # Triggers the workflow at 02:00 each days
- schedule:
- - cron: '0 2 * * *'
- # allow to launch the job manually
- workflow_dispatch:
-
-jobs:
- # This workflow contains a single job called "build"
- build:
- # The type of runner that the job will run on
- runs-on: windows-latest
-
- # Steps represent a sequence of tasks that will be executed as part of the job
- steps:
- # Checkout the branch fix/dependencies with the PAT
- - uses: actions/checkout@v2
- with:
- ref: maintain/1.0.0
- token: ${{ secrets.PAT }}
- fetch-depth: 0
- - name: Merge preview/1.0.0
- continue-on-error: true
- run: |
- git config user.name github-actions
- git config user.email github-actions@github.com
- git merge origin/preview/2.0.0 --allow-unrelated-histories
- # Setup .NET Core SDK
- - name: Setup .NET Core SDK
- uses: actions/setup-dotnet@v1.7.2
- with:
- dotnet-version: '5.0.103'
- # Run update depencies script
- - name: Update dependencies
- run: ./update-dependencies.ps1
- env:
- SRC_BRANCH: maintain/1.0.0
- DEST_BRANCH: preview/2.0.0
- GITHUB_TOKEN: ${{ secrets.PAT }}
diff --git a/.sonarlint/TheIdServer.slconfig b/.sonarlint/TheIdServer.slconfig
new file mode 100644
index 000000000..23c72844b
--- /dev/null
+++ b/.sonarlint/TheIdServer.slconfig
@@ -0,0 +1,15 @@
+{
+ "ServerUri": "https://sonarcloud.io/",
+ "Organization": {
+ "Key": "aguacongas",
+ "Name": "Olivier Lefebvre"
+ },
+ "ProjectKey": "aguacongas_TheIdServer",
+ "ProjectName": "TheIdServer",
+ "Profiles": {
+ "CSharp": {
+ "ProfileKey": "AW8e9NVJZPoDbtkGSYCm",
+ "ProfileTimestamp": "2021-03-03T08:15:42Z"
+ }
+ }
+}
\ No newline at end of file
diff --git a/.sonarlint/aguacongas_theidserver/CSharp/SonarLint.xml b/.sonarlint/aguacongas_theidserver/CSharp/SonarLint.xml
new file mode 100644
index 000000000..21acd70e2
--- /dev/null
+++ b/.sonarlint/aguacongas_theidserver/CSharp/SonarLint.xml
@@ -0,0 +1,89 @@
+
+
+
+
+ sonar.cs.analyzeGeneratedCode
+ false
+
+
+ sonar.cs.file.suffixes
+ .cs
+
+
+ sonar.cs.ignoreHeaderComments
+ true
+
+
+ sonar.cs.roslyn.ignoreIssues
+ false
+
+
+
+
+ S107
+
+
+ max
+ 7
+
+
+
+
+ S110
+
+
+ max
+ 5
+
+
+
+
+ S1479
+
+
+ maximum
+ 30
+
+
+
+
+ S2342
+
+
+ flagsAttributeFormat
+ ^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?s$
+
+
+ format
+ ^([A-Z]{1,3}[a-z0-9]+)*([A-Z]{2})?$
+
+
+
+
+ S2436
+
+
+ max
+ 2
+
+
+ maxMethod
+ 3
+
+
+
+
+ S3776
+
+
+ propertyThreshold
+ 3
+
+
+ threshold
+ 15
+
+
+
+
+
\ No newline at end of file
diff --git a/.sonarlint/aguacongas_theidservercsharp.ruleset b/.sonarlint/aguacongas_theidservercsharp.ruleset
new file mode 100644
index 000000000..4df530fd8
--- /dev/null
+++ b/.sonarlint/aguacongas_theidservercsharp.ruleset
@@ -0,0 +1,372 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 45690fe62..bc2e22559 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,47 @@
+# [2.2.0](https://github.com/Aguafrommars/TheIdServer/compare/2.1.0...2.2.0) (2021-03-26)
+
+
+### Bug Fixes
+
+* remove obsolets packages ([4429976](https://github.com/Aguafrommars/TheIdServer/commit/44299760e1422b654e4cc21c2be32abdda3b4327))
+* set valid audience ([86191d7](https://github.com/Aguafrommars/TheIdServer/commit/86191d7d17ffec066fa66264d1feaad76f082560)), closes [#388](https://github.com/Aguafrommars/TheIdServer/issues/388)
+* switch to Azure package ([baf95bf](https://github.com/Aguafrommars/TheIdServer/commit/baf95bf68a798d22f975a9e27c4fcea0fb9aa809))
+* update packages ([f7ffd29](https://github.com/Aguafrommars/TheIdServer/commit/f7ffd29a3b97462cdf1d7a74a9b1432ae7ecc764))
+* update packages ([e1803f6](https://github.com/Aguafrommars/TheIdServer/commit/e1803f6c1dee112e9a8ab294c64ab97d8e92fb6b))
+* update packages ([7e5ac1e](https://github.com/Aguafrommars/TheIdServer/commit/7e5ac1e14325c6dbe8fed71bb57c49a27c3a4608))
+* update packages ([b32882d](https://github.com/Aguafrommars/TheIdServer/commit/b32882d0f686eb6982c48ce562fb273970e8e5f4))
+* update packages ([a5e0441](https://github.com/Aguafrommars/TheIdServer/commit/a5e0441f3ae78a6fb0662b46ca547d50fbb39b34))
+* update packages ([3389cfc](https://github.com/Aguafrommars/TheIdServer/commit/3389cfc4ed60fc06df2b5362729cccfe01ef01d0))
+* update packages ([ef04e93](https://github.com/Aguafrommars/TheIdServer/commit/ef04e9345ab3b5c4a2822431cbf04fbd2da932fd))
+* update packages ([10b328a](https://github.com/Aguafrommars/TheIdServer/commit/10b328ad11df6c9b5500481996c8573c61f5d4c4))
+* update packages ([41594b1](https://github.com/Aguafrommars/TheIdServer/commit/41594b1fbe22eecdfd604cf0db9455d2f5ea4578))
+* update packages ([2ed76e8](https://github.com/Aguafrommars/TheIdServer/commit/2ed76e8268af630c004fa7f0fc283d2056905bd9))
+* update packages ([7bcb601](https://github.com/Aguafrommars/TheIdServer/commit/7bcb601679cb29dbc39e961f4ddc29a56fc5f7d5))
+* update packages ([0d5fd4c](https://github.com/Aguafrommars/TheIdServer/commit/0d5fd4c7bd83c1db4bc96d3ccaf572f5edd53727))
+* update packages ([e1d3a71](https://github.com/Aguafrommars/TheIdServer/commit/e1d3a71613a0925bfc921632a04e16d8c8b85bce))
+* update packages ([f95dc02](https://github.com/Aguafrommars/TheIdServer/commit/f95dc023021cd3b03cfd8e7f64551fac22df8751))
+* update packages ([4eb238a](https://github.com/Aguafrommars/TheIdServer/commit/4eb238ae29fe92a8a500701ce356dbf031b6a248))
+* update packages ([e6357c5](https://github.com/Aguafrommars/TheIdServer/commit/e6357c552318ae5afbafa03a0a8636cb1877abc1))
+* update packages ([50da361](https://github.com/Aguafrommars/TheIdServer/commit/50da361318032672373e445854dcded449b7942c))
+* update packages ([87c81c9](https://github.com/Aguafrommars/TheIdServer/commit/87c81c915c2076b40843566e6953b5ea5689fd08))
+* update packages ([6f1f2aa](https://github.com/Aguafrommars/TheIdServer/commit/6f1f2aa085b2c305f9c13ab145f5b6da131d25e1))
+* update packages ([5032108](https://github.com/Aguafrommars/TheIdServer/commit/503210829eb1d09d8ed36f66651f5b72162af2f8))
+* update packages ([5d13a7a](https://github.com/Aguafrommars/TheIdServer/commit/5d13a7a6149fe5ed031283bcaf977dabf8bbb3c7))
+* update packages ([83aba78](https://github.com/Aguafrommars/TheIdServer/commit/83aba78a0df12629d7993d3dc1b8d1a350901b35))
+* update packages ([5907af8](https://github.com/Aguafrommars/TheIdServer/commit/5907af8738f468cb577c04030f161b799235abc5))
+* update packages ([05dfb21](https://github.com/Aguafrommars/TheIdServer/commit/05dfb21616951e6a25523ce91752d5e85f41dc8d))
+* update packages ([6950511](https://github.com/Aguafrommars/TheIdServer/commit/6950511e1cc74b70e5dab478a1163650a51698db))
+* update packages ([c912af1](https://github.com/Aguafrommars/TheIdServer/commit/c912af195a5f9c3c7865bca0260073966c0b29f3))
+* update packages ([153175d](https://github.com/Aguafrommars/TheIdServer/commit/153175de8d4aa49bf610ed62c5cb146138a717cc))
+* update packages ([4ef29fb](https://github.com/Aguafrommars/TheIdServer/commit/4ef29fb9f888dbcc9274f746228a7fb6b36da686))
+* update packages ([2837ba1](https://github.com/Aguafrommars/TheIdServer/commit/2837ba184add421b48be970bb9d6d695289434ca))
+* update packages ([42258f7](https://github.com/Aguafrommars/TheIdServer/commit/42258f796984bbc1236ca7ec8bee783c6892a62d))
+
+
+### Features
+
+* log user name ([32fabc2](https://github.com/Aguafrommars/TheIdServer/commit/32fabc2020f89eb2cbe66bc154b2853791383cef))
+
# [2.1.0](https://github.com/Aguafrommars/TheIdServer/compare/2.0.4...2.1.0) (2020-12-18)
diff --git a/TheIdServer.sln b/TheIdServer.sln
index 673e0c919..e8a0148c5 100644
--- a/TheIdServer.sln
+++ b/TheIdServer.sln
@@ -181,6 +181,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aguacongas.TheIdServer.Blaz
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aguacongas.TheIdServer.BlazorApp.Pages.Users", "src\BlazorApp\Aguacongas.TheIdServer.BlazorApp.Pages.Users\Aguacongas.TheIdServer.BlazorApp.Pages.Users.csproj", "{E01CF9AF-CAB1-4C46-A9B8-12AB295D4A85}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aguacongas.IdentityServer.RavenDb.Store", "src\IdentityServer\Aguacongas.IdentityServer.RavenDb.Store\Aguacongas.IdentityServer.RavenDb.Store.csproj", "{D887CCE0-A999-4CE8-92B1-AE83587CDC2F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aguacongas.IdentityServer.RavenDb.Store.Test", "test\Aguacongas.IdentityServer.RavenDb.Store.Test\Aguacongas.IdentityServer.RavenDb.Store.Test.csproj", "{C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -971,6 +975,30 @@ Global
{E01CF9AF-CAB1-4C46-A9B8-12AB295D4A85}.Release|x64.Build.0 = Release|Any CPU
{E01CF9AF-CAB1-4C46-A9B8-12AB295D4A85}.Release|x86.ActiveCfg = Release|Any CPU
{E01CF9AF-CAB1-4C46-A9B8-12AB295D4A85}.Release|x86.Build.0 = Release|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Debug|x64.Build.0 = Debug|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Debug|x86.Build.0 = Debug|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Release|x64.ActiveCfg = Release|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Release|x64.Build.0 = Release|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Release|x86.ActiveCfg = Release|Any CPU
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F}.Release|x86.Build.0 = Release|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Debug|x64.Build.0 = Debug|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Debug|x86.Build.0 = Debug|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Release|x64.ActiveCfg = Release|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Release|x64.Build.0 = Release|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Release|x86.ActiveCfg = Release|Any CPU
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1046,6 +1074,8 @@ Global
{5C362E5C-BF03-48C4-ABEC-FEBA0F6ECAD2} = {8A3B91E5-02A3-42F0-B2E7-E419B5086FFA}
{36AAF482-3FAE-4633-80AA-B7525A158760} = {8A3B91E5-02A3-42F0-B2E7-E419B5086FFA}
{E01CF9AF-CAB1-4C46-A9B8-12AB295D4A85} = {8A3B91E5-02A3-42F0-B2E7-E419B5086FFA}
+ {D887CCE0-A999-4CE8-92B1-AE83587CDC2F} = {DF368D6C-D11F-49F9-BF41-090AE1D10C6D}
+ {C1560F0F-7B46-4DF1-AC04-01AF1E884DDB} = {DE50F426-4409-4573-8502-93364ED12E0C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5283BE0B-F6F2-4458-B12F-64C78CFF8CBA}
diff --git a/appveyor.yml b/appveyor.yml
index 0655a0d09..e5dc8853c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,7 +12,7 @@ image:
environment:
GH_TOKEN:
secure: 0NJdORJRFjpB0dwUYv7bVNsbkldkoBhnvWik/CTOwAF/k9kP+/uTWMFnDcpEpt8E
- donetsdk: 5.0.103
+ donetsdk: 5.0.200
JAVA_HOME: C:\Program Files\Java\jdk14
PATH: $(JAVA_HOME)\bin;$(PATH)
init:
diff --git a/build.ps1 b/build.ps1
index bacbcd19d..b376d49c7 100644
--- a/build.ps1
+++ b/build.ps1
@@ -22,7 +22,7 @@ Write-Host "dotnet sonarscanner begin /k:aguacongas_TheIdServer -o:aguacongas -d
dotnet sonarscanner begin /k:aguacongas_TheIdServer -o:aguacongas -d:sonar.host.url=https://sonarcloud.io -d:sonar.login=$env:sonarqube -d:sonar.coverageReportPaths=coverage\SonarQube.xml $prArgs -v:$env:Version
Write-Host "dotnet test -c Release --settings coverletArgs.runsettings --filter FullyQualifiedName!~Pages & FullyQualifiedName!~UserStore"
-dotnet test -c Release --settings coverletArgs.runsettings --filter "FullyQualifiedName!~UserStore"
+dotnet test -c Release --collect:"XPlat Code Coverage" --settings coverletArgs.runsettings --filter "FullyQualifiedName!~Aguacongas.TheIdServer.Identity.IntegrationTest" -v q
if ($LASTEXITCODE -ne 0) {
$result = $LASTEXITCODE
diff --git a/global.json b/global.json
index ed8ca68ff..29cf2c4d2 100644
--- a/global.json
+++ b/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "5.0.100"
+ "version": "5.0.200"
}
- }
\ No newline at end of file
+ }
diff --git a/publish.ps1 b/publish.ps1
index a29e505eb..d75e8ef3d 100644
--- a/publish.ps1
+++ b/publish.ps1
@@ -12,12 +12,12 @@ Get-ChildItem -Path src -rec `
}
}
-dotnet msbuild src\Aguacongas.TheIdServer\Aguacongas.TheIdServer.csproj -t:Publish -p:Configuration=Release -p:OutputPath=$path\artifacts\Aguacongas.TheIdServer -p:Version=$env:Version -p:FileVersion=$fileversion
+dotnet msbuild src\Aguacongas.TheIdServer\Aguacongas.TheIdServer.csproj -t:Publish -p:Configuration=Release -p:OutputPath=$path\artifacts\Aguacongas.TheIdServer -p:Version=$env:Version -p:FileVersion=$fileversion -noConsoleLogger -nr:false
if ($LASTEXITCODE -ne 0) {
throw "publis failed src/Aguacongas.TheIdServer/Aguacongas.TheIdServer.csproj"
}
-dotnet msbuild src\Aguacongas.TheIdServer.BlazorApp\Aguacongas.TheIdServer.BlazorApp.csproj -t:Publish -p:Configuration=Release -p:OutputPath=$path\artifacts\Aguacongas.TheIdServer.BlazorApp -p:Version=$env:Version -p:FileVersion=$fileversion
+dotnet msbuild src\Aguacongas.TheIdServer.BlazorApp\Aguacongas.TheIdServer.BlazorApp.csproj -t:Publish -p:Configuration=Release -p:OutputPath=$path\artifacts\Aguacongas.TheIdServer.BlazorApp -p:Version=$env:Version -p:FileVersion=$fileversion -noConsoleLogger -nr:false
if ($LASTEXITCODE -ne 0) {
throw "publish failed src/Aguacongas.TheIdServer.BlazorApp/Aguacongas.TheIdServer.BlazorApp.csproj"
}
diff --git a/sample/Aguacongas.TheIdServer.ApiSample/Aguacongas.TheIdServer.ApiSample.csproj b/sample/Aguacongas.TheIdServer.ApiSample/Aguacongas.TheIdServer.ApiSample.csproj
index c007468fb..1d523b185 100644
--- a/sample/Aguacongas.TheIdServer.ApiSample/Aguacongas.TheIdServer.ApiSample.csproj
+++ b/sample/Aguacongas.TheIdServer.ApiSample/Aguacongas.TheIdServer.ApiSample.csproj
@@ -19,7 +19,7 @@
-
+
diff --git a/sample/Aguacongas.TheIdServer.ClientCredentialSample/Aguacongas.TheIdServer.ClientCredentialSample.csproj b/sample/Aguacongas.TheIdServer.ClientCredentialSample/Aguacongas.TheIdServer.ClientCredentialSample.csproj
index 12913d70b..8312eabbe 100644
--- a/sample/Aguacongas.TheIdServer.ClientCredentialSample/Aguacongas.TheIdServer.ClientCredentialSample.csproj
+++ b/sample/Aguacongas.TheIdServer.ClientCredentialSample/Aguacongas.TheIdServer.ClientCredentialSample.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/sample/Aguacongas.TheIdServer.DeviceFlowSample/Aguacongas.TheIdServer.DeviceFlowSample.csproj b/sample/Aguacongas.TheIdServer.DeviceFlowSample/Aguacongas.TheIdServer.DeviceFlowSample.csproj
index ad0b0e7b9..f3c4ed82e 100644
--- a/sample/Aguacongas.TheIdServer.DeviceFlowSample/Aguacongas.TheIdServer.DeviceFlowSample.csproj
+++ b/sample/Aguacongas.TheIdServer.DeviceFlowSample/Aguacongas.TheIdServer.DeviceFlowSample.csproj
@@ -18,8 +18,8 @@
-
-
+
+
diff --git a/sample/Aguacongas.TheIdServer.MvcClient/Aguacongas.TheIdServer.MvcClient.csproj b/sample/Aguacongas.TheIdServer.MvcClient/Aguacongas.TheIdServer.MvcClient.csproj
index 991c727c2..1d60a59f0 100644
--- a/sample/Aguacongas.TheIdServer.MvcClient/Aguacongas.TheIdServer.MvcClient.csproj
+++ b/sample/Aguacongas.TheIdServer.MvcClient/Aguacongas.TheIdServer.MvcClient.csproj
@@ -17,10 +17,10 @@
-
-
+
+
-
+
diff --git a/sample/Aguacongas.TheIdentityServer.SpaSample/Aguacongas.TheIdentityServer.SpaSample.csproj b/sample/Aguacongas.TheIdentityServer.SpaSample/Aguacongas.TheIdentityServer.SpaSample.csproj
index 5ef792a52..51c929769 100644
--- a/sample/Aguacongas.TheIdentityServer.SpaSample/Aguacongas.TheIdentityServer.SpaSample.csproj
+++ b/sample/Aguacongas.TheIdentityServer.SpaSample/Aguacongas.TheIdentityServer.SpaSample.csproj
@@ -19,10 +19,10 @@
-
-
-
-
+
+
+
+
diff --git a/sample/Kubernetes/TheIdServer-public-configmap.yaml b/sample/Kubernetes/TheIdServer-public-configmap.yaml
index 9d099baa0..ad82b0932 100644
--- a/sample/Kubernetes/TheIdServer-public-configmap.yaml
+++ b/sample/Kubernetes/TheIdServer-public-configmap.yaml
@@ -12,11 +12,11 @@ data:
DisableStrictSsl: "true"
EnableOpenApiDoc: "false"
IdentityServer__Key__Type: KeysRotation
- IdentityServer__Key__StorageKind: FileSytem
+ IdentityServer__Key__StorageKind: FileSystem
IdentityServer__Key__StorageConnectionString: "/usr/local/share/keys/signing"
IdentityServer__Key__KeyProtectionOptions__KeyProtectionKind: "X509"
IdentityServer__Key__KeyProtectionOptions__X509CertificatePath: /usr/local/share/ca-certificates/theidserver.pfx
- DataProtectionOptions__StorageKind: FileSytem
+ DataProtectionOptions__StorageKind: FileSystem
DataProtectionOptions__StorageConnectionString: "/usr/local/share/keys/dataprotecttion"
DataProtectionOptions__KeyProtectionOptions__KeyProtectionKind: "X509"
DataProtectionOptions__KeyProtectionOptions__X509CertificatePath: /usr/local/share/ca-certificates/theidserver.pfx
diff --git a/sample/MultiTiers/Aguacongas.TheIdServer.Api/Aguacongas.TheIdServer.Api.csproj b/sample/MultiTiers/Aguacongas.TheIdServer.Api/Aguacongas.TheIdServer.Api.csproj
index 13f847aba..472a9ee93 100644
--- a/sample/MultiTiers/Aguacongas.TheIdServer.Api/Aguacongas.TheIdServer.Api.csproj
+++ b/sample/MultiTiers/Aguacongas.TheIdServer.Api/Aguacongas.TheIdServer.Api.csproj
@@ -18,13 +18,13 @@
-
-
+
+
-
-
-
-
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -32,7 +32,7 @@
-
+
diff --git a/sample/MultiTiers/Aguacongas.TheIdServer.Private/Aguacongas.TheIdServer.Private.csproj b/sample/MultiTiers/Aguacongas.TheIdServer.Private/Aguacongas.TheIdServer.Private.csproj
index ec3a5c41a..ecdddc43c 100644
--- a/sample/MultiTiers/Aguacongas.TheIdServer.Private/Aguacongas.TheIdServer.Private.csproj
+++ b/sample/MultiTiers/Aguacongas.TheIdServer.Private/Aguacongas.TheIdServer.Private.csproj
@@ -18,25 +18,25 @@
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -45,7 +45,7 @@
-
+
diff --git a/sample/MultiTiers/Aguacongas.TheIdServer.Public/Aguacongas.TheIdServer.Public.csproj b/sample/MultiTiers/Aguacongas.TheIdServer.Public/Aguacongas.TheIdServer.Public.csproj
index 046926c84..a24cd0473 100644
--- a/sample/MultiTiers/Aguacongas.TheIdServer.Public/Aguacongas.TheIdServer.Public.csproj
+++ b/sample/MultiTiers/Aguacongas.TheIdServer.Public/Aguacongas.TheIdServer.Public.csproj
@@ -18,20 +18,20 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -40,7 +40,7 @@
-
+
diff --git a/src/Aguacongas.TheIdServer.Authentication/Aguacongas.TheIdServer.Authentication.csproj b/src/Aguacongas.TheIdServer.Authentication/Aguacongas.TheIdServer.Authentication.csproj
index 8e8b04fdd..9d4adab53 100644
--- a/src/Aguacongas.TheIdServer.Authentication/Aguacongas.TheIdServer.Authentication.csproj
+++ b/src/Aguacongas.TheIdServer.Authentication/Aguacongas.TheIdServer.Authentication.csproj
@@ -1,30 +1,30 @@
-
-
-
- netstandard2.1
- Olivier Lefebvre
- Copyright (c) 2020 @Olivier Lefebvre
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/LICENSE
- https://github.com/Aguafrommars/TheIdServer/tree/master/src/Aguacongas.TheIdServer.Authentication
- https://github.com/Aguafrommars/TheIdServer
- git
- theidserver;aspnetcore;authentication;security
- Aguacongas.AspNetCore.Authentication store implementation for TheIdServer API.
- Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
- ..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ netstandard2.1
+ Olivier Lefebvre
+ Copyright (c) 2020 @Olivier Lefebvre
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/LICENSE
+ https://github.com/Aguafrommars/TheIdServer/tree/master/src/Aguacongas.TheIdServer.Authentication
+ https://github.com/Aguafrommars/TheIdServer
+ git
+ theidserver;aspnetcore;authentication;security
+ Aguacongas.AspNetCore.Authentication store implementation for TheIdServer API.
+ Full
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ ..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Aguacongas.TheIdServer.BlazorApp/Aguacongas.TheIdServer.BlazorApp.csproj b/src/Aguacongas.TheIdServer.BlazorApp/Aguacongas.TheIdServer.BlazorApp.csproj
index 12373ddab..6adb5177f 100644
--- a/src/Aguacongas.TheIdServer.BlazorApp/Aguacongas.TheIdServer.BlazorApp.csproj
+++ b/src/Aguacongas.TheIdServer.BlazorApp/Aguacongas.TheIdServer.BlazorApp.csproj
@@ -31,8 +31,8 @@
-
-
+
+
diff --git a/src/Aguacongas.TheIdServer.BlazorApp/README.md b/src/Aguacongas.TheIdServer.BlazorApp/README.md
index 91f11013e..d9f5ac4ca 100644
--- a/src/Aguacongas.TheIdServer.BlazorApp/README.md
+++ b/src/Aguacongas.TheIdServer.BlazorApp/README.md
@@ -23,7 +23,7 @@ NuGet packages composing the application are available on [nuget.org](https://ww
* **Aguacongas.TheIdServer.BlazorApp.Infrastructure** contains application models, services, validators and extensions
* **Aguacongas.TheIdServer.BlazorApp.Components** contains application components
-* **Aguacongas.TheIdServer.BlazorApp.Pages** contains application pages
+* **Aguacongas.TheIdServer.BlazorApp.Pages.*** contains application pages
## Configuration
diff --git a/src/Aguacongas.TheIdServer.Identity/Aguacongas.TheIdServer.Identity.csproj b/src/Aguacongas.TheIdServer.Identity/Aguacongas.TheIdServer.Identity.csproj
index b09000e5e..75d9ad14a 100644
--- a/src/Aguacongas.TheIdServer.Identity/Aguacongas.TheIdServer.Identity.csproj
+++ b/src/Aguacongas.TheIdServer.Identity/Aguacongas.TheIdServer.Identity.csproj
@@ -10,7 +10,7 @@
git
theidserver;aspnetcore;identity;security
TheIdServer management application.
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
@@ -27,7 +27,7 @@
-
+
diff --git a/src/Aguacongas.TheIdServer/Aguacongas - Backup.TheIdServer.csproj b/src/Aguacongas.TheIdServer/Aguacongas - Backup.TheIdServer.csproj
deleted file mode 100644
index 5d47196b4..000000000
--- a/src/Aguacongas.TheIdServer/Aguacongas - Backup.TheIdServer.csproj
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
- net5.0
- Olivier Lefebvre
- Copyright (c) 2020 @Olivier Lefebvre
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/LICENSE
- https://github.com/Aguafrommars/TheIdServer/tree/master/src/Aguacongas.TheIdServer
- https://github.com/Aguafrommars/TheIdServer
- git
- aspnetcore;identityserver4;oidc,oauth;authentication;security
- OpenID/Connect server base on IdentityServer4.
- Full
- f6987681-1871-440a-a6ea-a606c2c5ccf6
- ..\..\docker-compose.dcproj
- Linux
- ..\..
- --network agua
-
-
- Aguacongas.TheIdServer.ruleset
-
-
- Aguacongas.TheIdServer.ruleset
- 1701;1702;CA1416
-
-
-
-
-
- <_ContentIncludedByDefault Remove="compilerconfig.json" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- PreserveNewest
-
-
-
-
- PreserveNewest
-
-
-
\ No newline at end of file
diff --git a/src/Aguacongas.TheIdServer/Aguacongas.TheIdServer.csproj b/src/Aguacongas.TheIdServer/Aguacongas.TheIdServer.csproj
index 4129623e0..3384dddb8 100644
--- a/src/Aguacongas.TheIdServer/Aguacongas.TheIdServer.csproj
+++ b/src/Aguacongas.TheIdServer/Aguacongas.TheIdServer.csproj
@@ -41,19 +41,19 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
@@ -71,6 +71,7 @@
+
@@ -84,6 +85,12 @@
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
diff --git a/src/Aguacongas.TheIdServer/Extensions/DataProtectionBuilderExtentions.cs b/src/Aguacongas.TheIdServer/Extensions/DataProtectionBuilderExtentions.cs
index 7fd072355..e88f67438 100644
--- a/src/Aguacongas.TheIdServer/Extensions/DataProtectionBuilderExtentions.cs
+++ b/src/Aguacongas.TheIdServer/Extensions/DataProtectionBuilderExtentions.cs
@@ -2,6 +2,7 @@
// Copyright (c) 2021 @Olivier Lefebvre
using Aguacongas.IdentityServer.Admin.Configuration;
using Aguacongas.IdentityServer.EntityFramework.Store;
+using Aguacongas.IdentityServer.KeysRotation.RavenDb;
using Aguacongas.TheIdServer.Models;
using Azure.Identity;
using Microsoft.AspNetCore.DataProtection;
@@ -9,6 +10,9 @@
using Microsoft.AspNetCore.DataProtection.KeyManagement;
using Microsoft.AspNetCore.DataProtection.XmlEncryption;
using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Win32;
using StackExchange.Redis;
@@ -37,7 +41,10 @@ public static IDataProtectionBuilder ConfigureDataProtection(this IDataProtectio
case StorageKind.EntityFramework:
builder.PersistKeysToDbContext();
break;
- case StorageKind.FileSytem:
+ case StorageKind.RavenDb:
+ builder.PersistKeysToRavenDb();
+ break;
+ case StorageKind.FileSystem:
builder.PersistKeysToFileSystem(new DirectoryInfo(dataProtectionsOptions.StorageConnectionString));
break;
case StorageKind.Redis:
diff --git a/src/Aguacongas.TheIdServer/Extensions/IdentityServerBuilderExtensions.cs b/src/Aguacongas.TheIdServer/Extensions/IdentityServerBuilderExtensions.cs
index 97cc4f1b6..302dd332a 100644
--- a/src/Aguacongas.TheIdServer/Extensions/IdentityServerBuilderExtensions.cs
+++ b/src/Aguacongas.TheIdServer/Extensions/IdentityServerBuilderExtensions.cs
@@ -4,6 +4,7 @@
using Aguacongas.IdentityServer.EntityFramework.Store;
using Aguacongas.IdentityServer.KeysRotation;
using Aguacongas.IdentityServer.KeysRotation.Extentions;
+using Aguacongas.IdentityServer.KeysRotation.RavenDb;
using Aguacongas.TheIdServer.Models;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
@@ -34,7 +35,10 @@ public static IIdentityServerBuilder ConfigureKey(this IIdentityServerBuilder id
case StorageKind.EntityFramework:
builder.PersistKeysToDbContext();
break;
- case StorageKind.FileSytem:
+ case StorageKind.RavenDb:
+ builder.PersistKeysToRavenDb();
+ break;
+ case StorageKind.FileSystem:
builder.PersistKeysToFileSystem(new DirectoryInfo(dataProtectionsOptions.StorageConnectionString));
break;
case StorageKind.Redis:
diff --git a/src/Aguacongas.TheIdServer/Models/DataProtectionOptions.cs b/src/Aguacongas.TheIdServer/Models/DataProtectionOptions.cs
index d5a9a3697..66fdc7a98 100644
--- a/src/Aguacongas.TheIdServer/Models/DataProtectionOptions.cs
+++ b/src/Aguacongas.TheIdServer/Models/DataProtectionOptions.cs
@@ -10,8 +10,9 @@ public enum StorageKind
EntityFramework,
Redis,
AzureStorage,
- FileSytem,
- Registry
+ FileSystem,
+ Registry,
+ RavenDb
}
public enum KeyProtectionKind
diff --git a/src/Aguacongas.TheIdServer/Models/DbTypes.cs b/src/Aguacongas.TheIdServer/Models/DbTypes.cs
index 4d579e133..f18c0baa2 100644
--- a/src/Aguacongas.TheIdServer/Models/DbTypes.cs
+++ b/src/Aguacongas.TheIdServer/Models/DbTypes.cs
@@ -10,5 +10,6 @@ public enum DbTypes
MySql,
Oracle,
PostgreSQL,
+ RavenDb
}
}
diff --git a/src/Aguacongas.TheIdServer/Models/RavenDbOptions.cs b/src/Aguacongas.TheIdServer/Models/RavenDbOptions.cs
new file mode 100644
index 000000000..21f9ebaba
--- /dev/null
+++ b/src/Aguacongas.TheIdServer/Models/RavenDbOptions.cs
@@ -0,0 +1,16 @@
+// Project: Aguafrommars/TheIdServer
+// Copyright (c) 2021 @Olivier Lefebvre
+
+namespace Aguacongas.TheIdServer.Models
+{
+ public class RavenDbOptions
+ {
+ public string[] Urls { get; set; }
+
+ public string Database { get; set; }
+
+ public string CertificatePath { get; set; }
+
+ public string CertificatePassword { get; set; }
+ }
+}
diff --git a/src/Aguacongas.TheIdServer/SeedData.cs b/src/Aguacongas.TheIdServer/SeedData.cs
index 59d26368a..38ef08efb 100644
--- a/src/Aguacongas.TheIdServer/SeedData.cs
+++ b/src/Aguacongas.TheIdServer/SeedData.cs
@@ -15,33 +15,24 @@
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
+using Entity = Aguacongas.IdentityServer.Store.Entity;
namespace Aguacongas.TheIdServer
{
-#pragma warning disable S1118 // Utility classes should not have public constructors
- public static class SeedData
-#pragma warning restore S1118 // Utility classes should not have public constructors
+ static class SeedData
{
public static void EnsureSeedData(IConfiguration configuration)
{
var services = new ServiceCollection();
- services.AddLogging()
- .AddDbContext(options => options.UseDatabaseFromConfiguration(configuration))
- .AddConfigurationEntityFrameworkStores(options => options.UseDatabaseFromConfiguration(configuration))
- .AddOperationalEntityFrameworkStores(options => options.UseDatabaseFromConfiguration(configuration))
- .AddIdentity()
- .AddEntityFrameworkStores()
- .AddDefaultTokenProviders();
-
- services.AddIdentityServer()
- .AddAspNetIdentity();
+ var startup = new Startup(configuration, null);
+ startup.ConfigureServices(services);
using var serviceProvider = services.BuildServiceProvider();
using var scope = serviceProvider.CreateScope();
var dbType = configuration.GetValue("DbType");
- if (dbType != DbTypes.InMemory)
+ if (dbType != DbTypes.InMemory && dbType != DbTypes.RavenDb)
{
var configContext = scope.ServiceProvider.GetRequiredService();
configContext.Database.Migrate();
@@ -59,54 +50,427 @@ public static void EnsureSeedData(IConfiguration configuration)
public static void SeedConfiguration(IServiceScope scope, IConfiguration configuration)
{
- var provider = scope.ServiceProvider;
-
- var context = provider.GetRequiredService();
+ var provider = scope.ServiceProvider;
+ SeedClients(configuration, provider);
+ SeedIdentities(provider);
+ SeedApiScopes(configuration, provider);
+ SeedApis(configuration, provider);
+ }
+
+ private static void SeedApis(IConfiguration configuration, IServiceProvider provider)
+ {
+ var apiStore = provider.GetRequiredService>();
+ var apiClaimStore = provider.GetRequiredService>();
+ var apiSecretStore = provider.GetRequiredService>();
+ var apiApiScopeStore = provider.GetRequiredService>();
+ var apiPropertyStore = provider.GetRequiredService>();
- if (!context.Clients.Any())
+ foreach (var resource in Config.GetApis(configuration))
{
- foreach (var client in Config.GetClients(configuration))
- {
- context.Clients.Add(client.ToEntity());
- Console.WriteLine($"Add client {client.ClientName}");
+ if (apiStore.GetAsync(resource.Name, null).GetAwaiter().GetResult() != null)
+ {
+ continue;
}
- }
- if (!context.Identities.Any())
- {
- foreach (var resource in Config.GetIdentityResources())
- {
- context.Identities.Add(resource.ToEntity());
- Console.WriteLine($"Add identity resource {resource.DisplayName}");
- }
+ apiStore.CreateAsync(new Entity.ProtectResource
+ {
+ Description = resource.Description,
+ DisplayName = resource.DisplayName,
+ Enabled = resource.Enabled,
+ Id = resource.Name,
+ }).GetAwaiter().GetResult();
+ SeedApiClaims(apiClaimStore, resource);
+ SeedApiSecrets(apiSecretStore, resource);
+ SeedApiApiScopes(apiApiScopeStore, resource);
+ SeedApiProperties(apiPropertyStore, resource);
+
+ Console.WriteLine($"Add api resource {resource.DisplayName}");
}
+ }
+
+ private static void SeedApiProperties(IAdminStore apiPropertyStore, IdentityServer4.Models.ApiResource resource)
+ {
+ foreach (var property in resource.Properties)
+ {
+ apiPropertyStore.CreateAsync(new Entity.ApiProperty
+ {
+ ApiId = resource.Name,
+ Id = Guid.NewGuid().ToString(),
+ Key = property.Key,
+ Value = property.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedApiApiScopes(IAdminStore apiApiScopeStore, IdentityServer4.Models.ApiResource resource)
+ {
+ foreach (var apiScope in resource.Scopes)
+ {
+ apiApiScopeStore.CreateAsync(new Entity.ApiApiScope
+ {
+ ApiId = resource.Name,
+ ApiScopeId = apiScope,
+ Id = Guid.NewGuid().ToString()
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedApiSecrets(IAdminStore apiSecretStore, IdentityServer4.Models.ApiResource resource)
+ {
+ foreach (var secret in resource.ApiSecrets)
+ {
+ apiSecretStore.CreateAsync(new Entity.ApiSecret
+ {
+ ApiId = resource.Name,
+ Expiration = secret.Expiration,
+ Description = secret.Description,
+ Id = Guid.NewGuid().ToString(),
+ Type = secret.Type,
+ Value = secret.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedApiClaims(IAdminStore apiClaimStore, IdentityServer4.Models.ApiResource resource)
+ {
+ foreach (var claim in resource.UserClaims)
+ {
+ apiClaimStore.CreateAsync(new Entity.ApiClaim
+ {
+ ApiId = resource.Name,
+ Id = Guid.NewGuid().ToString(),
+ Type = claim
+ }).GetAwaiter().GetResult();
+ }
+ }
- if (!context.ApiScopes.Any())
+ private static void SeedApiScopes(IConfiguration configuration, IServiceProvider provider)
+ {
+ var apiScopeStore = provider.GetRequiredService>();
+ var apiScopeClaimStore = provider.GetRequiredService>();
+ var apiScopePropertyStore = provider.GetRequiredService>();
+ foreach (var resource in Config.GetApiScopes(configuration))
{
- foreach (var resource in Config.GetApiScopes(configuration))
- {
- context.ApiScopes.Add(resource.ToEntity());
- Console.WriteLine($"Add api scope resource {resource.DisplayName}");
+ if (apiScopeStore.GetAsync(resource.Name, null).GetAwaiter().GetResult() != null)
+ {
+ continue;
}
- }
- if (!context.Apis.Any())
+ apiScopeStore.CreateAsync(new Entity.ApiScope
+ {
+ Description = resource.Description,
+ DisplayName = resource.DisplayName,
+ Emphasize = resource.Emphasize,
+ Enabled = resource.Enabled,
+ Id = resource.Name,
+ Required = resource.Required,
+ ShowInDiscoveryDocument = resource.ShowInDiscoveryDocument
+ }).GetAwaiter().GetResult();
+
+ SeedApiScopeClaims(apiScopeClaimStore, resource);
+ SeedApiScopeProperties(apiScopePropertyStore, resource);
+
+ Console.WriteLine($"Add api scope resource {resource.DisplayName}");
+ }
+ }
+
+ private static void SeedApiScopeProperties(IAdminStore apiScopePropertyStore, IdentityServer4.Models.ApiScope resource)
+ {
+ foreach (var property in resource.Properties)
+ {
+ apiScopePropertyStore.CreateAsync(new Entity.ApiScopeProperty
+ {
+ ApiScopeId = resource.Name,
+ Id = Guid.NewGuid().ToString(),
+ Key = property.Key,
+ Value = property.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedApiScopeClaims(IAdminStore apiScopeClaimStore, IdentityServer4.Models.ApiScope resource)
+ {
+ foreach (var claim in resource.UserClaims)
+ {
+ apiScopeClaimStore.CreateAsync(new Entity.ApiScopeClaim
+ {
+ ApiScopeId = resource.Name,
+ Id = Guid.NewGuid().ToString(),
+ Type = claim
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedIdentities(IServiceProvider provider)
+ {
+ var identityStore = provider.GetRequiredService>();
+ var identityClaimStore = provider.GetRequiredService>();
+ var identityPropertyStore = provider.GetRequiredService>();
+ foreach (var resource in Config.GetIdentityResources())
{
- foreach (var resource in Config.GetApis(configuration))
- {
- context.Apis.Add(resource.ToEntity());
- Console.WriteLine($"Add api resource {resource.DisplayName}");
+ if (identityStore.GetAsync(resource.Name, null).GetAwaiter().GetResult() != null)
+ {
+ continue;
}
- }
- context.SaveChanges();
- }
+ identityStore.CreateAsync(new Entity.IdentityResource
+ {
+ Description = resource.Description,
+ DisplayName = resource.DisplayName,
+ Emphasize = resource.Emphasize,
+ Enabled = resource.Enabled,
+ Id = resource.Name,
+ Required = resource.Required,
+ ShowInDiscoveryDocument = resource.ShowInDiscoveryDocument
+ }).GetAwaiter().GetResult();
+ SeedIdentityClaims(identityClaimStore, resource);
+ SeedIdentityProperties(identityPropertyStore, resource);
+
+ Console.WriteLine($"Add identity resource {resource.DisplayName}");
+ }
+ }
+
+ private static void SeedIdentityProperties(IAdminStore identityPropertyStore, IdentityServer4.Models.IdentityResource resource)
+ {
+ foreach (var property in resource.Properties)
+ {
+ identityPropertyStore.CreateAsync(new Entity.IdentityProperty
+ {
+ Id = Guid.NewGuid().ToString(),
+ IdentityId = resource.Name,
+ Key = property.Key,
+ Value = property.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedIdentityClaims(IAdminStore identityClaimStore, IdentityServer4.Models.IdentityResource resource)
+ {
+ foreach (var claim in resource.UserClaims)
+ {
+ identityClaimStore.CreateAsync(new Entity.IdentityClaim
+ {
+ Id = Guid.NewGuid().ToString(),
+ IdentityId = resource.Name,
+ Type = claim
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClients(IConfiguration configuration, IServiceProvider provider)
+ {
+ var clientStore = provider.GetRequiredService>();
+ var clientGrantTypeStore = provider.GetRequiredService>();
+ var clientScopeStore = provider.GetRequiredService>();
+ var clientClaimStore = provider.GetRequiredService>();
+ var clientSecretStore = provider.GetRequiredService>();
+ var clientIdpRestrictionStore = provider.GetRequiredService>();
+ var clientUriStore = provider.GetRequiredService>();
+ var clientPropertyStore = provider.GetRequiredService>();
+ foreach (var client in Config.GetClients(configuration))
+ {
+ if (clientStore.GetAsync(client.ClientId, null).GetAwaiter().GetResult() != null)
+ {
+ continue;
+ }
+
+ clientStore.CreateAsync(new Entity.Client
+ {
+ AbsoluteRefreshTokenLifetime = client.AbsoluteRefreshTokenLifetime,
+ AccessTokenLifetime = client.AccessTokenLifetime,
+ AccessTokenType = (int)client.AccessTokenType,
+ AllowAccessTokensViaBrowser = client.AllowAccessTokensViaBrowser,
+ AllowOfflineAccess = client.AllowOfflineAccess,
+ AllowPlainTextPkce = client.AllowPlainTextPkce,
+ AllowRememberConsent = client.AllowRememberConsent,
+ AlwaysIncludeUserClaimsInIdToken = client.AlwaysIncludeUserClaimsInIdToken,
+ AlwaysSendClientClaims = client.AlwaysSendClientClaims,
+ AuthorizationCodeLifetime = client.AuthorizationCodeLifetime,
+ BackChannelLogoutSessionRequired = client.BackChannelLogoutSessionRequired,
+ BackChannelLogoutUri = client.BackChannelLogoutUri,
+ ClientClaimsPrefix = client.ClientClaimsPrefix,
+ ClientName = client.ClientName,
+ ClientUri = client.ClientUri,
+ ConsentLifetime = client.ConsentLifetime,
+ Description = client.Description,
+ DeviceCodeLifetime = client.DeviceCodeLifetime,
+ Enabled = client.Enabled,
+ EnableLocalLogin = client.EnableLocalLogin,
+ FrontChannelLogoutSessionRequired = client.FrontChannelLogoutSessionRequired,
+ FrontChannelLogoutUri = client.FrontChannelLogoutUri,
+ Id = client.ClientId,
+ IdentityTokenLifetime = client.IdentityTokenLifetime,
+ IncludeJwtId = client.IncludeJwtId,
+ LogoUri = client.LogoUri,
+ PairWiseSubjectSalt = client.PairWiseSubjectSalt,
+ ProtocolType = client.ProtocolType,
+ RefreshTokenExpiration = (int)client.RefreshTokenExpiration,
+ RefreshTokenUsage = (int)client.RefreshTokenUsage,
+ RequireClientSecret = client.RequireClientSecret,
+ RequireConsent = client.RequireConsent,
+ RequirePkce = client.RequirePkce,
+ SlidingRefreshTokenLifetime = client.SlidingRefreshTokenLifetime,
+ UpdateAccessTokenClaimsOnRefresh = client.UpdateAccessTokenClaimsOnRefresh,
+ UserCodeType = client.UserCodeType,
+ UserSsoLifetime = client.UserSsoLifetime
+ }).GetAwaiter().GetResult();
+ SeedClientGrantType(clientGrantTypeStore, client);
+ SeedClientScopes(clientScopeStore, client);
+ SeedClientClaims(clientClaimStore, client);
+ SeedClientSecrets(clientSecretStore, client);
+ SeedClientRestrictions(clientIdpRestrictionStore, client);
+ SeedClientProperties(clientPropertyStore, client);
+ SeedClientUris(clientUriStore, client);
+
+ Console.WriteLine($"Add client {client.ClientName}");
+ }
+ }
+
+ private static void SeedClientUris(IAdminStore clientUriStore, IdentityServer4.Models.Client client)
+ {
+ var uris = client.RedirectUris.Select(o => new Entity.ClientUri
+ {
+ Id = Guid.NewGuid().ToString(),
+ ClientId = client.ClientId,
+ Uri = o
+ }).ToList();
+
+ foreach (var origin in client.AllowedCorsOrigins)
+ {
+ var cors = new Uri(origin);
+ var uri = uris.FirstOrDefault(u => cors.CorsMatch(u.Uri));
+ var corsUri = new Uri(origin);
+ var sanetized = $"{corsUri.Scheme.ToUpperInvariant()}://{corsUri.Host.ToUpperInvariant()}:{corsUri.Port}";
+
+ if (uri == null)
+ {
+
+ uris.Add(new Entity.ClientUri
+ {
+ Id = Guid.NewGuid().ToString(),
+ ClientId = client.ClientId,
+ Uri = origin,
+ Kind = Entity.UriKinds.Cors,
+ SanetizedCorsUri = sanetized
+ });
+ continue;
+ }
+
+ uri.SanetizedCorsUri = sanetized;
+ uri.Kind = Entity.UriKinds.Redirect | Entity.UriKinds.Cors;
+ }
+
+ foreach (var postLogout in client.PostLogoutRedirectUris)
+ {
+ var uri = uris.FirstOrDefault(u => u.Uri == postLogout);
+ if (uri == null)
+ {
+ uris.Add(new Entity.ClientUri
+ {
+ Id = Guid.NewGuid().ToString(),
+ ClientId = client.ClientId,
+ Uri = postLogout,
+ Kind = Entity.UriKinds.PostLogout
+ });
+ continue;
+ }
+
+ uri.Kind |= Entity.UriKinds.Redirect;
+ }
+
+ foreach (var uri in uris)
+ {
+ clientUriStore.CreateAsync(uri).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClientProperties(IAdminStore clientPropertyStore, IdentityServer4.Models.Client client)
+ {
+ foreach (var property in client.Properties)
+ {
+ clientPropertyStore.CreateAsync(new Entity.ClientProperty
+ {
+ ClientId = client.ClientId,
+ Id = Guid.NewGuid().ToString(),
+ Key = property.Key,
+ Value = property.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClientRestrictions(IAdminStore clientIdpRestrictionStore, IdentityServer4.Models.Client client)
+ {
+ foreach (var restriction in client.IdentityProviderRestrictions)
+ {
+ clientIdpRestrictionStore.CreateAsync(new Entity.ClientIdpRestriction
+ {
+ ClientId = client.ClientId,
+ Id = Guid.NewGuid().ToString(),
+ Provider = restriction
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClientSecrets(IAdminStore clientSecretStore, IdentityServer4.Models.Client client)
+ {
+ foreach (var secret in client.ClientSecrets)
+ {
+ clientSecretStore.CreateAsync(new Entity.ClientSecret
+ {
+ ClientId = client.ClientId,
+ Description = secret.Description,
+ Expiration = secret.Expiration,
+ Id = Guid.NewGuid().ToString(),
+ Type = secret.Type,
+ Value = secret.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClientClaims(IAdminStore clientClaimStore, IdentityServer4.Models.Client client)
+ {
+ foreach (var claim in client.Claims)
+ {
+ clientClaimStore.CreateAsync(new Entity.ClientClaim
+ {
+ ClientId = client.ClientId,
+ Id = Guid.NewGuid().ToString(),
+ Type = claim.Type,
+ Value = claim.Value
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClientScopes(IAdminStore clientScopeStore, IdentityServer4.Models.Client client)
+ {
+ foreach (var clientScope in client.AllowedScopes)
+ {
+ clientScopeStore.CreateAsync(new Entity.ClientScope
+ {
+ ClientId = client.ClientId,
+ Scope = clientScope,
+ Id = Guid.NewGuid().ToString()
+ }).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void SeedClientGrantType(IAdminStore clientGrantTypeStore, IdentityServer4.Models.Client client)
+ {
+ foreach (var grantType in client.AllowedGrantTypes)
+ {
+ clientGrantTypeStore.CreateAsync(new Entity.ClientGrantType
+ {
+ ClientId = client.ClientId,
+ GrantType = grantType,
+ Id = Guid.NewGuid().ToString()
+ }).GetAwaiter().GetResult();
+ }
+ }
+
public static void SeedUsers(IServiceScope scope, IConfiguration configuration)
{
var provider = scope.ServiceProvider;
-
- var context = provider.GetService();
var roleMgr = provider.GetRequiredService>();
@@ -156,8 +520,6 @@ public static void SeedUsers(IServiceScope scope, IConfiguration configuration)
index++;
}
-
- context.SaveChanges();
}
[SuppressMessage("Major Code Smell", "S112:General exceptions should never be thrown", Justification = "Seeding")]
@@ -168,7 +530,6 @@ private static async Task ExcuteAndCheckResult(Func> action
{
throw new Exception(result.Errors.First().Description);
}
-
}
}
}
diff --git a/src/Aguacongas.TheIdServer/Services/PreRenderStringLocalizer.cs b/src/Aguacongas.TheIdServer/Services/PreRenderStringLocalizer.cs
index 90f511055..121900216 100644
--- a/src/Aguacongas.TheIdServer/Services/PreRenderStringLocalizer.cs
+++ b/src/Aguacongas.TheIdServer/Services/PreRenderStringLocalizer.cs
@@ -1,7 +1,5 @@
// Project: Aguafrommars/TheIdServer
// Copyright (c) 2021 @Olivier Lefebvre
-using Aguacongas.IdentityServer.Store;
-using Aguacongas.IdentityServer.Store.Entity;
using Aguacongas.TheIdServer.BlazorApp.Infrastructure.Services;
using Aguacongas.TheIdServer.BlazorApp.Services;
using Microsoft.Extensions.Localization;
@@ -11,7 +9,7 @@ namespace Aguacongas.TheIdServer.Services
{
public class PreRenderStringLocalizer : StringLocalizer
{
- public PreRenderStringLocalizer(IAdminStore store, IReadOnlyCultureStore cultureStore, ILogger logger) : base(store, cultureStore, logger)
+ public PreRenderStringLocalizer(IReadOnlyLocalizedResourceStore store, IReadOnlyCultureStore cultureStore, ILogger logger) : base(store, cultureStore, logger)
{
GetSupportedCulturesAsync().GetAwaiter().GetResult();
}
diff --git a/src/Aguacongas.TheIdServer/Startup.cs b/src/Aguacongas.TheIdServer/Startup.cs
index 31b11a01a..8603cd8e3 100644
--- a/src/Aguacongas.TheIdServer/Startup.cs
+++ b/src/Aguacongas.TheIdServer/Startup.cs
@@ -1,52 +1,55 @@
-// Project: Aguafrommars/TheIdServer
-// Copyright (c) 2021 @Olivier Lefebvre
-using Aguacongas.IdentityServer;
-using Aguacongas.IdentityServer.Abstractions;
-using Aguacongas.IdentityServer.Admin.Http.Store;
-using Aguacongas.IdentityServer.Admin.Options;
-using Aguacongas.IdentityServer.Admin.Services;
-using Aguacongas.IdentityServer.EntityFramework.Store;
-using Aguacongas.IdentityServer.Store;
-using Aguacongas.TheIdServer.Admin.Hubs;
-using Aguacongas.TheIdServer.BlazorApp.Infrastructure.Services;
-using Aguacongas.TheIdServer.BlazorApp.Models;
-using Aguacongas.TheIdServer.BlazorApp.Services;
+// Project: Aguafrommars/TheIdServer
+// Copyright (c) 2021 @Olivier Lefebvre
+using Aguacongas.IdentityServer;
+using Aguacongas.IdentityServer.Abstractions;
+using Aguacongas.IdentityServer.Admin.Http.Store;
+using Aguacongas.IdentityServer.Admin.Options;
+using Aguacongas.IdentityServer.Admin.Services;
+using Aguacongas.IdentityServer.EntityFramework.Store;
+using Aguacongas.IdentityServer.Store;
+using Aguacongas.TheIdServer.Admin.Hubs;
+using Aguacongas.TheIdServer.BlazorApp.Infrastructure.Services;
+using Aguacongas.TheIdServer.BlazorApp.Models;
+using Aguacongas.TheIdServer.BlazorApp.Services;
using Aguacongas.TheIdServer.Data;
-using Aguacongas.TheIdServer.Models;
-using Aguacongas.TheIdServer.Services;
-using IdentityModel.AspNetCore.OAuth2Introspection;
-using IdentityServer4.Quickstart.UI;
-using IdentityServer4.Services;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Aguacongas.TheIdServer.Models;
+using Aguacongas.TheIdServer.Services;
+using IdentityModel.AspNetCore.OAuth2Introspection;
+using IdentityServer4.Quickstart.UI;
+using IdentityServer4.Services;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Components.Authorization;
-using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
-using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
-using Microsoft.AspNetCore.Components.WebAssembly.Services;
+using Microsoft.AspNetCore.Components.Authorization;
+using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
+using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
+using Microsoft.AspNetCore.Components.WebAssembly.Services;
using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.AspNetCore.Localization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.IdentityModel.Tokens;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
+using Raven.Client.Documents;
using Serilog;
-using System;
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
using Auth = Aguacongas.TheIdServer.Authentication;
-
+using RavenDbStore = Aguacongas.IdentityServer.RavenDb.Store;
+
namespace Aguacongas.TheIdServer
{
public class Startup
@@ -54,144 +57,153 @@ public class Startup
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; }
+ public DbTypes DbType { get; }
+
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
+ DbType = Configuration.GetValue("DbType");
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
- {
- var isProxy = Configuration.GetValue("Proxy");
-
- void configureOptions(IdentityServerOptions options)
- => Configuration.GetSection("PrivateServerAuthentication").Bind(options);
-
- services.AddConfigurationHttpStores(configureOptions);
-
- if (isProxy)
- {
- AddProxyServices(services, configureOptions);
- }
- else
- {
- AddDefaultServices(services);
- }
-
- ConfigureDataProtection(services);
-
- var identityBuilder = services.AddClaimsProviders(Configuration)
- .Configure(Configuration.GetSection(nameof(ForwardedHeadersOptions)))
- .Configure(Configuration.GetSection(nameof(AccountOptions)))
- .Configure(Configuration.GetSection(nameof(DynamicClientRegistrationOptions)))
- .Configure(Configuration.GetSection(nameof(TokenValidationParameters)))
- .Configure(Configuration.GetSection(nameof(SiteOptions)))
- .ConfigureNonBreakingSameSiteCookies()
- .AddOidcStateDataFormatterCache()
- .AddIdentityServer(Configuration.GetSection(nameof(IdentityServerOptions)))
- .AddAspNetIdentity()
- .AddDynamicClientRegistration()
- .ConfigureKey(Configuration.GetSection("IdentityServer:Key"));
-
- identityBuilder.AddJwtRequestUriHttpClient();
-
- if (isProxy)
- {
- identityBuilder.Services.AddTransient(p =>
- {
- var options = p.GetRequiredService>().Value;
- var httpClient = p.GetRequiredService().CreateClient(options.HttpClientName);
- return new ProxyProfilService(httpClient,
- p.GetRequiredService>(),
- p.GetRequiredService>(),
- p.GetRequiredService>(),
- p.GetRequiredService>>());
- });
- }
- else
- {
- identityBuilder.AddProfileService>();
- if (!Configuration.GetValue("DisableTokenCleanup"))
- {
- identityBuilder.AddTokenCleaner(Configuration.GetValue("TokenCleanupInterval") ?? TimeSpan.FromMinutes(1));
- }
- }
-
- services.AddTransient(p =>
- {
- var handler = new HttpClientHandler();
- if (Configuration.GetValue("DisableStrictSsl"))
- {
-#pragma warning disable S4830 // Server certificates should be verified during SSL/TLS connections
- handler.ServerCertificateCustomValidationCallback = (message, cert, chain, policy) => true;
-#pragma warning restore S4830 // Server certificates should be verified during SSL/TLS connections
- }
- return handler;
- })
- .AddHttpClient(OAuth2IntrospectionDefaults.BackChannelHttpClientName)
- .ConfigurePrimaryHttpMessageHandler(p => p.GetRequiredService());
-
+ {
+ var isProxy = Configuration.GetValue("Proxy");
+
+ void configureOptions(IdentityServerOptions options)
+ => Configuration.GetSection("PrivateServerAuthentication").Bind(options);
+
+ services.AddConfigurationHttpStores(configureOptions);
+
+ if (isProxy)
+ {
+ AddProxyServices(services, configureOptions);
+ }
+ else
+ {
+ AddDefaultServices(services);
+ }
+
+ ConfigureDataProtection(services);
+
+ var identityBuilder = services.AddClaimsProviders(Configuration)
+ .Configure(Configuration.GetSection(nameof(ForwardedHeadersOptions)))
+ .Configure(Configuration.GetSection(nameof(AccountOptions)))
+ .Configure(Configuration.GetSection(nameof(DynamicClientRegistrationOptions)))
+ .Configure(Configuration.GetSection(nameof(TokenValidationParameters)))
+ .Configure(Configuration.GetSection(nameof(SiteOptions)))
+ .ConfigureNonBreakingSameSiteCookies()
+ .AddOidcStateDataFormatterCache()
+ .AddIdentityServer(Configuration.GetSection(nameof(IdentityServerOptions)))
+ .AddAspNetIdentity()
+ .AddDynamicClientRegistration()
+ .ConfigureKey(Configuration.GetSection("IdentityServer:Key"));
+
+ identityBuilder.AddJwtRequestUriHttpClient();
+
+ if (isProxy)
+ {
+ identityBuilder.Services.AddTransient(p =>
+ {
+ var options = p.GetRequiredService>().Value;
+ var httpClient = p.GetRequiredService().CreateClient(options.HttpClientName);
+ return new ProxyProfilService(httpClient,
+ p.GetRequiredService>(),
+ p.GetRequiredService>(),
+ p.GetRequiredService>(),
+ p.GetRequiredService>>());
+ });
+ }
+ else
+ {
+ identityBuilder.AddProfileService>();
+ if (!Configuration.GetValue("DisableTokenCleanup"))
+ {
+ identityBuilder.AddTokenCleaner(Configuration.GetValue("TokenCleanupInterval") ?? TimeSpan.FromMinutes(1));
+ }
+ }
+
+ services.AddTransient(p =>
+ {
+ var handler = new HttpClientHandler();
+ if (Configuration.GetValue("DisableStrictSsl"))
+ {
+#pragma warning disable S4830 // Server certificates should be verified during SSL/TLS connections
+ handler.ServerCertificateCustomValidationCallback = (message, cert, chain, policy) => true;
+#pragma warning restore S4830 // Server certificates should be verified during SSL/TLS connections
+ }
+ return handler;
+ })
+ .AddHttpClient(OAuth2IntrospectionDefaults.BackChannelHttpClientName)
+ .ConfigurePrimaryHttpMessageHandler(p => p.GetRequiredService());
+
services.Configure(Configuration.GetSection("Google"))
.AddAuthorization(options =>
options.AddIdentityServerPolicies())
.AddAuthentication()
- .AddJwtBearer("Bearer", options => ConfigureIdentityServerAuthenticationOptions(options))
- // reference tokens
- .AddOAuth2Introspection("introspection", options => ConfigureIdentityServerAuthenticationOptions(options));
-
-
+ .AddJwtBearer("Bearer", options => ConfigureIdentityServerAuthenticationOptions(options))
+ // reference tokens
+ .AddOAuth2Introspection("introspection", options => ConfigureIdentityServerAuthenticationOptions(options));
+
+
var mvcBuilder = services.Configure(Configuration)
.AddLocalization()
.AddControllersWithViews(options =>
options.AddIdentityServerAdminFilters())
- .AddViewLocalization()
+ .AddViewLocalization()
.AddDataAnnotationsLocalization()
.AddNewtonsoftJson(options =>
{
var settings = options.SerializerSettings;
settings.NullValueHandling = NullValueHandling.Ignore;
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
- });
-
- if (isProxy)
- {
- mvcBuilder.AddIdentityServerAdmin()
- .AddTheIdServerHttpStore();
+ });
+
+ if (isProxy)
+ {
+ mvcBuilder.AddIdentityServerAdmin()
+ .AddTheIdServerHttpStore();
+ }
+ else if (DbType == DbTypes.RavenDb)
+ {
+ mvcBuilder.AddIdentityServerAdmin()
+ .AddRavenDbStore();
}
- else
- {
- mvcBuilder.AddIdentityServerAdmin()
- .AddEntityFrameworkStore();
- }
-
- services.AddRemoteAuthentication();
- services.AddScoped()
- .AddScoped()
- .AddScoped()
- .AddScoped()
- .AddTransient()
- .AddTransient()
- .AddTransient()
- .AddTransient>(p => new KeyStore(p.CreateApiHttpClient(p.GetRequiredService>().Value),
- p.GetRequiredService>>()))
- .AddTransient>(p => new KeyStore(p.CreateApiHttpClient(p.GetRequiredService>().Value),
- p.GetRequiredService>>()))
- .AddAdminApplication(new Settings())
- .AddDatabaseDeveloperPageExceptionFilter()
+ else
+ {
+ mvcBuilder.AddIdentityServerAdmin()
+ .AddEntityFrameworkStore();
+ }
+
+ services.AddRemoteAuthentication();
+ services.AddScoped()
+ .AddScoped()
+ .AddScoped()
+ .AddScoped()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient()
+ .AddTransient>(p => new KeyStore(p.CreateApiHttpClient(p.GetRequiredService>().Value),
+ p.GetRequiredService>>()))
+ .AddTransient>(p => new KeyStore(p.CreateApiHttpClient(p.GetRequiredService>().Value),
+ p.GetRequiredService>>()))
+ .AddAdminApplication(new Settings())
+ .AddDatabaseDeveloperPageExceptionFilter()
.AddRazorPages(options => options.Conventions.AuthorizeAreaFolder("Identity", "/Account"));
- }
-
+ }
+
[SuppressMessage("Usage", "ASP0001:Authorization middleware is incorrectly configured.", Justification = "")]
public void Configure(IApplicationBuilder app)
{
var isProxy = Configuration.GetValue("Proxy");
var disableHttps = Configuration.GetValue("DisableHttps");
- app.UseForwardedHeaders();
+ app.UseForwardedHeaders();
AddForceHttpsSchemeMiddleware(app);
- if (!isProxy)
- {
+ if (!isProxy)
+ {
ConfigureInitialData(app);
}
@@ -207,20 +219,20 @@ public void Configure(IApplicationBuilder app)
{
app.UseHsts();
}
- }
-
+ }
+
var scope = app.ApplicationServices.CreateScope();
var scopedProvider = scope.ServiceProvider;
- var supportedCulture = scopedProvider.GetRequiredService().CulturesNames.ToArray();
-
-
- app.UseRequestLocalization(options =>
- {
- options.DefaultRequestCulture = new RequestCulture("en");
- options.SupportedCultures = supportedCulture.Select(c => new CultureInfo(c)).ToList();
- options.SupportedUICultures = options.SupportedCultures;
- options.FallBackToParentCultures = true;
- options.AddInitialRequestCultureProvider(new SetCookieFromQueryStringRequestCultureProvider());
+ var supportedCulture = scopedProvider.GetRequiredService().CulturesNames.ToArray();
+
+
+ app.UseRequestLocalization(options =>
+ {
+ options.DefaultRequestCulture = new RequestCulture("en");
+ options.SupportedCultures = supportedCulture.Select(c => new CultureInfo(c)).ToList();
+ options.SupportedUICultures = options.SupportedCultures;
+ options.FallBackToParentCultures = true;
+ options.AddInitialRequestCultureProvider(new SetCookieFromQueryStringRequestCultureProvider());
})
.UseSerilogRequestLogging();
@@ -229,246 +241,282 @@ public void Configure(IApplicationBuilder app)
app.UseHttpsRedirection();
}
- app.UseIdentityServerAdminApi("/api", child =>
- {
- if (Configuration.GetValue("EnableOpenApiDoc"))
- {
- child.UseOpenApi()
- .UseSwaggerUi3(options =>
- {
- var settings = Configuration.GetSection("SwaggerUiSettings").Get();
- options.OAuth2Client = settings.OAuth2Client;
- });
- }
- var allowedOrigin = Configuration.GetSection("CorsAllowedOrigin").Get>();
- if (allowedOrigin != null)
- {
- child.UseCors(configure =>
- {
- configure.SetIsOriginAllowed(origin => allowedOrigin.Any(o => o == origin))
- .AllowAnyMethod()
- .AllowAnyHeader()
- .AllowCredentials();
- });
- }
+ app.UseIdentityServerAdminApi("/api", child =>
+ {
+ if (Configuration.GetValue("EnableOpenApiDoc"))
+ {
+ child.UseOpenApi()
+ .UseSwaggerUi3(options =>
+ {
+ var settings = Configuration.GetSection("SwaggerUiSettings").Get();
+ options.OAuth2Client = settings.OAuth2Client;
+ });
+ }
+ var allowedOrigin = Configuration.GetSection("CorsAllowedOrigin").Get>();
+ if (allowedOrigin != null)
+ {
+ child.UseCors(configure =>
+ {
+ configure.SetIsOriginAllowed(origin => allowedOrigin.Any(o => o == origin))
+ .AllowAnyMethod()
+ .AllowAnyHeader()
+ .AllowCredentials();
+ });
+ }
})
.UseBlazorFrameworkFiles()
.UseStaticFiles()
.UseRouting()
- .UseIdentityServer();
-
- if (!isProxy)
- {
- app.UseIdentityServerAdminAuthentication("/providerhub", JwtBearerDefaults.AuthenticationScheme);
- }
+ .UseIdentityServer();
+
+ if (!isProxy)
+ {
+ app.UseIdentityServerAdminAuthentication("/providerhub", JwtBearerDefaults.AuthenticationScheme);
+ }
app
.UseAuthorization()
- .Use((context, next) =>
- {
- var service = context.RequestServices;
- var settings = service.GetRequiredService();
- var request = context.Request;
- settings.WelcomeContenUrl = $"{request.Scheme}://{request.Host}/api/welcomefragment";
- var remotePathOptions = service.GetRequiredService>().Value;
- remotePathOptions.RemoteProfilePath = $"{request.Scheme}://{request.Host}/identity/account/manage";
- remotePathOptions.RemoteRegisterPath = $"{request.Scheme}://{request.Host}/identity/account/register";
- return next();
+ .Use((context, next) =>
+ {
+ var service = context.RequestServices;
+ var settings = service.GetRequiredService();
+ var request = context.Request;
+ settings.WelcomeContenUrl = $"{request.Scheme}://{request.Host}/api/welcomefragment";
+ var remotePathOptions = service.GetRequiredService>().Value;
+ remotePathOptions.RemoteProfilePath = $"{request.Scheme}://{request.Host}/identity/account/manage";
+ remotePathOptions.RemoteRegisterPath = $"{request.Scheme}://{request.Host}/identity/account/register";
+ return next();
})
.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapDefaultControllerRoute();
- if (!isProxy)
- {
- endpoints.MapHub("/providerhub");
- }
-
+ if (!isProxy)
+ {
+ endpoints.MapHub("/providerhub");
+ }
+
endpoints.MapFallbackToPage("/_Host");
});
- if (isProxy)
- {
- app.LoadDynamicAuthenticationConfiguration();
+ if (isProxy)
+ {
+ app.LoadDynamicAuthenticationConfiguration();
+ return;
}
- else
- {
- app.LoadDynamicAuthenticationConfiguration();
- }
- }
-
- private void AddForceHttpsSchemeMiddleware(IApplicationBuilder app)
- {
+ if (DbType == DbTypes.RavenDb)
+ {
+ app.LoadDynamicAuthenticationConfiguration();
+ return;
+ }
+ app.LoadDynamicAuthenticationConfiguration();
+ }
+
+ private void AddForceHttpsSchemeMiddleware(IApplicationBuilder app)
+ {
var forceHttpsScheme = Configuration.GetValue("ForceHttpsScheme");
- if (forceHttpsScheme)
- {
- app.Use((context, next) =>
- {
- context.Request.Scheme = "https";
- return next();
- });
- }
- }
-
- private void ConfigureIdentityServerAuthenticationOptions(JwtBearerOptions options)
- {
- Configuration.GetSection("ApiAuthentication").Bind(options);
- if (Configuration.GetValue("DisableStrictSsl"))
- {
- options.BackchannelHttpHandler = new HttpClientHandler
- {
-#pragma warning disable S4830 // Server certificates should be verified during SSL/TLS connections
- ServerCertificateCustomValidationCallback = (message, cert, chain, policy) => true
-#pragma warning restore S4830 // Server certificates should be verified during SSL/TLS connections
- };
- }
-
- options.Events = new JwtBearerEvents
- {
- OnMessageReceived = context =>
- {
- var request = context.HttpContext.Request;
- var path = request.Path;
- var accessToken = TokenRetrieval.FromQueryString()(request);
- if (path.StartsWithSegments("/providerhub") && !string.IsNullOrEmpty(accessToken))
- {
- context.Token = accessToken;
- return Task.CompletedTask;
- }
- var oneTimeToken = TokenRetrieval.FromQueryString("otk")(request);
- if (!string.IsNullOrEmpty(oneTimeToken))
- {
- context.Token = request.HttpContext
- .RequestServices
- .GetRequiredService()
- .GetOneTimeToken(oneTimeToken);
- }
- return Task.CompletedTask;
- }
- };
-
- options.ForwardDefaultSelector = context =>
- {
- var authHeader = context.Request.Headers[HttpRequestHeader.Authorization.ToString()];
- if (string.IsNullOrEmpty(authHeader))
- {
- return null;
- }
-
- var parts = authHeader.First().Split(' ', StringSplitOptions.RemoveEmptyEntries);
- if (parts.Length != 2)
- {
- return null;
- }
-
- if (!parts[1].Contains("."))
- {
- return "introspection";
- }
-
- return null;
- };
- }
-
- private void ConfigureIdentityServerAuthenticationOptions(OAuth2IntrospectionOptions options)
- {
- Configuration.GetSection("ApiAuthentication").Bind(options);
- options.ClientId = Configuration.GetValue("ApiAuthentication:ApiName");
- options.ClientSecret = Configuration.GetValue("ApiAuthentication:ApiSecret");
- static string tokenRetriever(HttpRequest request)
- {
- var path = request.Path;
- var accessToken = TokenRetrieval.FromQueryString()(request);
- if (path.StartsWithSegments("/providerhub") && !string.IsNullOrEmpty(accessToken))
- {
- return accessToken;
- }
- var oneTimeToken = TokenRetrieval.FromQueryString("otk")(request);
- if (!string.IsNullOrEmpty(oneTimeToken))
- {
- return request.HttpContext
- .RequestServices
- .GetRequiredService()
- .GetOneTimeToken(oneTimeToken);
- }
- return TokenRetrieval.FromAuthorizationHeader()(request);
- }
-
- options.TokenRetriever = tokenRetriever;
- }
-
- private void AddDefaultServices(IServiceCollection services)
- {
- services.Configure(options => Configuration.GetSection("ApiAuthentication").Bind(options))
- .AddTransient>()
- .AddDbContext(options => options.UseDatabaseFromConfiguration(Configuration))
- .AddIdentityServer4AdminEntityFrameworkStores()
- .AddConfigurationEntityFrameworkStores(options => options.UseDatabaseFromConfiguration(Configuration))
- .AddOperationalEntityFrameworkStores(options => options.UseDatabaseFromConfiguration(Configuration))
- .AddIdentityProviderStore();
-
- services.AddIdentity(
- options => Configuration.GetSection(nameof(IdentityOptions)).Bind(options))
- .AddEntityFrameworkStores()
- .AddDefaultTokenProviders();
-
- var signalRBuilder = services.AddSignalR(options => Configuration.GetSection("SignalR:HubOptions").Bind(options));
- if (Configuration.GetValue("SignalR:UseMessagePack"))
- {
- signalRBuilder.AddMessagePackProtocol();
- }
-
- var redisConnectionString = Configuration.GetValue("SignalR:RedisConnectionString");
- if (!string.IsNullOrEmpty(redisConnectionString))
- {
- signalRBuilder.AddStackExchangeRedis(redisConnectionString, options => Configuration.GetSection("SignalR:RedisOptions").Bind(options));
- }
- }
-
- private void AddProxyServices(IServiceCollection services, Action configureOptions)
- {
- services.AddTransient>()
- .AddIdentityProviderStore()
- .AddOperationalHttpStores()
- .AddIdentity(
- options => Configuration.GetSection(nameof(IdentityOptions)).Bind(options))
- .AddTheIdServerStores(configureOptions)
- .AddDefaultTokenProviders();
- }
-
- private void ConfigureInitialData(IApplicationBuilder app)
- {
- var dbType = Configuration.GetValue("DbType");
- if (Configuration.GetValue("Migrate") &&
- dbType != DbTypes.InMemory)
- {
- using var scope = app.ApplicationServices.CreateScope();
- var configContext = scope.ServiceProvider.GetRequiredService();
- configContext.Database.Migrate();
-
- var opContext = scope.ServiceProvider.GetRequiredService();
- opContext.Database.Migrate();
-
- var appcontext = scope.ServiceProvider.GetService();
- appcontext.Database.Migrate();
- }
-
- if (Configuration.GetValue("Seed"))
- {
- using var scope = app.ApplicationServices.CreateScope();
- SeedData.SeedConfiguration(scope, Configuration);
- SeedData.SeedUsers(scope, Configuration);
- }
-
- }
- private void ConfigureDataProtection(IServiceCollection services)
- {
- var dataprotectionSection = Configuration.GetSection(nameof(DataProtectionOptions));
- if (dataprotectionSection != null)
- {
- services.AddDataProtection(options => dataprotectionSection.Bind(options)).ConfigureDataProtection(Configuration.GetSection(nameof(DataProtectionOptions)));
- }
- }
+ if (forceHttpsScheme)
+ {
+ app.Use((context, next) =>
+ {
+ context.Request.Scheme = "https";
+ return next();
+ });
+ }
+ }
+
+ private void ConfigureIdentityServerAuthenticationOptions(JwtBearerOptions options)
+ {
+ Configuration.GetSection("ApiAuthentication").Bind(options);
+ if (Configuration.GetValue("DisableStrictSsl"))
+ {
+ options.BackchannelHttpHandler = new HttpClientHandler
+ {
+#pragma warning disable S4830 // Server certificates should be verified during SSL/TLS connections
+ ServerCertificateCustomValidationCallback = (message, cert, chain, policy) => true
+#pragma warning restore S4830 // Server certificates should be verified during SSL/TLS connections
+ };
+ }
+ options.Audience = Configuration["ApiAuthentication:ApiName"];
+ options.Events = new JwtBearerEvents
+ {
+ OnMessageReceived = context =>
+ {
+ var request = context.HttpContext.Request;
+ var path = request.Path;
+ var accessToken = TokenRetrieval.FromQueryString()(request);
+ if (path.StartsWithSegments("/providerhub") && !string.IsNullOrEmpty(accessToken))
+ {
+ context.Token = accessToken;
+ return Task.CompletedTask;
+ }
+ var oneTimeToken = TokenRetrieval.FromQueryString("otk")(request);
+ if (!string.IsNullOrEmpty(oneTimeToken))
+ {
+ context.Token = request.HttpContext
+ .RequestServices
+ .GetRequiredService()
+ .GetOneTimeToken(oneTimeToken);
+ return Task.CompletedTask;
+ }
+ context.Token = TokenRetrieval.FromAuthorizationHeader()(request);
+ return Task.CompletedTask;
+ }
+ };
+
+ options.ForwardDefaultSelector = context =>
+ {
+ var authHeader = context.Request.Headers[HttpRequestHeader.Authorization.ToString()];
+ if (string.IsNullOrEmpty(authHeader))
+ {
+ return null;
+ }
+
+ var parts = authHeader.First().Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ if (parts.Length != 2)
+ {
+ return null;
+ }
+
+ if (!parts[1].Contains("."))
+ {
+ return "introspection";
+ }
+
+ return null;
+ };
+ }
+
+ private void ConfigureIdentityServerAuthenticationOptions(OAuth2IntrospectionOptions options)
+ {
+ Configuration.GetSection("ApiAuthentication").Bind(options);
+ options.ClientId = Configuration.GetValue("ApiAuthentication:ApiName");
+ options.ClientSecret = Configuration.GetValue("ApiAuthentication:ApiSecret");
+ static string tokenRetriever(HttpRequest request)
+ {
+ var path = request.Path;
+ var accessToken = TokenRetrieval.FromQueryString()(request);
+ if (path.StartsWithSegments("/providerhub") && !string.IsNullOrEmpty(accessToken))
+ {
+ return accessToken;
+ }
+ var oneTimeToken = TokenRetrieval.FromQueryString("otk")(request);
+ if (!string.IsNullOrEmpty(oneTimeToken))
+ {
+ return request.HttpContext
+ .RequestServices
+ .GetRequiredService()
+ .GetOneTimeToken(oneTimeToken);
+ }
+ return TokenRetrieval.FromAuthorizationHeader()(request);
+ }
+
+ options.TokenRetriever = tokenRetriever;
+ }
+
+ private void AddDefaultServices(IServiceCollection services)
+ {
+ services.Configure(options => Configuration.GetSection("ApiAuthentication").Bind(options))
+ .AddIdentityProviderStore();
+
+ var identityBuilder = services.AddIdentity(
+ options => Configuration.GetSection(nameof(IdentityOptions)).Bind(options))
+ .AddDefaultTokenProviders();
+
+ if (DbType == DbTypes.RavenDb)
+ {
+ services.Configure(options => Configuration.GetSection(nameof(RavenDbOptions)).Bind(options))
+ .AddSingleton(p =>
+ {
+ var options = p.GetRequiredService>().Value;
+ var documentStore = new DocumentStore
+ {
+ Urls = options.Urls,
+ Database = options.Database,
+ };
+ if (!string.IsNullOrWhiteSpace(options.CertificatePath))
+ {
+ documentStore.Certificate = new X509Certificate2(options.CertificatePath, options.CertificatePassword);
+ }
+ documentStore.SetFindIdentityPropertyForIdentityServerStores();
+ return documentStore.Initialize();
+ })
+ .AddTransient>()
+ .AddIdentityServer4AdminRavenDbkStores()
+ .AddConfigurationRavenDbkStores()
+ .AddOperationalRavenDbStores();
+
+ identityBuilder.AddRavenDbStores();
+ }
+ else
+ {
+ services.AddTransient>()
+ .AddDbContext(options => options.UseDatabaseFromConfiguration(Configuration))
+ .AddIdentityServer4AdminEntityFrameworkStores()
+ .AddConfigurationEntityFrameworkStores(options => options.UseDatabaseFromConfiguration(Configuration))
+ .AddOperationalEntityFrameworkStores(options => options.UseDatabaseFromConfiguration(Configuration));
+
+ identityBuilder.AddEntityFrameworkStores();
+ }
+
+
+ var signalRBuilder = services.AddSignalR(options => Configuration.GetSection("SignalR:HubOptions").Bind(options));
+ if (Configuration.GetValue("SignalR:UseMessagePack"))
+ {
+ signalRBuilder.AddMessagePackProtocol();
+ }
+
+ var redisConnectionString = Configuration.GetValue("SignalR:RedisConnectionString");
+ if (!string.IsNullOrEmpty(redisConnectionString))
+ {
+ signalRBuilder.AddStackExchangeRedis(redisConnectionString, options => Configuration.GetSection("SignalR:RedisOptions").Bind(options));
+ }
+ }
+
+ private void AddProxyServices(IServiceCollection services, Action configureOptions)
+ {
+ services.AddTransient>()
+ .AddIdentityProviderStore()
+ .AddOperationalHttpStores()
+ .AddIdentity(
+ options => Configuration.GetSection(nameof(IdentityOptions)).Bind(options))
+ .AddTheIdServerStores(configureOptions)
+ .AddDefaultTokenProviders();
+ }
+
+ private void ConfigureInitialData(IApplicationBuilder app)
+ {
+ var dbType = Configuration.GetValue("DbType");
+ if (Configuration.GetValue("Migrate") &&
+ dbType != DbTypes.InMemory && dbType != DbTypes.RavenDb)
+ {
+ using var scope = app.ApplicationServices.CreateScope();
+ var configContext = scope.ServiceProvider.GetRequiredService();
+ configContext.Database.Migrate();
+
+ var opContext = scope.ServiceProvider.GetRequiredService();
+ opContext.Database.Migrate();
+
+ var appcontext = scope.ServiceProvider.GetService();
+ appcontext.Database.Migrate();
+ }
+
+ if (Configuration.GetValue("Seed"))
+ {
+ using var scope = app.ApplicationServices.CreateScope();
+ SeedData.SeedConfiguration(scope, Configuration);
+ SeedData.SeedUsers(scope, Configuration);
+ }
+
+ }
+ private void ConfigureDataProtection(IServiceCollection services)
+ {
+ var dataprotectionSection = Configuration.GetSection(nameof(DataProtectionOptions));
+ if (dataprotectionSection != null)
+ {
+ services.AddDataProtection(options => dataprotectionSection.Bind(options)).ConfigureDataProtection(Configuration.GetSection(nameof(DataProtectionOptions)));
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/Aguacongas.TheIdServer/appsettings.Development.json b/src/Aguacongas.TheIdServer/appsettings.Development.json
index 84cf9f0ef..a06bbf568 100644
--- a/src/Aguacongas.TheIdServer/appsettings.Development.json
+++ b/src/Aguacongas.TheIdServer/appsettings.Development.json
@@ -1,10 +1,15 @@
-{
+{
+ "DbType": "RavenDb",
"IdentityServer": {
"Key": {
"KeyRotationOptions": {
"NewKeyLifetime": "14.00:00:00",
"KeyPropagationWindow": "30.00:00:00"
- }
+ },
+ "StorageKind": "RavenDb"
}
+ },
+ "DataProtectionOptions": {
+ "StorageKind": "RavenDb"
}
}
\ No newline at end of file
diff --git a/src/Aguacongas.TheIdServer/appsettings.json b/src/Aguacongas.TheIdServer/appsettings.json
index f859da307..7f25f4d2b 100644
--- a/src/Aguacongas.TheIdServer/appsettings.json
+++ b/src/Aguacongas.TheIdServer/appsettings.json
@@ -2,6 +2,16 @@
"ConnectionStrings": {
"DefaultConnection": "Data Source=(LocalDb)\\MSSQLLocalDB;database=TheIdServer;trusted_connection=yes;"
},
+ "RavenDbOptions": {
+ "Urls": [
+ "https://a.ravendb.local",
+ "https://b.ravendb.local",
+ "https://c.ravendb.local"
+ ],
+ "Database": "TheIdServer",
+ "CertificatePath": "TheIdServer.pfx",
+ "CertificatePassword": "TheIdServer"
+ },
"SiteOptions": {
"Name": "TheIdServer"
},
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/Aguacongas.TheIdServer.BlazorApp.Components.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/Aguacongas.TheIdServer.BlazorApp.Components.csproj
index a2e8dd05b..7e3862788 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/Aguacongas.TheIdServer.BlazorApp.Components.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/Aguacongas.TheIdServer.BlazorApp.Components.csproj
@@ -11,7 +11,7 @@
theidserver;identityserver4;oidc;oauth;identity,authentication;security
TheIdServer administration application components.
Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -20,8 +20,8 @@
-
-
+
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/EntitesGridModel.cs b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/EntitesGridModel.cs
index a38bd7c26..e2cbb8478 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/EntitesGridModel.cs
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Components/EntitesGridModel.cs
@@ -52,7 +52,7 @@ protected virtual void OnStort(SortEventArgs arg)
private void HandleModificationState_OnStateChange(ModificationKind kind, object entity)
{
- if (entity is T)
+ if (entity is T && (kind == ModificationKind.Add || kind == ModificationKind.Delete))
{
StateHasChanged();
}
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Aguacongas.TheIdServer.BlazorApp.Infrastructure.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Aguacongas.TheIdServer.BlazorApp.Infrastructure.csproj
index 31324e5cb..72cbf928f 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Aguacongas.TheIdServer.BlazorApp.Infrastructure.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Aguacongas.TheIdServer.BlazorApp.Infrastructure.csproj
@@ -12,7 +12,7 @@
TheIdServer administration application models, services, validators and extensions.
Full
Aguacongas.TheIdServer.BlazorApp
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -21,13 +21,13 @@
-
-
-
+
+
+
-
-
-
+
+
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Extensions/WebAssemblyHostBuilderExtensions.cs b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Extensions/WebAssemblyHostBuilderExtensions.cs
index a30de9cfa..8cb3eeb24 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Extensions/WebAssemblyHostBuilderExtensions.cs
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Extensions/WebAssemblyHostBuilderExtensions.cs
@@ -77,10 +77,10 @@ public static void ConfigureServices(IServiceCollection services, IConfiguration
.AddHttpMessageHandler();
services.AddScoped()
- .AddTransient>(p =>
+ .AddTransient(p =>
{
var factory = p.GetRequiredService();
- return new AdminStore(Task.FromResult(factory.CreateClient("localizer")), p.GetRequiredService>>());
+ return new ReadOnlyLocalizedResourceStore(new AdminStore(Task.FromResult(factory.CreateClient("localizer")), p.GetRequiredService>>()));
}).AddTransient(p =>
{
var factory = p.GetRequiredService();
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/IReadOnlyLocalizedResourceStore.cs b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/IReadOnlyLocalizedResourceStore.cs
new file mode 100644
index 000000000..136a1fffe
--- /dev/null
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/IReadOnlyLocalizedResourceStore.cs
@@ -0,0 +1,14 @@
+// Project: Aguafrommars/TheIdServer
+// Copyright (c) 2021 @Olivier Lefebvre
+using Aguacongas.IdentityServer.Store;
+using Aguacongas.IdentityServer.Store.Entity;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Aguacongas.TheIdServer.BlazorApp.Services
+{
+ public interface IReadOnlyLocalizedResourceStore
+ {
+ Task> GetAsync(PageRequest pageRequest, CancellationToken cancellationToken = default);
+ }
+}
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/ReadOnlyLocalizedResourceStore.cs b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/ReadOnlyLocalizedResourceStore.cs
new file mode 100644
index 000000000..e3ff67f77
--- /dev/null
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/ReadOnlyLocalizedResourceStore.cs
@@ -0,0 +1,23 @@
+// Project: Aguafrommars/TheIdServer
+// Copyright (c) 2021 @Olivier Lefebvre
+using Aguacongas.IdentityServer.Store;
+using Aguacongas.IdentityServer.Store.Entity;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Aguacongas.TheIdServer.BlazorApp.Services
+{
+ public class ReadOnlyLocalizedResourceStore : IReadOnlyLocalizedResourceStore
+ {
+ private readonly IAdminStore _adminStore;
+
+ public ReadOnlyLocalizedResourceStore(IAdminStore adminStore)
+ {
+ _adminStore = adminStore ?? throw new ArgumentNullException(nameof(adminStore));
+ }
+
+ public Task> GetAsync(PageRequest pageRequest, CancellationToken cancellationToken = default)
+ => _adminStore.GetAsync(pageRequest, cancellationToken);
+ }
+}
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/StringLocalizer.cs b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/StringLocalizer.cs
index 7e6bca509..27aa83958 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/StringLocalizer.cs
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/Services/StringLocalizer.cs
@@ -16,7 +16,7 @@ namespace Aguacongas.TheIdServer.BlazorApp.Infrastructure.Services
{
public class StringLocalizer : ISharedStringLocalizerAsync
{
- private readonly IAdminStore _store;
+ private readonly IReadOnlyLocalizedResourceStore _store;
private readonly IReadOnlyCultureStore _cultureStore;
private IEnumerable _resources;
private IEnumerable _cultureList;
@@ -28,7 +28,7 @@ public class StringLocalizer : ISharedStringLocalizerAsync
public event Action ResourceReady;
- public StringLocalizer(IAdminStore store,
+ public StringLocalizer(IReadOnlyLocalizedResourceStore store,
IReadOnlyCultureStore cultureStore,
ILogger logger)
{
@@ -219,7 +219,7 @@ public void Dispose()
[SuppressMessage("Major Code Smell", "S2326:Unused type parameters should be removed", Justification = "Create an instance by T")]
public class SharedStringLocalizer : StringLocalizer
{
- public SharedStringLocalizer(IAdminStore store,
+ public SharedStringLocalizer(IReadOnlyLocalizedResourceStore store,
IReadOnlyCultureStore cultureStore,
ILogger> logger)
: base(store, cultureStore, logger)
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/wwwroot/TheIdServerInterop.js b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/wwwroot/TheIdServerInterop.js
index d4d7c64d3..80f483192 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/wwwroot/TheIdServerInterop.js
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Infrastructure/wwwroot/TheIdServerInterop.js
@@ -3,7 +3,7 @@
const query = `#${id}`;
$(query).on('hidden.bs.toast', function () {
dotnetHelper.invokeMethodAsync('ToastClosed', id)
- .then(_ => { });
+ .then(_ => { /* invoke it */ });
});
$(query).toast('show');
},
@@ -34,7 +34,7 @@ window.browserInteropt = {
if (key === 13) {
e.preventDefault();
dotnetHelper.invokeMethodAsync('EnterKeyPressed', id)
- .then(_ => { });
+ .then(_ => { /* invoke it */ });
}
};
},
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Api/Aguacongas.TheIdServer.BlazorApp.Pages.Api.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Api/Aguacongas.TheIdServer.BlazorApp.Pages.Api.csproj
index 40763effa..0a93ca78b 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Api/Aguacongas.TheIdServer.BlazorApp.Pages.Api.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Api/Aguacongas.TheIdServer.BlazorApp.Pages.Api.csproj
@@ -11,7 +11,7 @@
theidserver;identityserver4;oidc;oauth;identity,authentication;security
TheIdServer administration application api page and components.
Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -25,7 +25,7 @@
-
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope.csproj
index 3668c1c89..4749dda59 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScope.csproj
@@ -11,7 +11,7 @@
theidserver;identityserver4;oidc;oauth;identity,authentication;security
TheIdServer administration application api scope page and components.
Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -25,7 +25,7 @@
-
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes.csproj
index fcb7431e8..4c0ebf6bc 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes/Aguacongas.TheIdServer.BlazorApp.Pages.ApiScopes.csproj
@@ -11,7 +11,7 @@
theidserver;identityserver4;oidc;oauth;identity,authentication;security
TheIdServer administration application api scope list page.
Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -25,7 +25,7 @@
-
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Apis/Aguacongas.TheIdServer.BlazorApp.Pages.Apis.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Apis/Aguacongas.TheIdServer.BlazorApp.Pages.Apis.csproj
index 0d6805c4f..a146c0a7f 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Apis/Aguacongas.TheIdServer.BlazorApp.Pages.Apis.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Apis/Aguacongas.TheIdServer.BlazorApp.Pages.Apis.csproj
@@ -11,7 +11,7 @@
theidserver;identityserver4;oidc;oauth;identity,authentication;security
TheIdServer administration application api list page.
Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -25,7 +25,7 @@
-
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Aguacongas.TheIdServer.BlazorApp.Pages.Client.csproj b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Aguacongas.TheIdServer.BlazorApp.Pages.Client.csproj
index e3feebf5a..10eb14767 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Aguacongas.TheIdServer.BlazorApp.Pages.Client.csproj
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Aguacongas.TheIdServer.BlazorApp.Pages.Client.csproj
@@ -11,7 +11,7 @@
theidserver;identityserver4;oidc;oauth;identity,authentication;security
TheIdServer administration application client page and components.
Full
- https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
+ https://raw.githubusercontent.com/Aguafrommars/TheIdServer/master/package-icon.png
..\..\..\.sonarlint\aguacongas_theidservercsharp.ruleset
@@ -25,7 +25,7 @@
-
+
diff --git a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Client.razor b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Client.razor
index d1db9ecda..2efad63f3 100644
--- a/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Client.razor
+++ b/src/BlazorApp/Aguacongas.TheIdServer.BlazorApp.Pages.Client/Client.razor
@@ -156,14 +156,7 @@ else
-
+
+
+