90 lines
3.1 KiB
C#
90 lines
3.1 KiB
C#
using System.Security.Claims;
|
|
using Hutopy.Application.Common.Interfaces;
|
|
using Hutopy.Infrastructure.Identity;
|
|
using Hutopy.Infrastructure.Utils;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Options;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace Hutopy.Web.Controllers;
|
|
|
|
public class GoogleController(
|
|
IIdentityService identityService,
|
|
IHttpClientFactory httpClientFactory,
|
|
IOptionsSnapshot<JwtOptions> jwtOptions)
|
|
: Controller
|
|
{
|
|
[Microsoft.AspNetCore.Mvc.HttpPost("/api/google/sign-in")]
|
|
public async Task<IActionResult> SignIn([Microsoft.AspNetCore.Mvc.FromBody] GoogleSignInRequest request)
|
|
{
|
|
using var httpClient = httpClientFactory.CreateClient();
|
|
|
|
// Verify the token with Google
|
|
var response = await httpClient.GetAsync($"https://www.googleapis.com/oauth2/v1/userinfo?access_token={request.AccessToken}");
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
return BadRequest("Invalid Google token.");
|
|
}
|
|
|
|
var userInfo = JObject.Parse(await response.Content.ReadAsStringAsync());
|
|
var email = userInfo["email"]?.ToString() ?? "";
|
|
var name = userInfo["name"]?.ToString() ?? "";
|
|
var givenName = userInfo["given_name"]?.ToString() ?? "";
|
|
var familyName = userInfo["family_name"]?.ToString() ?? "";
|
|
|
|
if (string.IsNullOrEmpty(email))
|
|
{
|
|
return BadRequest("Google token did not contain an email.");
|
|
}
|
|
|
|
// Check if user exists or create a new one
|
|
var user = await identityService.FindUserByEmailAsync(email);
|
|
if (user == null)
|
|
{
|
|
await identityService.CreateUserAsync(email, email, givenName, familyName, RandomGenerator.RandomString(24));
|
|
user = await identityService.FindUserByEmailAsync(email);
|
|
}
|
|
|
|
if (user?.Id is null)
|
|
{
|
|
return BadRequest("Unable to find or create the user.");
|
|
}
|
|
|
|
// Sign in the user
|
|
var claimsIdentity = new ClaimsIdentity(
|
|
new List<Claim>
|
|
{
|
|
new(ClaimTypes.Name, name),
|
|
new(ClaimTypes.Email, email),
|
|
new(ClaimTypes.GivenName, givenName),
|
|
new(ClaimTypes.Surname, familyName)
|
|
},
|
|
CookieAuthenticationDefaults.AuthenticationScheme);
|
|
|
|
await HttpContext.SignInAsync(
|
|
CookieAuthenticationDefaults.AuthenticationScheme,
|
|
new ClaimsPrincipal(claimsIdentity));
|
|
|
|
var token = JwtTokenHelper.GenerateJwtToken(
|
|
jwtOptions.Value.Lifetime,
|
|
jwtOptions.Value.Issuer,
|
|
jwtOptions.Value.Audience,
|
|
jwtOptions.Value.Key,
|
|
user.Id.ToString(),
|
|
user.Email,
|
|
user.Alias,
|
|
user.FirstName,
|
|
user.LastName,
|
|
user.PortraitUrl);
|
|
|
|
return Ok(new { accessToken = token, email });
|
|
}
|
|
|
|
public class GoogleSignInRequest
|
|
{
|
|
public required string AccessToken { get; set; }
|
|
}
|
|
}
|