98 lines
4.1 KiB
C#
98 lines
4.1 KiB
C#
using System.Security.Claims;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
using TaxBaik.Application.Services;
|
|
using TaxBaik.Web.Services;
|
|
|
|
namespace TaxBaik.Web.Pages.Portal;
|
|
|
|
public class ExternalCallbackModel : PageModel
|
|
{
|
|
private readonly PortalUserService _portalUserService;
|
|
private readonly ClientService _clientService;
|
|
|
|
public ExternalCallbackModel(PortalUserService portalUserService, ClientService clientService)
|
|
{
|
|
_portalUserService = portalUserService;
|
|
_clientService = clientService;
|
|
}
|
|
|
|
public async Task<IActionResult> OnGetAsync(string provider)
|
|
{
|
|
var external = await HttpContext.AuthenticateAsync(PortalOAuthDefaults.ExternalScheme);
|
|
if (external?.Principal is null)
|
|
return RedirectToPage("/Portal/Login");
|
|
|
|
var email = external.Principal.FindFirstValue(ClaimTypes.Email);
|
|
var name = external.Principal.FindFirstValue(ClaimTypes.Name) ?? "고객";
|
|
var providerId = external.Principal.FindFirstValue(ClaimTypes.NameIdentifier) ?? "";
|
|
|
|
if (string.IsNullOrWhiteSpace(providerId))
|
|
return RedirectToPage("/Portal/Login");
|
|
|
|
var existing = await _portalUserService.GetByProviderAsync(provider, providerId);
|
|
if (existing is null && !string.IsNullOrWhiteSpace(email))
|
|
{
|
|
existing = await _portalUserService.GetByEmailAsync(email);
|
|
if (existing is null)
|
|
{
|
|
int? clientId = null;
|
|
var linkedClient = await _clientService.GetByEmailAsync(email);
|
|
if (linkedClient is null && !string.IsNullOrWhiteSpace(external.Principal.FindFirstValue("phone")))
|
|
linkedClient = await _clientService.GetByPhoneAsync(external.Principal.FindFirstValue("phone")!);
|
|
if (linkedClient is not null)
|
|
clientId = linkedClient.Id;
|
|
|
|
await _portalUserService.RegisterOAuthAsync(
|
|
name,
|
|
email,
|
|
external.Principal.FindFirstValue("phone") ?? "",
|
|
provider,
|
|
providerId,
|
|
clientId);
|
|
existing = await _portalUserService.GetByEmailAsync(email);
|
|
}
|
|
else if (!string.Equals(existing.Provider, provider, StringComparison.OrdinalIgnoreCase) ||
|
|
!string.Equals(existing.ProviderId, providerId, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
await _portalUserService.LinkOAuthAsync(existing, provider, providerId, name, email);
|
|
}
|
|
}
|
|
|
|
if (existing is not null && !existing.ClientId.HasValue && !string.IsNullOrWhiteSpace(email))
|
|
{
|
|
var linkedClient = await _clientService.GetByEmailAsync(email);
|
|
if (linkedClient is null && !string.IsNullOrWhiteSpace(external.Principal.FindFirstValue("phone")))
|
|
linkedClient = await _clientService.GetByPhoneAsync(external.Principal.FindFirstValue("phone")!);
|
|
if (linkedClient is not null)
|
|
{
|
|
await _portalUserService.AttachClientAsync(existing, linkedClient.Id);
|
|
existing.ClientId = linkedClient.Id;
|
|
}
|
|
}
|
|
|
|
if (existing is null)
|
|
return RedirectToPage("/Portal/Login");
|
|
|
|
var claims = new List<Claim>
|
|
{
|
|
new(ClaimTypes.NameIdentifier, existing.Id.ToString()),
|
|
new(ClaimTypes.Name, existing.Name),
|
|
new(ClaimTypes.Email, existing.Email),
|
|
new("portal_user_id", existing.Id.ToString())
|
|
};
|
|
|
|
if (existing.ClientId.HasValue)
|
|
claims.Add(new("client_id", existing.ClientId.Value.ToString()));
|
|
|
|
await HttpContext.SignInAsync(
|
|
PortalAuthDefaults.Scheme,
|
|
new ClaimsPrincipal(new ClaimsIdentity(claims, PortalAuthDefaults.Scheme)),
|
|
new AuthenticationProperties { IsPersistent = true });
|
|
|
|
await HttpContext.SignOutAsync(PortalOAuthDefaults.ExternalScheme);
|
|
return RedirectToPage("/Portal/Index");
|
|
}
|
|
}
|