Browse Source

Merge pull request #1150 from colinin/some-commits

Some commits
pull/1162/head
yx lin 11 months ago
committed by GitHub
parent
commit
079a2213c6
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterGroup.cs
  2. 18
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterRule.cs
  3. 4
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResource.cs
  4. 20
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResourceChangeEvent.cs
  5. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DisableDataProtectedAttribute.cs
  6. 6
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/Resources/en.json
  7. 6
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/Resources/zh-Hans.json
  8. 7
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityEnumInfoModel.cs
  9. 33
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityPropertyInfoModel.cs
  10. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityTypeInfoGetModel.cs
  11. 19
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityTypeInfoModel.cs
  12. 3
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/FodyWeavers.xml
  13. 24
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN.Abp.DataProtection.Application.Contracts.csproj
  14. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/AbpDataProtectionApplicationContractsModule.cs
  15. 7
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityEnumInfoDto.cs
  16. 29
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityPropertyInfoDto.cs
  17. 17
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityTypeInfoDto.cs
  18. 6
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityTypeInfoGetInput.cs
  19. 14
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/IEntityTypeInfoAppService.cs
  20. 3
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/FodyWeavers.xml
  21. 25
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/LINGYUN.Abp.DataProtection.Application.csproj
  22. 13
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/LINGYUN/Abp/DataProtection/AbpDataProtectionApplicationModule.cs
  23. 47
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/LINGYUN/Abp/DataProtection/EntityTypeInfoAppService.cs
  24. 10
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/System/NullableTypeExtensions.cs
  25. 64
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedReadEntityInterceptor.cs
  26. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWritePropertiesInterceptor.cs
  27. 1
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs
  28. 22
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/EfCoreDataProtectionRepository.cs
  29. 23
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/AbpDataProtectionOptions.cs
  30. 22
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessEntitTypeInfoContext.cs
  31. 103
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessEntityTypeInfoProvider.cs
  32. 18
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessResourceCacheInvalidator.cs
  33. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAuthorizationService.cs
  34. 1
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataProtectedInterceptor.cs
  35. 47
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/EntityPropertyResultBuilder.cs
  36. 19
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/EntityTypeFilterBuilder.cs
  37. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessEntityTypeInfoProvider.cs
  38. 5
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessSubjectContributor.cs
  39. 10
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataProtectedResourceStore.cs
  40. 5
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IEntityPropertyResultBuilder.cs
  41. 5
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IEntityTypeFilterBuilder.cs
  42. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IJavaScriptTypeConvert.cs
  43. 20
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/InMemoryDataProtectedResourceStore.cs
  44. 132
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/JavaScriptTypeConvert.cs
  45. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/JavaScriptTypeConvertResult.cs
  46. 13
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessClientIdContributor.cs
  47. 13
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessOrganizationUnitContributor.cs
  48. 13
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessRoleNameContributor.cs
  49. 13
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessUserIdContributor.cs
  50. 14
      aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj
  51. 5314
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315061656_Remove-Identity-Server-And-Add-Entity-Enum-Info.Designer.cs
  52. 768
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315061656_Remove-Identity-Server-And-Add-Entity-Enum-Info.cs
  53. 5320
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315064423_Add-Javascript-Type.Designer.cs
  54. 31
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315064423_Add-Javascript-Type.cs
  55. 5320
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315084750_Rename-Allow-Properties-To-Accessed-Properties.Designer.cs
  56. 38
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315084750_Rename-Allow-Properties-To-Accessed-Properties.cs
  57. 1373
      aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs
  58. 4
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/UserProfilePictureProvider.cs
  59. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web.IdentityServer/LINGYUN.Abp.Account.Web.IdentityServer.csproj
  60. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web.OpenIddict/LINGYUN.Abp.Account.Web.OpenIddict.csproj
  61. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj
  62. 20
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityEnumInfoDto.cs
  63. 9
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityPropertyInfoDto.cs
  64. 2
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityRuleCreateOrUpdateDto.cs
  65. 2
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityRuleDtoBase.cs
  66. 8
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application/LINGYUN/Abp/DataProtectionManagement/DataProtectionManagementApplicationMappingProfile.cs
  67. 40
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application/LINGYUN/Abp/DataProtectionManagement/OrganizationUnitEntityRuleAppService.cs
  68. 40
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application/LINGYUN/Abp/DataProtectionManagement/RoleEntityRuleAppService.cs
  69. 4
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/DataProtectionManagementErrorCodes.cs
  70. 8
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/EntityEnumInfoConsts.cs
  71. 1
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/EntityRuleBaseEto.cs
  72. 2
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/EntityRuleConsts.cs
  73. 5
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/AbpDataProtectionManagementDomainModule.cs
  74. 34
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCache.cs
  75. 8
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCacheItem.cs
  76. 56
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCacheItemInvalidator.cs
  77. 35
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCacheStore.cs
  78. 47
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityEnumInfo.cs
  79. 58
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityPropertyInfo.cs
  80. 6
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityRuleBase.cs
  81. 4
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityTypeInfo.cs
  82. 20
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/IDataProtectedResourceCache.cs
  83. 102
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/ProtectedEntitiesSaver.cs
  84. 47
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore/LINGYUN/Abp/DataProtectionManagement/EntityFrameworkCore/AbpDataProtectionManagementDbContextModelCreatingExtensions.cs
  85. 4
      aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore/LINGYUN/Abp/DataProtectionManagement/EntityFrameworkCore/EfCoreEntityTypeInfoRepository.cs
  86. 1
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN.Abp.Demo.Application.Contracts.csproj
  87. 4
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/AbpDemoApplicationContractsModule.cs
  88. 9
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/IBookAppService.cs
  89. 4
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/AbpDemoApplicationModule.cs
  90. 38
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/Books/BookAppService.cs
  91. 11
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain.Shared/LINGYUN/Abp/Demo/Localization/Resources/en.json
  92. 11
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain.Shared/LINGYUN/Abp/Demo/Localization/Resources/zh-Hans.json
  93. 19
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain/LINGYUN/Abp/Demo/AbpDemoDomainModule.cs
  94. 9
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/Books/EfCoreBookRepository.cs
  95. 10
      aspnet-core/modules/demo/LINGYUN.Abp.Demo.HttpApi/LINGYUN/Abp/Demo/Books/BookController.cs
  96. 12
      aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Aliyun/LINGYUN/Abp/OssManagement/Aliyun/AbpOssManagementAliyunModule.cs
  97. 21
      aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Aliyun/Microsoft/Extensions/DependencyInjection/AliyunOssContainerServiceCollectionExtensions.cs
  98. 14
      aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.FileSystem/LINGYUN/Abp/OssManagement/FileSystem/AbpOssManagementFileSystemModule.cs
  99. 21
      aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.FileSystem/Microsoft/Extensions/DependencyInjection/FileSystemOssContainerServiceCollectionExtensions.cs
  100. 14
      aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Minio/LINGYUN/Abp/OssManagement/Minio/AbpOssManagementMinioModule.cs

9
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterGroup.cs

@ -32,8 +32,13 @@ public class DataAccessFilterGroup
return this; return this;
} }
public DataAccessFilterGroup AddRule(string field, object value, DataAccessFilterOperate operate = DataAccessFilterOperate.Equal) public DataAccessFilterGroup AddRule(
string field,
object value,
string typeFullName,
string javaScriptType,
DataAccessFilterOperate operate = DataAccessFilterOperate.Equal)
{ {
return AddRule(new DataAccessFilterRule(field, value, operate)); return AddRule(new DataAccessFilterRule(field, value, typeFullName, javaScriptType, operate));
} }
} }

18
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterRule.cs

@ -14,6 +14,14 @@ public class DataAccessFilterRule
/// </summary> /// </summary>
public object Value { get; set; } public object Value { get; set; }
/// <summary> /// <summary>
/// 类型全名
/// </summary>
public string TypeFullName { get; set; }
/// <summary>
/// Js类型
/// </summary>
public string JavaScriptType { get; set; }
/// <summary>
/// 操作类型 /// 操作类型
/// </summary> /// </summary>
public DataAccessFilterOperate Operate { get; set; } public DataAccessFilterOperate Operate { get; set; }
@ -27,10 +35,18 @@ public class DataAccessFilterRule
} }
public DataAccessFilterRule(string field, object value, DataAccessFilterOperate operate = DataAccessFilterOperate.Equal, bool isLeft = false) public DataAccessFilterRule(
string field,
object value,
string typeFullName,
string javaScriptType,
DataAccessFilterOperate operate = DataAccessFilterOperate.Equal,
bool isLeft = false)
{ {
Field = field; Field = field;
Value = value; Value = value;
TypeFullName = typeFullName;
JavaScriptType = javaScriptType;
Operate = operate; Operate = operate;
IsLeft = isLeft; IsLeft = isLeft;
} }

4
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResource.cs

@ -34,7 +34,7 @@ public class DataAccessResource
/// <summary> /// <summary>
/// 允许操作的属性列表 /// 允许操作的属性列表
/// </summary> /// </summary>
public List<string> AllowProperties { get; set; } public List<string> AccessedProperties { get; set; }
public DataAccessResource() public DataAccessResource()
{ {
@ -53,6 +53,6 @@ public class DataAccessResource
EntityTypeFullName = entityTypeFullName; EntityTypeFullName = entityTypeFullName;
Operation = operation; Operation = operation;
FilterGroup = filterGroup; FilterGroup = filterGroup;
AllowProperties = new List<string>(); AccessedProperties = new List<string>();
} }
} }

20
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResourceChangeEvent.cs

@ -0,0 +1,20 @@
using System;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.DataProtection;
[Serializable]
[EventName("abp.data_protection.resource_changed")]
public class DataAccessResourceChangeEvent
{
public DataAccessResource Resource { get; set; }
public DataAccessResourceChangeEvent()
{
}
public DataAccessResourceChangeEvent(DataAccessResource resource)
{
Resource = resource;
}
}

9
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DisableDataProtectedAttribute.cs

@ -5,4 +5,13 @@ namespace LINGYUN.Abp.DataProtection;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
public class DisableDataProtectedAttribute : Attribute public class DisableDataProtectedAttribute : Attribute
{ {
public DataAccessOperation? Operation { get; }
public DisableDataProtectedAttribute()
{
}
public DisableDataProtectedAttribute(DataAccessOperation operation)
{
Operation = operation;
}
} }

6
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/Resources/en.json

@ -1,6 +1,10 @@
{ {
"culture": "en", "culture": "en",
"texts": { "texts": {
"DataProtection:010001": "Data access permission not granted to protected resources!" "DataProtection:010001": "Data access permission not granted to protected resources!",
"DisplayName:LastModifierId": "Last Modifier Id",
"DisplayName:LastModificationTime": "Last Modification Time",
"DisplayName:CreatorId": "Creator Id",
"DisplayName:CreationTime": "Creation Time"
} }
} }

6
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/Resources/zh-Hans.json

@ -1,6 +1,10 @@
{ {
"culture": "zh-Hans", "culture": "zh-Hans",
"texts": { "texts": {
"DataProtection:010001": "未授予受保护资源的数据访问权限!" "DataProtection:010001": "未授予受保护资源的数据访问权限!",
"DisplayName:LastModifierId": "上次修改人",
"DisplayName:LastModificationTime": "上次修改时间",
"DisplayName:CreatorId": "创建人",
"DisplayName:CreationTime": "创建时间"
} }
} }

7
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityEnumInfoModel.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.DataProtection.Models;
public class EntityEnumInfoModel
{
public string Key { get; set; }
public object Value { get; set; }
}

33
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityPropertyInfoModel.cs

@ -0,0 +1,33 @@
namespace LINGYUN.Abp.DataProtection.Models;
public class EntityPropertyInfoModel
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 类型全名
/// </summary>
public string TypeFullName { get; set; }
/// <summary>
/// JavaScript类型
/// </summary>
public string JavaScriptType { get; set; }
/// <summary>
/// JavaScript名称
/// </summary>
public string JavaScriptName { get; set; }
/// <summary>
/// 枚举列表
/// </summary>
public EntityEnumInfoModel[] Enums { get; set; }
/// <summary>
/// 允许的过滤操作列表
/// </summary>
public DataAccessFilterOperate[] Operates { get; set; }
}

9
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityTypeInfoGetModel.cs

@ -0,0 +1,9 @@
using System.ComponentModel.DataAnnotations;
namespace LINGYUN.Abp.DataProtection.Models;
public class EntityTypeInfoGetModel
{
[Required]
public DataAccessOperation Operation { get; set; }
}

19
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Models/EntityTypeInfoModel.cs

@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.DataProtection.Models;
public class EntityTypeInfoModel
{
/// <summary>
/// 实体名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 可访问属性列表
/// </summary>
public List<EntityPropertyInfoModel> Properties { get; set; } = new List<EntityPropertyInfoModel>();
}

3
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

24
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN.Abp.DataProtection.Application.Contracts.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.DataProtection.Application.Contracts</AssemblyName>
<PackageId>LINGYUN.Abp.DataProtection.Application.Contracts</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.DataProtection.Abstractions\LINGYUN.Abp.DataProtection.Abstractions.csproj" />
</ItemGroup>
</Project>

12
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/AbpDataProtectionApplicationContractsModule.cs

@ -0,0 +1,12 @@
using Volo.Abp.Application;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.DataProtection;
[DependsOn(
typeof(AbpDataProtectionAbstractionsModule),
typeof(AbpDddApplicationContractsModule))]
public class AbpDataProtectionApplicationContractsModule : AbpModule
{
}

7
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityEnumInfoDto.cs

@ -0,0 +1,7 @@
namespace LINGYUN.Abp.DataProtection;
public class EntityEnumInfoDto
{
public string Key { get; set; }
public object Value { get; set; }
}

29
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityPropertyInfoDto.cs

@ -0,0 +1,29 @@
namespace LINGYUN.Abp.DataProtection;
public class EntityPropertyInfoDto
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 类型全名
/// </summary>
public string TypeFullName { get; set; }
/// <summary>
/// JavaScript类型
/// </summary>
public string JavaScriptType { get; set; }
/// <summary>
/// 枚举列表
/// </summary>
public EntityEnumInfoDto[] Enums { get; set; } = new EntityEnumInfoDto[0];
/// <summary>
/// 允许的过滤操作列表
/// </summary>
public DataAccessFilterOperate[] Operates { get; set; }
}

17
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityTypeInfoDto.cs

@ -0,0 +1,17 @@
namespace LINGYUN.Abp.DataProtection;
public class EntityTypeInfoDto
{
/// <summary>
/// 实体名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 可访问属性列表
/// </summary>
public EntityPropertyInfoDto[] Properties { get; set; } = new EntityPropertyInfoDto[0];
}

6
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/EntityTypeInfoGetInput.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Abp.DataProtection;
public class EntityTypeInfoGetInput
{
public DataAccessOperation Operation { get; set; }
}

14
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application.Contracts/LINGYUN/Abp/DataProtection/IEntityTypeInfoAppService.cs

@ -0,0 +1,14 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.DataProtection;
public interface IEntityTypeInfoAppService : IApplicationService
{
/// <summary>
/// 获取实体可访问规则
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<EntityTypeInfoDto> GetEntityRuleAsync(EntityTypeInfoGetInput input);
}

3
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

25
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/LINGYUN.Abp.DataProtection.Application.csproj

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.DataProtection.Application</AssemblyName>
<PackageId>LINGYUN.Abp.DataProtection.Application</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Ddd.Application" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.DataProtection\LINGYUN.Abp.DataProtection.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.DataProtection.Application.Contracts\LINGYUN.Abp.DataProtection.Application.Contracts.csproj" />
</ItemGroup>
</Project>

13
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/LINGYUN/Abp/DataProtection/AbpDataProtectionApplicationModule.cs

@ -0,0 +1,13 @@
using Volo.Abp.Application;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.DataProtection;
[DependsOn(
typeof(AbpDataProtectionApplicationContractsModule),
typeof(AbpDataProtectionModule),
typeof(AbpDddApplicationModule))]
public class AbpDataProtectionApplicationModule : AbpModule
{
}

47
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/LINGYUN/Abp/DataProtection/EntityTypeInfoAppService.cs

@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.DataProtection;
public abstract class EntityTypeInfoAppService<TEntity> : ApplicationService, IEntityTypeInfoAppService
{
protected IDataAccessEntityTypeInfoProvider EntityTypeInfoProvider => LazyServiceProvider.GetRequiredService<IDataAccessEntityTypeInfoProvider>();
[Authorize]
public virtual async Task<EntityTypeInfoDto> GetEntityRuleAsync(EntityTypeInfoGetInput input)
{
var entityType = typeof(TEntity);
var resourceType = LocalizationResource ?? typeof(DefaultResource);
var context = new DataAccessEntitTypeInfoContext(
entityType,
resourceType,
input.Operation,
LazyServiceProvider);
var model = await EntityTypeInfoProvider.GetEntitTypeInfoAsync(context);
return new EntityTypeInfoDto
{
Name = model.Name,
DisplayName = model.DisplayName,
Properties = model.Properties.Select(prop => new EntityPropertyInfoDto
{
Name = prop.Name,
DisplayName = prop.DisplayName,
TypeFullName = prop.TypeFullName,
JavaScriptType = prop.JavaScriptType,
Operates = prop.Operates,
Enums = prop.Enums.Select(em => new EntityEnumInfoDto
{
Key = em.Key,
Value = em.Value,
}).ToArray()
}).ToArray(),
};
}
}

