Skip to content

Commit 95b2b83

Browse files
committed
PR Update and Revoke bug fix
1 parent 44b0e01 commit 95b2b83

File tree

6 files changed

+64
-39
lines changed

6 files changed

+64
-39
lines changed

src/Umbraco.AuthorizedServices/Controllers/AuthorizedServiceController.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,15 @@ public async Task<IActionResult> SendSampleRequest(string alias, string path)
130130
[HttpPost]
131131
public IActionResult RevokeAccess(RevokeAccess model)
132132
{
133-
_tokenStorage.DeleteToken(model.Alias);
134-
_keyStorage.DeleteKey(model.Alias);
133+
ServiceDetail serviceDetail = _serviceDetailOptions.Get(model.Alias);
134+
if (serviceDetail.AuthenticationMethod != AuthenticationMethod.ApiKey)
135+
{
136+
_tokenStorage.DeleteToken(model.Alias);
137+
}
138+
else
139+
{
140+
_keyStorage.DeleteKey(model.Alias);
141+
}
135142
return Ok();
136143
}
137144

src/Umbraco.AuthorizedServices/Services/Implement/AuthorizedServiceCaller.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,19 @@ public async Task<string> SendRequestRawAsync<TRequest>(string serviceAlias, str
8282
if (serviceDetail.AuthenticationMethod == AuthenticationMethod.ApiKey)
8383
{
8484
string? key = KeyStorage.GetKey(serviceAlias);
85+
86+
if (key is null && string.IsNullOrEmpty(serviceDetail.ApiKey))
87+
{
88+
throw new AuthorizedServiceException($"Cannot request service '{serviceAlias}' as access has not yet been authorized.");
89+
}
90+
8591
requestMessage = _authorizedRequestBuilder.CreateRequestMessageWithApiKey(
8692
serviceDetail,
8793
path,
8894
httpMethod,
89-
key is not null ? key : (!string.IsNullOrEmpty(serviceDetail.ApiKey) ? serviceDetail.ApiKey : string.Empty),
95+
!string.IsNullOrEmpty(serviceDetail.ApiKey)
96+
? serviceDetail.ApiKey
97+
: (key ?? string.Empty),
9098
requestContent);
9199
}
92100
else
@@ -119,9 +127,9 @@ public async Task<string> SendRequestRawAsync<TRequest>(string serviceAlias, str
119127
{
120128
ServiceDetail serviceDetail = GetServiceDetail(serviceAlias);
121129
string? key = KeyStorage.GetKey(serviceAlias);
122-
return key is not null
123-
? key
124-
: serviceDetail?.ApiKey;
130+
return !string.IsNullOrEmpty(serviceDetail.ApiKey)
131+
? serviceDetail.ApiKey
132+
: key;
125133
}
126134

127135
public string? GetToken(string serviceAlias)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Microsoft.Extensions.Logging;
2+
using Umbraco.Cms.Infrastructure.Scoping;
3+
4+
namespace Umbraco.AuthorizedServices.Services.Implement;
5+
6+
internal class DatabaseAuthorizationParameterStorageBase
7+
{
8+
protected IScopeProvider ScopeProvider { get; }
9+
10+
protected ISecretEncryptor Encryptor { get; }
11+
12+
protected ILogger<DatabaseAuthorizationParameterStorageBase> Logger { get; }
13+
14+
public DatabaseAuthorizationParameterStorageBase(
15+
IScopeProvider scopeProvider,
16+
ISecretEncryptor encryptor,
17+
ILogger<DatabaseAuthorizationParameterStorageBase> logger)
18+
{
19+
ScopeProvider = scopeProvider;
20+
Encryptor = encryptor;
21+
Logger = logger;
22+
}
23+
}

src/Umbraco.AuthorizedServices/Services/Implement/DatabaseKeyStorage.cs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.Extensions.Logging;
2-
using Umbraco.AuthorizedServices.Models;
32
using Umbraco.AuthorizedServices.Persistence.Dtos;
43
using Umbraco.Cms.Infrastructure.Scoping;
54

@@ -8,34 +7,28 @@ namespace Umbraco.AuthorizedServices.Services.Implement;
87
/// <summary>
98
/// Implements <see cref="IKeyStorage"/> for API key storage using a database table.
109
/// </summary>
11-
internal sealed class DatabaseKeyStorage : IKeyStorage
10+
internal sealed class DatabaseKeyStorage : DatabaseAuthorizationParameterStorageBase, IKeyStorage
1211
{
13-
private readonly IScopeProvider _scopeProvider;
14-
private readonly ISecretEncryptor _encryptor;
15-
private readonly ILogger<DatabaseKeyStorage> _logger;
16-
1712
/// <summary>
1813
/// Initializes a new instance of the <see cref="DatabaseKeyStorage"/> class.
1914
/// </summary>
2015
public DatabaseKeyStorage(IScopeProvider scopeProvider, ISecretEncryptor encryptor, ILogger<DatabaseKeyStorage> logger)
16+
: base(scopeProvider, encryptor, logger)
2117
{
22-
_scopeProvider = scopeProvider;
23-
_encryptor = encryptor;
24-
_logger = logger;
2518
}
2619

2720
/// <inheritdoc/>
2821
public string? GetKey(string serviceAlias)
2922
{
30-
using IScope scope = _scopeProvider.CreateScope();
23+
using IScope scope = ScopeProvider.CreateScope();
3124

3225
KeyDto entity = scope.Database.FirstOrDefault<KeyDto>("where serviceAlias = @0", serviceAlias);
3326
if (entity == null)
3427
{
3528
return null;
3629
}
3730

38-
if (!_encryptor.TryDecrypt(entity.ApiKey, out string apiKey))
31+
if (!Encryptor.TryDecrypt(entity.ApiKey, out string apiKey))
3932
{
4033
RemoveCorruptApiKey(serviceAlias);
4134
return null;
@@ -47,14 +40,14 @@ public DatabaseKeyStorage(IScopeProvider scopeProvider, ISecretEncryptor encrypt
4740
/// <inheritdoc/>
4841
public void SaveKey(string serviceAlias, string key)
4942
{
50-
using IScope scope = _scopeProvider.CreateScope();
43+
using IScope scope = ScopeProvider.CreateScope();
5144

5245
KeyDto entity = scope.Database.SingleOrDefault<KeyDto>("where serviceAlias = @0", serviceAlias);
5346

5447
bool insert = entity == null;
5548
entity ??= new KeyDto { ServiceAlias = serviceAlias };
5649

57-
entity.ApiKey = _encryptor.Encrypt(key);
50+
entity.ApiKey = Encryptor.Encrypt(key);
5851

5952
if (insert)
6053
{
@@ -71,7 +64,7 @@ public void SaveKey(string serviceAlias, string key)
7164
/// <inheritdoc/>
7265
public void DeleteKey(string serviceAlias)
7366
{
74-
using IScope scope = _scopeProvider.CreateScope();
67+
using IScope scope = ScopeProvider.CreateScope();
7568

7669
KeyDto entity = scope.Database.Single<KeyDto>("where serviceAlias = @0", serviceAlias);
7770

@@ -83,6 +76,6 @@ public void DeleteKey(string serviceAlias)
8376
private void RemoveCorruptApiKey(string serviceAlias)
8477
{
8578
DeleteKey(serviceAlias);
86-
_logger.LogWarning($"Could not decrypt the stored API key for authorized service with alias '{serviceAlias}'. API key has been removed from storage.");
79+
Logger.LogWarning($"Could not decrypt the stored API key for authorized service with alias '{serviceAlias}'. API key has been removed from storage.");
8780
}
8881
}

src/Umbraco.AuthorizedServices/Services/Implement/DatabaseTokenStorage.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,28 @@ namespace Umbraco.AuthorizedServices.Services.Implement;
88
/// <summary>
99
/// Implements <see cref="ITokenStorage"/> for token storage using a database table.
1010
/// </summary>
11-
internal sealed class DatabaseTokenStorage : ITokenStorage
11+
internal sealed class DatabaseTokenStorage : DatabaseAuthorizationParameterStorageBase, ITokenStorage
1212
{
13-
private readonly IScopeProvider _scopeProvider;
14-
private readonly ISecretEncryptor _encryptor;
15-
private readonly ILogger<DatabaseTokenStorage> _logger;
16-
1713
/// <summary>
1814
/// Initializes a new instance of the <see cref="DatabaseTokenStorage"/> class.
1915
/// </summary>
2016
public DatabaseTokenStorage(IScopeProvider scopeProvider, ISecretEncryptor encryptor, ILogger<DatabaseTokenStorage> logger)
17+
: base(scopeProvider, encryptor, logger)
2118
{
22-
_scopeProvider = scopeProvider;
23-
_encryptor = encryptor;
24-
_logger = logger;
2519
}
2620

2721
/// <inheritdoc/>
2822
public Token? GetToken(string serviceAlias)
2923
{
30-
using IScope scope = _scopeProvider.CreateScope();
24+
using IScope scope = ScopeProvider.CreateScope();
3125

3226
TokenDto entity = scope.Database.FirstOrDefault<TokenDto>("where serviceAlias = @0", serviceAlias);
3327
if (entity == null)
3428
{
3529
return null;
3630
}
3731

38-
if (!_encryptor.TryDecrypt(entity.AccessToken, out string accessToken))
32+
if (!Encryptor.TryDecrypt(entity.AccessToken, out string accessToken))
3933
{
4034
RemoveCorruptToken(serviceAlias, "access");
4135
return null;
@@ -44,7 +38,7 @@ public DatabaseTokenStorage(IScopeProvider scopeProvider, ISecretEncryptor encry
4438
var refreshToken = string.Empty;
4539
if (!string.IsNullOrEmpty(entity.RefreshToken))
4640
{
47-
if (!_encryptor.TryDecrypt(entity.RefreshToken, out refreshToken))
41+
if (!Encryptor.TryDecrypt(entity.RefreshToken, out refreshToken))
4842
{
4943
RemoveCorruptToken(serviceAlias, "refresh");
5044
return null;
@@ -57,22 +51,22 @@ public DatabaseTokenStorage(IScopeProvider scopeProvider, ISecretEncryptor encry
5751
private void RemoveCorruptToken(string serviceAlias, string tokenType)
5852
{
5953
DeleteToken(serviceAlias);
60-
_logger.LogWarning($"Could not decrypt the stored {tokenType} token for authorized service with alias '{serviceAlias}'. Token has been removed from storage.");
54+
Logger.LogWarning($"Could not decrypt the stored {tokenType} token for authorized service with alias '{serviceAlias}'. Token has been removed from storage.");
6155
}
6256

6357
/// <inheritdoc/>
6458
public void SaveToken(string serviceAlias, Token token)
6559
{
66-
using IScope scope = _scopeProvider.CreateScope();
60+
using IScope scope = ScopeProvider.CreateScope();
6761

6862
TokenDto entity = scope.Database.SingleOrDefault<TokenDto>("where serviceAlias = @0", serviceAlias);
6963

7064
bool insert = entity == null;
7165
entity ??= new TokenDto { ServiceAlias = serviceAlias };
7266

73-
entity.AccessToken = _encryptor.Encrypt(token.AccessToken);
67+
entity.AccessToken = Encryptor.Encrypt(token.AccessToken);
7468
entity.RefreshToken = !string.IsNullOrEmpty(token.RefreshToken)
75-
? _encryptor.Encrypt(token.RefreshToken)
69+
? Encryptor.Encrypt(token.RefreshToken)
7670
: string.Empty;
7771
entity.ExpiresOn = token.ExpiresOn;
7872

@@ -91,7 +85,7 @@ public void SaveToken(string serviceAlias, Token token)
9185
/// <inheritdoc/>
9286
public void DeleteToken(string serviceAlias)
9387
{
94-
using IScope scope = _scopeProvider.CreateScope();
88+
using IScope scope = ScopeProvider.CreateScope();
9589

9690
TokenDto entity = scope.Database.Single<TokenDto>("where serviceAlias = @0", serviceAlias);
9791

tests/Umbraco.AuthorizedServices.Tests/Services/AuthorizedServiceTestsBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ internal abstract class AuthorizedServiceTestsBase
88
{
99
protected const string ServiceAlias = "testService";
1010

11-
protected static Mock<ITokenStorage> TokenStorageMock { get; set; } = null!;
11+
protected Mock<ITokenStorage> TokenStorageMock { get; set; } = null!;
1212

13-
protected static Mock<IKeyStorage> KeyStorageMock { get; set; } = null!;
13+
protected Mock<IKeyStorage> KeyStorageMock { get; set; } = null!;
1414

1515
protected static Mock<IOptionsMonitor<ServiceDetail>> CreateOptionsMonitorServiceDetail(
1616
AuthenticationMethod authenticationMethod = AuthenticationMethod.OAuth2AuthorizationCode)

0 commit comments

Comments
 (0)