Tenant IsActive

This commit is contained in:
Sedat ÖZTÜRK 2025-05-29 16:25:02 +03:00
parent cd0b9d3b71
commit 4719ac24b8
17 changed files with 4078 additions and 17 deletions

View file

@ -5,7 +5,8 @@ namespace Kurs.Platform.ListForms.DynamicApi;
public class CreateUpdateTenantInput
{
public string Name { get; set; }
public bool IsActive { get; set; }
public Guid? Id { get; set; }
public string AdminEmail { get; set; }
public string AdminPassword { get; set; }

View file

@ -50,6 +50,10 @@ public static class PlatformSignInResultExtensions
{
return PlatformConsts.UserCannotSignInErrors.ShouldChangePasswordPeriodic;
}
if (resultP.IsNotAllowed_TenantIsPassive)
{
return PlatformConsts.UserCannotSignInErrors.LoginNotAllowed_TenantIsPassive;
}
}
/// Added -->

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Kurs.Platform.Extensions;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
@ -109,7 +110,11 @@ public class ListFormDynamicApiAppService : PlatformAppService, IListFormDynamic
public async Task PostTenantInsertAsync(DynamicApiBaseInput<CreateUpdateTenantInput> input)
{
var tenant = await tenantManager.CreateAsync(input.Data.Name);
await tenantRepository.InsertAsync(tenant);
var entity = await tenantRepository.InsertAsync(tenant, autoSave: true);
entity.SetIsActiveTenant(input.Data.IsActive);
await tenantRepository.UpdateAsync(entity, autoSave: true);
}
[Authorize(TenantManagementPermissions.Tenants.Update)]
@ -119,14 +124,15 @@ public class ListFormDynamicApiAppService : PlatformAppService, IListFormDynamic
{
throw new UserFriendlyException(L["RecordNotFound"]);
}
var id = Guid.Parse(input.Keys[0].ToString());
var entity = await tenantRepository.GetAsync(id) ?? throw new EntityNotFoundException(L["RecordNotFound"]);
var tenant = new TenantUpdateDto
{
Name = input.Data.Name ?? entity.Name,
};
await tenantRepository.UpdateAsync(ObjectMapper.Map<TenantUpdateDto, Tenant>(tenant), true);
var id = Guid.Parse(input.Keys[0].ToString());
var entity = await tenantRepository.GetAsync(id)
?? throw new EntityNotFoundException(L["RecordNotFound"]);
await tenantManager.ChangeNameAsync(entity, input.Data.Name);
entity.SetIsActiveTenant(input.Data.IsActive);
await tenantRepository.UpdateAsync(entity, autoSave: true);
}
[Authorize(TenantManagementPermissions.Tenants.Delete)]

View file

@ -147,9 +147,7 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
new() { Order=1, ColCount=1, ColSpan=2, ItemType="group", Items =
[
new EditingFormItemDto { Order=1, DataField="Name", ColSpan=2, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=2, DataField=IdentityDataSeedContributor.AdminEmailPropertyName, ColSpan=2, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=3, DataField=IdentityDataSeedContributor.AdminPasswordPropertyName, ColSpan=2, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=4, DataField="ConnectionString", ColSpan=2, IsRequired=true, EditorType2=EditorTypes.dxTextArea, EditorOptions="{\"height\":100}" },
new EditingFormItemDto { Order=2, DataField="IsActive", ColSpan=2, IsRequired=false, EditorType2=EditorTypes.dxCheckBox },
]
}
}),
@ -175,6 +173,14 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
Value = "@ID",
CustomValueType = FieldCustomValueTypeEnum.CustomKey }
}),
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new FieldsDefaultValue() {
FieldName = "IsActive",
FieldDbType = DbType.Boolean,
Value = "true",
CustomValueType = FieldCustomValueTypeEnum.Value }
})
}
);
@ -189,7 +195,7 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.Guid,
FieldName = "Id",
Width = 100,
Width = 500,
ListOrderNo = 1,
Visible = false,
IsActive = true,
@ -215,7 +221,7 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "Name",
Width = 200,
Width = 800,
ListOrderNo = 2,
Visible = true,
IsActive = true,
@ -234,6 +240,32 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
IsPivot = true
})
},
new ListFormField
{
ListFormCode = listFormTenants.ListFormCode,
RoleId = null,
UserId = null,
CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean,
FieldName = "IsActive",
Width = 100,
ListOrderNo = 3,
Visible = true,
IsActive = true,
IsDeleted = false,
PermissionJson = JsonSerializer.Serialize(new ListFormFieldPermissionDto
{
C = TenantManagementPermissions.Tenants.Create,
R = TenantManagementPermissions.Tenants.Default,
U = TenantManagementPermissions.Tenants.Update,
E = true,
Deny = false
}),
PivotSettingsJson = JsonSerializer.Serialize(new ListFormFieldPivotSettingsDto
{
IsPivot = true
})
},
]);
#endregion
#endregion