10
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Application/System/NullableTypeExtensions.cs

@ -0,0 +1,10 @@
namespace System;
internal static class NullableTypeExtensions
{
public static bool IsNullableType(this Type theType) =>
theType.IsGenericType(typeof(Nullable<>));
public static bool IsGenericType(this Type type, Type genericType) =>
type.IsGenericType && type.GetGenericTypeDefinition() == genericType;
}

64
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedReadEntityInterceptor.cs

@ -1,64 +0,0 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
public class AbpDataProtectedReadEntityInterceptor : IQueryExpressionInterceptor, ITransientDependency
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = default!;
public IOptions<AbpDataProtectionOptions> DataProtectionOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDataProtectionOptions>>();
public ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService<ICurrentUser>();
public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService<IDataFilter>();
public IEntityTypeFilterBuilder EntityTypeFilterBuilder => LazyServiceProvider.LazyGetRequiredService<IEntityTypeFilterBuilder>();
private static readonly MethodInfo WhereMethodInfo = typeof(Queryable).GetMethods().First(m => m.Name == nameof(Queryable.Where));
public Expression QueryCompilationStarting(Expression queryExpression, QueryExpressionEventData eventData)
{
if (DataFilter.IsEnabled<IDataProtected>() && queryExpression.Type.GenericTypeArguments.Length > 0)
{
var entityType = queryExpression.Type.GenericTypeArguments[0];
var exp = EntityTypeFilterBuilder.Build(entityType, DataAccessOperation.Read);
return Expression.Call(
method: WhereMethodInfo.MakeGenericMethod(entityType),
arg0: queryExpression,
arg1: exp);
}
return queryExpression;
}
public class DataProtectedExpressionVisitor : ExpressionVisitor
{
private readonly Type _entityType;
private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
public DataProtectedExpressionVisitor(Type entityType, IEntityTypeFilterBuilder entityTypeFilterBuilder)
{
_entityType = entityType;
_entityTypeFilterBuilder = entityTypeFilterBuilder;
}
private static readonly MethodInfo WhereMethodInfo = typeof(Queryable).GetMethods().First(m => m.Name == nameof(Queryable.Where));
protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
{
var method = WhereMethodInfo.MakeGenericMethod(_entityType);
var args0 = base.VisitMethodCall(methodCallExpression);
var args1 = _entityTypeFilterBuilder.Build(_entityType, DataAccessOperation.Read);
return Expression.Call(
method: method,
arg0: args0,
arg1: args1);
}
}
}

12
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWritePropertiesInterceptor.cs

@ -28,14 +28,20 @@ public class AbpDataProtectedWritePropertiesInterceptor : SaveChangesInterceptor
{ {
var allowProperties = new List<string>(); var allowProperties = new List<string>();
var entity = entry.Entity; var entity = entry.Entity;
var subjectContext = new DataAccessSubjectContributorContext(entity.GetType().FullName, DataAccessOperation.Write, LazyServiceProvider); var entityType = entry.Entity.GetType();
var subjectContext = new DataAccessSubjectContributorContext(entityType.FullName, DataAccessOperation.Write, LazyServiceProvider);
foreach (var contributor in DataProtectionOptions.Value.SubjectContributors) foreach (var contributor in DataProtectionOptions.Value.SubjectContributors)
{ {
var properties = contributor.GetAllowProperties(subjectContext); var properties = await contributor.GetAccessdProperties(subjectContext);
allowProperties.AddIfNotContains(properties); allowProperties.AddIfNotContains(properties);
} }
allowProperties.AddIfNotContains(DataProtectionOptions.Value.IgnoreAuditedProperties); if (DataProtectionOptions.Value.EntityIgnoreProperties.TryGetValue(entityType, out var entityIgnoreProps))
{
allowProperties.AddIfNotContains(entityIgnoreProps);
}
allowProperties.AddIfNotContains(DataProtectionOptions.Value.GlobalIgnoreProperties);
foreach (var property in entry.Properties) foreach (var property in entry.Properties)
{ {

1
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs

@ -27,7 +27,6 @@ public abstract class AbpDataProtectionDbContext<TDbContext> : AbpDbContext<TDbC
if (LazyServiceProvider != null) if (LazyServiceProvider != null)
{ {
// TODO: 需要优化表达式树 // TODO: 需要优化表达式树
// optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedReadEntityInterceptor>());
//optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedWriteEntityInterceptor>()); //optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedWriteEntityInterceptor>());
optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedWritePropertiesInterceptor>()); optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedWritePropertiesInterceptor>());
} }

22
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/EfCoreDataProtectionRepository.cs

@ -21,23 +21,28 @@ public abstract class EfCoreDataProtectionRepository<TDbContext, TEntity, TKey>
{ {
private readonly IDataAuthorizationService _dataAuthorizationService; private readonly IDataAuthorizationService _dataAuthorizationService;
private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder; private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
private readonly IEntityPropertyResultBuilder _entityPropertyResultBuilder;
protected EfCoreDataProtectionRepository( protected EfCoreDataProtectionRepository(
[NotNull] IDbContextProvider<TDbContext> dbContextProvider, [NotNull] IDbContextProvider<TDbContext> dbContextProvider,
[NotNull] IDataAuthorizationService dataAuthorizationService, [NotNull] IDataAuthorizationService dataAuthorizationService,
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder) [NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder,
[NotNull] IEntityPropertyResultBuilder entityPropertyResultBuilder)
: base(dbContextProvider) : base(dbContextProvider)
{ {
_dataAuthorizationService = dataAuthorizationService; _dataAuthorizationService = dataAuthorizationService;
_entityTypeFilterBuilder = entityTypeFilterBuilder; _entityTypeFilterBuilder = entityTypeFilterBuilder;
_entityPropertyResultBuilder = entityPropertyResultBuilder;
} }
public async override Task<IQueryable<TEntity>> GetQueryableAsync() public async override Task<IQueryable<TEntity>> GetQueryableAsync()
{ {
var queryable = await base.GetQueryableAsync(); var queryable = await base.GetQueryableAsync();
var dataAccessFilterExp = _entityTypeFilterBuilder.Build<TEntity>(DataAccessOperation.Read); var dataAccessFilterExp = await _entityTypeFilterBuilder.Build<TEntity>(DataAccessOperation.Read);
queryable = queryable.Where(dataAccessFilterExp); var accessFieldExp = await _entityPropertyResultBuilder.Build<TEntity>(DataAccessOperation.Read);
queryable = queryable.Where(dataAccessFilterExp).Select(accessFieldExp);
return queryable; return queryable;
} }
@ -91,23 +96,28 @@ public abstract class EfCoreDataProtectionRepository<TDbContext, TEntity> : EfCo
{ {
private readonly IDataAuthorizationService _dataAuthorizationService; private readonly IDataAuthorizationService _dataAuthorizationService;
private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder; private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
private readonly IEntityPropertyResultBuilder _entityPropertyResultBuilder;
protected EfCoreDataProtectionRepository( protected EfCoreDataProtectionRepository(
[NotNull] IDbContextProvider<TDbContext> dbContextProvider, [NotNull] IDbContextProvider<TDbContext> dbContextProvider,
[NotNull] IDataAuthorizationService dataAuthorizationService, [NotNull] IDataAuthorizationService dataAuthorizationService,
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder) [NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder,
[NotNull] IEntityPropertyResultBuilder entityPropertyResultBuilder)
: base(dbContextProvider) : base(dbContextProvider)
{ {
_dataAuthorizationService = dataAuthorizationService; _dataAuthorizationService = dataAuthorizationService;
_entityTypeFilterBuilder = entityTypeFilterBuilder; _entityTypeFilterBuilder = entityTypeFilterBuilder;
_entityPropertyResultBuilder = entityPropertyResultBuilder;
} }
public async override Task<IQueryable<TEntity>> GetQueryableAsync() public async override Task<IQueryable<TEntity>> GetQueryableAsync()
{ {
var queryable = await base.GetQueryableAsync(); var queryable = await base.GetQueryableAsync();
var dataAccessFilterExp = _entityTypeFilterBuilder.Build<TEntity>(DataAccessOperation.Read); var dataAccessFilterExp = await _entityTypeFilterBuilder.Build<TEntity>(DataAccessOperation.Read);
queryable = queryable.Where(dataAccessFilterExp); var accessFieldExp = await _entityPropertyResultBuilder.Build<TEntity>(DataAccessOperation.Read);
queryable = queryable.Where(dataAccessFilterExp).Select(accessFieldExp);
return queryable; return queryable;
} }

23
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/AbpDataProtectionOptions.cs

@ -31,9 +31,17 @@ public class AbpDataProtectionOptions
/// </summary> /// </summary>
public IDictionary<Type, Func<IServiceProvider, Type, DataAccessOperation, LambdaExpression>> DefaultEntityFilters { get; } public IDictionary<Type, Func<IServiceProvider, Type, DataAccessOperation, LambdaExpression>> DefaultEntityFilters { get; }
/// <summary> /// <summary>
/// 忽略审计字段列表 /// 实体忽略字段
/// </summary> /// </summary>
public IList<string> IgnoreAuditedProperties { get; set; } public IDictionary<Type, string[]> EntityIgnoreProperties { get; }
/// <summary>
/// 全局忽略字段列表(不参与字段级权限校验)
/// </summary>
public IList<string> GlobalIgnoreProperties { get; set; }
/// <summary>
/// 审计字段列表(这些字段写入受保护实体的属性列表中,用于前端过滤)
/// </summary>
public IList<string> AuditedObjectProperties { get; set; }
public AbpDataProtectionOptions() public AbpDataProtectionOptions()
{ {
IsEnabled = true; IsEnabled = true;
@ -41,8 +49,9 @@ public class AbpDataProtectionOptions
KeywordContributors = new Dictionary<string, IDataAccessKeywordContributor>(); KeywordContributors = new Dictionary<string, IDataAccessKeywordContributor>();
OperateContributors = new Dictionary<DataAccessFilterOperate, IDataAccessOperateContributor>(); OperateContributors = new Dictionary<DataAccessFilterOperate, IDataAccessOperateContributor>();
DefaultEntityFilters = new Dictionary<Type, Func<IServiceProvider, Type, DataAccessOperation, LambdaExpression>>(); DefaultEntityFilters = new Dictionary<Type, Func<IServiceProvider, Type, DataAccessOperation, LambdaExpression>>();
EntityIgnoreProperties = new Dictionary<Type, string[]>();
IgnoreAuditedProperties = new List<string> GlobalIgnoreProperties = new List<string>
{ {
nameof(IEntity<Guid>.Id), nameof(IEntity<Guid>.Id),
nameof(IAuditedObject.LastModifierId), nameof(IAuditedObject.LastModifierId),
@ -57,5 +66,13 @@ public class AbpDataProtectionOptions
nameof(IHasConcurrencyStamp.ConcurrencyStamp), nameof(IHasConcurrencyStamp.ConcurrencyStamp),
nameof(IHasExtraProperties.ExtraProperties), nameof(IHasExtraProperties.ExtraProperties),
}; };
AuditedObjectProperties = new List<string>
{
nameof(IAuditedObject.LastModifierId),
nameof(IAuditedObject.LastModificationTime),
nameof(IAuditedObject.CreatorId),
nameof(IAuditedObject.CreationTime),
};
} }
} }

22
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessEntitTypeInfoContext.cs

@ -0,0 +1,22 @@
using System;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessEntitTypeInfoContext
{
public Type EntityType { get; }
public Type ResourceType { get; }
public DataAccessOperation Operation { get; }
public IServiceProvider ServiceProvider { get; }
public DataAccessEntitTypeInfoContext(
Type entityType,
Type resourceType,
DataAccessOperation operation,
IServiceProvider serviceProvider)
{
EntityType = entityType;
ResourceType = resourceType;
Operation = operation;
ServiceProvider = serviceProvider;
}
}

103
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessEntityTypeInfoProvider.cs

@ -0,0 +1,103 @@
using LINGYUN.Abp.DataProtection.Models;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessEntityTypeInfoProvider : IDataAccessEntityTypeInfoProvider, ISingletonDependency
{
public async virtual Task<EntityTypeInfoModel> GetEntitTypeInfoAsync(DataAccessEntitTypeInfoContext context)
{
var allowProperties = new List<string>();
var dataProtectionOptions = context.ServiceProvider.GetRequiredService<IOptions<AbpDataProtectionOptions>>().Value;
var javaScriptTypeConvert = context.ServiceProvider.GetRequiredService<IJavaScriptTypeConvert>();
var localizerFactory = context.ServiceProvider.GetRequiredService<IStringLocalizerFactory>();
var stringLozalizer = localizerFactory.Create(context.ResourceType);
var entityTypeRuleModel = new EntityTypeInfoModel
{
Name = context.EntityType.Name,
DisplayName = stringLozalizer[$"DisplayName:{context.EntityType.Name}"].Value ?? context.EntityType.Name
};
var subjectContext = new DataAccessSubjectContributorContext(
context.EntityType.FullName,
context.Operation,
context.ServiceProvider);
foreach (var subjectContributor in dataProtectionOptions.SubjectContributors)
{
var subjectAllowProperties = await subjectContributor.GetAccessdProperties(subjectContext);
allowProperties.AddIfNotContains(subjectAllowProperties);
}
IEnumerable<PropertyInfo> entityPropeties = context.EntityType.GetProperties();
if (allowProperties.Count > 0)
{
if (dataProtectionOptions.EntityIgnoreProperties.TryGetValue(context.EntityType, out var entityIgnoreProps))
{
allowProperties.AddIfNotContains(entityIgnoreProps);
}
allowProperties.AddIfNotContains(dataProtectionOptions.GlobalIgnoreProperties);
entityPropeties = entityPropeties.Where(x => allowProperties.Contains(x.Name));
}
foreach (var propertyInfo in entityPropeties)
{
// 字段本地化描述规则
// 在本地化文件中定义 DisplayName:PropertyName
var localizedProp = stringLozalizer[$"DisplayName:{propertyInfo.Name}"];
var propertyInfoResult = javaScriptTypeConvert.Convert(propertyInfo.PropertyType);
var entityPropertyInfo = new EntityPropertyInfoModel
{
Name = propertyInfo.Name,
TypeFullName = propertyInfo.PropertyType.FullName,
DisplayName = localizedProp.Value ?? propertyInfo.Name,
JavaScriptType = propertyInfoResult.Type,
JavaScriptName = propertyInfo.Name.ToCamelCase(),
Operates = propertyInfoResult.AllowOperates
};
var propertyType = propertyInfo.PropertyType;
if (propertyType.IsNullableType())
{
propertyType = propertyType.GetGenericArguments().FirstOrDefault();
}
if (typeof(Enum).IsAssignableFrom(propertyType))
{
var enumNames = Enum.GetNames(propertyType);
var enumValues = Enum.GetValues(propertyType);
var paramterOptions = new EntityEnumInfoModel[enumNames.Length];
for (var index = 0; index < enumNames.Length; index++)
{
var enumName = enumNames[index];
var localizerEnumKey = $"{propertyInfo.Name}:{enumName}";
var localizerEnumName = stringLozalizer[localizerEnumKey];
paramterOptions[index] = new EntityEnumInfoModel
{
Key = localizerEnumName.ResourceNotFound ? enumName : localizerEnumName.Value,
Value = enumValues.GetValue(index),
};
}
entityPropertyInfo.Enums = paramterOptions;
}
entityTypeRuleModel.Properties.Add(entityPropertyInfo);
}
return entityTypeRuleModel;
}
}

18
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessResourceCacheInvalidator.cs

@ -0,0 +1,18 @@
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessResourceCacheInvalidator : IDistributedEventHandler<DataAccessResourceChangeEvent>, ITransientDependency
{
private readonly IDataProtectedResourceStore _resourceStore;
public DataAccessResourceCacheInvalidator(IDataProtectedResourceStore resourceStore)
{
_resourceStore = resourceStore;
}
public async virtual Task HandleEventAsync(DataAccessResourceChangeEvent eventData)
{
await _resourceStore.SetAsync(eventData.Resource);
}
}

8
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAuthorizationService.cs

@ -17,15 +17,15 @@ public class DataAuthorizationService : IDataAuthorizationService, ITransientDep
_entityTypeFilterBuilder = entityTypeFilterBuilder; _entityTypeFilterBuilder = entityTypeFilterBuilder;
} }
public virtual Task<AuthorizationResult> AuthorizeAsync<TEntity>(DataAccessOperation operation, IEnumerable<TEntity> entities) public async virtual Task<AuthorizationResult> AuthorizeAsync<TEntity>(DataAccessOperation operation, IEnumerable<TEntity> entities)
{ {
if (!entities.Any()) if (!entities.Any())
{ {
return Task.FromResult(AuthorizationResult.Success()); return AuthorizationResult.Success();
} }
var exp = _entityTypeFilterBuilder.Build<TEntity>(operation); var exp = await _entityTypeFilterBuilder.Build<TEntity>(operation);
return Task.FromResult(entities.All(exp.Compile()) ? AuthorizationResult.Success() : AuthorizationResult.Failed()); return entities.All(exp.Compile()) ? AuthorizationResult.Success() : AuthorizationResult.Failed();
} }
} }

1
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataProtectedInterceptor.cs

@ -38,6 +38,7 @@ public class DataProtectedInterceptor : AbpInterceptor, ITransientDependency
return true; return true;
} }
// TODO: 使用一个范围标志来确定当前需要禁用的数据权限操作
if (invocation.Method.IsDefined(typeof(DisableDataProtectedAttribute), true)) if (invocation.Method.IsDefined(typeof(DisableDataProtectedAttribute), true))
{ {
return true; return true;

47
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/EntityPropertyResultBuilder.cs

@ -5,12 +5,8 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.DataProtection; namespace LINGYUN.Abp.DataProtection;
public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransientDependency public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransientDependency
@ -29,7 +25,7 @@ public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransi
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
public virtual LambdaExpression Build(Type entityType, DataAccessOperation operation) public async virtual Task<LambdaExpression> Build(Type entityType, DataAccessOperation operation)
{ {
// Func<TEntity, TEntity> // Func<TEntity, TEntity>
var func = typeof(Func<,>).MakeGenericType(entityType, entityType); var func = typeof(Func<,>).MakeGenericType(entityType, entityType);
@ -45,18 +41,23 @@ public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransi
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider); var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors) foreach (var contributor in _options.SubjectContributors)
{ {
var properties = contributor.GetAllowProperties(subjectContext); var properties = await contributor.GetAccessdProperties(subjectContext);
allowProperties.AddIfNotContains(properties); allowProperties.AddIfNotContains(properties);
} }
// 默认实体相关标识需要带上, 否则无法返回查询结果
allowProperties.AddIfNotContains(_options.IgnoreAuditedProperties);
if (!allowProperties.Any()) if (!allowProperties.Any())
{ {
return selector; return selector;
} }
if (_options.EntityIgnoreProperties.TryGetValue(entityType, out var entityIgnoreProps))
{
allowProperties.AddIfNotContains(entityIgnoreProps);
}
// 默认实体相关标识需要带上, 否则无法返回查询结果
allowProperties.AddIfNotContains(_options.GlobalIgnoreProperties);
var memberBindings = new List<MemberBinding>(); var memberBindings = new List<MemberBinding>();
foreach (var propertyName in allowProperties) foreach (var propertyName in allowProperties)
{ {
@ -73,7 +74,7 @@ public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransi
return Expression.Lambda(func, memberInitExpression, param); return Expression.Lambda(func, memberInitExpression, param);
} }
public virtual Expression<Func<TEntity, TEntity>> Build<TEntity>(DataAccessOperation operation) public async virtual Task<Expression<Func<TEntity, TEntity>>> Build<TEntity>(DataAccessOperation operation)
{ {
var entityType = typeof(TEntity); var entityType = typeof(TEntity);
Expression<Func<TEntity, TEntity>> selector = e => e; Expression<Func<TEntity, TEntity>> selector = e => e;
@ -88,18 +89,23 @@ public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransi
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider); var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors) foreach (var contributor in _options.SubjectContributors)
{ {
var properties = contributor.GetAllowProperties(subjectContext); var properties = await contributor.GetAccessdProperties(subjectContext);
allowProperties.AddIfNotContains(properties); allowProperties.AddIfNotContains(properties);
} }
// 默认实体相关标识需要带上, 否则无法返回查询结果
allowProperties.AddIfNotContains(_options.IgnoreAuditedProperties);
if (!allowProperties.Any()) if (!allowProperties.Any())
{ {
return selector; return selector;
} }
if (_options.EntityIgnoreProperties.TryGetValue(entityType, out var entityIgnoreProps))
{
allowProperties.AddIfNotContains(entityIgnoreProps);
}
// 默认实体相关标识需要带上, 否则无法返回查询结果
allowProperties.AddIfNotContains(_options.GlobalIgnoreProperties);
var param = Expression.Parameter(typeof(TEntity), "e"); var param = Expression.Parameter(typeof(TEntity), "e");
var memberBindings = new List<MemberBinding>(); var memberBindings = new List<MemberBinding>();
foreach (var propertyName in allowProperties) foreach (var propertyName in allowProperties)
@ -119,13 +125,20 @@ public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransi
private bool ShouldApplyFilter(Type entityType, DataAccessOperation operation) private bool ShouldApplyFilter(Type entityType, DataAccessOperation operation)
{ {
// TODO: 使用一个范围标志来确定当前需要禁用的数据权限操作
if (!_dataFilter.IsEnabled<IDataProtected>()) if (!_dataFilter.IsEnabled<IDataProtected>())
{ {
return false; return false;
} }
if (entityType.IsDefined(typeof(DisableDataProtectedAttribute), true)) var disableAttr = entityType.GetCustomAttribute<DisableDataProtectedAttribute>();
if (disableAttr != null)
{ {
if (disableAttr.Operation.HasValue && disableAttr.Operation != operation)
{
return true;
}
return false; return false;
} }

19
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/EntityTypeFilterBuilder.cs

@ -7,7 +7,7 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Nodes; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -30,7 +30,7 @@ public class EntityTypeFilterBuilder : IEntityTypeFilterBuilder, ITransientDepen
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
public virtual LambdaExpression Build(Type entityType, DataAccessOperation operation, DataAccessFilterGroup group = null) public async virtual Task<LambdaExpression> Build(Type entityType, DataAccessOperation operation, DataAccessFilterGroup group = null)
{ {
// Func<TEntity, bool> // Func<TEntity, bool>
var func = typeof(Func<,>).MakeGenericType(entityType, typeof(bool)); var func = typeof(Func<,>).MakeGenericType(entityType, typeof(bool));
@ -56,7 +56,7 @@ public class EntityTypeFilterBuilder : IEntityTypeFilterBuilder, ITransientDepen
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider); var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors) foreach (var contributor in _options.SubjectContributors)
{ {
var subjectFilterGroup = contributor.GetFilterGroups(subjectContext); var subjectFilterGroup = await contributor.GetFilterGroups(subjectContext);
subjectFilterGroups.AddRange(subjectFilterGroup); subjectFilterGroups.AddRange(subjectFilterGroup);
} }
@ -87,7 +87,7 @@ public class EntityTypeFilterBuilder : IEntityTypeFilterBuilder, ITransientDepen
return exp; return exp;
} }
public virtual Expression<Func<TEntity, bool>> Build<TEntity>(DataAccessOperation operation, DataAccessFilterGroup group = null) public async virtual Task<Expression<Func<TEntity, bool>>> Build<TEntity>(DataAccessOperation operation, DataAccessFilterGroup group = null)
{ {
var entityType = typeof(TEntity); var entityType = typeof(TEntity);
Expression<Func<TEntity, bool>> exp = _ => true; Expression<Func<TEntity, bool>> exp = _ => true;
@ -107,7 +107,7 @@ public class EntityTypeFilterBuilder : IEntityTypeFilterBuilder, ITransientDepen
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider); var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors) foreach (var contributor in _options.SubjectContributors)
{ {
var subjectFilterGroup = contributor.GetFilterGroups(subjectContext); var subjectFilterGroup = await contributor.GetFilterGroups(subjectContext);
subjectFilterGroups.AddRange(subjectFilterGroup); subjectFilterGroups.AddRange(subjectFilterGroup);
} }
@ -284,13 +284,20 @@ public class EntityTypeFilterBuilder : IEntityTypeFilterBuilder, ITransientDepen
private bool ShouldApplyFilter(Type entityType, DataAccessOperation operation) private bool ShouldApplyFilter(Type entityType, DataAccessOperation operation)
{ {
// TODO: 使用一个范围标志来确定当前需要禁用的数据权限操作
if (!_dataFilter.IsEnabled<IDataProtected>()) if (!_dataFilter.IsEnabled<IDataProtected>())
{ {
return false; return false;
} }
if (entityType.IsDefined(typeof(DisableDataProtectedAttribute), true)) var disableAttr = entityType.GetCustomAttribute<DisableDataProtectedAttribute>();
if (disableAttr != null)
{ {
if (disableAttr.Operation.HasValue && disableAttr.Operation != operation)
{
return true;
}
return false; return false;
} }

9
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessEntityTypeInfoProvider.cs

@ -0,0 +1,9 @@
using LINGYUN.Abp.DataProtection.Models;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection;
public interface IDataAccessEntityTypeInfoProvider
{
Task<EntityTypeInfoModel> GetEntitTypeInfoAsync(DataAccessEntitTypeInfoContext context);
}

5
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessSubjectContributor.cs

@ -1,9 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection; namespace LINGYUN.Abp.DataProtection;
public interface IDataAccessSubjectContributor public interface IDataAccessSubjectContributor
{ {
string Name { get; } string Name { get; }
List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context); Task<List<DataAccessFilterGroup>> GetFilterGroups(DataAccessSubjectContributorContext context);
List<string> GetAllowProperties(DataAccessSubjectContributorContext context); Task<List<string>> GetAccessdProperties(DataAccessSubjectContributorContext context);
} }

10
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataProtectedResourceStore.cs

@ -1,9 +1,11 @@
namespace LINGYUN.Abp.DataProtection; using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection;
public interface IDataProtectedResourceStore public interface IDataProtectedResourceStore
{ {
void Set(DataAccessResource resource); Task SetAsync(DataAccessResource resource);
void Remove(DataAccessResource resource); Task RemoveAsync(DataAccessResource resource);
DataAccessResource Get(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation); Task<DataAccessResource> GetAsync(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation);
} }

5
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IEntityPropertyResultBuilder.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection; namespace LINGYUN.Abp.DataProtection;
/// <summary> /// <summary>
@ -13,12 +14,12 @@ public interface IEntityPropertyResultBuilder
/// <typeparam name="TEntity">实体类型</typeparam> /// <typeparam name="TEntity">实体类型</typeparam>
/// <param name="operation">数据操作方式</param> /// <param name="operation">数据操作方式</param>
/// <returns></returns> /// <returns></returns>
Expression<Func<TEntity, TEntity>> Build<TEntity>(DataAccessOperation operation); Task<Expression<Func<TEntity, TEntity>>> Build<TEntity>(DataAccessOperation operation);
/// <summary> /// <summary>
/// 获取实体的属性返回值过滤表达式 /// 获取实体的属性返回值过滤表达式
/// </summary> /// </summary>
/// <param name="entityType">实体类型</param> /// <param name="entityType">实体类型</param>
/// <param name="operation">数据操作方式</param> /// <param name="operation">数据操作方式</param>
/// <returns></returns> /// <returns></returns>
LambdaExpression Build(Type entityType, DataAccessOperation operation); Task<LambdaExpression> Build(Type entityType, DataAccessOperation operation);
} }

5
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IEntityTypeFilterBuilder.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection; namespace LINGYUN.Abp.DataProtection;
/// <summary> /// <summary>
@ -14,7 +15,7 @@ public interface IEntityTypeFilterBuilder
/// <param name="group">查询条件组</param> /// <param name="group">查询条件组</param>
/// <typeparam name="TEntity">实体类型</typeparam> /// <typeparam name="TEntity">实体类型</typeparam>
/// <returns></returns> /// <returns></returns>
Expression<Func<TEntity, bool>> Build<TEntity>(DataAccessOperation operation, DataAccessFilterGroup group = null); Task<Expression<Func<TEntity, bool>>> Build<TEntity>(DataAccessOperation operation, DataAccessFilterGroup group = null);
LambdaExpression Build(Type entityType, DataAccessOperation operation, DataAccessFilterGroup group = null); Task<LambdaExpression> Build(Type entityType, DataAccessOperation operation, DataAccessFilterGroup group = null);
} }

8
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IJavaScriptTypeConvert.cs

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Abp.DataProtection;
public interface IJavaScriptTypeConvert
{
JavaScriptTypeConvertResult Convert(Type propertyType);
}

20
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/InMemoryDataProtectedResourceStore.cs

@ -1,5 +1,6 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtection; namespace LINGYUN.Abp.DataProtection;
@ -34,4 +35,23 @@ public class InMemoryDataProtectedResourceStore : IDataProtectedResourceStore
{ {
return $"{subjectName}_{subjectId}_{entityTypeFullName}_{operation}"; return $"{subjectName}_{subjectId}_{entityTypeFullName}_{operation}";
} }
public Task SetAsync(DataAccessResource resource)
{
Set(resource);
return Task.CompletedTask;
}
public Task RemoveAsync(DataAccessResource resource)
{
Remove(resource);
return Task.CompletedTask;
}
public Task<DataAccessResource> GetAsync(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation)
{
return Task.FromResult(Get(subjectName, subjectId, entityTypeFullName, operation));
}
} }

132
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/JavaScriptTypeConvert.cs

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtection;
public class JavaScriptTypeConvert : IJavaScriptTypeConvert, ISingletonDependency
{
public JavaScriptTypeConvertResult Convert(Type propertyType)
{
var (JavaScriptType, AccessOperates) = InnerConvert(propertyType);
return new JavaScriptTypeConvertResult(JavaScriptType, AccessOperates);
}
protected virtual (string JavaScriptType, DataAccessFilterOperate[] AccessFilterOperates) InnerConvert(Type propertyType)
{
var availableComparator = new List<DataAccessFilterOperate>();
if (propertyType.IsNullableType())
{
propertyType = propertyType.GetGenericArguments().FirstOrDefault();
}
if (typeof(Enum).IsAssignableFrom(propertyType))
{
// 枚举类型只支持如下操作符
// 小于、小于等于、大于、大于等于、等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Greater,
DataAccessFilterOperate.GreaterOrEqual,
DataAccessFilterOperate.Less,
DataAccessFilterOperate.LessOrEqual,
DataAccessFilterOperate.Equal,
DataAccessFilterOperate.NotEqual,
});
return ("number", availableComparator.ToArray());
}
var typeFullName = propertyType.FullName;
switch (typeFullName)
{
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.UInt16":
case "System.UInt32":
case "System.UInt64":
case "System.Single":
case "System.Double":
case "System.Byte":
case "System.SByte":
case "System.Decimal":
// 数值类型只支持如下操作符
// 小于、小于等于、大于、大于等于、等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Greater,
DataAccessFilterOperate.GreaterOrEqual,
DataAccessFilterOperate.Less,
DataAccessFilterOperate.LessOrEqual,
DataAccessFilterOperate.Equal,
DataAccessFilterOperate.NotEqual,
});
return ("number", availableComparator.ToArray());
case "System.Boolean":
// 布尔类型只支持如下操作符
// 等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Equal,
DataAccessFilterOperate.NotEqual,
});
return ("boolean", availableComparator.ToArray());
case "System.Guid":
// Guid类型只支持如下操作符
// 等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Equal,
DataAccessFilterOperate.NotEqual,
});
return ("string", availableComparator.ToArray());
case "System.Char":
case "System.String":
// 字符类型支持所有操作符
return ("string", availableComparator.ToArray());
case "System.DateTime":
// 时间类型只支持如下操作符
// 小于、小于等于、大于、大于等于、等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Greater,
DataAccessFilterOperate.GreaterOrEqual,
DataAccessFilterOperate.Less,
DataAccessFilterOperate.LessOrEqual,
DataAccessFilterOperate.Equal,
DataAccessFilterOperate.NotEqual,
});
return ("Date", availableComparator.ToArray());
default:
case "System.Object":
case "System.DBNull":
if (propertyType.IsArray)
{
// 数组类型只支持如下操作符
// 包含、不包含、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Contains,
DataAccessFilterOperate.NotContains,
});
return ("array", availableComparator.ToArray());
}
else
{
// 未知对象类型只支持如下操作符
// 等于、不等于、空、非空
availableComparator.AddRange(new[]
{
DataAccessFilterOperate.Equal,
DataAccessFilterOperate.NotEqual,
});
return ("object", availableComparator.ToArray());
}
}
}
}

12
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/JavaScriptTypeConvertResult.cs

@ -0,0 +1,12 @@
namespace LINGYUN.Abp.DataProtection;
public class JavaScriptTypeConvertResult
{
public string Type { get; }
public DataAccessFilterOperate[] AllowOperates { get; }
public JavaScriptTypeConvertResult(string type, DataAccessFilterOperate[] allowOperates)
{
Type = type;
AllowOperates = allowOperates;
}
}

