Files
social-media/src/Web/Controllers/GoogleController.cs

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; }
}
}