diff --git a/api/src/Sozsoft.Platform.Application/Identity/PlatformSignInResultExtensions.cs b/api/src/Sozsoft.Platform.Application/Identity/PlatformSignInResultExtensions.cs index a620aa4..3362bb2 100644 --- a/api/src/Sozsoft.Platform.Application/Identity/PlatformSignInResultExtensions.cs +++ b/api/src/Sozsoft.Platform.Application/Identity/PlatformSignInResultExtensions.cs @@ -53,7 +53,11 @@ public static class PlatformSignInResultExtensions if (resultP.IsNotAllowed_TenantIsPassive) { return PlatformConsts.UserCannotSignInErrors.LoginNotAllowed_TenantIsPassive; - } + } + if (resultP.IsNotAllowed_WorkHour) + { + return PlatformConsts.UserCannotSignInErrors.LoginNotAllowed_WorkHour; + } } /// Added --> diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json index 00963e7..29a17e8 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/LanguagesData.json @@ -3102,6 +3102,12 @@ "en": "It's time to change your password periodically.", "tr": "Parolanızın periyodik olarak değiştirme zamanı gelmiştir." }, + { + "resourceName": "Platform", + "key": "Abp.Identity.LoginNotAllowed_WorkHour", + "en": "You cannot sign in outside of the allowed work hours.", + "tr": "İzin verilen iş saatleri dışında giriş yapamazsınız." + }, { "resourceName": "Platform", "key": "Abp.Identity.IpRestrictionError", diff --git a/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs b/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs index edac43f..c5b7449 100644 --- a/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs +++ b/api/src/Sozsoft.Platform.Domain.Shared/PlatformConsts.cs @@ -105,6 +105,7 @@ public static class PlatformConsts public const string IpRestrictionError = GroupName + ".IpRestrictionError"; public const string LoginEndDateError = GroupName + ".LoginEndDateError"; public const string TenantIsPassive = GroupName + ".TenantIsPassive"; + public const string LoginNotAllowed_WorkHour = GroupName + ".LoginNotAllowed_WorkHour"; public const string CaptchaWrongCode = GroupName + ".CaptchaWrongCode"; public const string TwoFactorWrongCode = GroupName + ".TwoFactorWrongCode"; public const string SignOut = GroupName + ".SignOut"; @@ -423,6 +424,7 @@ public static class PlatformConsts public static string ShouldChangePasswordPeriodic { get; set; } = "UserCannotSignInShouldChangePasswordPeriodic"; public static string LoginNotAllowed_TenantIsPassive { get; set; } = "UserCannotSignInTenantIsPassive"; public static string LoginNotAllowed_TenantNotFound { get; set; } = "UserCannotSignInTenantNotFound"; + public static string LoginNotAllowed_WorkHour { get; set; } = "UserCannotSignInWorkHour"; } public static class GridOptions diff --git a/api/src/Sozsoft.Platform.Domain/Identity/PlatformSignInResult.cs b/api/src/Sozsoft.Platform.Domain/Identity/PlatformSignInResult.cs index cbb0950..df13679 100644 --- a/api/src/Sozsoft.Platform.Domain/Identity/PlatformSignInResult.cs +++ b/api/src/Sozsoft.Platform.Domain/Identity/PlatformSignInResult.cs @@ -22,12 +22,14 @@ public class PlatformSignInResult : SignInResult /// True if login end date is due, otherwise false. public bool IsNotAllowed_LoginEndDateDue { get; set; } - public bool IsNotAllowed_TenantIsPassive { get; set; } - public bool ShouldChangePasswordOnNextLogin { get; set; } public bool ShouldChangePasswordPeriodic { get; set; } + public bool IsNotAllowed_TenantIsPassive { get; set; } + + public bool IsNotAllowed_WorkHour { get; set; } + public override string ToString() { return @@ -37,6 +39,7 @@ public class PlatformSignInResult : SignInResult ShouldChangePasswordOnNextLogin ? "ShouldChangePasswordOnNextLogin" : ShouldChangePasswordPeriodic ? "ShouldChangePasswordPeriodic" : IsNotAllowed_TenantIsPassive ? "NotAllowed_TenantIsPassive" : + IsNotAllowed_WorkHour ? "NotAllowed_WorkHour" : base.ToString(); } } diff --git a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformEventIds.cs b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformEventIds.cs index fdd36c2..ef20d89 100644 --- a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformEventIds.cs +++ b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformEventIds.cs @@ -21,6 +21,9 @@ public static class PlatformEventIds public static EventId UserCannotSignInTenantIsPassive = new(17, PlatformConsts.UserCannotSignInErrors.LoginNotAllowed_TenantIsPassive); + + public static EventId UserCannotSignInWorkHour = + new(18, PlatformConsts.UserCannotSignInErrors.LoginNotAllowed_WorkHour); } diff --git a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResult.cs b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResult.cs index 5b6d123..aaa1920 100644 --- a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResult.cs +++ b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResult.cs @@ -58,7 +58,12 @@ public class PlatformLoginResult : AbpLoginResult { PResult = PlatformLoginResultType.TenantIsPassive; Description = L[PlatformConsts.AbpIdentity.User.TenantIsPassive]; - } + } + else if (resultP.IsNotAllowed_WorkHour) + { + PResult = PlatformLoginResultType.NotAllowedWorkHour; + Description = L[PlatformConsts.AbpIdentity.User.LoginNotAllowed_WorkHour]; + } } else { diff --git a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResultType.cs b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResultType.cs index 219236a..61e5138 100644 --- a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResultType.cs +++ b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformLoginResultType.cs @@ -15,5 +15,6 @@ public enum PlatformLoginResultType : byte LoginEndDateDue, ShowCaptcha, TenantIsPassive, + NotAllowedWorkHour } diff --git a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformSignInManager.cs b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformSignInManager.cs index 129285e..8b5c152 100644 --- a/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformSignInManager.cs +++ b/api/src/Sozsoft.Platform.HttpApi.Host/Identity/PlatformSignInManager.cs @@ -30,6 +30,7 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager { private readonly IClock clock; private readonly IRepository repositoryIp; + private readonly IRepository repositoryWorkHour; private readonly ITenantRepository tenantRepository; private readonly IdentityUserManager userManager; @@ -45,6 +46,7 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager ISettingProvider settingProvider, IClock clock, IRepository repositoryIp, + IRepository repositoryWorkHour, ITenantRepository tenantRepository ) : base( userManager, @@ -59,6 +61,7 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager { this.clock = clock; this.repositoryIp = repositoryIp; + this.repositoryWorkHour = repositoryWorkHour; this.tenantRepository = tenantRepository; this.userManager = userManager; } @@ -87,10 +90,14 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager { return new PlatformSignInResult() { IsNotAllowed_NotAllowedIp = true }; } - if (!await IsTenantActiveAsync(user)) + if (!await CanSignInTenantActiveAsync(user)) { return new PlatformSignInResult() { IsNotAllowed_TenantIsPassive = true }; } + if (!await CanSignInWorkHourAsync()) + { + return new PlatformSignInResult() { IsNotAllowed_WorkHour = true }; + } } else { @@ -109,10 +116,54 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager return result; } + /// + /// Used to prevent login outside of defined work hours. + /// + private async Task CanSignInWorkHourAsync() + { + var workHours = await repositoryWorkHour.GetListAsync(); + + if (workHours.IsNullOrEmpty()) + { + return true; + } + + var now = clock.Now; + var currentTime = now.TimeOfDay; + var dayOfWeek = now.DayOfWeek; + + var isAllowed = workHours.Any(wh => + { + var dayMatches = dayOfWeek switch + { + DayOfWeek.Monday => wh.Monday == true, + DayOfWeek.Tuesday => wh.Tuesday == true, + DayOfWeek.Wednesday => wh.Wednesday == true, + DayOfWeek.Thursday => wh.Thursday == true, + DayOfWeek.Friday => wh.Friday == true, + DayOfWeek.Saturday => wh.Saturday == true, + DayOfWeek.Sunday => wh.Sunday == true, + _ => false + }; + + if (!dayMatches) return false; + + return currentTime >= wh.StartTime.TimeOfDay && currentTime <= wh.EndTime.TimeOfDay; + }); + + if (!isAllowed) + { + Logger.LogWarning(PlatformEventIds.UserCannotSignInWorkHour, "User cannot sign in outside work hours."); + return false; + } + + return true; + } + /// /// Tenant IsActive /// - private async Task IsTenantActiveAsync(IdentityUser user) + private async Task CanSignInTenantActiveAsync(IdentityUser user) { if (!user.TenantId.HasValue) {