Portal signin via Control Instance

This commit is contained in:
Andy Howard
2024-10-29 08:40:47 +00:00
parent bf6bb966bc
commit c5ee285e27
467 changed files with 25771 additions and 3347 deletions
@@ -0,0 +1,422 @@
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.AspNetCore.Mvc;
using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control;
using Sarand.BusinessMgr.Web.Control.Models;
using Sarand.BusinessMgr.Web.Control.Models.Account;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Bus;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Dbas;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Sarand.BusinessMgr.Web.Control.Controllers.Account
{
//=======================================================================
partial class UserAccountController
{
//-------------------------------------------------------------------
// Definitions.
// User data.
private class UserListData : AjaxResponse_Data.ItemData_Base
{
public String EmailAddress { get; set; }
public String DisplayName { get; set; }
public String Title { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Phone { get; set; }
public String LastLoginOn { get; set; }
public String LastLoginAt { get; set; }
}
private class UserItemData : UserListData
{
public String Initials { get; set; }
public String PhoneMain { get; set; }
public String PhoneMobile { get; set; }
public String PhoneAlt { get; set; }
}
private void PopulateUserResponseListData(SbmModel_Control model, UserListData data, SbmcUserAccount user)
{
data.Id = SysId.ToString(user.Id);
data.EmailAddress = user.EmailAddress;
data.DisplayName = user.GetDisplayName();
data.Title = user.Title;
data.FirstName = user.FirstName;
data.LastName = user.LastName;
data.Phone = StringUtil.OnBlank(user.PhoneMain, user.PhoneMobile, user.PhoneAlt);
data.LastLoginOn = model.FormatDateForDisplay(user.LastLoginAt);
data.LastLoginAt = model.FormatDateTimeForDisplay(user.LastLoginAt);
data.StatusCode = user.StatusCode;
data.StatusDesc = user.StatusDesc;
}
private void PopulateUserResponseItemData(SbmModel_Control model, UserItemData data, SbmcUserAccount user)
{
PopulateUserResponseListData(model, data, user);
data.Initials = user.Initials;
data.PhoneMain = user.PhoneMain;
data.PhoneMobile = user.PhoneMobile;
data.PhoneAlt = user.PhoneAlt;
}
//-------------------------------------------------------------------
// Get User List ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_UserList : AjaxResponse_Data
{
// Construction.
public AjaxResponse_UserList(SbmModel_Control model) : base(model) { }
// User list.
public List<UserListData> Users { get; } = new List<UserListData>();
// Reference data.
public List<CodeDesc> Statuses { get; } = new List<CodeDesc>();
public List<CodeDesc> StatusesCreate { get; } = new List<CodeDesc>();
public String StatusCodeDefault { get; set; }
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Account/UserAccount/Ajax/GetList")]
[Route("Account/UserAccount/Ajax/GetUsers")]
[Route("Account/UserAccount/Ajax/GetUserList")]
public IActionResult Ajax_GetUserList(Model_UserAccount model)
{
String fn = GetType().Name + ".Ajax_GetUserList";
String messageTitle = Localiser["label.users"];
AjaxResponse_UserList responseData = new AjaxResponse_UserList(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Reference data - statuses.
foreach (SaStatus status in SbmcUserAccount.ValidStatuses)
{
responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
if (status != SaStatus.Deleted)
responseData.StatusesCreate.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status));
}
responseData.StatusCodeDefault = SacsSystem.GetStatusCode(SbmcUserAccount.DefaultStatus);
// Item filter.
SbmcUserAccount.Params prmUserAccount = new SbmcUserAccount.Params();
prmUserAccount.Search = model.Filter.Search;
prmUserAccount.StatusCat = model.Filter.GetStatusCat();
model.Paging.ItemTotal = (ulong)ControlAccountMgr.GetUserAccountCount(prmUserAccount);
model.PopulatePagingTo(prmUserAccount.ResultsPaging);
// Item columns.
ColumnDfn colId = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.Id);
ColumnDfn colEmail = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.EmailAddress);
ColumnDfn colTitle = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.Title);
ColumnDfn colFirstName = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.FirstName);
ColumnDfn colLastName = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.LastName);
ColumnDfn colPhoneMain = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.PhoneMain);
ColumnDfn colPhoneMobile = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.PhoneMobile);
ColumnDfn colPhoneAlt = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.PhoneAlt);
ColumnDfn colLastLogin = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.LastLoginAt);
ColumnDfn colStatus = ControlAccountMgr.GetUserAccountColumnDfn(SbmcUserAccount.Column.Status);
List<ColumnDfn> columns = new List<ColumnDfn>()
{
colId, colEmail, colTitle, colFirstName, colLastName,
colPhoneMain, colPhoneMobile, colPhoneAlt, colLastLogin, colStatus
};
// Query items.
using (DbResultSet resultSet = ControlAccountMgr.ExecuteUserAccountQuery(columns, prmUserAccount))
{
while (resultSet != null && resultSet.HasRows && resultSet.NextRecord())
{
NamedValue.Map values = resultSet.GetRecordValues();
UserListData userData = new UserListData()
{
Id = values.GetString(colId.DataName),
EmailAddress = values.GetString(colEmail.DataName),
Title = values.GetString(colTitle.DataName),
FirstName = values.GetString(colFirstName.DataName),
LastName = values.GetString(colLastName.DataName),
Phone = StringUtil.OnBlank(values.GetString(colPhoneMain.DataName), values.GetString(colPhoneMobile.DataName), values.GetString(colPhoneAlt.DataName)),
LastLoginOn = model.FormatDateForDisplay(values.GetDateTime(colLastLogin.DataName)),
LastLoginAt = model.FormatDateTimeForDisplay(values.GetDateTime(colLastLogin.DataName)),
StatusCode = values.GetString(colStatus.DataName),
StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName))
};
userData.DisplayName = SbmcUserAccount.GetDisplayName(userData.FirstName, userData.LastName);
responseData.Users.Add(userData);
}
}
if (model.Paging.IsPaged)
model.Paging.ItemCount = (ushort)responseData.Users.Count;
// Complete response.
responseData.SetPaging(model);
responseData.Success = true;
return Json(responseData);
}
//-------------------------------------------------------------------
// Get User ajax request.
//-------------------------------------------------------------------
private class AjaxResponse_User : AjaxResponse_Data
{
// Construction.
public AjaxResponse_User(SbmModel_Control model) : base(model) { }
// User details.
public UserItemData user { get; } = new UserItemData();
}
//-------------------------------------------------------------------
[HttpPost]
[Route("Account/UserAccount/Ajax/GetItem")]
[Route("Account/UserAccount/Ajax/GetUser")]
public IActionResult Ajax_GetUser(Model_UserAccount model)
{
String fn = GetType().Name + ".Ajax_GetUser";
String messageTitle = Localiser["label.user"];
AjaxResponse_User responseData = new AjaxResponse_User(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// Identify item.
SysId userAccountId = model.User.Id.ToSysId();
if (!SysId.IsValid(userAccountId))
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"]));
// Retrieve item.
SbmcUserAccount user = ControlAccountMgr.GetUserAccountById(userAccountId);
disposables.Add(user);
if (user == null)
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Id: '" + userAccountId + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Construct response.
PopulateUserResponseItemData(model, responseData.user, user);
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
// Get User by email ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Account/UserAccount/Ajax/GetUserByEmail")]
public IActionResult Ajax_GetUserByEmail(Model_UserAccount model)
{
String fn = GetType().Name + ".Ajax_GetUserByEmail";
String messageTitle = Localiser["label.user"];
AjaxResponse_User responseData = new AjaxResponse_User(model);
StoreSessionData = false;
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// Identify user.
if (StringUtil.IsEmpty(model.Filter.EmailAddress))
{
SaLogger.Warn($"{SysUtil.Fn} Attempt to get user details with blank email.");
return Json(responseData);
}
// Retrieve user.
SbmcUserAccount user = ControlAccountMgr.GetUserAccountByEmailAddress(model.Filter.EmailAddress);
disposables.Add(user);
if (user == null)
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Email: " + model.Filter.EmailAddress);
return Json(responseData);
}
// Construct response.
PopulateUserResponseItemData(model, responseData.user, user);
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
// Store User ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Account/UserAccount/Ajax/StoreItem")]
[Route("Account/UserAccount/Ajax/StoreUser")]
public IActionResult Ajax_StoreUser(Model_UserAccount model)
{
String fn = GetType().Name + ".Ajax_StoreUser";
String messageTitle = Localiser["label.user"];
AjaxResponse_User responseData = new AjaxResponse_User(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Validate item Id.
SysId userAccountId = model.User.Id.ToSysId();
if (StringUtil.ToBool(model.User.Exists) && !SysId.IsValid(userAccountId))
{
SaLogger.Warn($"{SysUtil.Fn} User Id not supplied for existing item.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
if (!StringUtil.ToBool(model.User.Exists) && SysId.IsValid(userAccountId))
{
SaLogger.Warn($"{SysUtil.Fn} User Id supplied for new item.");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.system"]));
}
// Validate item properties.
model.ValidateUserData(responseData);
if (responseData.HasControlErrors())
return Json(responseData);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// Retrieve existing item.
SbmcUserAccount user = ControlAccountMgr.GetUserAccountById(userAccountId);
disposables.Add(user);
if (user == null && SysId.IsValid(userAccountId))
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Id: '" + model.User.Id + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Create new item if required.
if (user == null)
{
user = ControlAccountMgr.CreateUserAccount();
if (model.User.EmailAddress != null)
user.EmailAddress = model.User.EmailAddress;
}
// Populate item properties.
if (model.User.Title != null)
user.Title = model.User.Title;
if (model.User.FirstName != null)
user.FirstName = model.User.FirstName;
if (model.User.Initials != null)
user.Initials = model.User.Initials;
if (model.User.LastName != null)
user.LastName = model.User.LastName;
if (model.User.PhoneMain != null)
user.PhoneMain = model.User.PhoneMain;
if (model.User.PhoneMobile != null)
user.PhoneMobile = model.User.PhoneMobile;
if (model.User.PhoneAlt != null)
user.PhoneAlt = model.User.PhoneAlt;
if (model.User.StatusCode != null)
user.Status = model.User.GetStatus();
// Store item.
if (!SysId.IsValid(user.Id))
{
if (!ControlAccountMgr.InsertUserAccount(user, DbUpdateInfo))
{
SaLogger.Warn($"{SysUtil.Fn} Failed to insert user: " + ControlAccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + ControlAccountMgr.ErrorStateMessage));
}
}
else
{
if (!ControlAccountMgr.UpdateUserAccount(user, DbUpdateInfo))
{
SaLogger.Warn($"{SysUtil.Fn} Failed to update user [Id:" + SysId.ToString(user.Id) + "]: " + ControlAccountMgr.ErrorStateMessage);
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + ControlAccountMgr.ErrorStateMessage));
}
}
// Construct response.
PopulateUserResponseItemData(model, responseData.user, user);
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
// Send User Emails ajax request.
//-------------------------------------------------------------------
[HttpPost]
[Route("Account/UserAccount/Ajax/SendEmails")]
public IActionResult Ajax_SendEmails(Model_UserAccount model)
{
String fn = GetType().Name + ".Ajax_SendEmails";
String messageTitle = Localiser["label.emails"];
AjaxResponse_User responseData = new AjaxResponse_User(model);
// Validate session and referrer.
if (!ValidReferer) return Forbid();
if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData);
RefreshModel(model);
// Record disposable items as they are created so all can be disposed when needed.
using (DisposableCollection<SacsHierarchyItem> disposables = new DisposableCollection<SacsHierarchyItem>())
{
// Retrieve user.
SysId userAccountId = model.User.Id.ToSysId();
SbmcUserAccount userAccount = ControlAccountMgr.GetUserAccountById(userAccountId);
disposables.Add(userAccount);
if (userAccount == null)
{
SaLogger.Warn($"{SysUtil.Fn} Failed to retrieve user for Id: '" + model.User.Id + "'");
return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"]));
}
// Email types to send.
bool sendAcountActivationPortal = StringUtil.ToBool(model.UserEmailAcountActivationPortal);
bool sendRequestPasswordPortal = StringUtil.ToBool(model.UserEmailRequestPasswordPortal);
bool sendRequestPasswordControl = StringUtil.ToBool(model.UserEmailRequestPasswordControl);
if (!sendAcountActivationPortal && !sendRequestPasswordPortal && !sendRequestPasswordControl)
return Json(responseData.SetMessage(messageTitle, Localiser["msg.validation.select.option"]));
// Send emails.
int emailsSentCount = 0;
if (sendAcountActivationPortal)
{
//if (!OrganisationController.SendAccountActivatedEmail(this, userAccount))
return Json(responseData.SetMessage(messageTitle, "Failed to send Online Account Activation email."));
//emailsSentCount++;
}
if (sendRequestPasswordPortal)
{
if (!SecurityController.SendRequestPasswordEmail(this, userAccount, true))
return Json(responseData.SetMessage(messageTitle, "Failed to send Online Request Password email."));
emailsSentCount++;
}
if (sendRequestPasswordControl)
{
if (!SecurityController.SendRequestPasswordEmail(this, userAccount, false))
return Json(responseData.SetMessage(messageTitle, "Failed to send Control Request Password email."));
emailsSentCount++;
}
// Construct response.
PopulateUserResponseItemData(model, responseData.user, userAccount);
responseData.SetNotification(messageTitle, "Emails sent: " + emailsSentCount);
responseData.Success = true;
}
return Json(responseData);
}
//-------------------------------------------------------------------
}
//=======================================================================
}
@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Sarand.BusinessMgr.Net.Core.Web.App;
using Sarand.BusinessMgr.Web.Control.Models.Account;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace Sarand.BusinessMgr.Web.Control.Controllers.Account
{
//======================================================================
public partial class UserAccountController : SbmController_Control
{
//-------------------------------------------------------------------
// Data members.
//-------------------------------------------------------------------
// Construction.
public UserAccountController(SbmLocaliser localiser, ILogger<UserAccountController> logger) :
base(localiser, logger)
{
}
//-------------------------------------------------------------------
[Route("Account/UserAccount")]
public IActionResult Account_UserAccount()
{
// Redirect to sign-in if not signed-in.
if (!ValidUserSession)
AutoLoginUser();
if (!ValidUserSession)
{
ClearKeepLoggedInCookie();
return RedirectToAction("", "Security");
}
// UserAccount page.
Model_UserAccount model = new Model_UserAccount(Localiser);
return View("Views/Account/UserAccount/Index.cshtml", model);
}
//-------------------------------------------------------------------
}
//======================================================================
}