Mike Phares b586da5c82 Removed PdfViewController, HtmlViewRenderer and FakeView to be replaced with ViewEngineResult Render method
Added HttpException class for missing HttpException for net8

Wrapped HttpContext.Session, GetJsonResult, IsAjaxRequest and GetUserIdentityName in controllers for net8

Added AuthenticationService to test Fab2ApprovalMKLink code for net8

Compile conditionally flags to debug in dotnet core
2025-05-23 12:27:09 -07:00

401 lines
12 KiB
C#

#if !NET8
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
#endif
#if NET8
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
#endif
#if !NET8
using Fab2ApprovalSystem.DMO;
using Fab2ApprovalSystem.Misc;
using Fab2ApprovalSystem.Models;
#endif
#if !NET8
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
#endif
#if !NET8
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using Newtonsoft.Json;
#endif
namespace Fab2ApprovalSystem.Controllers;
[Authorize]
#if NET8
[Route("[controller]")]
#endif
public class AccountController : Controller {
#if !NET8
public AccountController()
: this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) {
}
public AccountController(UserManager<ApplicationUser> userManager) {
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
#endif
#if !NET8
// GET: /Account/Login
[AllowAnonymous]
// try to make the browser refresh the login page every time, to prevent issues with changing usernames and the anti-forgery token validation
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
#endif
public ActionResult Login(string returnUrl) {
ViewBag.ReturnUrl = returnUrl;
return View();
}
#if !NET8
private void SetSessionParameters(LoginResult loginResult, LoginModel user) {
GlobalVars.SetSessionParameters(GetSession(), loginResult, user);
FormsAuthentication.SetAuthCookie(user.LoginID, true);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginModel model, string returnUrl) {
try {
bool isLoginValid;
HttpClient httpClient = HttpClientFactory.Create();
httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl);
LoginResult loginResult = await AccountDMO.LoginAsync(httpClient, model);
#if (DEBUG)
isLoginValid = true;
#endif
#if (!DEBUG)
bool isIFX = false;
if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
isLoginValid = true;
} else {
isLoginValid = loginResult.IsAuthenticated;
if (isLoginValid)
isIFX = true;
}
#endif
if (isLoginValid) {
UserAccountDMO userDMO = new UserAccountDMO();
LoginModel user = userDMO.GetUser(model.LoginID);
if (user != null) {
SetSessionParameters(loginResult, user);
return RedirectToLocal(returnUrl);
} else {
ModelState.AddModelError("", "The user name does not exist in the DB. Please contact the System Admin");
}
} else {
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
} catch (Exception ex) {
Functions.WriteEvent(GlobalVars.AppSettings, GetUserIdentityName() + " " + ex.InnerException, System.Diagnostics.EventLogEntryType.Error);
EventLogDMO.Add(new WinEventLog() { IssueID = 99999, UserID = GetUserIdentityName(), DocumentType = "Login", OperationType = "Error", Comments = "Reject - " + ex.Message });
ModelState.AddModelError("", ex.Message);
}
return View(model);
// If we got this far, something failed, redisplay form
}
[HttpPost]
[AllowAnonymous]
public async Task<HttpResponseMessage> ExternalAuthSetup(AuthAttempt authAttempt) {
try {
bool isLoginValid;
HttpClient httpClient = HttpClientFactory.Create();
httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl);
LoginResult loginResult = await AccountDMO.ExternalAuthSetupAsync(httpClient, authAttempt);
#if (DEBUG)
isLoginValid = true;
#endif
#if (!DEBUG)
bool isIFX = false;
if (GlobalVars.DBConnection.ToUpper() == "TEST" || GlobalVars.DBConnection.ToUpper() == "QUALITY") {
isLoginValid = true;
} else {
isLoginValid = loginResult.IsAuthenticated;
if (isLoginValid)
isIFX = true;
}
#endif
if (isLoginValid) {
UserAccountDMO userDMO = new UserAccountDMO();
LoginModel user = userDMO.GetUser(authAttempt.LoginID);
if (user != null) {
SetSessionParameters(loginResult, user);
return new HttpResponseMessage(HttpStatusCode.OK);
} else {
ModelState.AddModelError("", "The user name does not exist in the DB. Please contact the System Admin");
return new HttpResponseMessage(HttpStatusCode.NotFound);
}
} else {
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return new HttpResponseMessage(HttpStatusCode.Unauthorized);
}
} catch (Exception ex) {
Functions.WriteEvent(GlobalVars.AppSettings, GetUserIdentityName() + " " + ex.InnerException, System.Diagnostics.EventLogEntryType.Error);
EventLogDMO.Add(new WinEventLog() { IssueID = 99999, UserID = GetUserIdentityName(), DocumentType = "Login", OperationType = "Error", Comments = "Reject - " + ex.Message });
ModelState.AddModelError("", ex.Message);
return new HttpResponseMessage(HttpStatusCode.InternalServerError);
}
}
#endif
// GET: /Account/Register
[AllowAnonymous]
public ActionResult Register() {
return View();
}
#if !NET8
// POST: /Account/Disassociate
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Disassociate(string loginProvider, string providerKey) {
ManageMessageId? message = null;
IdentityResult result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey));
if (result.Succeeded) {
message = ManageMessageId.RemoveLoginSuccess;
} else {
message = ManageMessageId.Error;
}
return RedirectToAction("Manage", new { Message = message });
}
#endif
// GET: /Account/Manage
#pragma warning disable IDE0060 // Remove unused parameter
public ActionResult Manage(ManageMessageId? message) {
return View();
}
#pragma warning restore IDE0060 // Remove unused parameter
#if !NET8
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl) {
// Request a redirect to the external login provider
return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
}
// POST: /Account/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LinkLogin(string provider) {
// Request a redirect to the external login provider to link a login for the current user
return new ChallengeResult(provider, Url.Action("LinkLoginCallback", "Account"), User.Identity.GetUserId());
}
// GET: /Account/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback() {
ExternalLoginInfo loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
if (loginInfo == null) {
return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
}
IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login);
if (result.Succeeded) {
return RedirectToAction("Manage");
}
return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff() {
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
#endif
[AllowAnonymous]
public ActionResult ExternalLoginFailure() {
return View();
}
#if !NET8
[ChildActionOnly]
public ActionResult RemoveAccountList() {
IList<UserLoginInfo> linkedAccounts = UserManager.GetLogins(User.Identity.GetUserId());
ViewBag.ShowRemoveButton = HasPassword() || linkedAccounts.Count > 1;
return (ActionResult)PartialView("_RemoveAccountPartial", linkedAccounts);
}
protected override void Dispose(bool disposing) {
if (disposing && UserManager != null) {
UserManager.Dispose();
UserManager = null;
}
base.Dispose(disposing);
}
#endif
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
#if !NET8
private IAuthenticationManager AuthenticationManager {
get {
return HttpContext.GetOwinContext().Authentication;
}
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent) {
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
private void AddErrors(IdentityResult result) {
foreach (string error in result.Errors) {
ModelState.AddModelError("", error);
}
}
private bool HasPassword() {
ApplicationUser user = UserManager.FindById(User.Identity.GetUserId());
if (user != null) {
return user.PasswordHash != null;
}
return false;
}
#endif
public enum ManageMessageId {
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
Error
}
private ActionResult RedirectToLocal(string returnUrl) {
if (Url.IsLocalUrl(returnUrl)) {
return Redirect(returnUrl);
} else {
return RedirectToAction("MyTasks", "Home");
}
}
#if !NET8
private class ChallengeResult : HttpUnauthorizedResult {
#endif
#if NET8
private class ChallengeResult {
#endif
public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null) {
}
public ChallengeResult(string provider, string redirectUri, string userId) {
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
#if !NET8
public override void ExecuteResult(ControllerContext context) {
AuthenticationProperties properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
if (UserId != null) {
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
#endif
}
#endregion
#if !NET8
private System.Web.HttpSessionStateBase GetSession() =>
Session;
private JsonResult GetJsonResult(object? data) =>
Json(data, JsonRequestBehavior.AllowGet);
private bool IsAjaxRequest() =>
Request.IsAjaxRequest();
#endif
#if NET8
private Microsoft.AspNetCore.Http.ISession GetSession() =>
HttpContext.Session;
private JsonResult GetJsonResult(object? data) =>
Json(data);
private bool IsAjaxRequest() =>
Request.Headers.TryGetValue("X-Requested-With", out Microsoft.Extensions.Primitives.StringValues strings) && strings[0] == "XMLHttpRequest";
#endif
private string GetUserIdentityName() =>
@User.Identity.Name;
}