From 3af6af8b40ecb8a334f721b3044b95f74753c2cb Mon Sep 17 00:00:00 2001 From: Kieran Date: Thu, 8 Sep 2022 14:29:31 +0100 Subject: [PATCH] Fix google OAuth flow --- VoidCat/Model/User/UserAuthToken.cs | 2 ++ .../Users/Auth/GenericOAuth2Service.cs | 28 ++++++++++++++----- .../Users/Auth/GoogleOAuthProvider.cs | 20 ++++++++----- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/VoidCat/Model/User/UserAuthToken.cs b/VoidCat/Model/User/UserAuthToken.cs index 774b29f..775a3dc 100644 --- a/VoidCat/Model/User/UserAuthToken.cs +++ b/VoidCat/Model/User/UserAuthToken.cs @@ -20,4 +20,6 @@ public sealed class UserAuthToken public string RefreshToken { get; init; } public string Scope { get; init; } + + public string IdToken { get; init; } } \ No newline at end of file diff --git a/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs b/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs index 46dc0ac..eb41ebd 100644 --- a/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs +++ b/VoidCat/Services/Users/Auth/GenericOAuth2Service.cs @@ -61,7 +61,7 @@ public abstract class GenericOAuth2Service : IOAuthProvider {"response_type", "code"}, {"client_id", Details.ClientId!}, {"scope", string.Join(" ", Scopes)}, - {"prompt", "none"}, + {"prompt", Prompt}, {"redirect_uri", new Uri(_uri, $"/auth/{Id}/token").ToString()} }; @@ -79,6 +79,11 @@ public abstract class GenericOAuth2Service : IOAuthProvider {"redirect_uri", new Uri(_uri, $"/auth/{Id}/token").ToString()} }; + /// + /// Prompt type for authorization + /// + protected virtual string Prompt => "none"; + /// /// Authorize url for this service /// @@ -114,20 +119,29 @@ public abstract class GenericOAuth2Service : IOAuthProvider Expires = DateTime.UtcNow.AddSeconds(dto.ExpiresIn), TokenType = dto.TokenType, RefreshToken = dto.RefreshToken, - Scope = dto.Scope + Scope = dto.Scope, + IdToken = dto.IdToken }; } protected class OAuthAccessToken { - [JsonProperty("access_token")] public string AccessToken { get; init; } + [JsonProperty("access_token")] + public string AccessToken { get; init; } - [JsonProperty("expires_in")] public int ExpiresIn { get; init; } + [JsonProperty("expires_in")] + public int ExpiresIn { get; init; } - [JsonProperty("token_type")] public string TokenType { get; init; } + [JsonProperty("token_type")] + public string TokenType { get; init; } - [JsonProperty("refresh_token")] public string RefreshToken { get; init; } + [JsonProperty("refresh_token")] + public string RefreshToken { get; init; } - [JsonProperty("scope")] public string Scope { get; init; } + [JsonProperty("scope")] + public string Scope { get; init; } + + [JsonProperty("id_token")] + public string IdToken { get; init; } } } \ No newline at end of file diff --git a/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs b/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs index 8e23dfc..d4b7ff6 100644 --- a/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs +++ b/VoidCat/Services/Users/Auth/GoogleOAuthProvider.cs @@ -20,18 +20,28 @@ public class GoogleOAuthProvider : GenericOAuth2Service /// public override ValueTask GetUserDetails(UserAuthToken token) { - var jwt = JwtPayload.Base64UrlDeserialize(token.AccessToken); + var jwt = new JwtSecurityToken(token.IdToken); + + string? GetPayloadValue(string key) + => jwt.Payload.TryGetValue(key, out var v) + ? v as string + : default; + return ValueTask.FromResult(new InternalUser() { Id = Guid.NewGuid(), Created = DateTimeOffset.UtcNow, LastLogin = DateTimeOffset.UtcNow, AuthType = AuthType.OAuth2, - Email = jwt.Jti, - DisplayName = jwt.Acr + Email = GetPayloadValue("email") ?? throw new InvalidOperationException("Failed to get email from Google JWT"), + DisplayName = GetPayloadValue("name"), + Avatar = GetPayloadValue("picture") })!; } + /// + protected override string Prompt => "select_account"; + /// protected override Uri AuthorizeEndpoint => new("https://accounts.google.com/o/oauth2/v2/auth"); @@ -44,8 +54,4 @@ public class GoogleOAuthProvider : GenericOAuth2Service /// protected override string[] Scopes => new[] {"https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"}; -} - -public sealed class GoogleUserAccount -{ } \ No newline at end of file