13
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessClientIdContributor.cs

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Clients; using Volo.Abp.Clients;
@ -9,30 +10,30 @@ public class DataAccessClientIdContributor : IDataAccessSubjectContributor
{ {
public string Name => ClientPermissionValueProvider.ProviderName; public string Name => ClientPermissionValueProvider.ProviderName;
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context) public async virtual Task<List<string>> GetAccessdProperties(DataAccessSubjectContributorContext context)
{ {
var allowProperties = new List<string>(); var allowProperties = new List<string>();
var currentClient = context.ServiceProvider.GetRequiredService<ICurrentClient>(); var currentClient = context.ServiceProvider.GetRequiredService<ICurrentClient>();
if (currentClient.IsAuthenticated) if (currentClient.IsAuthenticated)
{ {
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>(); var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var resource = resourceStore.Get(Name, currentClient.Id, context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, currentClient.Id, context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true) if (resource?.AccessedProperties.Any() == true)
{ {
allowProperties.AddIfNotContains(resource.AllowProperties); allowProperties.AddIfNotContains(resource.AccessedProperties);
} }
} }
return allowProperties; return allowProperties;
} }
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context) public async virtual Task<List<DataAccessFilterGroup>> GetFilterGroups(DataAccessSubjectContributorContext context)
{ {
var groups = new List<DataAccessFilterGroup>(); var groups = new List<DataAccessFilterGroup>();
var currentClient = context.ServiceProvider.GetRequiredService<ICurrentClient>(); var currentClient = context.ServiceProvider.GetRequiredService<ICurrentClient>();
if (currentClient.IsAuthenticated) if (currentClient.IsAuthenticated)
{ {
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>(); var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var resource = resourceStore.Get(Name, currentClient.Id, context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, currentClient.Id, context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null) if (resource?.FilterGroup != null)
{ {
groups.Add(resource.FilterGroup); groups.Add(resource.FilterGroup);

13
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessOrganizationUnitContributor.cs

@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Users; using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.Subjects; namespace LINGYUN.Abp.DataProtection.Subjects;
@ -10,7 +11,7 @@ public class DataAccessOrganizationUnitContributor : IDataAccessSubjectContribut
{ {
public string Name => OrganizationUnitPermissionValueProvider.ProviderName; public string Name => OrganizationUnitPermissionValueProvider.ProviderName;
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context) public async virtual Task<List<DataAccessFilterGroup>> GetFilterGroups(DataAccessSubjectContributorContext context)
{ {
var groups = new List<DataAccessFilterGroup>(); var groups = new List<DataAccessFilterGroup>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>(); var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
@ -20,7 +21,7 @@ public class DataAccessOrganizationUnitContributor : IDataAccessSubjectContribut
var orgCodes = currentUser.FindOrganizationUnits(); var orgCodes = currentUser.FindOrganizationUnits();
foreach (var orgCode in orgCodes) foreach (var orgCode in orgCodes)
{ {
var resource = resourceStore.Get(Name, orgCode, context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, orgCode, context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null) if (resource?.FilterGroup != null)
{ {
groups.Add(resource.FilterGroup); groups.Add(resource.FilterGroup);
@ -30,7 +31,7 @@ public class DataAccessOrganizationUnitContributor : IDataAccessSubjectContribut
return groups; return groups;
} }
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context) public async virtual Task<List<string>> GetAccessdProperties(DataAccessSubjectContributorContext context)
{ {
var allowProperties = new List<string>(); var allowProperties = new List<string>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>(); var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
@ -40,10 +41,10 @@ public class DataAccessOrganizationUnitContributor : IDataAccessSubjectContribut
var orgCodes = currentUser.FindOrganizationUnits(); var orgCodes = currentUser.FindOrganizationUnits();
foreach (var orgCode in orgCodes) foreach (var orgCode in orgCodes)
{ {
var resource = resourceStore.Get(Name, orgCode, context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, orgCode, context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true) if (resource?.AccessedProperties.Any() == true)
{ {
allowProperties.AddIfNotContains(resource.AllowProperties); allowProperties.AddIfNotContains(resource.AccessedProperties);
} }
} }
} }

13
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessRoleNameContributor.cs

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Users; using Volo.Abp.Users;
@ -10,7 +11,7 @@ public class DataAccessRoleNameContributor : IDataAccessSubjectContributor
{ {
public string Name => RolePermissionValueProvider.ProviderName; public string Name => RolePermissionValueProvider.ProviderName;
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context) public async virtual Task<List<DataAccessFilterGroup>> GetFilterGroups(DataAccessSubjectContributorContext context)
{ {
var groups = new List<DataAccessFilterGroup>(); var groups = new List<DataAccessFilterGroup>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>(); var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
@ -20,7 +21,7 @@ public class DataAccessRoleNameContributor : IDataAccessSubjectContributor
var roles = currentUser.Roles; var roles = currentUser.Roles;
foreach (var role in roles) foreach (var role in roles)
{ {
var resource = resourceStore.Get(Name, role, context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, role, context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null) if (resource?.FilterGroup != null)
{ {
groups.Add(resource.FilterGroup); groups.Add(resource.FilterGroup);
@ -30,7 +31,7 @@ public class DataAccessRoleNameContributor : IDataAccessSubjectContributor
return groups; return groups;
} }
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context) public async virtual Task<List<string>> GetAccessdProperties(DataAccessSubjectContributorContext context)
{ {
var allowProperties = new List<string>(); var allowProperties = new List<string>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>(); var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
@ -40,10 +41,10 @@ public class DataAccessRoleNameContributor : IDataAccessSubjectContributor
var roles = currentUser.Roles; var roles = currentUser.Roles;
foreach (var role in roles) foreach (var role in roles)
{ {
var resource = resourceStore.Get(Name, role, context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, role, context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true) if (resource?.AccessedProperties.Any() == true)
{ {
allowProperties.AddIfNotContains(resource.AllowProperties); allowProperties.AddIfNotContains(resource.AccessedProperties);
} }
} }
} }

13
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessUserIdContributor.cs

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions; using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Users; using Volo.Abp.Users;
@ -10,14 +11,14 @@ public class DataAccessUserIdContributor : IDataAccessSubjectContributor
{ {
public string Name => UserPermissionValueProvider.ProviderName; public string Name => UserPermissionValueProvider.ProviderName;
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context) public async virtual Task<List<DataAccessFilterGroup>> GetFilterGroups(DataAccessSubjectContributorContext context)
{ {
var groups = new List<DataAccessFilterGroup>(); var groups = new List<DataAccessFilterGroup>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>(); var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated) if (currentUser.IsAuthenticated)
{ {
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>(); var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var resource = resourceStore.Get(Name, currentUser.Id.ToString(), context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, currentUser.Id.ToString(), context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null) if (resource?.FilterGroup != null)
{ {
groups.Add(resource.FilterGroup); groups.Add(resource.FilterGroup);
@ -26,17 +27,17 @@ public class DataAccessUserIdContributor : IDataAccessSubjectContributor
return groups; return groups;
} }
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context) public async virtual Task<List<string>> GetAccessdProperties(DataAccessSubjectContributorContext context)
{ {
var allowProperties = new List<string>(); var allowProperties = new List<string>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>(); var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated) if (currentUser.IsAuthenticated)
{ {
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>(); var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var resource = resourceStore.Get(Name, currentUser.Id.ToString(), context.EntityTypeFullName, context.Operation); var resource = await resourceStore.GetAsync(Name, currentUser.Id.ToString(), context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true) if (resource?.AccessedProperties.Any() == true)
{ {
allowProperties.AddIfNotContains(resource.AllowProperties); allowProperties.AddIfNotContains(resource.AccessedProperties);
} }
} }
return allowProperties; return allowProperties;

14
aspnet-core/migrations/LY.MicroService.Applications.Single.DbMigrator/LY.MicroService.Applications.Single.DbMigrator.csproj

@ -26,26 +26,12 @@
<Content Remove="Logs\**" /> <Content Remove="Logs\**" />
<EmbeddedResource Remove="Logs\**" /> <EmbeddedResource Remove="Logs\**" />
<None Remove="Logs\**" /> <None Remove="Logs\**" />
<Content Update="appsettings.PostgreSql.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<None Remove="appsettings.PostgreSql.json" />
<Content Include="appsettings.PostgreSql.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Remove="appsettings.json" /> <None Remove="appsettings.json" />
<Content Include="appsettings.json"> <Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Remove="appsettings.Development.json" />
<None Remove="appsettings.Production.json" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin\LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj" /> <ProjectReference Include="..\..\modules\platform\LINGYUN.Abp.UI.Navigation.VueVbenAdmin\LINGYUN.Abp.UI.Navigation.VueVbenAdmin.csproj" />
<ProjectReference Include="..\LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql\LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql.csproj" /> <ProjectReference Include="..\LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql\LY.MicroService.Applications.Single.EntityFrameworkCore.PostgreSql.csproj" />

5314
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315061656_Remove-Identity-Server-And-Add-Entity-Enum-Info.Designer.cs

File diff suppressed because it is too large

768
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315061656_Remove-Identity-Server-And-Add-Entity-Enum-Info.cs

@ -0,0 +1,768 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migrations
{
/// <inheritdoc />
public partial class RemoveIdentityServerAndAddEntityEnumInfo : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "IdentityServerApiResourceClaims");
migrationBuilder.DropTable(
name: "IdentityServerApiResourceProperties");
migrationBuilder.DropTable(
name: "IdentityServerApiResourceScopes");
migrationBuilder.DropTable(
name: "IdentityServerApiResourceSecrets");
migrationBuilder.DropTable(
name: "IdentityServerApiScopeClaims");
migrationBuilder.DropTable(
name: "IdentityServerApiScopeProperties");
migrationBuilder.DropTable(
name: "IdentityServerClientClaims");
migrationBuilder.DropTable(
name: "IdentityServerClientCorsOrigins");
migrationBuilder.DropTable(
name: "IdentityServerClientGrantTypes");
migrationBuilder.DropTable(
name: "IdentityServerClientIdPRestrictions");
migrationBuilder.DropTable(
name: "IdentityServerClientPostLogoutRedirectUris");
migrationBuilder.DropTable(
name: "IdentityServerClientProperties");
migrationBuilder.DropTable(
name: "IdentityServerClientRedirectUris");
migrationBuilder.DropTable(
name: "IdentityServerClientScopes");
migrationBuilder.DropTable(
name: "IdentityServerClientSecrets");
migrationBuilder.DropTable(
name: "IdentityServerDeviceFlowCodes");
migrationBuilder.DropTable(
name: "IdentityServerIdentityResourceClaims");
migrationBuilder.DropTable(
name: "IdentityServerIdentityResourceProperties");
migrationBuilder.DropTable(
name: "IdentityServerPersistedGrants");
migrationBuilder.DropTable(
name: "IdentityServerApiResources");
migrationBuilder.DropTable(
name: "IdentityServerApiScopes");
migrationBuilder.DropTable(
name: "IdentityServerClients");
migrationBuilder.DropTable(
name: "IdentityServerIdentityResources");
migrationBuilder.DropColumn(
name: "ValueRange",
table: "AbpAuthEntityProperties");
migrationBuilder.CreateTable(
name: "AbpAuthEntityEnums",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(64)", maxLength: 64, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
DisplayName = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(10)", maxLength: 10, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
PropertyInfoId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthEntityEnums", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthEntityEnums_AbpAuthEntityProperties_PropertyInfoId",
column: x => x.PropertyInfoId,
principalTable: "AbpAuthEntityProperties",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthEntityEnums_PropertyInfoId_Name",
table: "AbpAuthEntityEnums",
columns: new[] { "PropertyInfoId", "Name" });
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpAuthEntityEnums");
migrationBuilder.AddColumn<string>(
name: "ValueRange",
table: "AbpAuthEntityProperties",
type: "varchar(512)",
maxLength: 512,
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiResources",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
AllowedAccessTokenSigningAlgorithms = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
DisplayName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Enabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ShowInDiscoveryDocument = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiResources", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiScopes",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
DisplayName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Emphasize = table.Column<bool>(type: "tinyint(1)", nullable: false),
Enabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Required = table.Column<bool>(type: "tinyint(1)", nullable: false),
ShowInDiscoveryDocument = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiScopes", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClients",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
AbsoluteRefreshTokenLifetime = table.Column<int>(type: "int", nullable: false),
AccessTokenLifetime = table.Column<int>(type: "int", nullable: false),
AccessTokenType = table.Column<int>(type: "int", nullable: false),
AllowAccessTokensViaBrowser = table.Column<bool>(type: "tinyint(1)", nullable: false),
AllowOfflineAccess = table.Column<bool>(type: "tinyint(1)", nullable: false),
AllowPlainTextPkce = table.Column<bool>(type: "tinyint(1)", nullable: false),
AllowRememberConsent = table.Column<bool>(type: "tinyint(1)", nullable: false),
AllowedIdentityTokenSigningAlgorithms = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
AlwaysIncludeUserClaimsInIdToken = table.Column<bool>(type: "tinyint(1)", nullable: false),
AlwaysSendClientClaims = table.Column<bool>(type: "tinyint(1)", nullable: false),
AuthorizationCodeLifetime = table.Column<int>(type: "int", nullable: false),
BackChannelLogoutSessionRequired = table.Column<bool>(type: "tinyint(1)", nullable: false),
BackChannelLogoutUri = table.Column<string>(type: "varchar(2000)", maxLength: 2000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClientClaimsPrefix = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClientId = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ClientName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClientUri = table.Column<string>(type: "varchar(2000)", maxLength: 2000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConsentLifetime = table.Column<int>(type: "int", nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
DeviceCodeLifetime = table.Column<int>(type: "int", nullable: false),
EnableLocalLogin = table.Column<bool>(type: "tinyint(1)", nullable: false),
Enabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
FrontChannelLogoutSessionRequired = table.Column<bool>(type: "tinyint(1)", nullable: false),
FrontChannelLogoutUri = table.Column<string>(type: "varchar(2000)", maxLength: 2000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
IdentityTokenLifetime = table.Column<int>(type: "int", nullable: false),
IncludeJwtId = table.Column<bool>(type: "tinyint(1)", nullable: false),
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
LogoUri = table.Column<string>(type: "varchar(2000)", maxLength: 2000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PairWiseSubjectSalt = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ProtocolType = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
RefreshTokenExpiration = table.Column<int>(type: "int", nullable: false),
RefreshTokenUsage = table.Column<int>(type: "int", nullable: false),
RequireClientSecret = table.Column<bool>(type: "tinyint(1)", nullable: false),
RequireConsent = table.Column<bool>(type: "tinyint(1)", nullable: false),
RequirePkce = table.Column<bool>(type: "tinyint(1)", nullable: false),
RequireRequestObject = table.Column<bool>(type: "tinyint(1)", nullable: false),
SlidingRefreshTokenLifetime = table.Column<int>(type: "int", nullable: false),
UpdateAccessTokenClaimsOnRefresh = table.Column<bool>(type: "tinyint(1)", nullable: false),
UserCodeType = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
UserSsoLifetime = table.Column<int>(type: "int", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClients", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerDeviceFlowCodes",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ClientId = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
Data = table.Column<string>(type: "varchar(10000)", maxLength: 10000, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
DeviceCode = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Expiration = table.Column<DateTime>(type: "datetime(6)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
SessionId = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
SubjectId = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
UserCode = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerDeviceFlowCodes", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerIdentityResources",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
CreatorId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeleterId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
DeletionTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
DisplayName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Emphasize = table.Column<bool>(type: "tinyint(1)", nullable: false),
Enabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsDeleted = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValue: false),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
Name = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Required = table.Column<bool>(type: "tinyint(1)", nullable: false),
ShowInDiscoveryDocument = table.Column<bool>(type: "tinyint(1)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerIdentityResources", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerPersistedGrants",
columns: table => new
{
Key = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ClientId = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ConsumedTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
CreationTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
Data = table.Column<string>(type: "varchar(10000)", maxLength: 10000, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Expiration = table.Column<DateTime>(type: "datetime(6)", nullable: true),
ExtraProperties = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
SessionId = table.Column<string>(type: "varchar(100)", maxLength: 100, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
SubjectId = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Type = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerPersistedGrants", x => x.Key);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiResourceClaims",
columns: table => new
{
ApiResourceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Type = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiResourceClaims", x => new { x.ApiResourceId, x.Type });
table.ForeignKey(
name: "FK_IdentityServerApiResourceClaims_IdentityServerApiResources_A~",
column: x => x.ApiResourceId,
principalTable: "IdentityServerApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiResourceProperties",
columns: table => new
{
ApiResourceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Key = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiResourceProperties", x => new { x.ApiResourceId, x.Key, x.Value });
table.ForeignKey(
name: "FK_IdentityServerApiResourceProperties_IdentityServerApiResourc~",
column: x => x.ApiResourceId,
principalTable: "IdentityServerApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiResourceScopes",
columns: table => new
{
ApiResourceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Scope = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiResourceScopes", x => new { x.ApiResourceId, x.Scope });
table.ForeignKey(
name: "FK_IdentityServerApiResourceScopes_IdentityServerApiResources_A~",
column: x => x.ApiResourceId,
principalTable: "IdentityServerApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiResourceSecrets",
columns: table => new
{
ApiResourceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Type = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "varchar(1000)", maxLength: 1000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Expiration = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiResourceSecrets", x => new { x.ApiResourceId, x.Type, x.Value });
table.ForeignKey(
name: "FK_IdentityServerApiResourceSecrets_IdentityServerApiResources_~",
column: x => x.ApiResourceId,
principalTable: "IdentityServerApiResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiScopeClaims",
columns: table => new
{
ApiScopeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Type = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiScopeClaims", x => new { x.ApiScopeId, x.Type });
table.ForeignKey(
name: "FK_IdentityServerApiScopeClaims_IdentityServerApiScopes_ApiScop~",
column: x => x.ApiScopeId,
principalTable: "IdentityServerApiScopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerApiScopeProperties",
columns: table => new
{
ApiScopeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Key = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerApiScopeProperties", x => new { x.ApiScopeId, x.Key, x.Value });
table.ForeignKey(
name: "FK_IdentityServerApiScopeProperties_IdentityServerApiScopes_Api~",
column: x => x.ApiScopeId,
principalTable: "IdentityServerApiScopes",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientClaims",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Type = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientClaims", x => new { x.ClientId, x.Type, x.Value });
table.ForeignKey(
name: "FK_IdentityServerClientClaims_IdentityServerClients_ClientId",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientCorsOrigins",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Origin = table.Column<string>(type: "varchar(150)", maxLength: 150, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientCorsOrigins", x => new { x.ClientId, x.Origin });
table.ForeignKey(
name: "FK_IdentityServerClientCorsOrigins_IdentityServerClients_Client~",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientGrantTypes",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
GrantType = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientGrantTypes", x => new { x.ClientId, x.GrantType });
table.ForeignKey(
name: "FK_IdentityServerClientGrantTypes_IdentityServerClients_ClientId",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientIdPRestrictions",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Provider = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientIdPRestrictions", x => new { x.ClientId, x.Provider });
table.ForeignKey(
name: "FK_IdentityServerClientIdPRestrictions_IdentityServerClients_Cl~",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientPostLogoutRedirectUris",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
PostLogoutRedirectUri = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientPostLogoutRedirectUris", x => new { x.ClientId, x.PostLogoutRedirectUri });
table.ForeignKey(
name: "FK_IdentityServerClientPostLogoutRedirectUris_IdentityServerCli~",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientProperties",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Key = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientProperties", x => new { x.ClientId, x.Key, x.Value });
table.ForeignKey(
name: "FK_IdentityServerClientProperties_IdentityServerClients_ClientId",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientRedirectUris",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
RedirectUri = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientRedirectUris", x => new { x.ClientId, x.RedirectUri });
table.ForeignKey(
name: "FK_IdentityServerClientRedirectUris_IdentityServerClients_Clien~",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientScopes",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Scope = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientScopes", x => new { x.ClientId, x.Scope });
table.ForeignKey(
name: "FK_IdentityServerClientScopes_IdentityServerClients_ClientId",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerClientSecrets",
columns: table => new
{
ClientId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Type = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Description = table.Column<string>(type: "varchar(2000)", maxLength: 2000, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Expiration = table.Column<DateTime>(type: "datetime(6)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerClientSecrets", x => new { x.ClientId, x.Type, x.Value });
table.ForeignKey(
name: "FK_IdentityServerClientSecrets_IdentityServerClients_ClientId",
column: x => x.ClientId,
principalTable: "IdentityServerClients",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerIdentityResourceClaims",
columns: table => new
{
IdentityResourceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Type = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerIdentityResourceClaims", x => new { x.IdentityResourceId, x.Type });
table.ForeignKey(
name: "FK_IdentityServerIdentityResourceClaims_IdentityServerIdentityR~",
column: x => x.IdentityResourceId,
principalTable: "IdentityServerIdentityResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "IdentityServerIdentityResourceProperties",
columns: table => new
{
IdentityResourceId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
Key = table.Column<string>(type: "varchar(250)", maxLength: 250, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "varchar(300)", maxLength: 300, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_IdentityServerIdentityResourceProperties", x => new { x.IdentityResourceId, x.Key, x.Value });
table.ForeignKey(
name: "FK_IdentityServerIdentityResourceProperties_IdentityServerIdent~",
column: x => x.IdentityResourceId,
principalTable: "IdentityServerIdentityResources",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_IdentityServerClients_ClientId",
table: "IdentityServerClients",
column: "ClientId");
migrationBuilder.CreateIndex(
name: "IX_IdentityServerDeviceFlowCodes_DeviceCode",
table: "IdentityServerDeviceFlowCodes",
column: "DeviceCode",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_IdentityServerDeviceFlowCodes_Expiration",
table: "IdentityServerDeviceFlowCodes",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_IdentityServerDeviceFlowCodes_UserCode",
table: "IdentityServerDeviceFlowCodes",
column: "UserCode");
migrationBuilder.CreateIndex(
name: "IX_IdentityServerPersistedGrants_Expiration",
table: "IdentityServerPersistedGrants",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_IdentityServerPersistedGrants_SubjectId_ClientId_Type",
table: "IdentityServerPersistedGrants",
columns: new[] { "SubjectId", "ClientId", "Type" });
migrationBuilder.CreateIndex(
name: "IX_IdentityServerPersistedGrants_SubjectId_SessionId_Type",
table: "IdentityServerPersistedGrants",
columns: new[] { "SubjectId", "SessionId", "Type" });
}
}
}

5320
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315064423_Add-Javascript-Type.Designer.cs

File diff suppressed because it is too large

31
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315064423_Add-Javascript-Type.cs

@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migrations
{
/// <inheritdoc />
public partial class AddJavascriptType : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "JavaScriptType",
table: "AbpAuthEntityProperties",
type: "varchar(256)",
maxLength: 256,
nullable: false,
defaultValue: "")
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "JavaScriptType",
table: "AbpAuthEntityProperties");
}
}
}

5320
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315084750_Rename-Allow-Properties-To-Accessed-Properties.Designer.cs

File diff suppressed because it is too large

38
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/20250315084750_Rename-Allow-Properties-To-Accessed-Properties.cs

@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.Applications.Single.EntityFrameworkCore.MySql.Migrations
{
/// <inheritdoc />
public partial class RenameAllowPropertiesToAccessedProperties : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "AllowProperties",
table: "AbpAuthRoleEntityRules",
newName: "AccessedProperties");
migrationBuilder.RenameColumn(
name: "AllowProperties",
table: "AbpAuthOrganizationUnitEntityRules",
newName: "AccessedProperties");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.RenameColumn(
name: "AccessedProperties",
table: "AbpAuthRoleEntityRules",
newName: "AllowProperties");
migrationBuilder.RenameColumn(
name: "AccessedProperties",
table: "AbpAuthOrganizationUnitEntityRules",
newName: "AllowProperties");
}
}
}

1373
aspnet-core/migrations/LY.MicroService.Applications.Single.EntityFrameworkCore.MySql/Migrations/SingleMigrationsDbContextModelSnapshot.cs

File diff suppressed because it is too large

4
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/UserProfilePictureProvider.cs

@ -68,7 +68,7 @@ public class UserProfileUserPictureProvider : IUserPictureProvider
(await UserManager.UpdateAsync(user)).CheckErrors(); (await UserManager.UpdateAsync(user)).CheckErrors();
var pictureName = $"{userId}/avatar/{pictureBlobId}"; var pictureName = $"users/{userId}/avatar/{pictureBlobId}";
await AccountBlobContainer.SaveAsync(pictureName, stream, true); await AccountBlobContainer.SaveAsync(pictureName, stream, true);
} }
@ -90,7 +90,7 @@ public class UserProfileUserPictureProvider : IUserPictureProvider
return Stream.Null; return Stream.Null;
} }
var pictureName = $"{user.Id:N}/avatar/{picture}"; var pictureName = $"users/{user.Id:N}/avatar/{picture}";
return await AccountBlobContainer.ExistsAsync(pictureName) return await AccountBlobContainer.ExistsAsync(pictureName)
? await AccountBlobContainer.GetAsync(pictureName) ? await AccountBlobContainer.GetAsync(pictureName)

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Web.IdentityServer/LINGYUN.Abp.Account.Web.IdentityServer.csproj

@ -11,7 +11,9 @@
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace>LINGYUN.Abp.Account.Web.IdentityServer</RootNamespace> <RootNamespace>LINGYUN.Abp.Account.Web.IdentityServer</RootNamespace>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<IsPackable>true</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Web.OpenIddict/LINGYUN.Abp.Account.Web.OpenIddict.csproj

@ -10,8 +10,10 @@
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<RootNamespace>LINGYUN.Abp.Account.Web.OpenIddict</RootNamespace> <RootNamespace>LINGYUN.Abp.Account.Web.OpenIddict</RootNamespace>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<IsPackable>true</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Web/LINGYUN.Abp.Account.Web.csproj

@ -12,8 +12,8 @@
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest> <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<RootNamespace>LINGYUN.Abp.Account.Web</RootNamespace> <RootNamespace>LINGYUN.Abp.Account.Web</RootNamespace>
<IsPackable>true</IsPackable>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<IsPackable>true</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

20
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityEnumInfoDto.cs

@ -0,0 +1,20 @@
using System;
using Volo.Abp.Application.Dtos;
namespace LINGYUN.Abp.DataProtectionManagement;
public class EntityEnumInfoDto : EntityDto<Guid>
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 枚举值
/// </summary>
public string Value { get; set; }
}

9
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityPropertyInfoDto.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
namespace LINGYUN.Abp.DataProtectionManagement; namespace LINGYUN.Abp.DataProtectionManagement;
@ -17,7 +18,11 @@ public class EntityPropertyInfoDto : EntityDto<Guid>
/// </summary> /// </summary>
public string TypeFullName { get; set; } public string TypeFullName { get; set; }
/// <summary> /// <summary>
/// 数据值范围集合(主要针对枚举类型) /// Js类型
/// </summary> /// </summary>
public string[] ValueRange { get; set; } public string JavaScriptType { get; set; }
/// <summary>
/// 枚举列表
/// </summary>
public virtual List<EntityEnumInfoDto> Enums { get; set; } = new List<EntityEnumInfoDto>();
} }

2
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityRuleCreateOrUpdateDto.cs

@ -13,5 +13,5 @@ public abstract class EntityRuleCreateOrUpdateDto
[Required] [Required]
public DataAccessFilterGroup FilterGroup { get; set; } public DataAccessFilterGroup FilterGroup { get; set; }
public string[] AllowProperties { get; set; } public string[] AccessedProperties { get; set; }
} }

2
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application.Contracts/LINGYUN/Abp/DataProtectionManagement/Dto/EntityRuleDtoBase.cs

@ -11,5 +11,5 @@ public abstract class EntityRuleDtoBase : AuditedEntityDto<Guid>
public DataAccessFilterGroup FilterGroup { get; set; } public DataAccessFilterGroup FilterGroup { get; set; }
public Guid EntityTypeId { get; set; } public Guid EntityTypeId { get; set; }
public string EntityTypeFullName { get; set; } public string EntityTypeFullName { get; set; }
public string[] AllowProperties { get; set; } public string[] AccessedProperties { get; set; }
} }

8
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application/LINGYUN/Abp/DataProtectionManagement/DataProtectionManagementApplicationMappingProfile.cs

@ -7,13 +7,13 @@ public class DataProtectionManagementApplicationMappingProfile :Profile
{ {
public DataProtectionManagementApplicationMappingProfile() public DataProtectionManagementApplicationMappingProfile()
{ {
CreateMap<EntityPropertyInfo, EntityPropertyInfoDto>() CreateMap<EntityEnumInfo, EntityEnumInfoDto>();
.ForMember(dto => dto.ValueRange, map => map.MapFrom(src => MapToArray(src.ValueRange))); CreateMap<EntityPropertyInfo, EntityPropertyInfoDto>();
CreateMap<EntityTypeInfo, EntityTypeInfoDto>(); CreateMap<EntityTypeInfo, EntityTypeInfoDto>();
CreateMap<RoleEntityRule, RoleEntityRuleDto>() CreateMap<RoleEntityRule, RoleEntityRuleDto>()
.ForMember(dto => dto.AllowProperties, map => map.MapFrom(src => MapToArray(src.AllowProperties))); .ForMember(dto => dto.AccessedProperties, map => map.MapFrom(src => MapToArray(src.AccessedProperties)));
CreateMap<OrganizationUnitEntityRule, OrganizationUnitEntityRuleDto>() CreateMap<OrganizationUnitEntityRule, OrganizationUnitEntityRuleDto>()
.ForMember(dto => dto.AllowProperties, map => map.MapFrom(src => MapToArray(src.AllowProperties))); .ForMember(dto => dto.AccessedProperties, map => map.MapFrom(src => MapToArray(src.AccessedProperties)));
} }
private string[] MapToArray(string val) private string[] MapToArray(string val)

40
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application/LINGYUN/Abp/DataProtectionManagement/OrganizationUnitEntityRuleAppService.cs

@ -1,15 +1,21 @@
using LINGYUN.Abp.DataProtectionManagement.Permissions; using LINGYUN.Abp.Authorization.Permissions;
using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.DataProtectionManagement.Permissions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.DataProtectionManagement; namespace LINGYUN.Abp.DataProtectionManagement;
[Authorize(DataProtectionManagementPermissionNames.OrganizationUnitEntityRule.Default)] [Authorize(DataProtectionManagementPermissionNames.OrganizationUnitEntityRule.Default)]
public class OrganizationUnitEntityRuleAppService : DataProtectionManagementApplicationServiceBase, IOrganizationUnitEntityRuleAppService public class OrganizationUnitEntityRuleAppService : DataProtectionManagementApplicationServiceBase, IOrganizationUnitEntityRuleAppService
{ {
protected IDistributedEventBus EventBus => LazyServiceProvider.LazyGetRequiredService<IDistributedEventBus>();
private readonly IEntityTypeInfoRepository _entityTypeInfoRepository; private readonly IEntityTypeInfoRepository _entityTypeInfoRepository;
private readonly IOrganizationUnitEntityRuleRepository _organizationUnitEntityRuleRepository; private readonly IOrganizationUnitEntityRuleRepository _organizationUnitEntityRuleRepository;
@ -47,7 +53,7 @@ public class OrganizationUnitEntityRuleAppService : DataProtectionManagementAppl
entityTypeInfo.Id, entityTypeInfo.Id,
entityTypeInfo.TypeFullName, entityTypeInfo.TypeFullName,
input.Operation, input.Operation,
input.AllowProperties?.JoinAsString(","), input.AccessedProperties?.JoinAsString(","),
input.FilterGroup, input.FilterGroup,
CurrentTenant.Id) CurrentTenant.Id)
{ {
@ -56,6 +62,18 @@ public class OrganizationUnitEntityRuleAppService : DataProtectionManagementAppl
entityRule = await _organizationUnitEntityRuleRepository.InsertAsync(entityRule); entityRule = await _organizationUnitEntityRuleRepository.InsertAsync(entityRule);
await EventBus.PublishAsync(
new DataAccessResourceChangeEvent(
new DataAccessResource(
OrganizationUnitPermissionValueProvider.ProviderName,
entityRule.OrgCode,
entityRule.EntityTypeFullName,
entityRule.Operation,
entityRule.FilterGroup)
{
AccessedProperties = input.AccessedProperties.ToList()
}));
await CurrentUnitOfWork.SaveChangesAsync(); await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<OrganizationUnitEntityRule, OrganizationUnitEntityRuleDto>(entityRule); return ObjectMapper.Map<OrganizationUnitEntityRule, OrganizationUnitEntityRuleDto>(entityRule);
@ -73,15 +91,27 @@ public class OrganizationUnitEntityRuleAppService : DataProtectionManagementAppl
{ {
entityRule.Operation = input.Operation; entityRule.Operation = input.Operation;
} }
var allowPropertites = input.AllowProperties?.JoinAsString(","); var allowPropertites = input.AccessedProperties?.JoinAsString(",");
if (!string.Equals(entityRule.AllowProperties, allowPropertites, StringComparison.InvariantCultureIgnoreCase)) if (!string.Equals(entityRule.AccessedProperties, allowPropertites, StringComparison.InvariantCultureIgnoreCase))
{ {
entityRule.AllowProperties = allowPropertites; entityRule.AccessedProperties = allowPropertites;
} }
entityRule.FilterGroup = input.FilterGroup; entityRule.FilterGroup = input.FilterGroup;
entityRule = await _organizationUnitEntityRuleRepository.UpdateAsync(entityRule); entityRule = await _organizationUnitEntityRuleRepository.UpdateAsync(entityRule);
await EventBus.PublishAsync(
new DataAccessResourceChangeEvent(
new DataAccessResource(
OrganizationUnitPermissionValueProvider.ProviderName,
entityRule.OrgCode,
entityRule.EntityTypeFullName,
entityRule.Operation,
entityRule.FilterGroup)
{
AccessedProperties = input.AccessedProperties.ToList()
}));
await CurrentUnitOfWork.SaveChangesAsync(); await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<OrganizationUnitEntityRule, OrganizationUnitEntityRuleDto>(entityRule); return ObjectMapper.Map<OrganizationUnitEntityRule, OrganizationUnitEntityRuleDto>(entityRule);

40
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Application/LINGYUN/Abp/DataProtectionManagement/RoleEntityRuleAppService.cs

@ -1,15 +1,21 @@
using LINGYUN.Abp.DataProtectionManagement.Permissions; using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.DataProtectionManagement.Permissions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.EventBus.Distributed;
namespace LINGYUN.Abp.DataProtectionManagement; namespace LINGYUN.Abp.DataProtectionManagement;
[Authorize(DataProtectionManagementPermissionNames.RoleEntityRule.Default)] [Authorize(DataProtectionManagementPermissionNames.RoleEntityRule.Default)]
public class RoleEntityRuleAppService : DataProtectionManagementApplicationServiceBase, IRoleEntityRuleAppService public class RoleEntityRuleAppService : DataProtectionManagementApplicationServiceBase, IRoleEntityRuleAppService
{ {
protected IDistributedEventBus EventBus => LazyServiceProvider.LazyGetRequiredService<IDistributedEventBus>();
private readonly IEntityTypeInfoRepository _entityTypeInfoRepository; private readonly IEntityTypeInfoRepository _entityTypeInfoRepository;
private readonly IRoleEntityRuleRepository _roleEntityRuleRepository; private readonly IRoleEntityRuleRepository _roleEntityRuleRepository;
@ -47,7 +53,7 @@ public class RoleEntityRuleAppService : DataProtectionManagementApplicationServi
entityTypeInfo.Id, entityTypeInfo.Id,
entityTypeInfo.TypeFullName, entityTypeInfo.TypeFullName,
input.Operation, input.Operation,
input.AllowProperties?.JoinAsString(","), input.AccessedProperties?.JoinAsString(","),
input.FilterGroup, input.FilterGroup,
CurrentTenant.Id) CurrentTenant.Id)
{ {
@ -56,6 +62,18 @@ public class RoleEntityRuleAppService : DataProtectionManagementApplicationServi
entityRule = await _roleEntityRuleRepository.InsertAsync(entityRule); entityRule = await _roleEntityRuleRepository.InsertAsync(entityRule);
await EventBus.PublishAsync(
new DataAccessResourceChangeEvent(
new DataAccessResource(
RolePermissionValueProvider.ProviderName,
entityRule.RoleName,
entityRule.EntityTypeFullName,
entityRule.Operation,
entityRule.FilterGroup)
{
AccessedProperties = input.AccessedProperties?.ToList()
}));
await CurrentUnitOfWork.SaveChangesAsync(); await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<RoleEntityRule, RoleEntityRuleDto>(entityRule); return ObjectMapper.Map<RoleEntityRule, RoleEntityRuleDto>(entityRule);
@ -73,16 +91,28 @@ public class RoleEntityRuleAppService : DataProtectionManagementApplicationServi
{ {
entityRule.Operation = input.Operation; entityRule.Operation = input.Operation;
} }
var allowPropertites = input.AllowProperties?.JoinAsString(","); var allowPropertites = input.AccessedProperties?.JoinAsString(",");
if (!string.Equals(entityRule.AllowProperties, allowPropertites, StringComparison.InvariantCultureIgnoreCase)) if (!string.Equals(entityRule.AccessedProperties, allowPropertites, StringComparison.InvariantCultureIgnoreCase))
{ {
entityRule.AllowProperties = allowPropertites; entityRule.AccessedProperties = allowPropertites;
} }
entityRule.FilterGroup = input.FilterGroup; entityRule.FilterGroup = input.FilterGroup;
entityRule = await _roleEntityRuleRepository.UpdateAsync(entityRule); entityRule = await _roleEntityRuleRepository.UpdateAsync(entityRule);
await EventBus.PublishAsync(
new DataAccessResourceChangeEvent(
new DataAccessResource(
RolePermissionValueProvider.ProviderName,
entityRule.RoleName,
entityRule.EntityTypeFullName,
entityRule.Operation,
entityRule.FilterGroup)
{
AccessedProperties = input.AccessedProperties?.ToList()
}));
await CurrentUnitOfWork.SaveChangesAsync(); await CurrentUnitOfWork.SaveChangesAsync();
return ObjectMapper.Map<RoleEntityRule, RoleEntityRuleDto>(entityRule); return ObjectMapper.Map<RoleEntityRule, RoleEntityRuleDto>(entityRule);

4
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/DataProtectionManagementErrorCodes.cs

@ -15,6 +15,10 @@ public static class DataProtectionManagementErrorCodes
/// 实体类型已经存在名为 {Name} 的属性定义 /// 实体类型已经存在名为 {Name} 的属性定义
/// </summary> /// </summary>
public const string DuplicateProperty = Prefix + "200"; public const string DuplicateProperty = Prefix + "200";
/// <summary>
/// 实体属性已经存在名为 {Name} 的枚举定义
/// </summary>
public const string DuplicateEnum = Prefix + "300";
} }
public static class RoleEntityRule public static class RoleEntityRule

8
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/EntityEnumInfoConsts.cs

@ -0,0 +1,8 @@
namespace LINGYUN.Abp.DataProtectionManagement;
public static class EntityEnumInfoConsts
{
public static int MaxNameLength { get; set; } = EntityTypeInfoConsts.MaxNameLength;
public static int MaxDisplayNameLength { get; set; } = EntityTypeInfoConsts.MaxDisplayNameLength;
public static int MaxValueLength { get; set; } = 10;
}

1
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/EntityRuleBaseEto.cs

@ -13,4 +13,5 @@ public abstract class EntityRuleBaseEto : EntityEto<Guid>, IMultiTenant
public DataAccessOperation Operation { get; set; } public DataAccessOperation Operation { get; set; }
public Guid EntityTypeId { get; set; } public Guid EntityTypeId { get; set; }
public string EntityTypeFullName { get; set; } public string EntityTypeFullName { get; set; }
public DataAccessFilterGroup FilterGroup { get; set; }
} }

2
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain.Shared/LINGYUN/Abp/DataProtectionManagement/EntityRuleConsts.cs

@ -2,5 +2,5 @@
public static class EntityRuleConsts public static class EntityRuleConsts
{ {
public static int MaxEntityTypeFullNameLength { get; set; } = EntityPropertyInfoConsts.MaxTypeFullNameLength; public static int MaxEntityTypeFullNameLength { get; set; } = EntityPropertyInfoConsts.MaxTypeFullNameLength;
public static int MaxAllowPropertiesLength { get; set; } = 512; public static int MaxAccessedPropertiesLength { get; set; } = 512;
} }

5
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/AbpDataProtectionManagementDomainModule.cs

@ -37,11 +37,6 @@ public class AbpDataProtectionManagementDomainModule : AbpModule
options.AutoEventSelectors.Add<OrganizationUnitEntityRule>(); options.AutoEventSelectors.Add<OrganizationUnitEntityRule>();
}); });
Configure<AbpDistributedCacheOptions>(options =>
{
options.ConfigureCache<DataProtectedResourceCacheItem>(new DistributedCacheEntryOptions());
});
context.Services.AddHostedService<ProtectedEntitiesSaverService>(); context.Services.AddHostedService<ProtectedEntitiesSaverService>();
} }
} }

34
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCache.cs

@ -1,4 +1,6 @@
using LINGYUN.Abp.DataProtection; using LINGYUN.Abp.DataProtection;
using Microsoft.Extensions.Caching.Distributed;
using System.Threading.Tasks;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -19,12 +21,25 @@ public class DataProtectedResourceCache : IDataProtectedResourceCache, ITransien
return cacheItem; return cacheItem;
} }
public async virtual Task<DataProtectedResourceCacheItem> GetCacheAsync(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation)
{
var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(subjectName, subjectId, entityTypeFullName, operation);
var cacheItem = await _cache.GetAsync(cacheKey);
return cacheItem;
}
public virtual void RemoveCache(DataAccessResource resource) public virtual void RemoveCache(DataAccessResource resource)
{ {
var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation); var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation);
_cache.Remove(cacheKey); _cache.Remove(cacheKey);
} }
public async Task RemoveCacheAsync(DataAccessResource resource)
{
var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation);
await _cache.RemoveAsync(cacheKey);
}
public virtual void SetCache(DataAccessResource resource) public virtual void SetCache(DataAccessResource resource)
{ {
var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation); var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation);
@ -35,8 +50,23 @@ public class DataProtectedResourceCache : IDataProtectedResourceCache, ITransien
resource.Operation, resource.Operation,
resource.FilterGroup) resource.FilterGroup)
{ {
AllowProperties = resource.AllowProperties, AccessdProperties = resource.AccessedProperties,
};
_cache.Set(cacheKey, cacheItem, new DistributedCacheEntryOptions());
}
public async virtual Task SetCacheAsync(DataAccessResource resource)
{
var cacheKey = DataProtectedResourceCacheItem.CalculateCacheKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation);
var cacheItem = new DataProtectedResourceCacheItem(
resource.SubjectName,
resource.SubjectId,
resource.EntityTypeFullName,
resource.Operation,
resource.FilterGroup)
{
AccessdProperties = resource.AccessedProperties,
}; };
_cache.Set(cacheKey, cacheItem); await _cache.SetAsync(cacheKey, cacheItem, new DistributedCacheEntryOptions());
} }
} }

8
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCacheItem.cs

@ -36,7 +36,11 @@ public class DataProtectedResourceCacheItem
/// <summary> /// <summary>
/// 允许操作的属性列表 /// 允许操作的属性列表
/// </summary> /// </summary>
public List<string> AllowProperties { get; set; } public List<string> AccessdProperties { get; set; }
public DataProtectedResourceCacheItem()
{
}
public DataProtectedResourceCacheItem( public DataProtectedResourceCacheItem(
string subjectName, string subjectName,
@ -50,7 +54,7 @@ public class DataProtectedResourceCacheItem
EntityTypeFullName = entityTypeFullName; EntityTypeFullName = entityTypeFullName;
Operation = operation; Operation = operation;
FilterGroup = filterGroup; FilterGroup = filterGroup;
AllowProperties = new List<string>(); AccessdProperties = new List<string>();
} }
public static string CalculateCacheKey(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation = DataAccessOperation.Read) public static string CalculateCacheKey(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation = DataAccessOperation.Read)

56
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCacheItemInvalidator.cs

@ -1,56 +0,0 @@
using LINGYUN.Abp.Authorization.Permissions;
using LINGYUN.Abp.DataProtection;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.DataProtectionManagement;
public class DataProtectedResourceCacheItemInvalidator :
ILocalEventHandler<EntityChangedEventData<RoleEntityRule>>,
ILocalEventHandler<EntityChangedEventData<OrganizationUnitEntityRule>>,
ITransientDependency
{
private readonly IDataProtectedResourceCache _resourceCache;
public DataProtectedResourceCacheItemInvalidator(IDataProtectedResourceCache resourceCache)
{
_resourceCache = resourceCache;
}
public virtual Task HandleEventAsync(EntityChangedEventData<RoleEntityRule> eventData)
{
var dataResource = new DataAccessResource(
RolePermissionValueProvider.ProviderName,
eventData.Entity.RoleName,
eventData.Entity.EntityTypeFullName,
eventData.Entity.Operation,
eventData.Entity.FilterGroup)
{
AllowProperties = eventData.Entity.AllowProperties?.Split(",").ToList(),
};
_resourceCache.SetCache(dataResource);
return Task.CompletedTask;
}
public virtual Task HandleEventAsync(EntityChangedEventData<OrganizationUnitEntityRule> eventData)
{
var dataResource = new DataAccessResource(
OrganizationUnitPermissionValueProvider.ProviderName,
eventData.Entity.OrgCode,
eventData.Entity.EntityTypeFullName,
eventData.Entity.Operation,
eventData.Entity.FilterGroup)
{
AllowProperties = eventData.Entity.AllowProperties?.Split(",").ToList(),
};
_resourceCache.SetCache(dataResource);
return Task.CompletedTask;
}
}

35
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/DataProtectedResourceCacheStore.cs

@ -1,5 +1,6 @@
using LINGYUN.Abp.DataProtection; using LINGYUN.Abp.DataProtection;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtectionManagement; namespace LINGYUN.Abp.DataProtectionManagement;
@ -15,7 +16,7 @@ public class DataProtectedResourceCacheStore : IDataProtectedResourceStore, ITra
_cache = cache; _cache = cache;
} }
public DataAccessResource Get(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation) public virtual DataAccessResource Get(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation)
{ {
var cacheItem = _cache.GetCache(subjectName, subjectId, entityTypeFullName, operation); var cacheItem = _cache.GetCache(subjectName, subjectId, entityTypeFullName, operation);
if (cacheItem == null) if (cacheItem == null)
@ -29,17 +30,45 @@ public class DataProtectedResourceCacheStore : IDataProtectedResourceStore, ITra
cacheItem.Operation, cacheItem.Operation,
cacheItem.FilterGroup) cacheItem.FilterGroup)
{ {
AllowProperties = cacheItem.AllowProperties, AccessedProperties = cacheItem.AccessdProperties,
}; };
} }
public void Remove(DataAccessResource resource) public async virtual Task<DataAccessResource> GetAsync(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation)
{
var cacheItem = await _cache.GetCacheAsync(subjectName, subjectId, entityTypeFullName, operation);
if (cacheItem == null)
{
return null;
}
return new DataAccessResource(
cacheItem.SubjectName,
cacheItem.SubjectId,
cacheItem.EntityTypeFullName,
cacheItem.Operation,
cacheItem.FilterGroup)
{
AccessedProperties = cacheItem.AccessdProperties,
};
}
public virtual void Remove(DataAccessResource resource)
{ {
_cache.RemoveCache(resource); _cache.RemoveCache(resource);
} }
public async virtual Task RemoveAsync(DataAccessResource resource)
{
await _cache.RemoveCacheAsync(resource);
}
public void Set(DataAccessResource resource) public void Set(DataAccessResource resource)
{ {
_cache.SetCache(resource); _cache.SetCache(resource);
} }
public async virtual Task SetAsync(DataAccessResource resource)
{
await _cache.SetCacheAsync(resource);
}
} }

47
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityEnumInfo.cs

@ -0,0 +1,47 @@
using System;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
namespace LINGYUN.Abp.DataProtectionManagement;
public class EntityEnumInfo : Entity<Guid>
{
/// <summary>
/// 名称
/// </summary>
public virtual string Name { get; protected set; }
/// <summary>
/// 显示名称
/// </summary>
public virtual string DisplayName { get; protected set; }
/// <summary>
/// 枚举值
/// </summary>
public virtual string Value { get; protected set; }
/// <summary>
/// 所属属性
/// </summary>
public virtual EntityPropertyInfo PropertyInfo { get; protected set; }
/// <summary>
/// 所属属性标识
/// </summary>
public virtual Guid PropertyInfoId { get; protected set; }
protected EntityEnumInfo()
{
}
public EntityEnumInfo(
Guid id,
Guid propertyInfoId,
string name,
string displayName,
string value)
: base(id)
{
PropertyInfoId = propertyInfoId;
Name = Check.NotNullOrWhiteSpace(name, nameof(name), EntityEnumInfoConsts.MaxNameLength);
DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), EntityEnumInfoConsts.MaxDisplayNameLength);
Value = Check.NotNullOrWhiteSpace(value, nameof(value), EntityEnumInfoConsts.MaxValueLength);
}
}

58
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityPropertyInfo.cs

@ -1,6 +1,10 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.Guids;
namespace LINGYUN.Abp.DataProtectionManagement; namespace LINGYUN.Abp.DataProtectionManagement;
@ -19,9 +23,9 @@ public class EntityPropertyInfo : Entity<Guid>
/// </summary> /// </summary>
public virtual string TypeFullName { get; protected set; } public virtual string TypeFullName { get; protected set; }
/// <summary> /// <summary>
/// 数据值范围集合(主要针对枚举类型) /// Js类型
/// </summary> /// </summary>
public virtual string ValueRange { get; protected set; } public virtual string JavaScriptType { get; protected set; }
/// <summary> /// <summary>
/// 所属类型 /// 所属类型
/// </summary> /// </summary>
@ -30,9 +34,14 @@ public class EntityPropertyInfo : Entity<Guid>
/// 所属类型标识 /// 所属类型标识
/// </summary> /// </summary>
public virtual Guid TypeInfoId { get; protected set; } public virtual Guid TypeInfoId { get; protected set; }
/// <summary>
/// 枚举列表
/// </summary>
public virtual ICollection<EntityEnumInfo> Enums { get; protected set; }
protected EntityPropertyInfo() protected EntityPropertyInfo()
{ {
Enums = new Collection<EntityEnumInfo>();
} }
public EntityPropertyInfo( public EntityPropertyInfo(
@ -41,13 +50,54 @@ public class EntityPropertyInfo : Entity<Guid>
string name, string name,
string displayName, string displayName,
string typeFullName, string typeFullName,
string valueRange = null) string javaScriptType)
: base(id) : base(id)
{ {
Name = Check.NotNullOrWhiteSpace(name, nameof(name), EntityPropertyInfoConsts.MaxNameLength); Name = Check.NotNullOrWhiteSpace(name, nameof(name), EntityPropertyInfoConsts.MaxNameLength);
DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), EntityPropertyInfoConsts.MaxDisplayNameLength); DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), EntityPropertyInfoConsts.MaxDisplayNameLength);
TypeFullName = Check.NotNullOrWhiteSpace(typeFullName, nameof(typeFullName), EntityPropertyInfoConsts.MaxTypeFullNameLength); TypeFullName = Check.NotNullOrWhiteSpace(typeFullName, nameof(typeFullName), EntityPropertyInfoConsts.MaxTypeFullNameLength);
ValueRange = Check.Length(valueRange, nameof(valueRange), EntityPropertyInfoConsts.MaxValueRangeLength); JavaScriptType = Check.NotNullOrWhiteSpace(javaScriptType, nameof(javaScriptType), EntityPropertyInfoConsts.MaxTypeFullNameLength);
TypeInfoId = typeInfoId; TypeInfoId = typeInfoId;
Enums = new Collection<EntityEnumInfo>();
}
public EntityEnumInfo FindEnum(string name)
{
return Enums.FirstOrDefault(x => x.Name == name);
}
public void RemoveEnum(string name)
{
Enums.RemoveAll(x => x.Name == name);
}
public EntityEnumInfo AddEnum(
IGuidGenerator guidGenerator,
string name,
string displayName,
string value)
{
if (HasExistsEnum(name))
{
throw new BusinessException(DataProtectionManagementErrorCodes.EntityTypeInfo.DuplicateEnum)
.WithData(nameof(EntityEnumInfo.Name), name);
}
var enumInfo = new EntityEnumInfo(
guidGenerator.Create(),
Id,
name,
displayName,
value);
Enums.Add(enumInfo);
return enumInfo;
}
public bool HasExistsEnum(string name)
{
return Enums.Any(x => x.Name == name);
} }
} }

