Skip to content

Commit

Permalink
Merge pull request #28 from clickviewapp/remove-extra-await
Browse files Browse the repository at this point in the history
HttpContextTokenStore updates
  • Loading branch information
MrSmoke authored Apr 20, 2023
2 parents 1065961 + 7349f88 commit f018e68
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<PackageTags>restclient rest http oauth aspnetcore</PackageTags>
<Description>AspNetCore OAuth authenticator for ClickView.Extensions.RestClient</Description>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,25 @@ public HttpContextTokenStore(IHttpContextAccessor httpContextAccessor, ILoggerFa
_logger = loggerFactory.CreateLogger<HttpContextTokenStore>();
}

public async Task<Token> GetTokenAsync(TokenType tokenType)
public async Task<Token?> GetTokenAsync(TokenType tokenType)
{
var httpContext = GetHttpContext();

var expireTime = GetTokenExpireTimeAsync(httpContext);
var tokenValue = httpContext.GetTokenAsync(GetHttpTokenName(tokenType));
var authResult = await httpContext.AuthenticateAsync();
var properties = authResult.Properties;

if (properties is null)
return null;

var tokenValue = properties.GetTokenValue(GetHttpTokenName(tokenType));

DateTimeOffset? expireTime = null;

return CreateToken(tokenType, await tokenValue, await expireTime);
// Only access tokens have expire time
if (tokenType == TokenType.AccessToken)
expireTime = GetTokenExpireTime(properties);

return CreateToken(tokenType, tokenValue, expireTime);
}

//Token reference https://github.com/aspnet/AspNetCore/blob/master/src/Security/Authentication/OAuth/src/OAuthHandler.cs#L116
Expand All @@ -42,18 +53,34 @@ public async Task StoreTokensAsync(IEnumerable<Token> tokens)
var httpContext = GetHttpContext();
var authResult = await httpContext.AuthenticateAsync();

var principal = authResult.Principal;
if (principal is null)
{
_logger.LogWarning("Failed to store tokens. No principal set");
return;
}

var properties = authResult.Properties;

// todo: Should this null check or should this create a new properties?
if (properties is null)
{
_logger.LogWarning("Failed to store tokens. No properties");
return;
}

foreach (var token in tokens)
{
var tokenName = GetHttpTokenName(token.TokenType);

UpdateTokenValue(authResult.Properties, tokenName, token.Value);
UpdateTokenValue(properties, tokenName, token.Value);

// update expires_at token for access tokens
if (token.TokenType == TokenType.AccessToken && token.ExpireTime.HasValue)
if (token is { TokenType: TokenType.AccessToken, ExpireTime: not null })
{
var expireValue = token.ExpireTime.Value.ToString("o", CultureInfo.InvariantCulture);

UpdateTokenValue(authResult.Properties, ExpiresAtKey, expireValue);
UpdateTokenValue(properties, ExpiresAtKey, expireValue);
}
}

Expand All @@ -62,15 +89,14 @@ public async Task StoreTokensAsync(IEnumerable<Token> tokens)
var scheme = (await schemeProvider.GetDefaultSignInSchemeAsync())?.Name;
var cookieOptions = options.Get(scheme);

if (authResult.Properties.AllowRefresh == true || authResult.Properties.AllowRefresh
== null && cookieOptions.SlidingExpiration)
if (properties.AllowRefresh == true || properties.AllowRefresh == null && cookieOptions.SlidingExpiration)
{
// this will allow the cookie to be issued with a new issuedUtc (and thus a new expiration)
authResult.Properties.IssuedUtc = null;
authResult.Properties.ExpiresUtc = null;
properties.IssuedUtc = null;
properties.ExpiresUtc = null;
}

await httpContext.SignInAsync(authResult.Principal, authResult.Properties);
await httpContext.SignInAsync(principal, properties);
}

private void UpdateTokenValue(AuthenticationProperties properties, string tokenName, string tokenValue)
Expand All @@ -93,11 +119,11 @@ private HttpContext GetHttpContext()
return context;
}

private Token CreateToken(TokenType tokenType, string value, DateTimeOffset? expireTime)
private Token? CreateToken(TokenType tokenType, string? value, DateTimeOffset? expireTime)
{
if (string.IsNullOrWhiteSpace(value))
{
_logger.LogDebug("Failed to fetch token {TokenType} from HttpContext", tokenType);
_logger.LogDebug("Failed to fetch token {TokenType} from HttpContext. Missing value", tokenType);
return null;
}

Expand All @@ -109,9 +135,9 @@ private Token CreateToken(TokenType tokenType, string value, DateTimeOffset? exp
};
}

private static async Task<DateTimeOffset?> GetTokenExpireTimeAsync(HttpContext httpContext)
private static DateTimeOffset? GetTokenExpireTime(AuthenticationProperties properties)
{
var token = await httpContext.GetTokenAsync(ExpiresAtKey).ConfigureAwait(false);
var token = properties.GetTokenValue(ExpiresAtKey);

if (string.IsNullOrWhiteSpace(token))
return null;
Expand All @@ -124,15 +150,12 @@ private Token CreateToken(TokenType tokenType, string value, DateTimeOffset? exp

private static string GetHttpTokenName(TokenType tokenType)
{
switch (tokenType)
return tokenType switch
{
case TokenType.AccessToken:
return "access_token";
case TokenType.RefreshToken:
return "refresh_token";
default:
throw new ArgumentOutOfRangeException(nameof(tokenType), tokenType, null);
}
TokenType.AccessToken => "access_token",
TokenType.RefreshToken => "refresh_token",
_ => throw new ArgumentOutOfRangeException(nameof(tokenType), tokenType, null)
};
}
}
}

0 comments on commit f018e68

Please sign in to comment.