using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Sarand.BusinessMgr.Net.Core.Web.App; using Sarand.BusinessMgr.Net.Standard.Base.App; using Sarand.BusinessMgr.Net.Standard.Base.Bus; using Sarand.BusinessMgr.Net.Standard.Base.Bus.Control; using Sarand.BusinessMgr.Net.Standard.Base.Data; using Sarand.BusinessMgr.Web.Control.Components; using Sarand.BusinessMgr.Web.Control.Consoles; using Sarand.BusinessMgr.Web.Control.Models.Instance; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Security; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Linq; namespace Sarand.BusinessMgr.Web.Control.Controllers.Instance { //======================================================================= public partial class RepositoryInitController : SbmController_Control { //------------------------------------------------------------------- // Definitions. // Repository data. /// /// Repository initialisation data. /// - May have multiple (internal) Organisations. /// - Each Organisation may have multiple 'Superuser' users. /// public class RepositoryData { // Repository data. public String Id { get; set; } public String OwnerId { get; set; } public String OwnerName { get; set; } public String Context { get; set; } // Organisations. public List Organisations { get; } = new List(); } public class RepositoryOrganisationData { // Organisation data. public String AffiliateId { get; set; } public String AssociationId { get; set; } public String Name { get; set; } public String Website { get; set; } public String CompanyNo { get; set; } public String VatReg { get; set; } // Registered users. public List Users { get; } = new List(); } public class RepositoryUserData { public String AffiliateId { get; set; } public String SecurityItemId { get; set; } public String FirstName { get; set; } public String LastName { get; set; } public String Email { get; set; } public String Code { get; set; } public String Password { get; set; } } //------------------------------------------------------------------- // Construction. public RepositoryInitController(SbmLocaliser localiser, ILogger logger) : base(localiser, logger) { } //------------------------------------------------------------------- // Get Repository Initialisation Info ajax request. //------------------------------------------------------------------- private class AjaxResponse_RepositoryInitInfo : AjaxResponse_Data { // Construction. public AjaxResponse_RepositoryInitInfo(SbmModel_Control model) : base(model) { } // Repository initialisation info. public RepositoryData Repository { get; } = new RepositoryData(); } //------------------------------------------------------------------- [HttpPost] [Route("Instance/Repository/Ajax/GetInitInfo")] public IActionResult Ajax_GetRepositoryInitInfo(Model_RepositoryInit model) { String messageTitle = Localiser["label.repository"]; AjaxResponse_RepositoryInitInfo responseData = new AjaxResponse_RepositoryInitInfo(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 disposables = new DisposableCollection()) { // Validate Repository. SysId repositoryId = SysId.ToSysId(model.Repository.Id); if (!SysId.IsValid(repositoryId)) { SaLogger.Warn($"{SysUtil.Fn} Repository Id not supplied."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } SbmcRepository repository = ControlInstanceMgr.GetRepositoryById(repositoryId); if (repository == null) { SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Id: {repositoryId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } responseData.Repository.Id = $"{SysId.ToLong(repository.Id)}"; responseData.Repository.Context = repository.Context; // Owner. SbmcOwner owner = ControlInstanceMgr.GetOwnerById(repository.OwnerId); if (owner == null) { SaLogger.Warn($"{SysUtil.Fn} Owner does not exist. Id: {repository.OwnerId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } responseData.Repository.OwnerId = $"{SysId.ToLong(owner.Id)}"; responseData.Repository.OwnerName = owner.Name; // Core Instance Console. SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(instanceConsole); // Query Organisations. SbmAssociation.Params prm = new SbmAssociation.Params(); prm.AssociationType = Sbm.AssociationType.Internal; prm.StatusCat = SbmAssociation.StatusCat.CurrentOnly; foreach (SbmAssociation association in instanceConsole.Internals.AccountMgr.GetAssociationList(prm)) { // Retrieve Organisation details. SbmAffiliate affiliateOrganisation = instanceConsole.Internals.AccountMgr.GetAffiliateById(association.AffiliateIdOwner); // Organisation details. RepositoryOrganisationData organisation = new RepositoryOrganisationData() { AssociationId = SysId.ToString(association.Id), AffiliateId = SysId.ToString(affiliateOrganisation.Id), Name = affiliateOrganisation.Name, Website = affiliateOrganisation.Website, CompanyNo = affiliateOrganisation.CompanyNo, VatReg = affiliateOrganisation.VatReg, }; // Retrieve user details. SbmAffiliate.Params prmAffiliateUser = new SbmAffiliate.Params(); prmAffiliateUser.AffiliateIdAssocOwner = affiliateOrganisation.Id; prmAffiliateUser.AssociationType = Sbm.AssociationType.Member; prmAffiliateUser.StatusCat = SbmAffiliate.StatusCat.CurrentOnly; prmAffiliateUser.SortColumns.Add(instanceConsole.Internals.AccountMgr.GetAffiliateColumnDfn(SbmAffiliate.Column.Id)); foreach (SbmAffiliate affiliateUser in instanceConsole.Internals.AccountMgr.GetAffiliateList(prmAffiliateUser)) { // Lookup security details. if (!SysId.IsValid(affiliateUser.UserId)) continue; SaSecurityItem securityItemUser = instanceConsole.Internals.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, affiliateUser.UserId); if (securityItemUser == null) continue; // Confirm security rights (SuperUser). SaSecurityProfile securityProfile = instanceConsole.Internals.SecurityConsole.GetUserSecurityProfile(securityItemUser.Id); if (!securityProfile.Groups.Any(group => group.Code.EqualsCI(SaSecurityConsole.GroupCode_Super))) continue; // Add User to the Organisation. RepositoryUserData userData = new RepositoryUserData() { AffiliateId = SysId.ToString(affiliateUser.Id), SecurityItemId = SysId.ToString(securityItemUser.Id), FirstName = affiliateUser.FirstName, LastName = affiliateUser.LastName, Email = StringUtil.OnBlank(securityItemUser.EmailAddress, affiliateUser.Email), Code = securityItemUser.Code, }; organisation.Users.Add(userData); } // Add this Organisation to the list. responseData.Repository.Organisations.Add(organisation); } // Complete response. responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- // Initialise Repository ajax request. //------------------------------------------------------------------- private class AjaxResponse_RepositoryInitialise : AjaxResponse_Data { // Construction. public AjaxResponse_RepositoryInitialise(SbmModel_Control model) : base(model) { } // Repository details - to mimic response from GetRepositoryList. public RepositoryController.RepositoryListData Repository { get; } = new(); } [HttpPost] [Route("Instance/Repository/Ajax/Initialise")] public IActionResult Ajax_StoreRepository(Model_RepositoryInit model) { String messageTitle = Localiser["label.repository"]; AjaxResponse_RepositoryInitialise responseData = new AjaxResponse_RepositoryInitialise(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 disposables = new DisposableCollection()) { // Validate Repository. SysId repositoryId = SysId.ToSysId(model.Repository.Id); if (!SysId.IsValid(repositoryId)) { SaLogger.Warn($"{SysUtil.Fn} Repository Id not supplied."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } SbmcRepository repository = ControlInstanceMgr.GetRepositoryById(repositoryId); if (repository == null) { SaLogger.Warn($"{SysUtil.Fn} Repository does not exist. Id: {repositoryId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } SbmcOwner owner = ControlInstanceMgr.GetOwnerById(repository.OwnerId); if (owner == null) { SaLogger.Warn($"{SysUtil.Fn} Owner does not exist. Id: {repository.OwnerId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } // Core Instance Console. SbmCoreInstanceConsole_Control instanceConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(instanceConsole); // Validate Existing Organisation properties. if (StringUtil.ToBool(model.Organisation.Exists)) { // Validate existing Organisation Affiliate. SysId affiliateIdOrganisation = SysId.ToSysId(model.Organisation.AffiliateId); if (!SysId.IsValid(affiliateIdOrganisation)) { SaLogger.Warn($"{SysUtil.Fn} Affiliate Id not specified for existing Organisation."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } // Validate Organisation Affiliate. SbmAffiliate affiliateOrganisation = instanceConsole.Internals.AccountMgr.GetAffiliateById(affiliateIdOrganisation); if (affiliateOrganisation == null) { SaLogger.Warn($"{SysUtil.Fn} Affiliate not found for existing Organisation. Id: {model.Organisation.AffiliateId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (!affiliateOrganisation.IsOrganisation()) { SaLogger.Warn($"{SysUtil.Fn} Affiliate for existing Organisation is not an organisation. Id: {model.Organisation.AffiliateId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } // Validate existing Organisation Internal Association. SysId associationIdInternal = SysId.ToSysId(model.Organisation.AssociationId); if (!SysId.IsValid(associationIdInternal)) { SaLogger.Warn($"{SysUtil.Fn} Association Id not specified for existing Organisation."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } else { // Validate Internal Association. SbmAssociation associationOrganisation = instanceConsole.Internals.AccountMgr.GetAssociationById(associationIdInternal); if (associationOrganisation == null) { SaLogger.Warn($"{SysUtil.Fn} Association not found for existing Organisation. Id: {model.Organisation.AssociationId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (!associationOrganisation.AffiliateIdOwner.Equals(affiliateIdOrganisation)) { SaLogger.Warn($"{SysUtil.Fn} Association for existing Organisation does not match Owner Affiliate. Id: {model.Organisation.AssociationId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (!associationOrganisation.AffiliateIdTarget.Equals(affiliateIdOrganisation)) { SaLogger.Warn($"{SysUtil.Fn} Association for existing Organisation does not match Target Affiliate. Id: {model.Organisation.AssociationId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (!associationOrganisation.IsInternal()) { SaLogger.Warn($"{SysUtil.Fn} Association for existing Organisation is not internal. Id: {model.Organisation.AssociationId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } } } else { // Organisation does not exist. if (SysId.IsValid(SysId.ToSysId(model.Organisation.AffiliateId))) { SaLogger.Warn($"{SysUtil.Fn} Affiliate Id specified for new Organisation. Id: {model.Organisation.AffiliateId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (SysId.IsValid(SysId.ToSysId(model.Organisation.AssociationId))) { SaLogger.Warn($"{SysUtil.Fn} Association Id specified for new Organisation. Id: {model.Organisation.AssociationId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } } // Validate Existing User properties. if (StringUtil.ToBool(model.User.Exists)) { // Validate existing User Affiliate. SysId affiliateIdUser = SysId.ToSysId(model.User.AffiliateId); if (!SysId.IsValid(affiliateIdUser)) { SaLogger.Warn($"{SysUtil.Fn} Affiliate Id not specified for existing User."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } // Validate User Affiliate. SbmAffiliate affiliateUser = instanceConsole.Internals.AccountMgr.GetAffiliateById(affiliateIdUser); if (affiliateUser == null) { SaLogger.Warn($"{SysUtil.Fn} Affiliate not found for existing User. Id: {model.User.AffiliateId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (!affiliateUser.IsIndividual()) { SaLogger.Warn($"{SysUtil.Fn} Affiliate for existing User is not an individual. Id: {model.User.AffiliateId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } // Validate existing User Security Item. SysId secItemIdUser = SysId.ToSysId(model.User.SecurityItemId); if (!SysId.IsValid(secItemIdUser)) { SaLogger.Warn($"{SysUtil.Fn} Security Item Id not specified for existing User."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } else { // Validate User Security Item. SaSecurityItem securityItemUser = instanceConsole.Internals.SecurityConsole.GetSecurityItemById(SaSecurity.ItemType.User, secItemIdUser); if (securityItemUser == null) { SaLogger.Warn($"{SysUtil.Fn} Security Item not found for existing User. Id: {model.User.SecurityItemId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (!securityItemUser.Id.Equals(affiliateUser.UserId)) { SaLogger.Warn($"{SysUtil.Fn} Security Item for existing User does not match User Id on Affilliate. Expected: {model.User.SecurityItemId}. Found: {affiliateUser.UserId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } } } else { // User does not exist. if (SysId.IsValid(SysId.ToSysId(model.User.AffiliateId))) { SaLogger.Warn($"{SysUtil.Fn} Affiliate Id specified for new User. Id: {model.User.AffiliateId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } if (SysId.IsValid(SysId.ToSysId(model.User.SecurityItemId))) { SaLogger.Warn($"{SysUtil.Fn} Security Item Id specified for new User. Id: {model.User.SecurityItemId}."); return Json(responseData.SetPopupMessage(messageTitle, Localiser["msg.error.system"])); } } // Validate item properties. model.ValidateRepositoryData(responseData, repository); if (responseData.HasControlErrors()) return Json(responseData); // Repository Console. SbmCoreInstanceConsole_Control repositoryConsole = new SbmCoreInstanceConsole_Control(SessionData_Control, repository); disposables.Add(repositoryConsole); SbmRepositoryInitialisationData repoInitData = new SbmRepositoryInitialisationData(); repoInitData.Organisation.AffiliateId = SysId.ToSysId(model.Organisation.AffiliateId); repoInitData.Organisation.AssociationId = SysId.ToSysId(model.Organisation.AssociationId); repoInitData.Organisation.Name = model.Organisation.Name; repoInitData.Organisation.VatReg = model.Organisation.VatReg; repoInitData.Organisation.CompanyNo = model.Organisation.CompanyNo; repoInitData.Organisation.Website = model.Organisation.Website; repoInitData.User.AffiliateId = SysId.ToSysId(model.User.AffiliateId); repoInitData.User.FirstName = model.User.FirstName; repoInitData.User.LastName = model.User.LastName; repoInitData.User.Email = model.User.Email; repoInitData.User.SecurityItemId = SysId.ToSysId(model.User.SecurityItemId); // User Email is used for the Security Item Code for login. repoInitData.User.Code = model.User.Email; repoInitData.User.Password = model.User.Password; repoInitData.User.PasswordSet = StringUtil.ToBool(model.User.PasswordSet); if (!repositoryConsole.InitialiseRepository(repoInitData)) return Json(responseData.SetPopupMessage(messageTitle, repositoryConsole.ErrorStateMessage)); // Complete response. RepositoryController.PopulateRepositoryResponseListData(model, responseData.Repository, owner, repository); responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }