Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secrets module (Lombiq Technologies: OCORE-124) #7891

Closed
wants to merge 198 commits into from
Closed
Show file tree
Hide file tree
Changes from 159 commits
Commits
Show all changes
198 commits
Select commit Hold shift + click to select a range
a9b9516
Secrets module
deanmarcussen Aug 7, 2020
c08ab79
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Aug 7, 2020
83b742f
Updates after merging dev
deanmarcussen Aug 7, 2020
6d9b807
Force binding to exist before retrieving secret (stops crossover cont…
deanmarcussen Aug 8, 2020
5742373
Implement for email
deanmarcussen Aug 8, 2020
bb1d25d
poc encryption / decryption service for secrets
deanmarcussen Aug 10, 2020
0c9b104
add recipe step for secrets. validate that it is usable from a setup …
deanmarcussen Aug 11, 2020
2e8824c
Minor tweak
deanmarcussen Aug 15, 2020
fe005dc
Fix issue with casting
deanmarcussen Sep 7, 2020
7e52dc1
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Sep 7, 2020
fd6770d
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Nov 29, 2020
fa89087
Updates after merging dev
deanmarcussen Nov 29, 2020
5639dd3
wip. dropping liquid in favour of view component selectors
deanmarcussen Nov 29, 2020
b8a72cf
wip. viewcomponent picker
deanmarcussen Nov 30, 2020
3a038c8
wip. test coordinator
deanmarcussen Nov 30, 2020
0c3559b
Refactoring rsa key pair
deanmarcussen Nov 30, 2020
7d9f88c
wip. refactoring encryption to transient
deanmarcussen Nov 30, 2020
68d5667
encoding changes
deanmarcussen Nov 30, 2020
77e153a
add settings
deanmarcussen Nov 30, 2020
d421876
Missing view
deanmarcussen Nov 30, 2020
b277291
Merge branch 'deanmarcussen/secrets' of github.com:OrchardCMS/Orchard…
deanmarcussen Nov 30, 2020
baa555f
fix file download target
deanmarcussen Dec 1, 2020
f61bbe0
fix tests
deanmarcussen Dec 1, 2020
80bda2b
refactoring
deanmarcussen Dec 1, 2020
ac5d9f5
default values
deanmarcussen Dec 1, 2020
d0391bc
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Dec 2, 2020
8742202
maintain in one variable
deanmarcussen Dec 2, 2020
720573f
key type
deanmarcussen Dec 2, 2020
55e0951
remote instance secrets
deanmarcussen Dec 3, 2020
bb7f085
wip. workflows
deanmarcussen Dec 3, 2020
90df4e1
workflows
deanmarcussen Dec 6, 2020
2411da8
signing
deanmarcussen Dec 6, 2020
fd92ee9
start activities
deanmarcussen Dec 7, 2020
d11a60a
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Dec 7, 2020
0509433
Updates after merging dev
deanmarcussen Dec 7, 2020
58d1a1b
respond to feedback
deanmarcussen Dec 8, 2020
43f47da
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Dec 8, 2020
fe9eb04
Improve dependencies
deanmarcussen Dec 13, 2020
0740500
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Dec 13, 2020
7c64862
tip key vault store
deanmarcussen Dec 14, 2020
5216d02
Use UsingServiceScopeAsync()
jtkech Dec 14, 2020
ae0a9a6
Fixes unit tests
jtkech Dec 14, 2020
5bed0d1
Missing save
jtkech Dec 14, 2020
7c89eff
Merge branch 'dev' into deanmarcussen/secrets
deanmarcussen Feb 12, 2021
49849fb
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 17, 2023
5b9627f
Update csproj files after merging dev
jtkech Aug 17, 2023
3f9bb99
Fixing build after merging dev
jtkech Aug 17, 2023
f681faf
Fix bluid
jtkech Aug 17, 2023
0d40057
Fix calls of obsolete methods
jtkech Aug 17, 2023
ffabc98
Fixes other rules.
jtkech Aug 17, 2023
6818111
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 18, 2023
855e61f
wip
jtkech Aug 18, 2023
1a591d3
Minor changes
jtkech Aug 18, 2023
5796493
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 20, 2023
14cc856
Update after merging dev
jtkech Aug 21, 2023
cf65850
wip
jtkech Aug 21, 2023
d0b1489
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 22, 2023
0410058
Razor views fixes and tweaks
jtkech Aug 22, 2023
9091e4c
wip on razor views
jtkech Aug 22, 2023
f804caa
Minor changes
jtkech Aug 23, 2023
bcacb55
wip
jtkech Aug 24, 2023
428926e
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 25, 2023
c9ed315
Minor change
jtkech Aug 25, 2023
f736ef6
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 25, 2023
2900982
Wip
jtkech Aug 25, 2023
dd8d876
Wip
jtkech Aug 25, 2023
ea39c57
wip
jtkech Aug 25, 2023
0dc2697
wip
jtkech Aug 26, 2023
df29e70
Fix tests
jtkech Aug 26, 2023
8d28485
Wip
jtkech Aug 27, 2023
ed74442
wip
jtkech Aug 27, 2023
b3acb4d
wip
jtkech Aug 27, 2023
6a56aa1
wip
jtkech Aug 27, 2023
c840578
wip
jtkech Aug 27, 2023
f1959c2
Minor changes
jtkech Aug 27, 2023
8efc1f5
Wip
jtkech Aug 28, 2023
389a7fd
Minor change and revert testing code
jtkech Aug 29, 2023
d838be5
Minor changes
jtkech Aug 29, 2023
c583964
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Aug 29, 2023
8d261d1
Wip and fix unit tests
jtkech Aug 29, 2023
05e31db
Simplification
jtkech Aug 30, 2023
ce983f3
Refactoring
jtkech Aug 31, 2023
fca2f9e
Fix build
jtkech Aug 31, 2023
a9a652c
Refactoring
jtkech Aug 31, 2023
fc76553
Minor Refactoring
jtkech Aug 31, 2023
79c7e41
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Sep 1, 2023
bfbb0f2
Typo on class name
jtkech Sep 1, 2023
666d4f5
wip
jtkech Sep 1, 2023
e42d638
Pre renaming files
jtkech Sep 1, 2023
eb72437
Renaming files
jtkech Sep 1, 2023
f8cc227
Pre renaming
jtkech Sep 1, 2023
ecd077f
Renaming
jtkech Sep 1, 2023
c453565
Wip
jtkech Sep 2, 2023
a42d1d7
Minor changes
jtkech Sep 2, 2023
b2f22ac
Minor tweak
jtkech Sep 2, 2023
5d08ae7
wip
jtkech Sep 3, 2023
577d75b
wip
jtkech Sep 3, 2023
fd922be
refactoring
jtkech Sep 3, 2023
8efa928
wip
jtkech Sep 3, 2023
64a9e0f
Use Remote Impot Api Key Secret
jtkech Sep 4, 2023
66e36e9
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Sep 4, 2023
7bc4759
wip
jtkech Sep 5, 2023
43057dd
Minor change
jtkech Sep 5, 2023
d6b57e5
Wip on Request Event Secret
jtkech Sep 5, 2023
c53c140
wip
jtkech Sep 6, 2023
a3ddf3f
Tweaks
jtkech Sep 6, 2023
4aa3217
tweak
jtkech Sep 6, 2023
34c6d69
wip
jtkech Sep 6, 2023
21f4454
wip
jtkech Sep 7, 2023
ea69c4f
Minor changes
jtkech Sep 7, 2023
2be5230
Cleanups
jtkech Sep 7, 2023
ff71113
Minor changes
jtkech Sep 7, 2023
39fca00
wip
jtkech Sep 7, 2023
c233e92
Simplification
jtkech Sep 8, 2023
9939f2d
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Sep 9, 2023
7d88a60
Simplification
jtkech Sep 10, 2023
e1c03f2
wip on simplification
jtkech Sep 10, 2023
c4f543a
Simplification
jtkech Sep 10, 2023
9196823
Revert unnecessary changes
jtkech Sep 11, 2023
79a3ff4
Fix build
jtkech Sep 11, 2023
51c67ba
Unnecessary changes
jtkech Sep 11, 2023
ad127b1
Unecessary change
jtkech Sep 11, 2023
dddf7b4
typo
jtkech Sep 11, 2023
a01fc60
Minor change
jtkech Sep 11, 2023
b079c58
UI tweak
jtkech Sep 12, 2023
0995d58
Wip on OpenId using RSA Secrets
jtkech Sep 12, 2023
ba89c4b
Fix unit tests
jtkech Sep 12, 2023
66de075
wip
jtkech Sep 12, 2023
26dcd37
wip
jtkech Sep 12, 2023
a519303
Bad name
jtkech Sep 12, 2023
751afa8
wip
jtkech Sep 12, 2023
d361f4e
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Sep 13, 2023
67484c5
Updates after merging dev
jtkech Sep 13, 2023
82ee50f
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Oct 20, 2023
28948a4
Minor changes
jtkech Oct 21, 2023
5aa11ec
Useless property
jtkech Oct 21, 2023
04f7aee
Minor changes
jtkech Oct 21, 2023
da4e195
Update src/OrchardCore.Modules/OrchardCore.Deployment.Remote/Views/Re…
jtkech Nov 16, 2023
d968d41
Update src/OrchardCore.Modules/OrchardCore.Deployment/Models/FileDown…
jtkech Nov 16, 2023
dca5452
Update src/OrchardCore.Modules/OrchardCore.Secrets.KeyVault/Models/Se…
jtkech Nov 16, 2023
78dc717
Update src/OrchardCore.Modules/OrchardCore.Secrets.KeyVault/Services/…
jtkech Nov 16, 2023
1ae5240
Update src/OrchardCore.Modules/OrchardCore.Secrets.KeyVault/Services/…
jtkech Nov 16, 2023
f83a562
Update src/OrchardCore.Modules/OrchardCore.Secrets.KeyVault/Services/…
jtkech Nov 16, 2023
0ff38fe
Update src/OrchardCore.Modules/OrchardCore.Secrets/Manifest.cs
jtkech Nov 16, 2023
0305f31
Update src/OrchardCore.Modules/OrchardCore.Secrets/Views/Admin/Index.…
jtkech Nov 16, 2023
0830908
Update test/OrchardCore.Tests/Apis/Context/BlogPostDeploymentContext.cs
jtkech Nov 16, 2023
f198c8b
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Nov 16, 2023
5493c30
Fix build
jtkech Nov 17, 2023
51cee40
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Nov 17, 2023
c7d1b73
Rename project OC.Secrets.Azure
jtkech Nov 17, 2023
912b68e
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Nov 18, 2023
c9476f8
RSA in uppercase everywhere in views
jtkech Nov 18, 2023
74bba87
Formatting
jtkech Nov 18, 2023
f564bc5
Return null if KeyVault Secret not found
jtkech Nov 18, 2023
f9fce09
Remove unnecessary variable assignment
jtkech Nov 18, 2023
c15f80f
Update src/OrchardCore.Modules/OrchardCore.Secrets/Services/SecretSer…
jtkech Nov 19, 2023
ce99831
Fix Index View Color and Styles
jtkech Nov 19, 2023
cc5d9aa
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Nov 21, 2023
348036e
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Dec 2, 2023
4fdf2e2
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Dec 8, 2023
e7e5beb
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Dec 9, 2023
5f09589
Minor change
jtkech Dec 9, 2023
2a212ad
Wip wip
jtkech Dec 10, 2023
3bbf2f8
Minor changes
jtkech Dec 10, 2023
b0b905e
Refactoring
jtkech Dec 10, 2023
2b0449e
wip
jtkech Dec 11, 2023
60bf3b4
wip
jtkech Dec 11, 2023
b9e0979
wip
jtkech Dec 11, 2023
be3189a
Refactoring
jtkech Dec 12, 2023
8b1ff18
Wip
jtkech Dec 12, 2023
39c6083
wip
jtkech Dec 12, 2023
975f85b
Merge main and solve conflicts
jtkech Dec 13, 2023
30a6091
Refactoring
jtkech Dec 13, 2023
a94edbf
Missing file
jtkech Dec 13, 2023
08be794
Remove useless changes
jtkech Dec 14, 2023
21d2b71
Fix build
jtkech Dec 14, 2023
5cee26b
Start on 'ISecretTokenService'
jtkech Dec 14, 2023
5bf5ea9
Revert 'OC.Forms' changes
jtkech Dec 14, 2023
87a15f0
Revert useless changes
jtkech Dec 14, 2023
f45c88e
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Dec 14, 2023
9f3661e
Secret Envelope Expiration and Renaming
jtkech Dec 15, 2023
8b2c553
Embed Expiration in the protected Payload
jtkech Dec 16, 2023
11acac3
Make secret protector async
jtkech Dec 16, 2023
7916138
Refactoring
jtkech Dec 17, 2023
d1ad67f
Wip on X509Secret and refactoring
jtkech Dec 17, 2023
30a0b6d
Minor change
jtkech Dec 17, 2023
0d63f75
Refactoring
jtkech Dec 17, 2023
1ac8119
wip
jtkech Dec 18, 2023
f4bc4cc
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Dec 19, 2023
b7e8a55
Merge main and solve conflicts
jtkech Dec 21, 2023
e0c52b2
Merge remote-tracking branch 'origin/main' into deanmarcussen/secrets
jtkech Dec 21, 2023
7048eaf
Refactoring
jtkech Dec 22, 2023
f95def3
WIP
jtkech Dec 22, 2023
acdfb0a
Secrets Index Background Color
jtkech Dec 22, 2023
6acccf7
Wip on X509Secret UI
jtkech Dec 22, 2023
4f4140a
WIP
jtkech Dec 23, 2023
cfa2543
WIP
jtkech Dec 24, 2023
3f601f1
Removing unused IDataProtectionProvider injections
Piedone Jan 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion OrchardCore.sln
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Sms.Abstraction
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Sms", "src\OrchardCore.Modules\OrchardCore.Sms\OrchardCore.Sms.csproj", "{CBF6DB53-FD0C-47F8-9E60-A1D247ACFD05}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrchardCore.Sms.Core", "src\OrchardCore\OrchardCore.Sms.Core\OrchardCore.Sms.Core.csproj", "{20356393-B16D-466C-8203-877A534E287D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Sms.Core", "src\OrchardCore\OrchardCore.Sms.Core\OrchardCore.Sms.Core.csproj", "{20356393-B16D-466C-8203-877A534E287D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Secrets.Abstractions", "src\OrchardCore\OrchardCore.Secrets.Abstractions\OrchardCore.Secrets.Abstractions.csproj", "{E19C8D65-7C32-43FA-BB3D-41F12EB4259D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Secrets", "src\OrchardCore.Modules\OrchardCore.Secrets\OrchardCore.Secrets.csproj", "{7DC59AC8-E9EE-4015-AA63-8E18DB4AD88F}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add docs about the module, especially about its configuration (including the basic appsettings, as well as configuring ConfigurationSecretStore).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I don't like writing doc ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can imagine :D. But this is an awesome feature and without even a mention in the docs people will be confused, or not even know about it (thinking mostly about newcomers who first evaluate the feature set based on the docs).

EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Secrets.Azure", "src\OrchardCore.Modules\OrchardCore.Secrets.KeyVault\OrchardCore.Secrets.Azure.csproj", "{854511CE-6DC6-4AE1-A135-B21A94D7E784}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -1335,6 +1341,18 @@ Global
{20356393-B16D-466C-8203-877A534E287D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20356393-B16D-466C-8203-877A534E287D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20356393-B16D-466C-8203-877A534E287D}.Release|Any CPU.Build.0 = Release|Any CPU
{E19C8D65-7C32-43FA-BB3D-41F12EB4259D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E19C8D65-7C32-43FA-BB3D-41F12EB4259D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E19C8D65-7C32-43FA-BB3D-41F12EB4259D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E19C8D65-7C32-43FA-BB3D-41F12EB4259D}.Release|Any CPU.Build.0 = Release|Any CPU
{7DC59AC8-E9EE-4015-AA63-8E18DB4AD88F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DC59AC8-E9EE-4015-AA63-8E18DB4AD88F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7DC59AC8-E9EE-4015-AA63-8E18DB4AD88F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DC59AC8-E9EE-4015-AA63-8E18DB4AD88F}.Release|Any CPU.Build.0 = Release|Any CPU
{854511CE-6DC6-4AE1-A135-B21A94D7E784}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{854511CE-6DC6-4AE1-A135-B21A94D7E784}.Debug|Any CPU.Build.0 = Debug|Any CPU
{854511CE-6DC6-4AE1-A135-B21A94D7E784}.Release|Any CPU.ActiveCfg = Release|Any CPU
{854511CE-6DC6-4AE1-A135-B21A94D7E784}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1566,6 +1584,9 @@ Global
{2D93F509-1FB3-4E22-92F0-588D0EFBA921} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{CBF6DB53-FD0C-47F8-9E60-A1D247ACFD05} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
{20356393-B16D-466C-8203-877A534E287D} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{E19C8D65-7C32-43FA-BB3D-41F12EB4259D} = {F23AC6C2-DE44-4699-999D-3C478EF3D691}
{7DC59AC8-E9EE-4015-AA63-8E18DB4AD88F} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
{854511CE-6DC6-4AE1-A135-B21A94D7E784} = {A066395F-6F73-45DC-B5A6-B4E306110DCE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46A1D25A-78D1-4476-9CBF-25B75E296341}
Expand Down
1 change: 1 addition & 0 deletions src/OrchardCore.Build/Dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<PackageManagement Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.0" />
<PackageManagement Include="Azure.Extensions.AspNetCore.DataProtection.Blobs" Version="1.3.2" />
<PackageManagement Include="Azure.Identity" Version="1.10.4" />
<PackageManagement Include="Azure.Security.KeyVault.Secrets" Version="4.1.0" />
<PackageManagement Include="Azure.Storage.Blobs" Version="12.19.1" />
<PackageManagement Include="BenchmarkDotNet" Version="0.13.10" />
<PackageManagement Include="Castle.Core" Version="5.1.1" />
Expand Down
15 changes: 14 additions & 1 deletion src/OrchardCore.Cms.Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,19 @@
//},
//"OrchardCore_Tenants": {
// "TenantRemovalAllowed": true // Whether tenant removal is allowed, false by default.
//}
//},
//"OrchardCore_Secrets": {
// "Secrets": {
// "configuredRsaSecret1": {
// "PublicKey": "...",
// "PrivateKey": "...",
// "KeyType": "PublicPrivatePair"
// }
// },
// "KeyVault": {
// "KeyVaultName": "",
// "Prefix": ""
// }
//},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public async Task<IActionResult> List(ContentOptions options, PagerParameters pa
var pageSize = pager.PageSize;
IEnumerable<Models.AdminMenu> results = new List<Models.AdminMenu>();

//todo: handle the case where there is a deserialization exception on some of the presets.
// Todo: handle the case where there is a deserialization exception on some of the presets.
// load at least the ones without error. Provide a way to delete the ones on error.
try
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
Expand All @@ -14,6 +15,8 @@
using OrchardCore.DisplayManagement.Notify;
using OrchardCore.Mvc.Utilities;
using OrchardCore.Recipes.Models;
using OrchardCore.Secrets;
using OrchardCore.Secrets.Models;
using YesSql;

namespace OrchardCore.Deployment.Remote.Controllers
Expand All @@ -27,6 +30,7 @@ public class ExportRemoteInstanceController : Controller
private readonly IAuthorizationService _authorizationService;
private readonly ISession _session;
private readonly RemoteInstanceService _service;
private readonly ISecretService _secretService;
private readonly INotifier _notifier;
protected readonly IHtmlLocalizer H;

Expand All @@ -35,13 +39,15 @@ public ExportRemoteInstanceController(
ISession session,
RemoteInstanceService service,
IDeploymentManager deploymentManager,
ISecretService secretService,
INotifier notifier,
IHtmlLocalizer<ExportRemoteInstanceController> localizer)
{
_authorizationService = authorizationService;
_deploymentManager = deploymentManager;
_session = session;
_service = service;
_secretService = secretService;
_notifier = notifier;
H = localizer;
}
Expand Down Expand Up @@ -75,7 +81,7 @@ public async Task<IActionResult> Execute(long id, string remoteInstanceId, strin
{
archiveFileName = PathExtensions.Combine(Path.GetTempPath(), filename);

var deploymentPlanResult = new DeploymentPlanResult(fileBuilder, new RecipeDescriptor());
var deploymentPlanResult = new DeploymentPlanResult(fileBuilder, new RecipeDescriptor(), remoteInstance.RsaEncryptionSecret, remoteInstance.RsaSigningSecret);
await _deploymentManager.ExecuteDeploymentPlanAsync(deploymentPlan, deploymentPlanResult);

if (System.IO.File.Exists(archiveFileName))
Expand All @@ -93,17 +99,32 @@ public async Task<IActionResult> Execute(long id, string remoteInstanceId, strin
using (var requestContent = new MultipartFormDataContent())
{
requestContent.Add(new StreamContent(
new FileStream(archiveFileName,
FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 1, FileOptions.Asynchronous | FileOptions.SequentialScan)
),
nameof(ImportViewModel.Content), Path.GetFileName(archiveFileName));
new FileStream(
archiveFileName,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite,
1,
FileOptions.Asynchronous | FileOptions.SequentialScan)),
nameof(ImportViewModel.Content),
Path.GetFileName(archiveFileName));

requestContent.Add(new StringContent(remoteInstance.ClientName), nameof(ImportViewModel.ClientName));
requestContent.Add(new StringContent(remoteInstance.ApiKey), nameof(ImportViewModel.ApiKey));

if (!string.IsNullOrEmpty(remoteInstance.ApiKeySecret))
{
var secret = await _secretService.GetSecretAsync<TextSecret>(remoteInstance.ApiKeySecret);
requestContent.Add(new StringContent(secret?.Text), nameof(ImportViewModel.ApiKey));
}
else
{
requestContent.Add(new StringContent(remoteInstance.ApiKey), nameof(ImportViewModel.ApiKey));
}

response = await _httpClient.PostAsync(remoteInstance.Url, requestContent);
}

if (response.StatusCode == System.Net.HttpStatusCode.OK)
if (response.StatusCode == HttpStatusCode.OK)
{
await _notifier.SuccessAsync(H["Deployment executed successfully."]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
Expand All @@ -7,9 +8,12 @@
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using OrchardCore.Deployment.Remote.Services;
using OrchardCore.Deployment.Remote.ViewModels;
using OrchardCore.Deployment.Services;
using OrchardCore.Secrets;
using OrchardCore.Secrets.Models;

namespace OrchardCore.Deployment.Remote.Controllers
{
Expand All @@ -18,15 +22,21 @@ public class ImportRemoteInstanceController : Controller
private readonly RemoteClientService _remoteClientService;
private readonly IDeploymentManager _deploymentManager;
private readonly IDataProtector _dataProtector;
private readonly ISecretService _secretService;
private readonly ILogger _logger;

public ImportRemoteInstanceController(
IDataProtectionProvider dataProtectionProvider,
RemoteClientService remoteClientService,
IDeploymentManager deploymentManager)
IDeploymentManager deploymentManager,
IDataProtectionProvider dataProtectionProvider,
ISecretService secretService,
ILogger<ImportRemoteInstanceController> logger)
{
_deploymentManager = deploymentManager;
_remoteClientService = remoteClientService;
_deploymentManager = deploymentManager;
_dataProtector = dataProtectionProvider.CreateProtector("OrchardCore.Deployment").ToTimeLimitedDataProtector();
_secretService = secretService;
_logger = logger;
}

/// <remarks>
Expand All @@ -40,13 +50,27 @@ public async Task<IActionResult> Import(ImportViewModel model)
var remoteClientList = await _remoteClientService.GetRemoteClientListAsync();

var remoteClient = remoteClientList.RemoteClients.FirstOrDefault(x => x.ClientName == model.ClientName);

if (remoteClient == null)
{
return StatusCode((int)HttpStatusCode.BadRequest, "The remote client was not provided");
}

var apiKey = Encoding.UTF8.GetString(_dataProtector.Unprotect(remoteClient.ProtectedApiKey));
var apiKey = string.Empty;
if (!string.IsNullOrEmpty(remoteClient.ApiKeySecret))
{
apiKey = (await _secretService.GetSecretAsync<TextSecret>(remoteClient.ApiKeySecret))?.Text;
}
else
{
try
{
apiKey = Encoding.UTF8.GetString(_dataProtector.Unprotect(remoteClient.ProtectedApiKey));
}
catch
{
_logger.LogError("The Api Key could not be decrypted. It may have been encrypted using a different key.");
}
}
Piedone marked this conversation as resolved.
Show resolved Hide resolved

if (model.ApiKey != apiKey || model.ClientName != remoteClient.ClientName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
{
RemoteClients = remoteClients,
Pager = pagerShape,
Options = options
Options = options,
};

model.Options.ContentsBulkAction = new List<SelectListItem>() {
new SelectListItem() { Text = S["Delete"], Value = nameof(ContentsBulkAction.Remove) }
model.Options.ContentsBulkAction = new List<SelectListItem>()
{
new() { Text = S["Delete"], Value = nameof(ContentsBulkAction.Remove) },
};

return View(model);
Expand All @@ -100,8 +101,9 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
[FormValueRequired("submit.Filter")]
public ActionResult IndexFilterPOST(RemoteClientIndexViewModel model)
{
return RedirectToAction("Index", new RouteValueDictionary {
{ "Options.Search", model.Options.Search }
return RedirectToAction("Index", new RouteValueDictionary
{
{ "Options.Search", model.Options.Search },
});
}

Expand Down Expand Up @@ -132,7 +134,7 @@ public async Task<IActionResult> Create(EditRemoteClientViewModel model)

if (ModelState.IsValid)
{
await _remoteClientService.CreateRemoteClientAsync(model.ClientName, model.ApiKey);
await _remoteClientService.CreateRemoteClientAsync(model.ClientName, model.ApiKey, model.ApiKeySecret);

await _notifier.SuccessAsync(H["Remote client created successfully."]);
return RedirectToAction(nameof(Index));
Expand Down Expand Up @@ -160,9 +162,14 @@ public async Task<IActionResult> Edit(string id)
{
Id = remoteClient.Id,
ClientName = remoteClient.ClientName,
ApiKey = Encoding.UTF8.GetString(_dataProtector.Unprotect(remoteClient.ProtectedApiKey)),
ApiKeySecret = remoteClient.ApiKeySecret,
};

if (remoteClient.ProtectedApiKey?.Length > 0)
{
model.ApiKey = Encoding.UTF8.GetString(_dataProtector.Unprotect(remoteClient.ProtectedApiKey));
}

return View(model);
}

Expand All @@ -188,7 +195,7 @@ public async Task<IActionResult> Edit(EditRemoteClientViewModel model)

if (ModelState.IsValid)
{
await _remoteClientService.TryUpdateRemoteClient(model.Id, model.ClientName, model.ApiKey);
await _remoteClientService.TryUpdateRemoteClient(model.Id, model.ClientName, model.ApiKey, model.ApiKeySecret);

await _notifier.SuccessAsync(H["Remote client updated successfully."]);

Expand Down Expand Up @@ -261,7 +268,7 @@ private void ValidateViewModel(EditRemoteClientViewModel model)
ModelState.AddModelError(nameof(EditRemoteClientViewModel.ClientName), S["The client name is mandatory."]);
}

if (string.IsNullOrWhiteSpace(model.ApiKey))
if (string.IsNullOrWhiteSpace(model.ApiKey) && string.IsNullOrWhiteSpace(model.ApiKeySecret))
{
ModelState.AddModelError(nameof(EditRemoteClientViewModel.ApiKey), S["The api key is mandatory."]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
{
RemoteInstances = remoteInstances,
Pager = pagerShape,
Options = options
Options = options,
};

model.Options.ContentsBulkAction = new List<SelectListItem>() {
new SelectListItem() { Text = S["Delete"], Value = nameof(ContentsBulkAction.Remove) }
model.Options.ContentsBulkAction = new List<SelectListItem>()
{
new() { Text = S["Delete"], Value = nameof(ContentsBulkAction.Remove) },
};

return View(model);
Expand All @@ -93,8 +94,9 @@ public async Task<IActionResult> Index(ContentOptions options, PagerParameters p
[FormValueRequired("submit.Filter")]
public ActionResult IndexFilterPOST(RemoteInstanceIndexViewModel model)
{
return RedirectToAction(nameof(Index), new RouteValueDictionary {
{ "Options.Search", model.Options.Search }
return RedirectToAction(nameof(Index), new RouteValueDictionary
{
{ "Options.Search", model.Options.Search },
});
}

Expand Down Expand Up @@ -125,7 +127,7 @@ public async Task<IActionResult> Create(EditRemoteInstanceViewModel model)

if (ModelState.IsValid)
{
await _service.CreateRemoteInstanceAsync(model.Name, model.Url, model.ClientName, model.ApiKey);
await _service.CreateRemoteInstanceAsync(model.Name, model.Url, model.ClientName, model.ApiKey, model.ApiKeySecret, model.RsaEncryptionSecret, model.RsaSigningSecret);

await _notifier.SuccessAsync(H["Remote instance created successfully."]);
return RedirectToAction(nameof(Index));
Expand Down Expand Up @@ -155,7 +157,10 @@ public async Task<IActionResult> Edit(string id)
Name = remoteInstance.Name,
ClientName = remoteInstance.ClientName,
ApiKey = remoteInstance.ApiKey,
Url = remoteInstance.Url
ApiKeySecret = remoteInstance.ApiKeySecret,
Url = remoteInstance.Url,
RsaEncryptionSecret = remoteInstance.RsaEncryptionSecret,
RsaSigningSecret = remoteInstance.RsaSigningSecret,
};

return View(model);
Expand Down Expand Up @@ -183,7 +188,7 @@ public async Task<IActionResult> Edit(EditRemoteInstanceViewModel model)

if (ModelState.IsValid)
{
await _service.UpdateRemoteInstance(model.Id, model.Name, model.Url, model.ClientName, model.ApiKey);
await _service.UpdateRemoteInstance(model.Id, model.Name, model.Url, model.ClientName, model.ApiKey, model.ApiKeySecret, model.RsaEncryptionSecret, model.RsaSigningSecret);

await _notifier.SuccessAsync(H["Remote instance updated successfully."]);

Expand Down Expand Up @@ -261,7 +266,7 @@ private void ValidateViewModel(EditRemoteInstanceViewModel model)
ModelState.AddModelError(nameof(EditRemoteInstanceViewModel.ClientName), S["The client name is mandatory."]);
}

if (string.IsNullOrWhiteSpace(model.ApiKey))
if (string.IsNullOrWhiteSpace(model.ApiKey) && string.IsNullOrWhiteSpace(model.ApiKeySecret))
{
ModelState.AddModelError(nameof(EditRemoteInstanceViewModel.ApiKey), S["The api key is mandatory."]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@ public class RemoteClient
public string Id { get; set; }
public string ClientName { get; set; }
public byte[] ProtectedApiKey { get; set; }

/// <summary>
/// The name of the api key secret that will be used to authenticate this remote client.
/// When a secret key is provided, it overrides the <see cref="ProtectedApiKey"/> value.
/// </summary>
public string ApiKeySecret { get; set; }
}
}
Loading