6
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityRuleBase.cs

@ -14,7 +14,7 @@ public abstract class EntityRuleBase : AuditedAggregateRoot<Guid>, IMultiTenant
public virtual Guid EntityTypeId { get; protected set; } public virtual Guid EntityTypeId { get; protected set; }
public virtual string EntityTypeFullName { get; protected set; } public virtual string EntityTypeFullName { get; protected set; }
public virtual EntityTypeInfo EntityTypeInfo { get; protected set; } public virtual EntityTypeInfo EntityTypeInfo { get; protected set; }
public virtual string AllowProperties { get; set; } public virtual string AccessedProperties { get; set; }
protected EntityRuleBase() protected EntityRuleBase()
{ {
} }
@ -24,7 +24,7 @@ public abstract class EntityRuleBase : AuditedAggregateRoot<Guid>, IMultiTenant
Guid entityTypeId, Guid entityTypeId,
string enetityTypeFullName, string enetityTypeFullName,
DataAccessOperation operation, DataAccessOperation operation,
string allowProperties = null, string accessedProperties = null,
DataAccessFilterGroup filterGroup = null, DataAccessFilterGroup filterGroup = null,
Guid? tenantId = null) Guid? tenantId = null)
: base(id) : base(id)
@ -35,7 +35,7 @@ public abstract class EntityRuleBase : AuditedAggregateRoot<Guid>, IMultiTenant
EntityTypeId = entityTypeId; EntityTypeId = entityTypeId;
EntityTypeFullName = Check.NotNullOrWhiteSpace(enetityTypeFullName, nameof(enetityTypeFullName), EntityRuleConsts.MaxEntityTypeFullNameLength); EntityTypeFullName = Check.NotNullOrWhiteSpace(enetityTypeFullName, nameof(enetityTypeFullName), EntityRuleConsts.MaxEntityTypeFullNameLength);
AllowProperties = Check.Length(allowProperties, nameof(allowProperties), EntityRuleConsts.MaxAllowPropertiesLength); AccessedProperties = Check.Length(accessedProperties, nameof(accessedProperties), EntityRuleConsts.MaxAccessedPropertiesLength);
} }

4
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/EntityTypeInfo.cs

@ -64,7 +64,7 @@ public class EntityTypeInfo : AuditedAggregateRoot<Guid>
string name, string name,
string displayName, string displayName,
string typeFullName, string typeFullName,
string valueRange = null) string javaScriptType)
{ {
if (HasExistsProperty(name)) if (HasExistsProperty(name))
{ {
@ -78,7 +78,7 @@ public class EntityTypeInfo : AuditedAggregateRoot<Guid>
name, name,
displayName, displayName,
typeFullName, typeFullName,
valueRange); javaScriptType);
Properties.Add(propertyInfo); Properties.Add(propertyInfo);

20
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/IDataProtectedResourceCache.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.DataProtection; using LINGYUN.Abp.DataProtection;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtectionManagement; namespace LINGYUN.Abp.DataProtectionManagement;
public interface IDataProtectedResourceCache public interface IDataProtectedResourceCache
@ -9,11 +10,21 @@ public interface IDataProtectedResourceCache
/// <param name="item">要更新的数据权限缓存项</param> /// <param name="item">要更新的数据权限缓存项</param>
void SetCache(DataAccessResource resource); void SetCache(DataAccessResource resource);
/// <summary> /// <summary>
/// 设置指定数据权限的缓存
/// </summary>
/// <param name="item">要更新的数据权限缓存项</param>
Task SetCacheAsync(DataAccessResource resource);
/// <summary>
/// 移除指定主体与实体类型的缓存项 /// 移除指定主体与实体类型的缓存项
/// </summary> /// </summary>
/// <param name="item">要移除的数据权限缓存项信息</param> /// <param name="item">要移除的数据权限缓存项信息</param>
void RemoveCache(DataAccessResource resource); void RemoveCache(DataAccessResource resource);
/// <summary> /// <summary>
/// 移除指定主体与实体类型的缓存项
/// </summary>
/// <param name="item">要移除的数据权限缓存项信息</param>
Task RemoveCacheAsync(DataAccessResource resource);
/// <summary>
/// 获取指定主体与实体类型的数据权限过滤规则 /// 获取指定主体与实体类型的数据权限过滤规则
/// </summary> /// </summary>
/// <param name="subjectName">权限主体</param> /// <param name="subjectName">权限主体</param>
@ -22,4 +33,13 @@ public interface IDataProtectedResourceCache
/// <param name="operation">数据权限操作</param> /// <param name="operation">数据权限操作</param>
/// <returns>数据过滤条件组</returns> /// <returns>数据过滤条件组</returns>
DataProtectedResourceCacheItem GetCache(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation); DataProtectedResourceCacheItem GetCache(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation);
/// <summary>
/// 获取指定主体与实体类型的数据权限过滤规则
/// </summary>
/// <param name="subjectName">权限主体</param>
/// <param name="subjectId">权限主体标识</param>
/// <param name="entityTypeFullName">实体类型名称</param>
/// <param name="operation">数据权限操作</param>
/// <returns>数据过滤条件组</returns>
Task<DataProtectedResourceCacheItem> GetCacheAsync(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation);
} }

