diff --git a/server/AyaNova/Controllers/AuthController.cs b/server/AyaNova/Controllers/AuthController.cs index 6bcc8fc0..b03bd4f9 100644 --- a/server/AyaNova/Controllers/AuthController.cs +++ b/server/AyaNova/Controllers/AuthController.cs @@ -352,6 +352,13 @@ namespace AyaNova.Api.Controllers { //customer type has special rights restrictions for UI features so return them here so client UI can enable or disable var effectiveRights = await UserBiz.CustomerUserEffectiveRightsAsync(u.Id); + //A non active Customer or Head Office record's contacts are also not allowed to login + if (!effectiveRights.EntityActive) + { + log.LogInformation($"Customer contact user \"{u.Name}\" attempted login was denied due to inactive parent (Customer or HeadOffice)"); + await Task.Delay(AyaNova.Util.ServerBootConfig.FAILED_AUTH_DELAY); + return StatusCode(401, new ApiErrorResponse(ApiErrorCode.AUTHENTICATION_FAILED)); + } return Ok(ApiOkResponse.Response(new { token = token, diff --git a/server/AyaNova/Program.cs b/server/AyaNova/Program.cs index 8cc93423..d0a3f58c 100644 --- a/server/AyaNova/Program.cs +++ b/server/AyaNova/Program.cs @@ -160,6 +160,7 @@ namespace AyaNova //This is the first log entry logger.Info($"AYANOVA SERVER {AyaNovaVersion.VersionString} BOOTING"); + Console.WriteLine($"AYANOVA SERVER {AyaNovaVersion.VersionString} BOOTING ..."); //log configuration try @@ -185,7 +186,7 @@ namespace AyaNova logger.Info("OS - {0}", Environment.OSVersion.ToString()); logger.Info("TimeZone - {0}", TimeZoneInfo.Local.DisplayName); - logger.Info("OS Locale - {0}", System.Globalization.CultureInfo.CurrentCulture.EnglishName); + logger.Info("OS Locale - {0}", System.Globalization.CultureInfo.CurrentCulture.EnglishName); logger.Debug("Machine - {0}", Environment.MachineName); logger.Debug("User - {0}", Environment.UserName); logger.Debug(".Net Version - {0}", Environment.Version.ToString()); diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs index be1c99b0..db852451 100644 --- a/server/AyaNova/biz/UserBiz.cs +++ b/server/AyaNova/biz/UserBiz.cs @@ -119,22 +119,27 @@ namespace AyaNova.Biz List AllTags = new List(); AllTags.AddRange(UserInfo.Tags); + bool EntityActive = false; //Contact is for a customer or for a head office not both so... if (UserInfo.CustomerId != null && UserInfo.CustomerId != 0) { - var CustomerInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == UserInfo.CustomerId).Select(x => new { x.HeadOfficeId, x.Tags }).FirstAsync(); + var CustomerInfo = await ct.Customer.AsNoTracking().Where(x => x.Id == UserInfo.CustomerId).Select(x => new { x.HeadOfficeId, x.Tags, x.Active }).FirstAsync(); AllTags.AddRange(CustomerInfo.Tags); + EntityActive = CustomerInfo.Active; //does the customer have a head office?? if (CustomerInfo.HeadOfficeId != null && CustomerInfo.HeadOfficeId != 0) AllTags.AddRange(await ct.HeadOffice.AsNoTracking().Where(x => x.Id == CustomerInfo.HeadOfficeId).Select(x => x.Tags).FirstAsync()); } - else - if (UserInfo.HeadOfficeId != null && UserInfo.HeadOfficeId != 0) - AllTags.AddRange(await ct.HeadOffice.AsNoTracking().Where(x => x.Id == UserInfo.HeadOfficeId).Select(x => x.Tags).FirstAsync()); + else if (UserInfo.HeadOfficeId != null && UserInfo.HeadOfficeId != 0) + { + var HOInfo = await ct.HeadOffice.AsNoTracking().Where(x => x.Id == UserInfo.HeadOfficeId).Select(x => new { x.Tags, x.Active }).FirstAsync(); + AllTags.AddRange(HOInfo.Tags); + EntityActive = HOInfo.Active; + } - long EntityId=0; - if(UserInfo.UserType==UserType.Customer) EntityId=UserInfo.CustomerId??0; - if(UserInfo.UserType==UserType.HeadOffice) EntityId=UserInfo.HeadOfficeId??0; + long EntityId = 0; + if (UserInfo.UserType == UserType.Customer) EntityId = UserInfo.CustomerId ?? 0; + if (UserInfo.UserType == UserType.HeadOffice) EntityId = UserInfo.HeadOfficeId ?? 0; return new CustomerRightsRecord( @@ -182,7 +187,8 @@ namespace AyaNova.Biz AllTags, AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyWOCompletedInTags, AyaNova.Util.ServerGlobalBizSettings.Cache.CustomerAllowNotifyWOCompletedOutTags), - EntityId + EntityId, + EntityActive ); } @@ -742,7 +748,7 @@ namespace AyaNova.Biz private async Task ValidateAsync(User proposedObj, User currentObj) { //skip validation if seeding - if(ServerBootConfig.SEEDING) return; + if (ServerBootConfig.SEEDING) return; //run validation and biz rules bool isNew = currentObj == null; @@ -1179,7 +1185,7 @@ namespace AyaNova.Biz public async Task HandlePotentialNotificationEvent(AyaEvent ayaEvent, ICoreBizObjectModel proposedObj, ICoreBizObjectModel currentObj = null) { ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger(); - if(ServerBootConfig.SEEDING || ServerBootConfig.MIGRATING) return; + if (ServerBootConfig.SEEDING || ServerBootConfig.MIGRATING) return; log.LogDebug($"HandlePotentialNotificationEvent processing: [AyaType:{this.BizType}, AyaEvent:{ayaEvent}]"); bool isNew = currentObj == null; diff --git a/server/AyaNova/models/GlobalBizSettings.cs b/server/AyaNova/models/GlobalBizSettings.cs index 2e9bb08c..1535abc9 100644 --- a/server/AyaNova/models/GlobalBizSettings.cs +++ b/server/AyaNova/models/GlobalBizSettings.cs @@ -98,7 +98,7 @@ namespace AyaNova.Models } //Used internally and at client end as extended rights atop roles system in relation only to Contact (customer type users) - public record CustomerRightsRecord(bool CSR, bool WO, bool WOWIKI, bool UserSettings, bool NotifyServiceImminent, bool NotifyCSRAccepted, bool NotifyCSRRejected, bool NotifyWOCreated, bool NotifyWOCompleted, long EntityId); + public record CustomerRightsRecord(bool CSR, bool WO, bool WOWIKI, bool UserSettings, bool NotifyServiceImminent, bool NotifyCSRAccepted, bool NotifyCSRRejected, bool NotifyWOCreated, bool NotifyWOCompleted, long EntityId, bool EntityActive); } /* CREATE TABLE [dbo].[AGLOBAL](