Skip to content

Commit 3e6b91c

Browse files
authored
Refresh token with client credentials flow and use async for data access. (#43)
* Obtained new token with expiring OAuth2 client credentials flow. * Made data access async. * Refactored to simplify parameter lists.
1 parent dc7a6ca commit 3e6b91c

17 files changed

+226
-166
lines changed

examples/Umbraco.AuthorizedServices.TestSite/Controllers/TestAuthorizedServicesController.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,15 +200,15 @@ public async Task<IActionResult> GetTwitterProfileUsingOAuth2()
200200
return Content(response);
201201
}
202202

203-
public IActionResult GetApiKey(string serviceAlias)
203+
public async Task<IActionResult> GetApiKey(string serviceAlias)
204204
{
205-
Attempt<string?> apiKeyAttempt = AuthorizedServiceCaller.GetApiKey(serviceAlias);
205+
Attempt<string?> apiKeyAttempt = await AuthorizedServiceCaller.GetApiKey(serviceAlias);
206206
return Content(apiKeyAttempt.Result ?? string.Empty);
207207
}
208208

209-
public IActionResult GetOAuthToken(string serviceAlias)
209+
public async Task<IActionResult> GetOAuthToken(string serviceAlias)
210210
{
211-
Attempt<string?> responseAttempt = AuthorizedServiceCaller.GetOAuth2AccessToken(serviceAlias);
211+
Attempt<string?> responseAttempt = await AuthorizedServiceCaller.GetOAuth2AccessToken(serviceAlias);
212212
if (!responseAttempt.Success || responseAttempt.Result is null)
213213
{
214214
return HandleFailedRequest(responseAttempt.Exception, "Could not retrieve access token.");
@@ -218,9 +218,9 @@ public IActionResult GetOAuthToken(string serviceAlias)
218218
return Content(response);
219219
}
220220

221-
public IActionResult GetOAuth1Token(string serviceAlias)
221+
public async Task<IActionResult> GetOAuth1Token(string serviceAlias)
222222
{
223-
Attempt<string?> responseAttempt = AuthorizedServiceCaller.GetOAuth1Token(serviceAlias);
223+
Attempt<string?> responseAttempt = await AuthorizedServiceCaller.GetOAuth1Token(serviceAlias);
224224
if (!responseAttempt.Success || responseAttempt.Result is null)
225225
{
226226
return Problem("Could not retrieve the OAuth token.");

src/Umbraco.AuthorizedServices/Controllers/AuthorizedServiceController.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ public AuthorizedServiceController(
6363
/// </summary>
6464
/// <param name="alias">The service alias.</param>
6565
[HttpGet]
66-
public AuthorizedServiceDisplay? GetByAlias(string alias)
66+
public async Task<AuthorizedServiceDisplay?> GetByAlias(string alias)
6767
{
6868
ServiceDetail serviceDetail = _serviceDetailOptions.Get(alias);
6969

70-
bool isAuthorized = CheckAuthorizationStatus(serviceDetail);
70+
bool isAuthorized = await CheckAuthorizationStatus(serviceDetail);
7171

7272
string? authorizationUrl = null;
7373
if (serviceDetail.AuthenticationMethod == AuthenticationMethod.OAuth2AuthorizationCode)
@@ -156,23 +156,23 @@ public async Task<IActionResult> SendSampleRequest(string alias)
156156
/// </summary>
157157
/// <param name="model">Request model identifying the service.</param>
158158
[HttpPost]
159-
public IActionResult RevokeAccess(RevokeAccess model)
159+
public async Task<IActionResult> RevokeAccess(RevokeAccess model)
160160
{
161161
ServiceDetail serviceDetail = _serviceDetailOptions.Get(model.Alias);
162162

163163
switch (serviceDetail.AuthenticationMethod)
164164
{
165165
case AuthenticationMethod.ApiKey:
166-
_keyStorage.DeleteKey(model.Alias);
166+
await _keyStorage.DeleteKeyAsync(model.Alias);
167167
ClearCachedApiKey(model.Alias);
168168
break;
169169
case AuthenticationMethod.OAuth1:
170-
_oauth1TokenStorage.DeleteToken(model.Alias);
170+
await _oauth1TokenStorage.DeleteTokenAsync(model.Alias);
171171
ClearCachedToken(model.Alias);
172172
break;
173173
case AuthenticationMethod.OAuth2AuthorizationCode:
174174
case AuthenticationMethod.OAuth2ClientCredentials:
175-
_oauth2TokenStorage.DeleteToken(model.Alias);
175+
await _oauth2TokenStorage.DeleteTokenAsync(model.Alias);
176176
ClearCachedToken(model.Alias);
177177
break;
178178
default:
@@ -200,9 +200,9 @@ private void ClearCachedToken(string serviceAlias)
200200
/// <param name="model">Request model identifying the service.</param>
201201
/// <returns></returns>
202202
[HttpPost]
203-
public IActionResult SaveOAuth2Token(AddOAuth2Token model)
203+
public async Task<IActionResult> SaveOAuth2Token(AddOAuth2Token model)
204204
{
205-
_oauth2TokenStorage.SaveToken(model.Alias, new OAuth2Token(model.Token));
205+
await _oauth2TokenStorage.SaveTokenAsync(model.Alias, new OAuth2Token(model.Token));
206206
return Ok();
207207
}
208208

@@ -212,9 +212,9 @@ public IActionResult SaveOAuth2Token(AddOAuth2Token model)
212212
/// <param name="model">Request model identifying the service.</param>
213213
/// <returns></returns>
214214
[HttpPost]
215-
public IActionResult SaveOAuth1Token(AddOAuth1Token model)
215+
public async Task<IActionResult> SaveOAuth1Token(AddOAuth1Token model)
216216
{
217-
_oauth1TokenStorage.SaveToken(model.Alias, new OAuth1Token(model.Token, model.TokenSecret));
217+
await _oauth1TokenStorage.SaveTokenAsync(model.Alias, new OAuth1Token(model.Token, model.TokenSecret));
218218
return Ok();
219219
}
220220

@@ -224,9 +224,9 @@ public IActionResult SaveOAuth1Token(AddOAuth1Token model)
224224
/// <param name="model">Request model identifying the service.</param>
225225
/// <returns></returns>
226226
[HttpPost]
227-
public IActionResult SaveApiKey(AddApiKey model)
227+
public async Task<IActionResult> SaveApiKey(AddApiKey model)
228228
{
229-
_keyStorage.SaveKey(model.Alias, model.ApiKey);
229+
await _keyStorage.SaveKeyAsync(model.Alias, model.ApiKey);
230230
return Ok();
231231
}
232232

@@ -276,17 +276,17 @@ public async Task<IActionResult> GenerateOAuth1RequestToken(GenerateToken model)
276276
throw new AuthorizedServiceException("Failed to obtain request token");
277277
}
278278

279-
private bool CheckAuthorizationStatus(ServiceDetail serviceDetail) => serviceDetail.AuthenticationMethod switch
279+
private async Task<bool> CheckAuthorizationStatus(ServiceDetail serviceDetail) => serviceDetail.AuthenticationMethod switch
280280
{
281-
AuthenticationMethod.OAuth1 => StoredOAuth1TokenExists(serviceDetail),
282-
AuthenticationMethod.OAuth2AuthorizationCode => StoredOAuth2TokenExists(serviceDetail),
283-
AuthenticationMethod.OAuth2ClientCredentials => StoredOAuth2TokenExists(serviceDetail),
281+
AuthenticationMethod.OAuth1 => await StoredOAuth1TokenExists(serviceDetail),
282+
AuthenticationMethod.OAuth2AuthorizationCode => await StoredOAuth2TokenExists(serviceDetail),
283+
AuthenticationMethod.OAuth2ClientCredentials => await StoredOAuth2TokenExists(serviceDetail),
284284
AuthenticationMethod.ApiKey => !string.IsNullOrEmpty(serviceDetail.ApiKey)
285-
|| _keyStorage.GetKey(serviceDetail.Alias) is not null,
285+
|| await _keyStorage.GetKeyAsync(serviceDetail.Alias) is not null,
286286
_ => false
287287
};
288288

289-
private bool StoredOAuth2TokenExists(ServiceDetail serviceDetail) => _oauth2TokenStorage.GetToken(serviceDetail.Alias) != null;
289+
private async Task<bool> StoredOAuth2TokenExists(ServiceDetail serviceDetail) => await _oauth2TokenStorage.GetTokenAsync(serviceDetail.Alias) != null;
290290

291-
private bool StoredOAuth1TokenExists(ServiceDetail serviceDetail) => _oauth1TokenStorage.GetToken(serviceDetail.Alias) != null;
291+
private async Task<bool> StoredOAuth1TokenExists(ServiceDetail serviceDetail) => await _oauth1TokenStorage.GetTokenAsync(serviceDetail.Alias) != null;
292292
}

src/Umbraco.AuthorizedServices/Manifests/AuthorizedServicesManifestFilter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public void Filter(List<PackageManifest> manifests)
2424
};
2525

2626
// The PackageId property was added in Umbraco 12, so we have to use reflection here to set it if available
27-
// as the package depdendency is on Umbraco 10.
28-
// If and when we release a version with a depdendency on 12+, this should be removed and replaced with
27+
// as the package dependency is on Umbraco 10.
28+
// If and when we release a version with a dependency on 12+, this should be removed and replaced with
2929
// a standard property setter.
3030
ReflectionHelper.SetOptionalPropertyValue(manifest, "PackageId", Constants.PackageId);
3131

src/Umbraco.AuthorizedServices/Services/IAuthorizedServiceCaller.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,19 @@ public interface IAuthorizedServiceCaller
6464
/// </summary>
6565
/// <param name="serviceAlias">The service alias.</param>
6666
/// <returns>The access token if found, otherwise null.</returns>
67-
Attempt<string?> GetOAuth2AccessToken(string serviceAlias);
67+
Task<Attempt<string?>> GetOAuth2AccessToken(string serviceAlias);
6868

6969
/// <summary>
7070
/// Sends a request to an authorized service to receive the unencrypted OAuth token.
7171
/// </summary>
7272
/// <param name="serviceAlias">The service alias.</param>
7373
/// <returns>The OAuth token if found, otherwise null.</returns>
74-
Attempt<string?> GetOAuth1Token(string serviceAlias);
74+
Task<Attempt<string?>> GetOAuth1Token(string serviceAlias);
7575

7676
/// <summary>
7777
/// Retrieve's the configured API key for a service.
7878
/// </summary>
7979
/// <param name="serviceAlias"></param>
8080
/// <returns></returns>
81-
Attempt<string?> GetApiKey(string serviceAlias);
81+
Task<Attempt<string?>> GetApiKey(string serviceAlias);
8282
}

src/Umbraco.AuthorizedServices/Services/IKeyStorage.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ public interface IKeyStorage
1010
/// </summary>
1111
/// <param name="serviceAlias">The service alias.</param>
1212
/// <returns>The key value (or null, if not found).</returns>
13-
string? GetKey(string serviceAlias);
13+
Task<string?> GetKeyAsync(string serviceAlias);
1414

1515
/// <summary>
1616
/// Stores an API key for aa service.
1717
/// </summary>
1818
/// <param name="serviceAlias">The service alias.</param>
1919
/// <param name="key">The API key.</param>
20-
void SaveKey(string serviceAlias, string key);
20+
Task SaveKeyAsync(string serviceAlias, string key);
2121

2222
/// <summary>
2323
/// Deletes a stored API key.
2424
/// </summary>
2525
/// <param name="serviceAlias">The service alias.</param>
26-
void DeleteKey(string serviceAlias);
26+
Task DeleteKeyAsync(string serviceAlias);
2727
}

src/Umbraco.AuthorizedServices/Services/ITokenStorage.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ public interface ITokenStorage<T>
1313
/// </summary>
1414
/// <param name="serviceAlias">The service alias.</param>
1515
/// <returns>The <see cref="OAuth2Token"/> or <see cref="OAuth1Token"/> instance (or null, if not found).</returns>
16-
T? GetToken(string serviceAlias);
16+
Task<T?> GetTokenAsync(string serviceAlias);
1717

1818
/// <summary>
1919
/// Stores a token for a service.
2020
/// </summary>
2121
/// <param name="serviceAlias">The service alias.</param>
2222
/// <param name="token">The <see cref="OAuth2Token"/> or <see cref="OAuth1Token"/>.</param>
23-
void SaveToken(string serviceAlias, T token);
23+
Task SaveTokenAsync(string serviceAlias, T token);
2424

2525
/// <summary>
2626
/// Deletes a stored token.
2727
/// </summary>
2828
/// <param name="serviceAlias">The service alias.</param>
29-
void DeleteToken(string serviceAlias);
29+
Task DeleteTokenAsync(string serviceAlias);
3030
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public async Task<AuthorizationResult> ExchangeOAuth2AccessTokenAsync(string ser
5353
{
5454
ServiceDetail serviceDetail = GetServiceDetail(serviceAlias);
5555

56-
OAuth2Token? token = GetStoredToken(serviceAlias) ?? throw new AuthorizedServiceException($"Could not find the access token for {serviceAlias}");
56+
OAuth2Token? token = await GetStoredToken(serviceAlias) ?? throw new AuthorizedServiceException($"Could not find the access token for {serviceAlias}");
5757

5858
Dictionary<string, string> parameters = _exchangeTokenParametersBuilder.BuildParameters(serviceDetail, token.AccessToken);
5959

@@ -102,12 +102,12 @@ private async Task<AuthorizationResult> SendRequest(ServiceDetail serviceDetail,
102102
if (serviceDetail.AuthenticationMethod == AuthenticationMethod.OAuth1)
103103
{
104104
OAuth1Token token = await CreateOAuth1TokenFromResponse(response);
105-
StoreOAuth1Token(serviceDetail.Alias, token);
105+
await StoreOAuth1Token(serviceDetail.Alias, token);
106106
}
107107
else
108108
{
109109
OAuth2Token token = await CreateOAuth2TokenFromResponse(serviceDetail, response);
110-
StoreOAuth2Token(serviceDetail.Alias, token);
110+
await StoreOAuth2Token(serviceDetail.Alias, token);
111111
}
112112

113113
return AuthorizationResult.AsSuccess();

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,21 @@ protected async Task<OAuth1Token> CreateOAuth1TokenFromResponse(HttpResponseMess
5959
return _tokenFactory.CreateFromOAuth1ResponseContent(responseContent);
6060
}
6161

62-
protected OAuth2Token? GetStoredToken(string serviceAlias) => OAuth2TokenStorage.GetToken(serviceAlias);
62+
protected async Task<OAuth2Token?> GetStoredToken(string serviceAlias) => await OAuth2TokenStorage.GetTokenAsync(serviceAlias);
6363

64-
protected void StoreOAuth2Token(string serviceAlias, OAuth2Token token)
64+
protected async Task StoreOAuth2Token(string serviceAlias, OAuth2Token token)
6565
{
6666
// Add the access token details to the cache.
6767
var cacheKey = CacheHelper.GetTokenCacheKey(serviceAlias);
6868
AppCaches.RuntimeCache.InsertCacheItem(cacheKey, () => token);
6969

7070
// Save the refresh token into the storage.
71-
OAuth2TokenStorage.SaveToken(serviceAlias, token);
71+
await OAuth2TokenStorage.SaveTokenAsync(serviceAlias, token);
7272
}
7373

74-
protected void StoreOAuth1Token(string serviceAlias, OAuth1Token token)
74+
protected async Task StoreOAuth1Token(string serviceAlias, OAuth1Token token)
7575
{
7676
// Save the token information into the storage.
77-
OAuth1TokenStorage.SaveToken(serviceAlias, token);
77+
await OAuth1TokenStorage.SaveTokenAsync(serviceAlias, token);
7878
}
7979
}

0 commit comments

Comments
 (0)