102
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.Domain/LINGYUN/Abp/DataProtectionManagement/ProtectedEntitiesSaver.cs

@ -24,6 +24,7 @@ public class ProtectedEntitiesSaver : IProtectedEntitiesSaver, ITransientDepende
protected DataProtectionManagementOptions ManagementOptions { get; } protected DataProtectionManagementOptions ManagementOptions { get; }
protected IGuidGenerator GuidGenerator { get; } protected IGuidGenerator GuidGenerator { get; }
protected IAbpDistributedLock DistributedLock { get; } protected IAbpDistributedLock DistributedLock { get; }
protected IJavaScriptTypeConvert JavaScriptTypeConvert { get; }
protected IEntityTypeInfoRepository EntityTypeInfoRepository { get; } protected IEntityTypeInfoRepository EntityTypeInfoRepository { get; }
protected ILocalizableStringSerializer LocalizableStringSerializer { get; } protected ILocalizableStringSerializer LocalizableStringSerializer { get; }
@ -33,7 +34,8 @@ public class ProtectedEntitiesSaver : IProtectedEntitiesSaver, ITransientDepende
IOptions<AbpDataProtectionOptions> options, IOptions<AbpDataProtectionOptions> options,
IOptions<DataProtectionManagementOptions> managementOptions, IOptions<DataProtectionManagementOptions> managementOptions,
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
IAbpDistributedLock distributedLock, IAbpDistributedLock distributedLock,
IJavaScriptTypeConvert javaScriptTypeConvert,
IEntityTypeInfoRepository entityTypeInfoRepository, IEntityTypeInfoRepository entityTypeInfoRepository,
ILocalizableStringSerializer localizableStringSerializer) ILocalizableStringSerializer localizableStringSerializer)
{ {
@ -43,6 +45,7 @@ public class ProtectedEntitiesSaver : IProtectedEntitiesSaver, ITransientDepende
ManagementOptions = managementOptions.Value; ManagementOptions = managementOptions.Value;
GuidGenerator = guidGenerator; GuidGenerator = guidGenerator;
DistributedLock = distributedLock; DistributedLock = distributedLock;
JavaScriptTypeConvert = javaScriptTypeConvert;
EntityTypeInfoRepository = entityTypeInfoRepository; EntityTypeInfoRepository = entityTypeInfoRepository;
LocalizableStringSerializer = localizableStringSerializer; LocalizableStringSerializer = localizableStringSerializer;
} }
@ -81,7 +84,8 @@ public class ProtectedEntitiesSaver : IProtectedEntitiesSaver, ITransientDepende
var typeDisplayName = entityType.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName; var typeDisplayName = entityType.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;
if (typeDisplayName.IsNullOrWhiteSpace()) if (typeDisplayName.IsNullOrWhiteSpace())
{ {
var typeDisplayNameString = LocalizableString.Create($"DisplayName:{entityType.Name}", resourceName); // 类型多语言表现形式为:LocalizationResource.TypeName
var typeDisplayNameString = LocalizableString.Create(entityType.Name, resourceName);
typeDisplayName = LocalizableStringSerializer.Serialize(typeDisplayNameString); typeDisplayName = LocalizableStringSerializer.Serialize(typeDisplayNameString);
} }
var isDataAudited = entityType.GetCustomAttribute<DisableDataProtectedAttribute>() == null; var isDataAudited = entityType.GetCustomAttribute<DisableDataProtectedAttribute>() == null;
@ -92,39 +96,65 @@ public class ProtectedEntitiesSaver : IProtectedEntitiesSaver, ITransientDepende
entityType.FullName, entityType.FullName,
isDataAudited); isDataAudited);
var globalIgnoreProperties = Options.GlobalIgnoreProperties.Except(Options.AuditedObjectProperties);
var typeProperties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty) var typeProperties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty)
.Where(x => !Options.IgnoreAuditedProperties.Contains(x.Name)); .Where(x => !globalIgnoreProperties.Contains(x.Name));
foreach (var typeProperty in typeProperties) foreach (var typeProperty in typeProperties)
{ {
var propDisplayName = typeProperty.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName; var propDisplayName = typeProperty.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;
if (propDisplayName.IsNullOrWhiteSpace()) if (propDisplayName.IsNullOrWhiteSpace())
{ {
var propDisplayNameString = LocalizableString.Create($"DisplayName:{entityType.Name}", resourceName); // 属性多语言表现形式为:LocalizationResource.DisplayName:PropertyName
var propDisplayNameString = LocalizableString.Create($"DisplayName:{typeProperty.Name}", resourceName);
propDisplayName = LocalizableStringSerializer.Serialize(propDisplayNameString); propDisplayName = LocalizableStringSerializer.Serialize(propDisplayNameString);
} }
var propTypeFullName = typeProperty.PropertyType.FullName;
string valueRange = null; var javaScriptTypeResult = JavaScriptTypeConvert.Convert(typeProperty.PropertyType);
if (typeProperty.PropertyType.IsEnum)
{ var propertyInfo = entityTypeInfo.AddProperty(
propTypeFullName = typeof(int).FullName;
var enumType = typeProperty.PropertyType;
var enumValues = enumType.GetEnumValues().Cast<int>();
valueRange = enumValues.JoinAsString(",");
}
entityTypeInfo.AddProperty(
GuidGenerator, GuidGenerator,
typeProperty.Name, typeProperty.Name,
propDisplayName ?? typeProperty.Name, propDisplayName ?? typeProperty.Name,
typeProperty.PropertyType.FullName, typeProperty.PropertyType.FullName,
valueRange); javaScriptTypeResult.Type);
if (typeProperty.PropertyType.IsEnum)
{
var enumType = typeProperty.PropertyType;
var enumNames = enumType.GetEnumNames();
var enumValues = enumType.GetEnumValues().Cast<int>().ToArray();
for (var index = 0; index < enumNames.Length; index++)
{
var enumName = enumNames[index];
var enumValue = enumValues[index];
var localizerEnumKey = $"{propertyInfo.Name}:{enumName}";
// 枚举多语言表现形式为:LocalizationResource.EnumName:EnumValue
var enumDisplayNameString = LocalizableString.Create($"{enumType.Name}:{enumName}", resourceName);
var enumDisplayName = LocalizableStringSerializer.Serialize(enumDisplayNameString);
propertyInfo.AddEnum(
GuidGenerator,
enumName,
enumDisplayName,
enumValue.ToString());
}
}
} }
newRecords.Add(entityTypeInfo); newRecords.Add(entityTypeInfo);
} }
else else
{ {
var hasChanged = false; var hasChanged = false;
var globalIgnoreProperties = Options.GlobalIgnoreProperties.Except(Options.AuditedObjectProperties);
var typeProperties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty) var typeProperties = entityType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty)
.Where(x => !Options.IgnoreAuditedProperties.Contains(x.Name)); .Where(x => !globalIgnoreProperties.Contains(x.Name));
entityTypeInfo.Properties.RemoveAll(x => !typeProperties.Any(p => p.Name == x.Name)); entityTypeInfo.Properties.RemoveAll(x => !typeProperties.Any(p => p.Name == x.Name));
foreach (var typeProperty in typeProperties) foreach (var typeProperty in typeProperties)
{ {
@ -134,24 +164,42 @@ public class ProtectedEntitiesSaver : IProtectedEntitiesSaver, ITransientDepende
var propDisplayName = typeProperty.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName; var propDisplayName = typeProperty.GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;
if (propDisplayName.IsNullOrWhiteSpace()) if (propDisplayName.IsNullOrWhiteSpace())
{ {
// 属性多语言表现形式为:LocalizationResource.DisplayName:PropertyName
var propDisplayNameString = LocalizableString.Create($"DisplayName:{typeProperty.Name}", resourceName); var propDisplayNameString = LocalizableString.Create($"DisplayName:{typeProperty.Name}", resourceName);
propDisplayName = LocalizableStringSerializer.Serialize(propDisplayNameString); propDisplayName = LocalizableStringSerializer.Serialize(propDisplayNameString);
} }
var propTypeFullName = typeProperty.PropertyType.FullName; var javaScriptTypeResult = JavaScriptTypeConvert.Convert(typeProperty.PropertyType);
string valueRange = null; var propertyInfo = entityTypeInfo.AddProperty(
GuidGenerator,
typeProperty.Name,
propDisplayName ?? typeProperty.Name,
typeProperty.PropertyType.FullName,
javaScriptTypeResult.Type);
if (typeProperty.PropertyType.IsEnum) if (typeProperty.PropertyType.IsEnum)
{ {
propTypeFullName = typeof(int).FullName;
var enumType = typeProperty.PropertyType; var enumType = typeProperty.PropertyType;
var enumValues = enumType.GetEnumValues().Cast<int>();
valueRange = enumValues.JoinAsString(","); var enumNames = enumType.GetEnumNames();
var enumValues = enumType.GetEnumValues().Cast<int>().ToArray();
for (var index = 0; index < enumNames.Length; index++)
{
var enumName = enumNames[index];
var enumValue = enumValues[index];
var localizerEnumKey = $"{propertyInfo.Name}:{enumName}";
// 枚举多语言表现形式为:LocalizationResource.EnumName:EnumValue
var enumDisplayNameString = LocalizableString.Create($"{enumType.Name}:{enumName}", resourceName);
var enumDisplayName = LocalizableStringSerializer.Serialize(enumDisplayNameString);
propertyInfo.AddEnum(
GuidGenerator,
enumName,
enumDisplayName,
enumValue.ToString());
}
} }
entityTypeInfo.AddProperty(
GuidGenerator,
typeProperty.Name,
propDisplayName ?? typeProperty.Name,
typeProperty.PropertyType.FullName,
valueRange);
} }
} }
if (hasChanged) if (hasChanged)

47
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore/LINGYUN/Abp/DataProtectionManagement/EntityFrameworkCore/AbpDataProtectionManagementDbContextModelCreatingExtensions.cs

