using Microsoft.AspNetCore.Mvc; 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 Saxonite.Net.Core.Web.Admin.Models; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Saxonite.Net.Core.Web.Admin.Controllers { //======================================================================= partial class UserController { //------------------------------------------------------------------- // User data. private class UserData_List : 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 int UserRoleCount { get; set; } public bool? SystemAdmin { get; set; } = null; } private class UserData_Full : UserData_List { public List userRoleCodes { get; } = new List(); } private void PopulateUserResponseData(UserData_List data, SaxUserAccount user, List userRoles) { 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.UserRoleCount = userRoles?.GetUserRolesByStatus(SaStatus.Active).Count ?? 0; data.SystemAdmin = (userRoles != null && userRoles.Exists(item => item.UserRole == Sax.UserRole.SystemAdmin) ? true : (bool?)null); data.StatusCode = user.StatusCode; data.StatusDesc = user.StatusDesc; } private void PopulateUserResponseData(UserData_Full data, SaxUserAccount user, List userRoles) { PopulateUserResponseData(data as UserData_List, user, userRoles); if (userRoles != null) { foreach (SaxUserRole userRole in userRoles.GetUserRolesByStatus(SaStatus.Active)) data.userRoleCodes.Add(UserRoleCodes.GetCodeForType(userRole.UserRole)); } } //------------------------------------------------------------------- // Utilities. private List GetUserRoles(SysId userAccountId, SaxUserRole.StatusCat statusCat = SaxUserRole.StatusCat.NotDeleted) { if (!SysId.IsValid(userAccountId)) return new List(); SaxUserRole.Params prmUserRole = new SaxUserRole.Params(); prmUserRole.UserAccountIdsIncluded.Add(userAccountId); prmUserRole.StatusCat = statusCat; return AccountMgr.GetUserRoleList(prmUserRole); } //------------------------------------------------------------------- // Get User List ajax request. //------------------------------------------------------------------- private class AjaxResponse_UserList : AjaxResponse_Data { // Construction. public AjaxResponse_UserList(SaxModel_Admin model) : base(model) { } // User list. public List Users { get; } = new List(); // Reference data. public List UserRoles { get; } = new List(); public List Statuses { get; } = new List(); public String DefaultStatusCode { get; set; } } //------------------------------------------------------------------- [HttpPost] [Route("User/Ajax/GetList")] [Route("User/Ajax/GetUsers")] [Route("User/Ajax/GetUserList")] public IActionResult Ajax_GetUserList(Model_User model) { String fn = GetType().Name + ".Ajax_GetUserList"; String messageTitle = Localiser["user.caption.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 - user roles. foreach (TypeCodeDesc userRole in UserRoleCodes) responseData.UserRoles.Add(userRole.Code, Localiser.GetUserRoleCaption((Sax.UserRole)userRole.Type)); responseData.DefaultStatusCode = SacsSystem.GetStatusCode(SaxUserAccount.DefaultStatus); // Reference data - statuses. foreach (SaStatus status in SaxUserAccount.ValidStatuses.FindAll(item => item != SaStatus.Deleted)) responseData.Statuses.Add(SacsSystem.GetStatusCode(status), Localiser.GetStatusCaption(status)); // Item filter. SaxUserAccount.Params prmUserAccount = new SaxUserAccount.Params(); prmUserAccount.UserAccountFilter = model.Filter.User; prmUserAccount.StatusCat = SaxUserAccount.StatusCat.NotDeleted; model.Paging.ItemTotal = (ulong)AccountMgr.GetUserAccountCount(prmUserAccount); model.PopulatePagingTo(prmUserAccount.ResultsPaging); // Item columns. ColumnDfn colId = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.Id); ColumnDfn colEmail = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.EmailAddress); ColumnDfn colTitle = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.Title); ColumnDfn colFirstName = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.FirstName); ColumnDfn colLastName = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.LastName); ColumnDfn colUserRoleCount = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.UserRoleCount); ColumnDfn colSystemAdminUser = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.SystemAdminUser); ColumnDfn colStatus = AccountMgr.GetUserAccountColumnDfn(SaxUserAccount.Column.Status); List columns = new List() { colId, colEmail, colTitle, colFirstName, colLastName, colUserRoleCount, colSystemAdminUser, colStatus }; // Query items. using (DbResultSet resultSet = AccountMgr.ExecuteUserAccountQuery(columns, prmUserAccount)) { while (resultSet != null && resultSet.HasRows && resultSet.NextRecord()) { NamedValue.Map values = resultSet.GetRecordValues(); UserData_List userData = new UserData_List() { 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), UserRoleCount = StringUtil.ToInt(values.GetString(colUserRoleCount.DataName)), SystemAdmin = StringUtil.ToBool(values.GetString(colSystemAdminUser.DataName)), StatusCode = values.GetString(colStatus.DataName), StatusDesc = SacsSystem.GetStatusDescForCode(values.GetString(colStatus.DataName)) }; userData.DisplayName = SaxUserAccount.GetDisplayName(userData.Title, 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(SaxModel_Admin model) : base(model) { } // User details. public UserData_Full user { get; } = new UserData_Full(); } //------------------------------------------------------------------- [HttpPost] [Route("User/Ajax/GetItem")] [Route("User/Ajax/GetUser")] public IActionResult Ajax_GetUser(Model_User model) { String fn = GetType().Name + ".Ajax_GetUser"; String messageTitle = Localiser["user.caption.user"]; AjaxResponse_User responseData = new AjaxResponse_User(model); // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Identify item. SysId userAccountId = model.UserAccountId.ToSysId(); if (!SysId.IsValid(userAccountId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); // Retrieve item. SaxUserAccount user = AccountMgr.GetUserAccountById(userAccountId); if (user == null) { SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + userAccountId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Construct response. PopulateUserResponseData(responseData.user, user, GetUserRoles(user.Id).GetUserRolesByStatus(SaStatus.Active)); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Get User by email ajax request. //------------------------------------------------------------------- [HttpPost] [Route("User/Ajax/GetUserByEmail")] public IActionResult Ajax_GetUserByEmail(Model_User model) { String fn = GetType().Name + ".Ajax_GetUserByEmail"; String messageTitle = Localiser["user.caption.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); // Identify user. if (StringUtil.IsEmpty(model.UserEmailAddress)) { SaLogger.Warn(fn + " Attempt to get user details with blank email."); return Json(responseData); } // Retrieve user. SaxUserAccount user = AccountMgr.GetUserAccountByEmailAddress(model.UserEmailAddress); if (user == null) { SaLogger.Warn(fn + " Failed to retrieve user for Email: " + model.UserEmailAddress); return Json(responseData); } // Construct response. PopulateUserResponseData(responseData.user, user, GetUserRoles(user.Id).GetUserRolesByStatus(SaStatus.Active)); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Store User ajax request. //------------------------------------------------------------------- [HttpPost] [Route("User/Ajax/StoreItem")] [Route("User/Ajax/StoreUser")] public IActionResult Ajax_StoreUser(Model_User model) { String fn = GetType().Name + ".Ajax_StoreUser"; String messageTitle = Localiser["user.caption.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 properties. model.ValidateUserData(responseData); if (responseData.HasControlErrors()) return Json(responseData); // Retrieve existing item. SysId userAccountId = model.UserAccountId.ToSysId(); SaxUserAccount user = AccountMgr.GetUserAccountById(userAccountId); if (user == null && SysId.IsValid(userAccountId)) { SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + model.UserAccountId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // User roles, including deleted in case of reassignment. List userRoles = new List(); if (user != null) userRoles = GetUserRoles(user.Id, SaxUserRole.StatusCat.Any); if (model.UserRoleCodes != null) { List userRoleCodes = model.GetUserRoleCodes(); foreach (String userRoleCode in userRoleCodes) { // Role to activate. Sax.UserRole role = (Sax.UserRole)UserRoleCodes.GetTypeForCode(userRoleCode); SaxUserRole userRole = userRoles.GetUserRoleByRole(role); if (userRole == null) { userRole = AccountMgr.CreateUserRole(user?.Id, role); userRoles.Add(userRole); } userRole.Status = SaStatus.Active; } // Roles to deactivate. foreach (SaxUserRole userRole in userRoles) { if (!userRoleCodes.Exists(item => item.EqualsCI(UserRoleCodes.GetCodeForType(userRole.UserRole)))) userRole.Status = SaStatus.Inactive; } } // Create new item if required. if (user == null) { user = AccountMgr.CreateUserAccount(); if (model.UserEmailAddress != null) user.EmailAddress = model.UserEmailAddress; } // Populate item properties. if (model.UserTitle != null) user.Title = model.UserTitle; if (model.UserFirstName != null) user.FirstName = model.UserFirstName; if (model.UserLastName != null) user.LastName = model.UserLastName; if (model.UserStatusCode != null) user.Status = model.UserStatus; // Store item. if (!SysId.IsValid(user.Id)) { if (!AccountMgr.InsertUserAccount(user, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert user: " + AccountMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.insert.failed"] + "\n\n" + AccountMgr.ErrorStateMessage)); } } else { if (!AccountMgr.UpdateUserAccount(user, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update user [Id:" + SysId.ToString(user.Id) + "]: " + AccountMgr.ErrorStateMessage); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.update.failed"] + "\n\n" + AccountMgr.ErrorStateMessage)); } } if (model.UserRoleCodes != null) { // Associated data - User Roles. foreach (SaxUserRole userRole in (userRoles)) { // Store User Role. if (!SysId.IsValid(userRole.Id)) { // Apply User Account Id if not yet done (for new user). if (!SysId.IsValid(userRole.UserAccountId)) userRole.UserAccountId = user.Id; if (!AccountMgr.InsertUserRole(userRole, DbUpdateInfo)) SaLogger.Warn(fn + " Failed to insert user role: " + AccountMgr.ErrorStateMessage); } else { if (!AccountMgr.UpdateUserRole(userRole, DbUpdateInfo)) SaLogger.Warn(fn + " Failed to update user role [Id:" + SysId.ToString(userRole.Id) + "]: " + AccountMgr.ErrorStateMessage); } } } // Construct response. PopulateUserResponseData(responseData.user, user, userRoles.GetUserRolesByStatus(SaStatus.Active)); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Send User Emails ajax request. //------------------------------------------------------------------- [HttpPost] [Route("User/Ajax/SendEmails")] public IActionResult Ajax_SendEmails(Model_User 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); // Retrieve user. SysId userAccountId = model.UserAccountId.ToSysId(); SaxUserAccount userAccount = AccountMgr.GetUserAccountById(userAccountId); if (userAccount == null) { SaLogger.Warn(fn + " Failed to retrieve user for Id: '" + model.UserAccountId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // User roles. List userRoles = GetUserRoles(userAccount.Id, SaxUserRole.StatusCat.Any); bool systemAdmin = userRoles.Exists(item => item.UserRole == Sax.UserRole.SystemAdmin); // Email types to send. bool sendAcountActivationOnline = StringUtil.ToBool(model.UserEmailAcountActivationOnline); bool sendRequestPasswordOnline = StringUtil.ToBool(model.UserEmailRequestPasswordOnline); bool sendRequestPasswordAdmin = StringUtil.ToBool(model.UserEmailRequestPasswordAdmin); if (!sendAcountActivationOnline && !sendRequestPasswordOnline && !sendRequestPasswordAdmin) return Json(responseData.SetMessage(messageTitle, Localiser["msg.validation.select.option"])); if (sendRequestPasswordAdmin && !systemAdmin) return Json(responseData.SetMessage(messageTitle, Localiser["user.msg.not.system.admin"])); // Send emails. int emailsSentCount = 0; if (sendAcountActivationOnline) { if (!OrganisationController.SendAccountActivatedEmail(this, userAccount)) return Json(responseData.SetMessage(messageTitle, "Failed to send Online Accoutn Activation email.")); emailsSentCount++; } if (sendRequestPasswordOnline) { if (!SecurityController.SendRequestPasswordEmail(this, userAccount, true)) return Json(responseData.SetMessage(messageTitle, "Failed to send Online Request Password email.")); emailsSentCount++; } if (sendRequestPasswordAdmin) { if (!SecurityController.SendRequestPasswordEmail(this, userAccount, false)) return Json(responseData.SetMessage(messageTitle, "Failed to send Admin Request Password email.")); emailsSentCount++; } // Construct response. PopulateUserResponseData(responseData.user, userAccount, userRoles.GetUserRolesByStatus(SaStatus.Active)); responseData.SetNotification(messageTitle, "Emails sent: " + emailsSentCount); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }