Files
ZelWiki/TightWiki/Controllers/AccountController.cs
2025-02-07 16:16:10 +08:00

116 lines
4.9 KiB
C#

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using NTDLS.Helpers;
using System.Security.Claims;
using TightWiki.Models;
using TightWiki.Models.ViewModels;
using TightWiki.Repository;
namespace TightWiki.Controllers
{
[Area("Identity")]
[Route("Identity/Account")]
public class AccountController : WikiControllerBase
{
private readonly IUserStore<IdentityUser> _userStore;
private readonly IUserEmailStore<IdentityUser> _emailStore;
public AccountController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager, IUserStore<IdentityUser> userStore)
: base(signInManager, userManager)
{
_userStore = userStore;
_emailStore = (IUserEmailStore<IdentityUser>)_userStore;
}
[HttpGet("ExternalLogin")]
[ValidateAntiForgeryToken]
public IActionResult ExternalLoginHttpGet(string provider, string? returnUrl = null)
{
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new { area = "Identity", ReturnUrl = returnUrl });
var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
[HttpPost("ExternalLogin")]
[ValidateAntiForgeryToken]
public IActionResult ExternalLoginHttpPost(string provider, string? returnUrl = null)
{
var redirectUrl = Url.Action(nameof(ExternalLoginCallback), "Account", new { area = "Identity", ReturnUrl = returnUrl });
var properties = SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
public async Task<IActionResult> ExternalLoginCallback(string? returnUrl = null, string? remoteError = null)
{
//We use this model to display any errors that occur.
var model = new ExternalLoginCallbackViewModel();
returnUrl ??= Url.Content("~/");
if (remoteError != null)
{
return NotifyOfError($"外部提供程序出错: {remoteError}");
}
var info = await SignInManager.GetExternalLoginInfoAsync();
if (info == null)
{
return NotifyOfError($"无法从外部提供程序获取信息");
}
var user = await UserManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
if (user != null)
{
// User exists, sign them in:
await SignInManager.SignInAsync(user, isPersistent: false);
if (UsersRepository.TryGetBasicProfileByUserId(Guid.Parse(user.Id), out _) == false)
{
if (GlobalConfiguration.AllowSignup != true)
{
return Redirect($"{GlobalConfiguration.BasePath}/Identity/Account/RegistrationIsNotAllowed");
}
//User exits but does not have a profile.
//This means that the user has authenticated externally, but has yet to complete the signup process.
return RedirectToPage($"{GlobalConfiguration.BasePath}/Account/ExternalLoginSupplemental", new { ReturnUrl = returnUrl });
}
return LocalRedirect(returnUrl);
}
else
{
// If the user does not exist, check by email
var email = info.Principal.FindFirstValue(ClaimTypes.Email).EnsureNotNull();
if (string.IsNullOrEmpty(email))
{
return NotifyOfError($"电子邮件地址不是由外部提供商提供的.");
}
user = await UserManager.FindByEmailAsync(email);
if (user != null)
{
// User with this email exists but not linked with this external login, link them:
var result = await UserManager.AddLoginAsync(user, info);
if (!result.Succeeded)
{
return NotifyOfError(string.Join("<br />\r\n", result.Errors.Select(o => o.Description)));
}
await SignInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
else
{
// If user with this email does not exist, then we need to create the user and profile.
if (GlobalConfiguration.AllowSignup != true)
{
return Redirect($"{GlobalConfiguration.BasePath}/Identity/Account/RegistrationIsNotAllowed");
}
return RedirectToPage($"{GlobalConfiguration.BasePath}/Account/ExternalLoginSupplemental", new { ReturnUrl = returnUrl });
}
}
}
}
}