@ -64,16 +64,43 @@ namespace LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore
.HasColumnName(nameof(EntityPropertyInfo.TypeFullName)) .HasColumnName(nameof(EntityPropertyInfo.TypeFullName))
.HasMaxLength(EntityPropertyInfoConsts.MaxTypeFullNameLength) .HasMaxLength(EntityPropertyInfoConsts.MaxTypeFullNameLength)
.IsRequired(); .IsRequired();
b.Property(p => p.JavaScriptType)
.HasColumnName(nameof(EntityPropertyInfo.JavaScriptType))
.HasMaxLength(EntityPropertyInfoConsts.MaxTypeFullNameLength)
.IsRequired();
b.ConfigureByConvention(); b.HasMany(p => p.Enums)
.WithOne(p => p.PropertyInfo)
.HasForeignKey(f => f.PropertyInfoId)
.IsRequired();
b.Property(p => p.ValueRange) b.ConfigureByConvention();
.HasColumnName(nameof(EntityPropertyInfo.ValueRange))
.HasMaxLength(EntityPropertyInfoConsts.MaxValueRangeLength);
b.HasIndex(p => new { p.TypeInfoId, p.TypeFullName }); b.HasIndex(p => new { p.TypeInfoId, p.TypeFullName });
}); });
builder.Entity<EntityEnumInfo>(b =>
{
b.ToTable(options.TablePrefix + "EntityEnums", options.Schema);
b.Property(p => p.Name)
.HasColumnName(nameof(EntityEnumInfo.Name))
.HasMaxLength(EntityEnumInfoConsts.MaxNameLength)
.IsRequired();
b.Property(p => p.DisplayName)
.HasColumnName(nameof(EntityEnumInfo.DisplayName))
.HasMaxLength(EntityEnumInfoConsts.MaxDisplayNameLength)
.IsRequired();
b.Property(p => p.Value)
.HasColumnName(nameof(EntityEnumInfo.Value))
.HasMaxLength(EntityEnumInfoConsts.MaxValueLength)
.IsRequired();
b.ConfigureByConvention();
b.HasIndex(p => new { p.PropertyInfoId, p.Name });
});
builder.Entity<RoleEntityRule>(b => builder.Entity<RoleEntityRule>(b =>
{ {
b.ToTable(options.TablePrefix + "RoleEntityRules", options.Schema); b.ToTable(options.TablePrefix + "RoleEntityRules", options.Schema);
@ -82,9 +109,9 @@ namespace LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore
.HasColumnName(nameof(RoleEntityRule.RoleName)) .HasColumnName(nameof(RoleEntityRule.RoleName))
.HasMaxLength(RoleEntityRuleConsts.MaxRuletNameLength) .HasMaxLength(RoleEntityRuleConsts.MaxRuletNameLength)
.IsRequired(); .IsRequired();
b.Property(p => p.AllowProperties) b.Property(p => p.AccessedProperties)
.HasColumnName(nameof(RoleEntityRule.AllowProperties)) .HasColumnName(nameof(RoleEntityRule.AccessedProperties))
.HasMaxLength(EntityRuleConsts.MaxAllowPropertiesLength); .HasMaxLength(EntityRuleConsts.MaxAccessedPropertiesLength);
b.Property(p => p.FilterGroup) b.Property(p => p.FilterGroup)
.HasColumnName(nameof(RoleEntityRule.FilterGroup)) .HasColumnName(nameof(RoleEntityRule.FilterGroup))
@ -106,9 +133,9 @@ namespace LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore
.HasColumnName(nameof(OrganizationUnitEntityRule.OrgCode)) .HasColumnName(nameof(OrganizationUnitEntityRule.OrgCode))
.HasMaxLength(OrganizationUnitEntityRuleConsts.MaxCodeLength) .HasMaxLength(OrganizationUnitEntityRuleConsts.MaxCodeLength)
.IsRequired(); .IsRequired();
b.Property(p => p.AllowProperties) b.Property(p => p.AccessedProperties)
.HasColumnName(nameof(RoleEntityRule.AllowProperties)) .HasColumnName(nameof(RoleEntityRule.AccessedProperties))
.HasMaxLength(EntityRuleConsts.MaxAllowPropertiesLength); .HasMaxLength(EntityRuleConsts.MaxAccessedPropertiesLength);
b.Property(p => p.FilterGroup) b.Property(p => p.FilterGroup)
.HasColumnName(nameof(RoleEntityRule.FilterGroup)) .HasColumnName(nameof(RoleEntityRule.FilterGroup))

4
aspnet-core/modules/data-protection/LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore/LINGYUN/Abp/DataProtectionManagement/EntityFrameworkCore/EfCoreEntityTypeInfoRepository.cs

@ -52,6 +52,8 @@ public class EfCoreEntityTypeInfoRepository : EfCoreRepository<IAbpDataProtectio
public async override Task<IQueryable<EntityTypeInfo>> WithDetailsAsync() public async override Task<IQueryable<EntityTypeInfo>> WithDetailsAsync()
{ {
return (await base.WithDetailsAsync()).Include(x => x.Properties); return (await base.WithDetailsAsync())
.Include(x => x.Properties)
.ThenInclude(x => x.Enums);
} }
} }

1
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN.Abp.Demo.Application.Contracts.csproj

@ -20,6 +20,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\framework\data-protection\LINGYUN.Abp.DataProtection.Abstractions\LINGYUN.Abp.DataProtection.Abstractions.csproj" />
<ProjectReference Include="..\..\..\framework\exporter\LINGYUN.Abp.Exporter.Application.Contracts\LINGYUN.Abp.Exporter.Application.Contracts.csproj" /> <ProjectReference Include="..\..\..\framework\exporter\LINGYUN.Abp.Exporter.Application.Contracts\LINGYUN.Abp.Exporter.Application.Contracts.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Demo.Domain.Shared\LINGYUN.Abp.Demo.Domain.Shared.csproj" /> <ProjectReference Include="..\LINGYUN.Abp.Demo.Domain.Shared\LINGYUN.Abp.Demo.Domain.Shared.csproj" />
</ItemGroup> </ItemGroup>

4
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/AbpDemoApplicationContractsModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Exporter; using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.Exporter;
using Volo.Abp.Application; using Volo.Abp.Application;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
@ -6,6 +7,7 @@ using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Demo; namespace LINGYUN.Abp.Demo;
[DependsOn( [DependsOn(
typeof(AbpDataProtectionAbstractionsModule),
typeof(AbpExporterApplicationContractsModule), typeof(AbpExporterApplicationContractsModule),
typeof(AbpAuthorizationAbstractionsModule), typeof(AbpAuthorizationAbstractionsModule),
typeof(AbpDddApplicationContractsModule), typeof(AbpDddApplicationContractsModule),

9
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application.Contracts/LINGYUN/Abp/Demo/Books/IBookAppService.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Exporter; using LINGYUN.Abp.DataProtection.Models;
using LINGYUN.Abp.Exporter;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
@ -15,4 +16,10 @@ public interface IBookAppService :
IImporterAppService<BookImportInput> IImporterAppService<BookImportInput>
{ {
Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync(); Task<ListResultDto<AuthorLookupDto>> GetAuthorLookupAsync();
/// <summary>
/// 获取实体可访问规则
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<EntityTypeInfoModel> GetEntityRuleAsync(EntityTypeInfoGetModel input);
} }

4
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/AbpDemoApplicationModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Exporter; using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.Exporter;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application; using Volo.Abp.Application;
using Volo.Abp.AutoMapper; using Volo.Abp.AutoMapper;
@ -8,6 +9,7 @@ namespace LINGYUN.Abp.Demo;
[DependsOn( [DependsOn(
typeof(AbpDddApplicationModule), typeof(AbpDddApplicationModule),
typeof(AbpDataProtectionModule),
typeof(AbpDemoDomainModule), typeof(AbpDemoDomainModule),
typeof(AbpExporterApplicationModule), typeof(AbpExporterApplicationModule),
typeof(AbpDemoApplicationContractsModule))] typeof(AbpDemoApplicationContractsModule))]

38
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Application/LINGYUN/Abp/Demo/Books/BookAppService.cs

@ -1,4 +1,7 @@
using LINGYUN.Abp.Demo.Authors; using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.DataProtection.Models;
using LINGYUN.Abp.Demo.Authors;
using LINGYUN.Abp.Demo.Localization;
using LINGYUN.Abp.Demo.Permissions; using LINGYUN.Abp.Demo.Permissions;
using LINGYUN.Abp.Exporter; using LINGYUN.Abp.Exporter;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -7,6 +10,7 @@ using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Content; using Volo.Abp.Content;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Demo.Books; namespace LINGYUN.Abp.Demo.Books;
@ -26,6 +30,8 @@ public class BookAppService :
private readonly IExporterProvider _exporterProvider; private readonly IExporterProvider _exporterProvider;
private readonly IImporterProvider _importerProvider; private readonly IImporterProvider _importerProvider;
protected IDataAccessEntityTypeInfoProvider EntityTypeInfoProvider => LazyServiceProvider.LazyGetRequiredService<IDataAccessEntityTypeInfoProvider>();
public BookAppService( public BookAppService(
IExporterProvider exporterProvider, IExporterProvider exporterProvider,
IImporterProvider importerProvider, IImporterProvider importerProvider,
@ -38,13 +44,29 @@ public class BookAppService :
_importerProvider = importerProvider; _importerProvider = importerProvider;
_authorManager = authorManager; _authorManager = authorManager;
_authorRepository = authorRepository; _authorRepository = authorRepository;
GetPolicyName = DemoPermissions.Books.Default; GetPolicyName = DemoPermissions.Books.Default;
GetListPolicyName = DemoPermissions.Books.Default; GetListPolicyName = DemoPermissions.Books.Default;
CreatePolicyName = DemoPermissions.Books.Create; CreatePolicyName = DemoPermissions.Books.Create;
UpdatePolicyName = DemoPermissions.Books.Edit; UpdatePolicyName = DemoPermissions.Books.Edit;
DeletePolicyName = DemoPermissions.Books.Delete; DeletePolicyName = DemoPermissions.Books.Delete;
LocalizationResource = typeof(DemoResource);
ObjectMapperContext = typeof(AbpDemoApplicationModule);
} }
[DisableDataProtected(DataAccessOperation.Read)]// 更新时禁用查询过滤
public override Task<BookDto> UpdateAsync(Guid id, CreateUpdateBookDto input)
{
return base.UpdateAsync(id, input);
}
[DisableDataProtected(DataAccessOperation.Read)]
public override Task DeleteAsync(Guid id)
{
return base.DeleteAsync(id);
}
public async virtual Task ImportAsync(BookImportInput input) public async virtual Task ImportAsync(BookImportInput input)
{ {
await CheckCreatePolicyAsync(); await CheckCreatePolicyAsync();
@ -203,4 +225,18 @@ public class BookAppService :
return $"book.{sorting}"; return $"book.{sorting}";
} }
public async virtual Task<EntityTypeInfoModel> GetEntityRuleAsync(EntityTypeInfoGetModel input)
{
var entityType = typeof(Book);
var resourceType = LocalizationResource ?? typeof(DefaultResource);
var context = new DataAccessEntitTypeInfoContext(
entityType,
resourceType,
input.Operation,
LazyServiceProvider);
return await EntityTypeInfoProvider.GetEntitTypeInfoAsync(context);
}
} }

11
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain.Shared/LINGYUN/Abp/Demo/Localization/Resources/en.json

@ -12,6 +12,15 @@
"Permission:Authors.Create": "Create Authors", "Permission:Authors.Create": "Create Authors",
"Permission:Authors.Edit": "Edit Authors", "Permission:Authors.Edit": "Edit Authors",
"Permission:Authors.Delete": "Delete Authors", "Permission:Authors.Delete": "Delete Authors",
"Demo:00001": "Author {Name} already exists!" "Demo:00001": "Author {Name} already exists!",
"Author": "Authors",
"Book": "Books",
"DisplayName:Name": "Name",
"DisplayName:Type": "Type",
"DisplayName:PublishDate": "Publish Date",
"DisplayName:Price": "Price",
"DisplayName:AuthorId": "Author Id",
"DisplayName:BirthDate": "Birth Date",
"DisplayName:ShortBio": "Short Bio"
} }
} }

11
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain.Shared/LINGYUN/Abp/Demo/Localization/Resources/zh-Hans.json

@ -12,6 +12,15 @@
"Permission:Authors.Create": "新增作者", "Permission:Authors.Create": "新增作者",
"Permission:Authors.Edit": "编辑作者", "Permission:Authors.Edit": "编辑作者",
"Permission:Authors.Delete": "删除作者", "Permission:Authors.Delete": "删除作者",
"Demo:00001": "作者 {Name} 已经存在!" "Demo:00001": "作者 {Name} 已经存在!",
"Author": "作者",
"Book": "书籍",
"DisplayName:Name": "名称",
"DisplayName:Type": "类型",
"DisplayName:PublishDate": "出版日期",
"DisplayName:Price": "单价",
"DisplayName:AuthorId": "作者",
"DisplayName:BirthDate": "生日",
"DisplayName:ShortBio": "简介"
} }
} }

19
aspnet-core/modules/demo/LINGYUN.Abp.Demo.Domain/LINGYUN/Abp/Demo/AbpDemoDomainModule.cs

@ -1,7 +1,11 @@
using LINGYUN.Abp.DataProtection; using LINGYUN.Abp.DataProtection;
using LINGYUN.Abp.DataProtection.Localization;
using LINGYUN.Abp.Demo.Books;
using LINGYUN.Abp.Demo.Localization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AutoMapper; using Volo.Abp.AutoMapper;
using Volo.Abp.Domain; using Volo.Abp.Domain;
using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Demo; namespace LINGYUN.Abp.Demo;
@ -22,10 +26,11 @@ public class AbpDemoDomainModule : AbpModule
options.AddProfile<DemoDomainMapperProfile>(validate: true); options.AddProfile<DemoDomainMapperProfile>(validate: true);
}); });
//Configure<AbpLocalizationPersistenceOptions>(options => Configure<AbpLocalizationOptions>(options =>
//{ {
// options.AddPersistenceResource<DemoResource>(); options.Resources.Get<DemoResource>()
//}); .AddBaseTypes(typeof(DataProtectionResource));
});
// 分布式事件 // 分布式事件
//Configure<AbpDistributedEntityEventOptions>(options => //Configure<AbpDistributedEntityEventOptions>(options =>
@ -33,5 +38,11 @@ public class AbpDemoDomainModule : AbpModule
// options.AutoEventSelectors.Add<Text>(); // options.AutoEventSelectors.Add<Text>();
// options.EtoMappings.Add<Text, TextEto>(); // options.EtoMappings.Add<Text, TextEto>();
//}); //});
Configure<AbpDataProtectionOptions>(options =>
{
// 外键属性不可设定规则
options.EntityIgnoreProperties.Add(typeof(Book), new []{ nameof(Book.AuthorId) } );
});
} }
} }

9
aspnet-core/modules/demo/LINGYUN.Abp.Demo.EntityFrameworkCore/LINGYUN/Abp/Demo/Books/EfCoreBookRepository.cs

@ -8,10 +8,11 @@ namespace LINGYUN.Abp.Demo.Books;
public class EfCoreBookRepository : EfCoreDataProtectionRepository<DemoDbContext, Book, Guid>, IBookRepository public class EfCoreBookRepository : EfCoreDataProtectionRepository<DemoDbContext, Book, Guid>, IBookRepository
{ {
public EfCoreBookRepository( public EfCoreBookRepository(
[NotNull] IDbContextProvider<DemoDbContext> dbContextProvider, [NotNull] IDbContextProvider<DemoDbContext> dbContextProvider,
[NotNull] IDataAuthorizationService dataAuthorizationService, [NotNull] IDataAuthorizationService dataAuthorizationService,
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder) [NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder,
: base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder) [NotNull] IEntityPropertyResultBuilder entityPropertyResultBuilder)
: base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder, entityPropertyResultBuilder)
{ {
} }
} }

10
aspnet-core/modules/demo/LINGYUN.Abp.Demo.HttpApi/LINGYUN/Abp/Demo/Books/BookController.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Demo.Permissions; using LINGYUN.Abp.DataProtection.Models;
using LINGYUN.Abp.Demo.Permissions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp; using Volo.Abp;
@ -78,4 +79,11 @@ public class BookController : AbpControllerBase, IBookAppService
{ {
return _service.UpdateAsync(id, input); return _service.UpdateAsync(id, input);
} }
[HttpGet]
[Route("entity")]
public virtual Task<EntityTypeInfoModel> GetEntityRuleAsync(EntityTypeInfoGetModel input)
{
return _service.GetEntityRuleAsync(input);
}
} }

12
aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Aliyun/LINGYUN/Abp/OssManagement/Aliyun/AbpOssManagementAliyunModule.cs

@ -1,6 +1,4 @@
using LINGYUN.Abp.BlobStoring.Aliyun; using LINGYUN.Abp.BlobStoring.Aliyun;
using Microsoft.Extensions.DependencyInjection;
using System;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.OssManagement.Aliyun; namespace LINGYUN.Abp.OssManagement.Aliyun;
@ -10,14 +8,4 @@ namespace LINGYUN.Abp.OssManagement.Aliyun;
typeof(AbpOssManagementDomainModule))] typeof(AbpOssManagementDomainModule))]
public class AbpOssManagementAliyunModule : AbpModule public class AbpOssManagementAliyunModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<IOssContainerFactory, AliyunOssContainerFactory>();
context.Services.AddTransient<IOssObjectExpireor>(provider =>
provider
.GetRequiredService<IOssContainerFactory>()
.Create()
.As<AliyunOssContainer>());
}
} }

21
aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Aliyun/Microsoft/Extensions/DependencyInjection/AliyunOssContainerServiceCollectionExtensions.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.OssManagement;
using LINGYUN.Abp.OssManagement.Aliyun;
using System;
namespace Microsoft.Extensions.DependencyInjection;
public static class AliyunOssContainerServiceCollectionExtensions
{
public static IServiceCollection AddMinioContainer(this IServiceCollection services)
{
services.AddTransient<IOssContainerFactory, AliyunOssContainerFactory>();
services.AddTransient<IOssObjectExpireor>(provider =>
provider
.GetRequiredService<IOssContainerFactory>()
.Create()
.As<AliyunOssContainer>());
return services;
}
}

14
aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.FileSystem/LINGYUN/Abp/OssManagement/FileSystem/AbpOssManagementFileSystemModule.cs

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection; using Volo.Abp.BlobStoring.FileSystem;
using System;
using Volo.Abp.BlobStoring.FileSystem;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.OssManagement.FileSystem; namespace LINGYUN.Abp.OssManagement.FileSystem;
@ -10,14 +8,4 @@ namespace LINGYUN.Abp.OssManagement.FileSystem;
typeof(AbpOssManagementDomainModule))] typeof(AbpOssManagementDomainModule))]
public class AbpOssManagementFileSystemModule : AbpModule public class AbpOssManagementFileSystemModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<IOssContainerFactory, FileSystemOssContainerFactory>();
context.Services.AddTransient<IOssObjectExpireor>(provider =>
provider
.GetRequiredService<IOssContainerFactory>()
.Create()
.As<FileSystemOssContainer>());
}
} }

21
aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.FileSystem/Microsoft/Extensions/DependencyInjection/FileSystemOssContainerServiceCollectionExtensions.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.OssManagement;
using LINGYUN.Abp.OssManagement.FileSystem;
using System;
namespace Microsoft.Extensions.DependencyInjection;
public static class FileSystemOssContainerServiceCollectionExtensions
{
public static IServiceCollection AddFileSystemContainer(this IServiceCollection services)
{
services.AddTransient<IOssContainerFactory, FileSystemOssContainerFactory>();
services.AddTransient<IOssObjectExpireor>(provider =>
provider
.GetRequiredService<IOssContainerFactory>()
.Create()
.As<FileSystemOssContainer>());
return services;
}
}

14
aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Minio/LINGYUN/Abp/OssManagement/Minio/AbpOssManagementMinioModule.cs

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection; using Volo.Abp.BlobStoring.Minio;
using System;
using Volo.Abp.BlobStoring.Minio;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.OssManagement.Minio; namespace LINGYUN.Abp.OssManagement.Minio;
@ -10,14 +8,4 @@ namespace LINGYUN.Abp.OssManagement.Minio;
typeof(AbpOssManagementDomainModule))] typeof(AbpOssManagementDomainModule))]
public class AbpOssManagementMinioModule : AbpModule public class AbpOssManagementMinioModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTransient<IOssContainerFactory, MinioOssContainerFactory>();
context.Services.AddTransient<IOssObjectExpireor>(provider =>
provider
.GetRequiredService<IOssContainerFactory>()
.Create()
.As<MinioOssContainer>());
}
} }

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save