using BCards.Web.Services; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Google; using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace BCards.Web.Controllers; [Route("Auth")] public class AuthController : Controller { private readonly IAuthService _authService; public AuthController(IAuthService authService) { _authService = authService; } [HttpGet] [Route("Login")] public IActionResult Login(string? returnUrl = null) { ViewBag.ReturnUrl = returnUrl; return View(); } [HttpPost] [Route("LoginWithGoogle")] public IActionResult LoginWithGoogle(string? returnUrl = null) { var redirectUrl = Url.Action("GoogleCallback", "Auth", new { returnUrl }); var properties = new AuthenticationProperties { RedirectUri = redirectUrl }; return Challenge(properties, GoogleDefaults.AuthenticationScheme); } [HttpPost] [Route("LoginWithMicrosoft")] public IActionResult LoginWithMicrosoft(string? returnUrl = null) { var redirectUrl = Url.Action("MicrosoftCallback", "Auth", new { returnUrl }); var properties = new AuthenticationProperties { RedirectUri = redirectUrl }; return Challenge(properties, MicrosoftAccountDefaults.AuthenticationScheme); } [HttpGet] [Route("GoogleCallback")] public async Task GoogleCallback(string? returnUrl = null) { var result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme); if (!result.Succeeded) { TempData["Error"] = "Falha na autenticação com Google"; return RedirectToAction("Login"); } var user = await _authService.CreateOrUpdateUserFromClaimsAsync(result.Principal); var claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Name, user.Name), new Claim(ClaimTypes.Email, user.Email), new Claim("picture", user.ProfileImage ?? "") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); TempData["Success"] = $"Bem-vindo, {user.Name}!"; return RedirectToLocal(returnUrl); } [HttpGet] [Route("MicrosoftCallback")] public async Task MicrosoftCallback(string? returnUrl = null) { var result = await HttpContext.AuthenticateAsync(MicrosoftAccountDefaults.AuthenticationScheme); if (!result.Succeeded) { TempData["Error"] = "Falha na autenticação com Microsoft"; return RedirectToAction("Login"); } var user = await _authService.CreateOrUpdateUserFromClaimsAsync(result.Principal); var claims = new[] { new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.Name, user.Name), new Claim(ClaimTypes.Email, user.Email), new Claim("picture", user.ProfileImage ?? "") }; var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); var principal = new ClaimsPrincipal(identity); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); TempData["Success"] = $"Bem-vindo, {user.Name}!"; return RedirectToLocal(returnUrl); } [HttpGet] [Route("Logout")] [Authorize] public async Task Logout() { // Identifica qual provedor foi usado var authResult = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); var loginProvider = authResult.Principal?.FindFirst("LoginProvider")?.Value; // Faz logout local primeiro await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); TempData["Success"] = "Logout realizado com sucesso"; // Se foi Microsoft, faz logout completo no provedor if (loginProvider == "Microsoft") { return SignOut(MicrosoftAccountDefaults.AuthenticationScheme); } // Se foi Google, faz logout completo no provedor else if (loginProvider == "Google") { return SignOut(GoogleDefaults.AuthenticationScheme); } return RedirectToAction("Index", "Home"); } private IActionResult RedirectToLocal(string? returnUrl) { if (Url.IsLocalUrl(returnUrl)) return Redirect(returnUrl); return RedirectToAction("Dashboard", "Admin"); } }