View file

@ -2039,7 +2039,13 @@
"key": "Abp.Identity.User.LockoutManagement.ShouldChangePwOnNextLogin",
"en": "Should Change Password On Next Login?",
"tr": "Bir Sonraki Girişte Şifre Değiştirilsin mi?"
},
},
{
"resourceName": "Platform",
"key": "Abp.Identity.TenantIsPassive",
"en": "Tenant is inactive",
"tr": "Tenant pasif durumdadır"
},
{
"resourceName": "Platform",
"key": "Abp.Identity.User.LockoutManagement.AccessFailedCount",

View file

@ -23,6 +23,11 @@ public static class PlatformConsts
public const string Abp = "Abp";
}
public static class Tenants
{
public const string IsActive = "IsActive";
}
public static class AbpIdentity
{
public const string GroupName = $"{Prefix.Abp}.Identity";
@ -57,6 +62,7 @@ public static class PlatformConsts
public const string ShouldChangePasswordPeriodic = GroupName + ".ShouldChangePasswordPeriodic";
public const string IpRestrictionError = GroupName + ".IpRestrictionError";
public const string LoginEndDateError = GroupName + ".LoginEndDateError";
public const string TenantIsPassive = GroupName + ".TenantIsPassive";
public const string CaptchaWrongCode = GroupName + ".CaptchaWrongCode";
public const string TwoFactorWrongCode = GroupName + ".TwoFactorWrongCode";
public const string SignOut = GroupName + ".SignOut";
@ -709,6 +715,8 @@ public static class PlatformConsts
public static string LoginNotAllowed_LoginEndDateDue { get; set; } = "UserCannotSignInLoginEndDateDue";
public static string ShouldChangePasswordOnNextLogin { get; set; } = "UserCannotSignInShouldChangePasswordOnNextLogin";
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 class GridOptions

View file

@ -77,6 +77,16 @@ public static class PlatformModuleExtensionConfigurator
});
});
});
ObjectExtensionManager.Instance.Modules()
.ConfigureTenantManagement(tenantConfig =>
{
tenantConfig.ConfigureTenant(entity =>
{
entity.AddOrUpdateProperty<bool>("IsActive");
});
});
/* You can configure extra properties for the
* entities defined in the modules used by your application.
*

View file

@ -0,0 +1,17 @@
using Volo.Abp.Data;
using Volo.Abp.TenantManagement;
namespace Kurs.Platform.Extensions;
public static class AbpTenantExtensions
{
//IsActive Tenant
public static void SetIsActiveTenant(this Tenant tenant, bool isActive)
{
tenant.SetProperty(PlatformConsts.Tenants.IsActive, isActive);
}
public static bool GetIsActiveTenant(this Tenant tenant)
{
return tenant.GetProperty<bool>(PlatformConsts.Tenants.IsActive);
}
}

View file

@ -22,11 +22,12 @@ public class PlatformSignInResult : SignInResult
/// <value>True if login end date is due, otherwise false.</value>
public bool IsNotAllowed_LoginEndDateDue { get; set; }
public bool IsNotAllowed_TenantIsPassive { get; set; }
public bool ShouldChangePasswordOnNextLogin { get; set; }
public bool ShouldChangePasswordPeriodic { get; set; }
public override string ToString()
{
return
@ -35,6 +36,7 @@ public class PlatformSignInResult : SignInResult
IsNotAllowed_LoginEndDateDue ? "NotAllowed_LoginEndDateDue" :
ShouldChangePasswordOnNextLogin ? "ShouldChangePasswordOnNextLogin" :
ShouldChangePasswordPeriodic ? "ShouldChangePasswordPeriodic" :
IsNotAllowed_TenantIsPassive ? "NotAllowed_TenantIsPassive" :
base.ToString();
}
}

View file

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using System;
using Volo.Abp.Identity;
using Volo.Abp.ObjectExtending;
using Volo.Abp.TenantManagement;
using Volo.Abp.Threading;
namespace Kurs.Platform.EntityFrameworkCore;
@ -44,6 +45,16 @@ public static class PlatformEfCoreEntityExtensionMappings
propertyBuilder.HasDefaultValue(null);
}
);
ObjectExtensionManager.Instance
.MapEfCoreProperty<Tenant, bool>(
PlatformConsts.Tenants.IsActive,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasDefaultValue(true);
}
);
/* You can configure extra properties for the
* entities defined in the modules used by your application.
*

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Kurs.Platform.Migrations
{
/// <inheritdoc />
public partial class TenantIsActive : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsActive",
table: "AbpTenants",
type: "boolean",
nullable: false,
defaultValue: false);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsActive",
table: "AbpTenants");
}
}
}

View file

@ -3603,6 +3603,11 @@ namespace Kurs.Platform.Migrations
.HasColumnType("text")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsActive")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")
.HasDefaultValue(false);
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("boolean")

View file

@ -19,4 +19,7 @@ public static class PlatformEventIds
public static EventId ShouldChangePasswordPeriodic =
new(16, PlatformConsts.UserCannotSignInErrors.ShouldChangePasswordPeriodic);
public static EventId UserCannotSignInTenantIsPassive =
new(17, PlatformConsts.UserCannotSignInErrors.LoginNotAllowed_TenantIsPassive);
}

View file

@ -54,6 +54,11 @@ public class PlatformLoginResult : AbpLoginResult
PResult = PlatformLoginResultType.LoginEndDateDue;
Description = L[PlatformConsts.AbpIdentity.User.LoginEndDateError];
}
else if (resultP.IsNotAllowed_TenantIsPassive)
{
PResult = PlatformLoginResultType.TenantIsPassive;
Description = L[PlatformConsts.AbpIdentity.User.TenantIsPassive];
}
}
else
{

View file

@ -14,4 +14,5 @@ public enum PlatformLoginResultType : byte
NotAllowedIp,
LoginEndDateDue,
ShowCaptcha,
TenantIsPassive,
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Threading.Tasks;
using Kurs.Platform.Entities;
@ -13,6 +14,7 @@ using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.Settings;
using Volo.Abp.TenantManagement;
using Volo.Abp.Timing;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
@ -28,6 +30,7 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager
{
private readonly IClock clock;
private readonly IRepository<IpRestriction, Guid> repositoryIp;
private readonly ITenantRepository tenantRepository;
private readonly IdentityUserManager userManager;
public PlatformSignInManager(
@ -41,7 +44,8 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager
IOptions<AbpIdentityOptions> options,
ISettingProvider settingProvider,
IClock clock,
IRepository<IpRestriction, Guid> repositoryIp
IRepository<IpRestriction, Guid> repositoryIp,
ITenantRepository tenantRepository
) : base(
userManager,
contextAccessor,
@ -55,6 +59,7 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager
{
this.clock = clock;
this.repositoryIp = repositoryIp;
this.tenantRepository = tenantRepository;
this.userManager = userManager;
}
@ -82,6 +87,10 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager
{
return new PlatformSignInResult() { IsNotAllowed_NotAllowedIp = true };
}
if (!await IsTenantActiveAsync(user))
{
return new PlatformSignInResult() { IsNotAllowed_TenantIsPassive = true };
}
}
else
{
@ -100,6 +109,31 @@ public class PlatformSignInManager : AbpSignInManager, IPlatformSignInManager
return result;
}
/// <summary>
/// Tenant IsActive
/// </summary>
private async Task<bool> IsTenantActiveAsync(IdentityUser user)
{
if (!user.TenantId.HasValue)
{
return true;
}
var tenant = await tenantRepository.FindAsync(user.TenantId.Value);
if (tenant == null)
{
return false;
}
if (!tenant.GetIsActiveTenant())
{
Logger.LogWarning(PlatformEventIds.UserCannotSignInTenantIsPassive, "Tenant is inactive.");
return false;
}
return true;
}
/// <summary>
/// Used to prevent login for additional scenarios;
/// Account Not Verified