Browse Source

Merge pull request #946 from colinin/data-protection

Data protection
pull/955/head
yx lin 2 years ago
committed by GitHub
parent
commit
4c3440b739
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .github/workflows/publish.yml
  2. 4
      .github/workflows/release.yml
  3. 6
      Directory.Packages.props
  4. 10
      NuGet.Config
  5. 59
      aspnet-core/LINGYUN.MicroService.All.sln
  6. 27
      aspnet-core/LINGYUN.MicroService.TaskManagement.sln
  7. 7
      aspnet-core/NuGet.Config
  8. 2
      aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN/Abp/Authorization/OrganizationUnits/AbpOrganizationUnitClaimTypes.cs
  9. 17
      aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/System/Security/Principal/AbpClaimOrganizationUnitsExtensions.cs
  10. 17
      aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/Volo/Abp/Users/CurrentUserOrganizationUnitsExtensions.cs
  11. 3
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xml
  12. 30
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xsd
  13. 15
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN.Abp.DataProtection.Abstractions.csproj
  14. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/AbpDataProtectionAbstractionsModule.cs
  15. 39
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterGroup.cs
  16. 19
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterLogic.cs
  17. 69
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterOperate.cs
  18. 37
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterRule.cs
  19. 15
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessKeywords.cs
  20. 24
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessOperation.cs
  21. 58
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessResource.cs
  22. 17
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataProtectedAttribute.cs
  23. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DisableDataProtectedAttribute.cs
  24. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtected.cs
  25. 4
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/IDataProtectedEnabled.cs
  26. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/DataProtectionResource.cs
  27. 64
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedReadEntityInterceptor.cs
  28. 66
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWriteEntityInterceptor.cs
  29. 52
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWritePropertiesInterceptor.cs
  30. 160
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContext.cs
  31. 16
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContextModelBuilderExtensions.cs
  32. 13
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionEntityFrameworkCoreModule.cs
  33. 18
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionModelBuilderConfigurationOptions.cs
  34. 358
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionAsyncQueryableProvider.cs
  35. 86
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionQueryExpressionInterceptor.cs
  36. 41
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionSaveChangesInterceptor.cs
  37. 156
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/EfCoreDataProtectionRepository.cs
  38. 19
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/ProtectedEntityHelper.cs
  39. 104
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/README.md
  40. 1
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN.Abp.DataProtection.csproj
  41. 41
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/AbpDataProtectionModule.cs
  42. 55
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/AbpDataProtectionOptions.cs
  43. 30
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessCacheItem.cs
  44. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessEntityRule.cs
  45. 11
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessExpressionRule.cs
  46. 19
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessFiledRule.cs
  47. 11
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessKeywordContributorContext.cs
  48. 7
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessOperation.cs
  49. 34
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessOwner.cs
  50. 23
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessRole.cs
  51. 54
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessRule.cs
  52. 11
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessRuleInfo.cs
  53. 18
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessSubjectContributorContext.cs
  54. 31
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAuthorizationService.cs
  55. 48
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataProtectedInterceptor.cs
  56. 35
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataProtectedInterceptorRegistrar.cs
  57. 141
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/EntityPropertyResultBuilder.cs
  58. 326
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/EntityTypeFilterBuilder.cs
  59. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessCache.cs
  60. 6
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessKeywordContributor.cs
  61. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessOperateContributor.cs
  62. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessSubjectContributor.cs
  63. 19
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAuthorizationService.cs
  64. 20
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAuthorizationServiceExtensions.cs
  65. 9
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataProtectedResourceStore.cs
  66. 8
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataProtectionRepository.cs
  67. 24
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IEntityPropertyResultBuilder.cs
  68. 20
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IEntityTypeFilterBuilder.cs
  69. 5
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IHasDataAccess.cs
  70. 37
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/InMemoryDataProtectedResourceStore.cs
  71. 15
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Keywords/DataAccessCurrentUserContributor.cs
  72. 33
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessContainsContributor.cs
  73. 20
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessEndsWithContributor.cs
  74. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessEqualContributor.cs
  75. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessGreaterContributor.cs
  76. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessGreaterOrEqualContributor.cs
  77. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessLessContributor.cs
  78. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessLessOrEqualContributor.cs
  79. 37
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessNotContainsContributor.cs
  80. 12
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessNotEqualContributor.cs
  81. 20
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessStartsWithContributor.cs
  82. 52
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessOrganizationUnitContributor.cs
  83. 52
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessRoleNameContributor.cs
  84. 44
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Subjects/DataAccessUserIdContributor.cs
  85. 73
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Linq/Expressions/ExpressionFuncExtender.cs
  86. 30
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Linq/Expressions/ExpressionFuncExtensions.cs
  87. 28
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Linq/Expressions/ParameterRebinder.cs
  88. 16
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Reflection/NullableTypeExtensions.cs
  89. 28
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/TypeExtensions.cs
  90. 24
      aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/Volo/Abp/Uow/IUnitOfWorkDataAccessExtensions.cs
  91. 5
      aspnet-core/framework/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/LanguageAppService.cs
  92. 4
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/BackendAdminMigrationsDbContext.cs
  93. 2
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/BackendAdminMigrationsEntityFrameworkCoreModule.cs
  94. 1
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/LY.MicroService.BackendAdmin.EntityFrameworkCore.csproj
  95. 932
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515073346_Add-Data-Protected-Module.Designer.cs
  96. 179
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515073346_Add-Data-Protected-Module.cs
  97. 942
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515092715_Add-Allow-Properties.Designer.cs
  98. 42
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515092715_Add-Allow-Properties.cs
  99. 289
      aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/BackendAdminMigrationsDbContextModelSnapshot.cs
  100. 49
      aspnet-core/migrations/LY.MicroService.Platform.EntityFrameworkCore/PlatformDbMigrationEventHandler.cs

2
.github/workflows/publish.yml

@ -2,7 +2,7 @@ name: "Publish"
on: on:
push: push:
branches: [ rel-8.1.0 ] branches: [ rel-8.1.1 ]
env: env:
DOTNET_VERSION: "8.0.200" DOTNET_VERSION: "8.0.200"

4
.github/workflows/release.yml

@ -2,7 +2,7 @@ name: "Tagged Release"
on: on:
push: push:
branches: [ rel-8.1.0 ] branches: [ rel-8.1.1 ]
jobs: jobs:
tagged-release: tagged-release:
@ -14,4 +14,4 @@ jobs:
with: with:
repo_token: "${{ secrets.GITHUB_TOKEN }}" repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: false prerelease: false
automatic_release_tag: "8.1.0" automatic_release_tag: "8.1.1"

6
Directory.Packages.props

@ -1,8 +1,8 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<DotNetCoreCAPPackageVersion>8.1.0</DotNetCoreCAPPackageVersion> <DotNetCoreCAPPackageVersion>8.1.1</DotNetCoreCAPPackageVersion>
<ElsaPackageVersion>2.14.1</ElsaPackageVersion> <ElsaPackageVersion>2.14.1</ElsaPackageVersion>
<VoloAbpPackageVersion>8.1.0</VoloAbpPackageVersion> <VoloAbpPackageVersion>8.1.1</VoloAbpPackageVersion>
<MicrosoftExtensionsPackageVersion>8.0.0</MicrosoftExtensionsPackageVersion> <MicrosoftExtensionsPackageVersion>8.0.0</MicrosoftExtensionsPackageVersion>
<MicrosoftAspNetCorePackageVersion>8.0.0</MicrosoftAspNetCorePackageVersion> <MicrosoftAspNetCorePackageVersion>8.0.0</MicrosoftAspNetCorePackageVersion>
<MicrosoftEntityFrameworkCorePackageVersion>8.0.0</MicrosoftEntityFrameworkCorePackageVersion> <MicrosoftEntityFrameworkCorePackageVersion>8.0.0</MicrosoftEntityFrameworkCorePackageVersion>
@ -229,7 +229,7 @@
<PackageVersion Include="Hangfire.MySqlStorage" Version="2.0.3" /> <PackageVersion Include="Hangfire.MySqlStorage" Version="2.0.3" />
<PackageVersion Include="HangFire.SqlServer" Version="1.8.6" /> <PackageVersion Include="HangFire.SqlServer" Version="1.8.6" />
<PackageVersion Include="IdentityModel" Version="6.2.0" /> <PackageVersion Include="IdentityModel" Version="6.2.0" />
<PackageVersion Include="JetBrains.Annotations" Version="2022.1.0" /> <PackageVersion Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageVersion Include="Markdig" Version="0.34.0" /> <PackageVersion Include="Markdig" Version="0.34.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="NEST" Version="7.15.1" /> <PackageVersion Include="NEST" Version="7.15.1" />

10
NuGet.Config

@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<packageSources> <packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="local" value="./aspnet-core/LocalNuget" />
</packageSources> </packageSources>
<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="local">
<package pattern="LINGYUN.*" />
</packageSource>
</packageSourceMapping>
</configuration> </configuration>

59
aspnet-core/LINGYUN.MicroService.All.sln

@ -718,6 +718,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TaskManagement.
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TaskManagement.HttpApi.Client", "modules\task-management\LINGYUN.Abp.TaskManagement.HttpApi.Client\LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj", "{72D54834-7ADF-4B18-A745-FCBBC255073B}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TaskManagement.HttpApi.Client", "modules\task-management\LINGYUN.Abp.TaskManagement.HttpApi.Client\LINGYUN.Abp.TaskManagement.HttpApi.Client.csproj", "{72D54834-7ADF-4B18-A745-FCBBC255073B}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data-protection", "data-protection", "{F6A9D966-0022-440B-AE27-564A74CDED48}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtectionManagement.Domain.Shared", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Domain.Shared\LINGYUN.Abp.DataProtectionManagement.Domain.Shared.csproj", "{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtectionManagement.Domain", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Domain\LINGYUN.Abp.DataProtectionManagement.Domain.csproj", "{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore\LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore.csproj", "{D73200F6-CBB3-4BA8-B9BF-7110AAF05596}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Wrapper", "framework\common\LINGYUN.Abp.AspNetCore.Wrapper\LINGYUN.Abp.AspNetCore.Wrapper.csproj", "{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtectionManagement.Application.Contracts", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Application.Contracts\LINGYUN.Abp.DataProtectionManagement.Application.Contracts.csproj", "{40D7A0A3-68BD-431E-A67A-E2A35508D55D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtectionManagement.Application", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.Application\LINGYUN.Abp.DataProtectionManagement.Application.csproj", "{8EA8C998-F81A-46E9-8C7E-C944D2503A0A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtection.Abstractions", "framework\data-protection\LINGYUN.Abp.DataProtection.Abstractions\LINGYUN.Abp.DataProtection.Abstractions.csproj", "{47550AB9-FA06-42D6-A4B8-7DD12FE66563}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.DataProtectionManagement.HttpApi", "modules\data-protection\LINGYUN.Abp.DataProtectionManagement.HttpApi\LINGYUN.Abp.DataProtectionManagement.HttpApi.csproj", "{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -1824,6 +1842,38 @@ Global
{72D54834-7ADF-4B18-A745-FCBBC255073B}.Debug|Any CPU.Build.0 = Debug|Any CPU {72D54834-7ADF-4B18-A745-FCBBC255073B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72D54834-7ADF-4B18-A745-FCBBC255073B}.Release|Any CPU.ActiveCfg = Release|Any CPU {72D54834-7ADF-4B18-A745-FCBBC255073B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72D54834-7ADF-4B18-A745-FCBBC255073B}.Release|Any CPU.Build.0 = Release|Any CPU {72D54834-7ADF-4B18-A745-FCBBC255073B}.Release|Any CPU.Build.0 = Release|Any CPU
{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3}.Release|Any CPU.Build.0 = Release|Any CPU
{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918}.Release|Any CPU.Build.0 = Release|Any CPU
{D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D73200F6-CBB3-4BA8-B9BF-7110AAF05596}.Release|Any CPU.Build.0 = Release|Any CPU
{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C}.Release|Any CPU.Build.0 = Release|Any CPU
{40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40D7A0A3-68BD-431E-A67A-E2A35508D55D}.Release|Any CPU.Build.0 = Release|Any CPU
{8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8EA8C998-F81A-46E9-8C7E-C944D2503A0A}.Release|Any CPU.Build.0 = Release|Any CPU
{47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47550AB9-FA06-42D6-A4B8-7DD12FE66563}.Release|Any CPU.Build.0 = Release|Any CPU
{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -2170,6 +2220,15 @@ Global
{1E00BE51-A1AE-447D-B6E0-F28EC12B259A} = {77ED7922-BF30-4436-8A85-78F812583913} {1E00BE51-A1AE-447D-B6E0-F28EC12B259A} = {77ED7922-BF30-4436-8A85-78F812583913}
{61F0EEB2-5ED0-4809-8EF9-0676C7A680CE} = {77ED7922-BF30-4436-8A85-78F812583913} {61F0EEB2-5ED0-4809-8EF9-0676C7A680CE} = {77ED7922-BF30-4436-8A85-78F812583913}
{72D54834-7ADF-4B18-A745-FCBBC255073B} = {77ED7922-BF30-4436-8A85-78F812583913} {72D54834-7ADF-4B18-A745-FCBBC255073B} = {77ED7922-BF30-4436-8A85-78F812583913}
{F6A9D966-0022-440B-AE27-564A74CDED48} = {D52D5A11-78EF-4154-8298-267738A6715B}
{8C99C96A-AE0C-489B-A1A0-AD8442A3B6A3} = {F6A9D966-0022-440B-AE27-564A74CDED48}
{6C0DB8F2-FB0A-4922-B8FE-177DCF37A918} = {F6A9D966-0022-440B-AE27-564A74CDED48}
{D73200F6-CBB3-4BA8-B9BF-7110AAF05596} = {F6A9D966-0022-440B-AE27-564A74CDED48}
{30FB6AD7-3CC5-4A8D-B170-BDA772E6BA3C} = {848F6760-9B11-4C9A-9843-9D71DD66D9DA}
{40D7A0A3-68BD-431E-A67A-E2A35508D55D} = {F6A9D966-0022-440B-AE27-564A74CDED48}
{8EA8C998-F81A-46E9-8C7E-C944D2503A0A} = {F6A9D966-0022-440B-AE27-564A74CDED48}
{47550AB9-FA06-42D6-A4B8-7DD12FE66563} = {529DF802-97C4-4BF2-BE7C-39663B3D9EA3}
{835E51CE-1E6B-4C8C-9736-8C5B61F5E08E} = {F6A9D966-0022-440B-AE27-564A74CDED48}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

27
aspnet-core/LINGYUN.MicroService.TaskManagement.sln

@ -24,6 +24,12 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C99728F6-FB3C-4D26-8917-1D30725209B9}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C99728F6-FB3C-4D26-8917-1D30725209B9}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig .editorconfig = .editorconfig
..\common.props = ..\common.props
..\common.secrets.props = ..\common.secrets.props
..\configureawait.props = ..\configureawait.props
..\Directory.Build.props = ..\Directory.Build.props
..\Directory.Packages.props = ..\Directory.Packages.props
..\NuGet.Config = ..\NuGet.Config
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "provider", "provider", "{385578CC-C0F1-4377-A7A2-682B8F416234}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "provider", "provider", "{385578CC-C0F1-4377-A7A2-682B8F416234}"
@ -144,6 +150,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.A
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.HttpApi.Client", "modules\oss-management\LINGYUN.Abp.OssManagement.HttpApi.Client\LINGYUN.Abp.OssManagement.HttpApi.Client.csproj", "{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OssManagement.HttpApi.Client", "modules\oss-management\LINGYUN.Abp.OssManagement.HttpApi.Client\LINGYUN.Abp.OssManagement.HttpApi.Client.csproj", "{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks.Tests", "tests\LINGYUN.Abp.BackgroundTasks.Tests\LINGYUN.Abp.BackgroundTasks.Tests.csproj", "{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TestsBase", "tests\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj", "{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Activities.Tests", "tests\LINGYUN.Abp.BackgroundTasks.Activities.Tests\LINGYUN.Abp.BackgroundTasks.Activities.Tests.csproj", "{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -374,6 +386,18 @@ Global
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Debug|Any CPU.Build.0 = Debug|Any CPU {44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Release|Any CPU.ActiveCfg = Release|Any CPU {44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Release|Any CPU.Build.0 = Release|Any CPU {44778F3C-7610-4F1C-A2B6-DF8925B1CBE0}.Release|Any CPU.Build.0 = Release|Any CPU
{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C}.Release|Any CPU.Build.0 = Release|Any CPU
{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5}.Release|Any CPU.Build.0 = Release|Any CPU
{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -435,6 +459,9 @@ Global
{94D1C512-09E4-4A68-8989-6DB49FEABA67} = {F36E71F7-B05F-4513-A923-81E2A7474EAE} {94D1C512-09E4-4A68-8989-6DB49FEABA67} = {F36E71F7-B05F-4513-A923-81E2A7474EAE}
{96B4D255-BB21-4BAF-902A-ADE3F25A44C2} = {F36E71F7-B05F-4513-A923-81E2A7474EAE} {96B4D255-BB21-4BAF-902A-ADE3F25A44C2} = {F36E71F7-B05F-4513-A923-81E2A7474EAE}
{44778F3C-7610-4F1C-A2B6-DF8925B1CBE0} = {F36E71F7-B05F-4513-A923-81E2A7474EAE} {44778F3C-7610-4F1C-A2B6-DF8925B1CBE0} = {F36E71F7-B05F-4513-A923-81E2A7474EAE}
{A8EFC95D-6700-4840-A7FD-1F5BF4D0C71C} = {77341F31-F54C-436A-AF8D-F78D91303C45}
{6CC06BD8-FA30-45E0-BD3A-25FF39906EF5} = {77341F31-F54C-436A-AF8D-F78D91303C45}
{3EBB4CA4-82C2-41C6-94C5-CB0D4D2B6D07} = {77341F31-F54C-436A-AF8D-F78D91303C45}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293} SolutionGuid = {E1FD1F4C-D344-408B-97CF-B6F1F6D7D293}

7
aspnet-core/NuGet.Config

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<packageSources> <packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<!--<add key="LocalNuget" value="./LocalNuget" />--> </packageSources>
</packageSources>
</configuration> </configuration>

2
aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN/Abp/Authorization/OrganizationUnits/AbpOrganizationUnitClaimTypes.cs

@ -2,5 +2,5 @@
public static class AbpOrganizationUnitClaimTypes public static class AbpOrganizationUnitClaimTypes
{ {
public static string OrganizationUnit { get; set; } = "organization_unit"; public static string OrganizationUnit { get; set; } = "ou_code";
} }

17
aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/System/Security/Principal/AbpClaimOrganizationUnitsExtensions.cs

@ -1,6 +1,5 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using LINGYUN.Abp.Authorization.OrganizationUnits; using LINGYUN.Abp.Authorization.OrganizationUnits;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using Volo.Abp; using Volo.Abp;
@ -9,26 +8,16 @@ namespace System.Security.Principal;
public static class AbpClaimOrganizationUnitsExtensions public static class AbpClaimOrganizationUnitsExtensions
{ {
public static Guid[] FindOrganizationUnits([NotNull] this ClaimsPrincipal principal) public static string[] FindOrganizationUnits([NotNull] this ClaimsPrincipal principal)
{ {
Check.NotNull(principal, nameof(principal)); Check.NotNull(principal, nameof(principal));
var userOusOrNull = principal.Claims?.Where(c => c.Type == AbpOrganizationUnitClaimTypes.OrganizationUnit); var userOusOrNull = principal.Claims?.Where(c => c.Type == AbpOrganizationUnitClaimTypes.OrganizationUnit);
if (userOusOrNull == null || !userOusOrNull.Any()) if (userOusOrNull == null || !userOusOrNull.Any())
{ {
return new Guid[0]; return new string[0];
} }
var userOus = new List<Guid>(); return userOusOrNull.Select(x => x.Value).ToArray();
foreach (var userOusClaim in userOusOrNull)
{
if (Guid.TryParse(userOusClaim.Value, out var guid))
{
userOus.Add(guid);
}
}
return userOus.ToArray();
} }
} }

17
aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/Volo/Abp/Users/CurrentUserOrganizationUnitsExtensions.cs

@ -2,29 +2,20 @@
using LINGYUN.Abp.Authorization.OrganizationUnits; using LINGYUN.Abp.Authorization.OrganizationUnits;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Volo.Abp.Users; namespace Volo.Abp.Users;
public static class CurrentUserOrganizationUnitsExtensions public static class CurrentUserOrganizationUnitsExtensions
{ {
public static Guid[] FindOrganizationUnits([NotNull] this ICurrentUser currentUser) public static string[] FindOrganizationUnits([NotNull] this ICurrentUser currentUser)
{ {
var organizationUnits = currentUser.FindClaims(AbpOrganizationUnitClaimTypes.OrganizationUnit); var organizationUnits = currentUser.FindClaims(AbpOrganizationUnitClaimTypes.OrganizationUnit);
if (organizationUnits.IsNullOrEmpty()) if (organizationUnits.IsNullOrEmpty())
{ {
return new Guid[0]; return new string[0];
} }
var userOus = new List<Guid>(); return organizationUnits.Select(x => x.Value).ToArray();
foreach (var userOusClaim in organizationUnits)
{
if (Guid.TryParse(userOusClaim.Value, out var guid))
{
userOus.Add(guid);
}
}
return userOus.ToArray();
} }
} }

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

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

30
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

15
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN.Abp.DataProtection.Abstractions.csproj

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.ObjectExtending" />
</ItemGroup>
</Project>

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

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

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

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace LINGYUN.Abp.DataProtection;
[Serializable]
public class DataAccessFilterGroup
{
public List<DataAccessFilterGroup> Groups { get; set; }
public List<DataAccessFilterRule> Rules { get; set; }
public DataAccessFilterLogic Logic { get; set; }
public DataAccessFilterGroup() : this(DataAccessFilterLogic.And)
{
}
public DataAccessFilterGroup(DataAccessFilterLogic logic = DataAccessFilterLogic.And)
{
Logic = logic;
Rules = new List<DataAccessFilterRule>();
Groups = new List<DataAccessFilterGroup>();
}
public DataAccessFilterGroup AddRule(DataAccessFilterRule rule)
{
if (Rules.All(m => !m.Equals(rule)))
{
Rules.Add(rule);
}
return this;
}
public DataAccessFilterGroup AddRule(string field, object value, DataAccessFilterOperate operate = DataAccessFilterOperate.Equal)
{
return AddRule(new DataAccessFilterRule(field, value, operate));
}
}

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

@ -0,0 +1,19 @@
using System.ComponentModel;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据过滤连接方式
/// </summary>
public enum DataAccessFilterLogic
{
/// <summary>
/// 且
/// </summary>
[Description("且")]
And,
/// <summary>
/// 或
/// </summary>
[Description("或")]
Or
}

69
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessFilterOperate.cs

@ -0,0 +1,69 @@
using System.ComponentModel;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据过滤操作
/// </summary>
public enum DataAccessFilterOperate
{
/// <summary>
/// 且
/// </summary>
[Description("且")]
And = 1,
/// <summary>
/// 或
/// </summary>
[Description("或")]
Or = 2,
/// <summary>
/// 等于
/// </summary>
[Description("等于")]
Equal = 3,
/// <summary>
/// 不等于
/// </summary>
[Description("不等于")]
NotEqual = 4,
/// <summary>
/// 小于
/// </summary>
[Description("小于")]
Less = 5,
/// <summary>
/// 小于或等于
/// </summary>
[Description("小于等于")]
LessOrEqual = 6,
/// <summary>
/// 大于
/// </summary>
[Description("大于")]
Greater = 7,
/// <summary>
/// 大于或等于
/// </summary>
[Description("大于等于")]
GreaterOrEqual = 8,
/// <summary>
/// 左包含
/// </summary>
[Description("左包含")]
StartsWith = 9,
/// <summary>
/// 右包含
/// </summary>
[Description("右包含")]
EndsWith = 10,
/// <summary>
/// 包含
/// </summary>
[Description("包含")]
Contains = 11,
/// <summary>
/// 不包含
/// </summary>
[Description("不包含")]
NotContains = 12,
}

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

@ -0,0 +1,37 @@
using System;
namespace LINGYUN.Abp.DataProtection;
[Serializable]
public class DataAccessFilterRule
{
/// <summary>
/// 字段名称
/// </summary>
public string Field { get; set; }
/// <summary>
/// 字段值
/// </summary>
public object Value { get; set; }
/// <summary>
/// 操作类型
/// </summary>
public DataAccessFilterOperate Operate { get; set; }
/// <summary>
/// 左侧条件
/// </summary>
public bool IsLeft { get; set; }
public DataAccessFilterRule()
{
}
public DataAccessFilterRule(string field, object value, DataAccessFilterOperate operate = DataAccessFilterOperate.Equal, bool isLeft = false)
{
Field = field;
Value = value;
Operate = operate;
IsLeft = isLeft;
}
}

15
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessKeywords.cs

@ -0,0 +1,15 @@
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 系统保留关键字列表
/// </summary>
public static class DataAccessKeywords
{
/// <summary>
/// 授权角色
/// </summary>
public const string AUTH_ROLES = "AR";
/// <summary>
/// 授权组织机构
/// </summary>
public const string AUTH_ORGS = "AO";
}

24
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataAccessOperation.cs

@ -0,0 +1,24 @@
using System.ComponentModel;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据操作
/// </summary>
public enum DataAccessOperation
{
/// <summary>
/// 查询
/// </summary>
[Description("查询")]
Read,
/// <summary>
/// 更新
/// </summary>
[Description("更新")]
Write,
/// <summary>
/// 删除
/// </summary>
[Description("删除")]
Delete
}

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

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
namespace LINGYUN.Abp.DataProtection;
[Serializable]
public class DataAccessResource
{
/// <summary>
/// 权限主体
/// </summary>
public string SubjectName { get; set; }
/// <summary>
/// 权限主体标识
/// </summary>
public string SubjectId { get; set; }
/// <summary>
/// 实体类型全名
/// </summary>
public string EntityTypeFullName { get; set; }
/// <summary>
/// 数据权限操作
/// </summary>
public DataAccessOperation Operation { get; set; }
/// <summary>
/// 获取或设置 数据过滤规则
/// </summary>
public DataAccessFilterGroup FilterGroup { get; set; }
/// <summary>
/// 允许操作的属性列表
/// </summary>
public List<string> AllowProperties { get; set; }
public DataAccessResource()
{
}
public DataAccessResource(
string subjectName,
string subjectId,
string entityTypeFullName,
DataAccessOperation operation,
DataAccessFilterGroup filterGroup = null)
{
SubjectName = subjectName;
SubjectId = subjectId;
EntityTypeFullName = entityTypeFullName;
Operation = operation;
FilterGroup = filterGroup;
AllowProperties = new List<string>();
}
}

17
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/DataProtectedAttribute.cs

@ -0,0 +1,17 @@
using System;
namespace LINGYUN.Abp.DataProtection;
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DataProtectedAttribute : Attribute
{
public DataAccessOperation Operation { get; }
public DataProtectedAttribute() : this(DataAccessOperation.Read)
{
}
public DataProtectedAttribute(DataAccessOperation operation)
{
Operation = operation;
}
}

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

@ -0,0 +1,8 @@
using System;
namespace LINGYUN.Abp.DataProtection;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false)]
public class DisableDataProtectedAttribute : Attribute
{
}

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

@ -0,0 +1,8 @@
using Volo.Abp.Data;
namespace LINGYUN.Abp.DataProtection;
public interface IDataProtected : IHasExtraProperties
{
}

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

@ -0,0 +1,4 @@
namespace LINGYUN.Abp.DataProtection;
public interface IDataProtectedEnabled
{
}

8
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.Abstractions/LINGYUN/Abp/DataProtection/Localization/DataProtectionResource.cs

@ -0,0 +1,8 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.DataProtection.Localization;
[LocalizationResourceName("DataProtection")]
public class DataProtectionResource
{
}

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

@ -0,0 +1,64 @@
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);
}
}
}

66
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectedWriteEntityInterceptor.cs

@ -0,0 +1,66 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Authorization;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
public class AbpDataProtectedWriteEntityInterceptor : SaveChangesInterceptor, 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 IDataAuthorizationService DataAuthorizationService => LazyServiceProvider.LazyGetRequiredService<IDataAuthorizationService>();
public async override ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
{
if (DataFilter.IsEnabled<IDataProtected>() && eventData.Context != null)
{
var updateEntites = eventData.Context.ChangeTracker.Entries()
.Where(entry => entry.State.IsIn(EntityState.Modified) && (entry.Entity is not ISoftDelete || entry.Entity is ISoftDelete delete && delete.IsDeleted == false))
.Select(entry => entry.Entity as IEntity);
if (updateEntites.Any())
{
var updateGrant = await DataAuthorizationService.AuthorizeAsync(DataAccessOperation.Write, updateEntites);
if (!updateGrant.Succeeded)
{
var entityKeys = updateEntites
.Select(entity => (entity is IEntity abpEntity ? abpEntity.GetKeys() : new string[1] { entity.ToString() }).ToString())
.JoinAsString(";");
throw new AbpAuthorizationException(
$"Delete data permission not granted to entity {updateEntites.First().GetType()} for data {entityKeys}!");
}
}
var deleteEntites = eventData.Context.ChangeTracker.Entries()
.Where(entry => entry.State.IsIn(EntityState.Deleted) || entry.Entity is ISoftDelete delete && delete.IsDeleted == true)
.Select(entry => entry.Entity as IEntity);
if (deleteEntites.Any())
{
var deleteGrant = await DataAuthorizationService.AuthorizeAsync(DataAccessOperation.Delete, deleteEntites);
if (!deleteGrant.Succeeded)
{
var entityKeys = deleteEntites
.Select(entity => (entity is IEntity abpEntity ? abpEntity.GetKeys() : new string[1] { entity.ToString() }).ToString())
.JoinAsString(";");
throw new AbpAuthorizationException(
$"Delete data permission not granted to entity {deleteEntites.First().GetType()} for data {entityKeys}!");
}
}
}
return await base.SavingChangesAsync(eventData, result, cancellationToken);
}
}

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

@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
public class AbpDataProtectedWritePropertiesInterceptor : SaveChangesInterceptor, 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 async override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
if (DataFilter.IsEnabled<IDataProtected>() && eventData.Context != null)
{
foreach (var entry in eventData.Context.ChangeTracker.Entries().ToList())
{
if (entry.State.IsIn(EntityState.Modified))
{
var allowProperties = new List<string>();
var entity = entry.Entity;
var subjectContext = new DataAccessSubjectContributorContext(entity.GetType().FullName, DataAccessOperation.Write, LazyServiceProvider);
foreach (var contributor in DataProtectionOptions.Value.SubjectContributors)
{
var properties = contributor.GetAllowProperties(subjectContext);
allowProperties.AddIfNotContains(properties);
}
allowProperties.AddIfNotContains(DataProtectionOptions.Value.IgnoreAuditedProperties);
foreach (var property in entry.Properties)
{
if (!allowProperties.Contains(property.Metadata.Name))
{
property.IsModified = false;
}
}
}
}
}
return await base.SavingChangesAsync(eventData, result, cancellationToken);
}
}

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

@ -1,145 +1,55 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking;
using System; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using Volo.Abp.Data;
using System.Reflection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
using Volo.Abp.Users; using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
{
public class AbpDataProtectionDbContext : AbpDbContext<AbpDataProtectionDbContext>
{
protected ICurrentUser CurrentUser => LazyServiceProvider.LazyGetService<ICurrentUser>();
protected virtual bool IsDataAccessFilterEnabled => DataFilter?.IsEnabled<IHasDataAccess>() ?? false;
public AbpDataProtectionDbContext(
DbContextOptions<AbpDataProtectionDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (typeof(IHasDataAccess).IsAssignableFrom(entityType.ClrType))
{
modelBuilder.Entity(entityType.ClrType)
.OwnsOne(entityType.ClrType.FullName, nameof(IHasDataAccess.Owner), ownedNavigationBuilder =>
{
ownedNavigationBuilder.ToJson();
});
}
}
}
protected override void ApplyAbpConceptsForAddedEntity(EntityEntry entry)
{
base.ApplyAbpConceptsForAddedEntity(entry);
if (CurrentUser.IsAuthenticated)
{
if (entry is IHasDataAccess entity)
{
ProtectedEntityHelper.TrySetOwner(
entity,
() => new DataAccessOwner(
CurrentUser.Id,
CurrentUser.Roles,
CurrentUser.FindOrganizationUnits().Select(ou => ou.ToString()).ToArray()));
}
}
}
protected virtual DataAccessRuleInfo AccessRuleInfo => UnitOfWorkManager.Current.GetAccessRuleInfo(); public abstract class AbpDataProtectionDbContext<TDbContext> : AbpDbContext<TDbContext>
where TDbContext : DbContext
protected override void HandlePropertiesBeforeSave() {
{ public IOptions<AbpDataProtectionOptions> DataProtectionOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDataProtectionOptions>>();
foreach (var item in ChangeTracker.Entries().ToList()) public ICurrentUser CurrentUser => LazyServiceProvider.LazyGetRequiredService<ICurrentUser>();
{
HandleExtraPropertiesOnSave(item);
HandleCheckPropertiesOnSave(item);
if (item.State.IsIn(EntityState.Modified, EntityState.Deleted))
{
UpdateConcurrencyStamp(item);
}
}
}
protected virtual void HandleCheckPropertiesOnSave(EntityEntry entry) public AbpDataProtectionDbContext(
{ DbContextOptions<TDbContext> options) : base(options)
// 仅当启用过滤器时检查 {
if (IsDataAccessFilterEnabled) }
{
var entityAccessRules = AccessRuleInfo?.Rules.Where(r => r.EntityTypeFullName == entry.Metadata.ClrType.FullName);
if (entityAccessRules != null)
{
if (entry.State.IsIn(EntityState.Modified, EntityState.Added, EntityState.Deleted))
{
var entityAccessRule = entityAccessRules.FirstOrDefault(r => r.Operation.IsIn(DataAccessOperation.Write, DataAccessOperation.Delete));
if (entityAccessRule != null)
{
if (entityAccessRule.Fileds.Count != 0)
{
var notAccessProps = entry.Properties.Where(p => !entityAccessRule.Fileds.Any(f => f.Field == p.Metadata.Name));
if (notAccessProps != null)
{
foreach (var property in notAccessProps)
{
// 无字段权限不做变更
property.CurrentValue = property.OriginalValue;
}
}
}
}
else
{
// 无实体变更权限不做修改
entry.State = EntityState.Unchanged;
}
}
}
}
}
protected override Expression<Func<TEntity, bool>> CreateFilterExpression<TEntity>() protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
var expression = base.CreateFilterExpression<TEntity>(); base.OnConfiguring(optionsBuilder);
if (typeof(IHasDataAccess).IsAssignableFrom(typeof(TEntity))) // TODO: 需要优化表达式树
{ // optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedReadEntityInterceptor>());
Expression<Func<TEntity, bool>> expression2 = (TEntity e) => !IsDataAccessFilterEnabled || CreateFilterExpression(e, AccessRuleInfo); //optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedWriteEntityInterceptor>());
expression = (Expression<Func<TEntity, bool>>)((expression == null) ? ((LambdaExpression)expression2) : ((LambdaExpression)QueryFilterExpressionHelper.CombineExpressions(expression, expression2))); optionsBuilder.AddInterceptors(LazyServiceProvider.GetRequiredService<AbpDataProtectedWritePropertiesInterceptor>());
} }
return expression; protected override void ApplyAbpConceptsForAddedEntity(EntityEntry entry)
} {
base.ApplyAbpConceptsForAddedEntity(entry);
SetAuthorizationDataProperties(entry);
}
protected static bool CreateFilterExpression<TEntity>(TEntity entity, DataAccessRuleInfo accessRuleInfo) protected virtual void SetAuthorizationDataProperties(EntityEntry entry)
{
if (entry.Entity is IDataProtected data)
{ {
if (accessRuleInfo == null) // TODO: 埋点, 以后可用EF.Functions查询
if (data.GetProperty(DataAccessKeywords.AUTH_ROLES) == null)
{ {
return true; data.SetProperty(DataAccessKeywords.AUTH_ROLES, CurrentUser.Roles.Select(role => $"[{role}]").JoinAsString(","));
} }
if (data.GetProperty(DataAccessKeywords.AUTH_ORGS) == null)
if (!accessRuleInfo.Rules.Any(r => r.EntityTypeFullName == typeof(TEntity).FullName))
{ {
return false; data.SetProperty(DataAccessKeywords.AUTH_ORGS, CurrentUser.FindOrganizationUnits().Select(ou => $"[{ou}]").JoinAsString(","));
} }
if (entity is not IHasDataAccess accessEntity)
{
return true;
}
// TODO: 需要完成详细的过滤条件
return false;
} }
} }
} }

16
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionDbContextModelBuilderExtensions.cs

@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using System;
using Volo.Abp;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
{
public static class AbpDataProtectionDbContextModelBuilderExtensions
{
public static void ConfigureLocalization(
this ModelBuilder builder,
Action<AbpDataProtectionModelBuilderConfigurationOptions> optionsAction = null)
{
Check.NotNull(builder, nameof(builder));
}
}
}

13
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/AbpDataProtectionEntityFrameworkCoreModule.cs

@ -1,12 +1,11 @@
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
[DependsOn(
typeof(AbpDataProtectionModule),
typeof(AbpEntityFrameworkCoreModule))]
public class AbpDataProtectionEntityFrameworkCoreModule : AbpModule
{ {
[DependsOn(
typeof(AbpDataProtectionModule),
typeof(AbpEntityFrameworkCoreModule))]
public class AbpDataProtectionEntityFrameworkCoreModule : AbpModule
{
}
} }

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

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using Volo.Abp.EntityFrameworkCore.Modeling;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
{
public class AbpDataProtectionModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions
{
public AbpDataProtectionModelBuilderConfigurationOptions(
[NotNull] string tablePrefix = "",
[CanBeNull] string schema = null)
: base(
tablePrefix,
schema)
{
}
}
}

358
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionAsyncQueryableProvider.cs

@ -1,358 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Linq;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
{
/// <summary>
/// TODO: 需要实现动态数据权限规则
/// </summary>
[Dependency(ReplaceServices = true)]
public class DataProtectionAsyncQueryableProvider : IAsyncQueryableProvider, ISingletonDependency
{
public bool CanExecute<T>(IQueryable<T> queryable)
{
return queryable.Provider is EntityQueryProvider;
}
public Task<bool> ContainsAsync<T>(IQueryable<T> queryable, T item, CancellationToken cancellationToken = default)
{
return queryable.ContainsAsync(item, cancellationToken);
}
public Task<bool> AnyAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.AnyAsync(cancellationToken);
}
public Task<bool> AnyAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.AnyAsync(predicate, cancellationToken);
}
public Task<bool> AllAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.AllAsync(predicate, cancellationToken);
}
public Task<int> CountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.CountAsync(cancellationToken);
}
public Task<int> CountAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.CountAsync(predicate, cancellationToken);
}
public Task<long> LongCountAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.LongCountAsync(cancellationToken);
}
public Task<long> LongCountAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.LongCountAsync(predicate, cancellationToken);
}
public Task<T> FirstAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.FirstAsync(cancellationToken);
}
public Task<T> FirstAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.FirstAsync(predicate, cancellationToken);
}
public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.FirstOrDefaultAsync(cancellationToken);
}
public Task<T> FirstOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate,
CancellationToken cancellationToken = default)
{
return queryable.FirstOrDefaultAsync(predicate, cancellationToken);
}
public Task<T> LastAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.LastAsync(cancellationToken);
}
public Task<T> LastAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.LastAsync(predicate, cancellationToken);
}
public Task<T> LastOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.LastOrDefaultAsync(cancellationToken);
}
public Task<T> LastOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate,
CancellationToken cancellationToken = default)
{
return queryable.LastOrDefaultAsync(predicate, cancellationToken);
}
public Task<T> SingleAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.SingleAsync(cancellationToken);
}
public Task<T> SingleAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
return queryable.SingleAsync(predicate, cancellationToken);
}
public Task<T> SingleOrDefaultAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.SingleOrDefaultAsync(cancellationToken);
}
public Task<T> SingleOrDefaultAsync<T>(IQueryable<T> queryable, Expression<Func<T, bool>> predicate,
CancellationToken cancellationToken = default)
{
return queryable.SingleOrDefaultAsync(predicate, cancellationToken);
}
public Task<T> MinAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.MinAsync(cancellationToken);
}
public Task<TResult> MinAsync<T, TResult>(IQueryable<T> queryable, Expression<Func<T, TResult>> selector, CancellationToken cancellationToken = default)
{
return queryable.MinAsync(selector, cancellationToken);
}
public Task<T> MaxAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.MaxAsync(cancellationToken);
}
public Task<TResult> MaxAsync<T, TResult>(IQueryable<T> queryable, Expression<Func<T, TResult>> selector, CancellationToken cancellationToken = default)
{
return queryable.MaxAsync(selector, cancellationToken);
}
public Task<decimal> SumAsync(IQueryable<decimal> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<decimal?> SumAsync(IQueryable<decimal?> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<decimal> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, decimal>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<decimal?> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, decimal?>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<int> SumAsync(IQueryable<int> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<int?> SumAsync(IQueryable<int?> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<int> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, int>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<int?> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, int?>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<long> SumAsync(IQueryable<long> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<long?> SumAsync(IQueryable<long?> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<long> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, long>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<long?> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, long?>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<double> SumAsync(IQueryable<double> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<double?> SumAsync(IQueryable<double?> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<double> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, double>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<double?> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, double?>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<float> SumAsync(IQueryable<float> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<float?> SumAsync(IQueryable<float?> queryable, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(cancellationToken);
}
public Task<float> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, float>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<float?> SumAsync<T>(IQueryable<T> queryable, Expression<Func<T, float?>> selector, CancellationToken cancellationToken = default)
{
return queryable.SumAsync(selector, cancellationToken);
}
public Task<decimal> AverageAsync(IQueryable<decimal> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<decimal?> AverageAsync(IQueryable<decimal?> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<decimal> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, decimal>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<decimal?> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, decimal?>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<double> AverageAsync(IQueryable<int> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<double?> AverageAsync(IQueryable<int?> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<double> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, int>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<double?> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, int?>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<double> AverageAsync(IQueryable<long> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<double?> AverageAsync(IQueryable<long?> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<double> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, long>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<double?> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, long?>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<double> AverageAsync(IQueryable<double> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<double?> AverageAsync(IQueryable<double?> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<double> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, double>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<double?> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, double?>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<float> AverageAsync(IQueryable<float> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<float?> AverageAsync(IQueryable<float?> queryable, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(cancellationToken);
}
public Task<float> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, float>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<float?> AverageAsync<T>(IQueryable<T> queryable, Expression<Func<T, float?>> selector, CancellationToken cancellationToken = default)
{
return queryable.AverageAsync(selector, cancellationToken);
}
public Task<List<T>> ToListAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.ToListAsync(cancellationToken);
}
public Task<T[]> ToArrayAsync<T>(IQueryable<T> queryable, CancellationToken cancellationToken = default)
{
return queryable.ToArrayAsync(cancellationToken);
}
}
}

86
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionQueryExpressionInterceptor.cs

@ -1,86 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
public class DataProtectionQueryExpressionInterceptor : IQueryExpressionInterceptor
{
public Expression QueryCompilationStarting(Expression queryExpression, QueryExpressionEventData eventData)
{
var dataFilter = eventData.Context.GetService<IDataFilter>();
var dbContextProvider = eventData.Context.GetService<IDbContextProvider<AbpDataProtectionDbContext>>();
return new DataProtectionExpressionVisitor(dataFilter, dbContextProvider).Visit(queryExpression);
}
public class DataProtectionExpressionVisitor : ExpressionVisitor
{
private readonly static MethodInfo WhereMethodInfo = typeof(Queryable).GetMethod(nameof(Queryable.Where));
private readonly IDataFilter _dataFilter;
private readonly ICurrentUser _currentUser;
private readonly IDbContextProvider<AbpDataProtectionDbContext> _dbContextProvider;
public DataProtectionExpressionVisitor(
IDataFilter dataFilter,
IDbContextProvider<AbpDataProtectionDbContext> dbContextProvider)
{
_dataFilter = dataFilter;
_dbContextProvider = dbContextProvider;
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (_dataFilter.IsEnabled<IHasDataAccess>())
{
var methodInfo = node!.Method;
if (methodInfo.DeclaringType == typeof(Queryable)
&& methodInfo.Name == nameof(Queryable.Select)
&& methodInfo.GetParameters().Length == 2)
{
var sourceType = node.Type.GetGenericArguments()[0];
var lambdaExpression = (LambdaExpression)((UnaryExpression)node.Arguments[1]).Operand;
var entityParameterExpression = lambdaExpression.Parameters[0];
var rules = _currentUser.Roles;
var ous = _currentUser.FindOrganizationUnits();
var ownerParamter = Expression.PropertyOrField(entityParameterExpression, nameof(IHasDataAccess.Owner));
if (typeof(IEntity).IsAssignableFrom(sourceType))
{
// Join params[0]
// node
var test = Expression.Call(
method: WhereMethodInfo.MakeGenericMethod(sourceType, typeof(bool)),
arg0: base.VisitMethodCall(node),
arg1: Expression.Lambda(
typeof(Func<,>).MakeGenericType(entityParameterExpression.Type, typeof(bool)),
Expression.Property(entityParameterExpression, nameof(IHasDataAccess.Owner)),
true));
return test;
}
}
}
return base.VisitMethodCall(node);
}
}
}

41
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/LINGYUN/Abp/DataProtection/EntityFrameworkCore/DataProtectionSaveChangesInterceptor.cs

@ -1,41 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
public class DataProtectionSaveChangesInterceptor : SaveChangesInterceptor
{
private readonly static EntityState[] _protectedStates =
[
EntityState.Modified,
EntityState.Detached,
];
public async override ValueTask<InterceptionResult<int>> SavingChangesAsync(
DbContextEventData eventData,
InterceptionResult<int> result,
CancellationToken cancellationToken = default)
{
if (eventData.Context != null && eventData.Context is IAbpEfCoreDbContext)
{
// 存在资源所属者的实体将被检查访问权限
var changeEntires = eventData.Context.ChangeTracker.Entries<IMayHaveCreator>()
.Where(e => _protectedStates.Contains(e.State))
.Where(e => e.Entity.CreatorId.HasValue);
foreach (var changeEntity in changeEntires)
{
}
}
// return InterceptionResult<int>.SuppressWithResult(0);
return await base.SavingChangesAsync(eventData, result, cancellationToken);
}
}

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

@ -0,0 +1,156 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore;
public abstract class EfCoreDataProtectionRepository<TDbContext, TEntity, TKey> :
EfCoreRepository<TDbContext, TEntity, TKey>,
IDataProtectionRepository<TEntity>
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity<TKey>
{
private readonly IDataAuthorizationService _dataAuthorizationService;
private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
protected EfCoreDataProtectionRepository(
[NotNull] IDbContextProvider<TDbContext> dbContextProvider,
[NotNull] IDataAuthorizationService dataAuthorizationService,
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder)
: base(dbContextProvider)
{
_dataAuthorizationService = dataAuthorizationService;
_entityTypeFilterBuilder = entityTypeFilterBuilder;
}
public async override Task<IQueryable<TEntity>> GetQueryableAsync()
{
var queryable = await base.GetQueryableAsync();
var dataAccessFilterExp = _entityTypeFilterBuilder.Build<TEntity>(DataAccessOperation.Read);
queryable = queryable.Where(dataAccessFilterExp);
return queryable;
}
public async override Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
var dbSet = dbContext.Set<TEntity>();
var entities = await dbSet.Where(predicate).ToListAsync();
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Delete, entities);
await dbSet.Where(predicate).ExecuteDeleteAsync(GetCancellationToken(cancellationToken));
}
public async override Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Delete, new TEntity[1] { entity });
await base.DeleteAsync(entity, autoSave, cancellationToken);
}
public async override Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Delete, entities);
await base.DeleteManyAsync(entities, autoSave, cancellationToken);
}
public async override Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false,
CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Write, new TEntity[1] { entity });
return await base.UpdateAsync(entity, autoSave, cancellationToken);
}
public async override Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Write, entities);
await base.UpdateManyAsync(entities, autoSave, cancellationToken);
}
}
public abstract class EfCoreDataProtectionRepository<TDbContext, TEntity> : EfCoreRepository<TDbContext, TEntity>
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
private readonly IDataAuthorizationService _dataAuthorizationService;
private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
protected EfCoreDataProtectionRepository(
[NotNull] IDbContextProvider<TDbContext> dbContextProvider,
[NotNull] IDataAuthorizationService dataAuthorizationService,
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder)
: base(dbContextProvider)
{
_dataAuthorizationService = dataAuthorizationService;
_entityTypeFilterBuilder = entityTypeFilterBuilder;
}
public async override Task<IQueryable<TEntity>> GetQueryableAsync()
{
var queryable = await base.GetQueryableAsync();
var dataAccessFilterExp = _entityTypeFilterBuilder.Build<TEntity>(DataAccessOperation.Read);
queryable = queryable.Where(dataAccessFilterExp);
return queryable;
}
public async override Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
var dbSet = dbContext.Set<TEntity>();
var entities = await dbSet.Where(predicate).ToListAsync();
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Delete, entities);
await dbSet.Where(predicate).ExecuteDeleteAsync(GetCancellationToken(cancellationToken));
}
public async override Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Delete, new TEntity[1] { entity });
await base.DeleteAsync(entity, autoSave, cancellationToken);
}
public async override Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Delete, entities);
await base.DeleteManyAsync(entities, autoSave, cancellationToken);
}
public async override Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false,
CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Write, new TEntity[1] { entity });
return await base.UpdateAsync(entity, autoSave, cancellationToken);
}
public async override Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false,
CancellationToken cancellationToken = default)
{
await _dataAuthorizationService.CheckAsync(DataAccessOperation.Write, entities);
await base.UpdateManyAsync(entities, autoSave, cancellationToken);
}
}

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

@ -1,19 +0,0 @@
using System;
using Volo.Abp;
namespace LINGYUN.Abp.DataProtection.EntityFrameworkCore
{
public static class ProtectedEntityHelper
{
public static void TrySetOwner(
IHasDataAccess protectedEntity,
Func<DataAccessOwner> ownerFactory)
{
ObjectHelper.TrySetProperty(
protectedEntity,
x => x.Owner,
ownerFactory,
new Type[] { });
}
}
}

104
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection.EntityFrameworkCore/README.md

@ -0,0 +1,104 @@
# LINGYUN.Abp.DataProtection.EntityFrameworkCore
数据权限EF实现模块
## 接口描述
* DisableDataProtectedAttribute: 通过拦截器自动实现DataFilter.Disable<IDataProtected>(),数据过滤器在当前范围将被禁用
## 注意事项
* 使用仓储接口尽量避免直接使用 *await GetDbSetAsync()*, 而是使用 *await GetQueryableAsync()*, 因为 **DbSet** 设计模式原因,暂无法对其进行处理
* 您的仓库接口应继承自 **EfCoreDataProtectionRepository**, 您的 *DbContext* 应继承自 **AbpDataProtectionDbContext**
## 配置使用
```csharp
[DependsOn(
typeof(AbpDataProtectionEntityFrameworkCoreModule)
)]
public class YouProjectModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<DataProtectionManagementOptions>(options =>
{
// 受保护的实体列表持久化
options.AddEntities(typeof(YouResource), new Type[]
{
typeof(YouProtectionObject),
});
// 如下格式
// options.AddEntities(typeof(IdentityResource), new Type[]
// {
// typeof(IdentityUser),
// typeof(IdentityRole),
// typeof(OrganizationUnit),
// });
});
}
}
public class YouDbContext : AbpDataProtectionDbContext<YouDbContext>
{
public DbSet<YouProtectionObject> ProtectionObjects { get; set; }
public YouDbContext(
DbContextOptions<YouDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<YouProtectionObject>(b =>
{
// ...
});
}
}
public class EfCoreYouProtectionObjectRepository :
EfCoreDataProtectionRepository<YouDbContext, YouProtectionObject, int>,
IYouProtectionObjectRepository
{
protected IDataFilter DataFilter { get; }
public EfCoreYouProtectionObjectRepository(
[NotNull] IDbContextProvider<YouDbContext> dbContextProvider,
[NotNull] IDataAuthorizationService dataAuthorizationService,
[NotNull] IEntityTypeFilterBuilder entityTypeFilterBuilder,
IDataFilter dataFilter)
: base(dbContextProvider, dataAuthorizationService, entityTypeFilterBuilder)
{
DataFilter = dataFilter;
}
// 获取受保护的数据列表
public async virtual Task<List<YouProtectionObject>> GetProtectedListAsync()
{
return await (await GetQueryableAsync())
.ToListAsync();
}
// 标注 DisableDataProtected 获取全部数据列表, 通过拦截器自动处理 DataFilter.Disable<IDataProtected>()
[DisableDataProtected]
public async virtual Task<List<YouProtectionObject>> GetUnProtectedListAsync()
{
return await (await GetQueryableAsync())
.ToListAsync();
}
// 禁用 IDataProtected 过滤器获取全部数据列表(可在任意地方使用)
public async virtual Task<List<YouProtectionObject>> GetUnProtectedByFilterListAsync()
{
using (DataFilter.Disable<IDataProtected>())
{
return await (await GetQueryableAsync())
.ToListAsync();
}
}
}
```

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

@ -14,6 +14,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\authorization\LINGYUN.Abp.Authorization.OrganizationUnits\LINGYUN.Abp.Authorization.OrganizationUnits.csproj" /> <ProjectReference Include="..\..\authorization\LINGYUN.Abp.Authorization.OrganizationUnits\LINGYUN.Abp.Authorization.OrganizationUnits.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.DataProtection.Abstractions\LINGYUN.Abp.DataProtection.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

41
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/AbpDataProtectionModule.cs

@ -1,10 +1,49 @@
using Volo.Abp.Domain; using LINGYUN.Abp.DataProtection.Keywords;
using LINGYUN.Abp.DataProtection.Localization;
using LINGYUN.Abp.DataProtection.Operations;
using LINGYUN.Abp.DataProtection.Subjects;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Domain;
using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace LINGYUN.Abp.DataProtection; namespace LINGYUN.Abp.DataProtection;
[DependsOn( [DependsOn(
typeof(AbpDataProtectionAbstractionsModule),
typeof(AbpDddDomainModule))] typeof(AbpDddDomainModule))]
public class AbpDataProtectionModule : AbpModule public class AbpDataProtectionModule : AbpModule
{ {
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.OnRegistered(DataProtectedInterceptorRegistrar.RegisterIfNeeded);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpDataProtectionOptions>(options =>
{
options.KeywordContributors.Add(DataAccessCurrentUserContributor.Name, new DataAccessCurrentUserContributor());
options.OperateContributors.Add(DataAccessFilterOperate.Equal, new DataAccessEqualContributor());
options.OperateContributors.Add(DataAccessFilterOperate.NotEqual, new DataAccessNotEqualContributor());
options.OperateContributors.Add(DataAccessFilterOperate.Less, new DataAccessLessContributor());
options.OperateContributors.Add(DataAccessFilterOperate.LessOrEqual, new DataAccessLessOrEqualContributor());
options.OperateContributors.Add(DataAccessFilterOperate.Greater, new DataAccessGreaterContributor());
options.OperateContributors.Add(DataAccessFilterOperate.GreaterOrEqual, new DataAccessGreaterOrEqualContributor());
options.OperateContributors.Add(DataAccessFilterOperate.StartsWith, new DataAccessStartsWithContributor());
options.OperateContributors.Add(DataAccessFilterOperate.EndsWith, new DataAccessEndsWithContributor());
options.OperateContributors.Add(DataAccessFilterOperate.Contains, new DataAccessContainsContributor());
options.OperateContributors.Add(DataAccessFilterOperate.NotContains, new DataAccessNotContainsContributor());
options.SubjectContributors.Add(new DataAccessUserIdContributor());
options.SubjectContributors.Add(new DataAccessRoleNameContributor());
options.SubjectContributors.Add(new DataAccessOrganizationUnitContributor());
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources.Add<DataProtectionResource>();
});
}
} }

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

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.DataProtection;
public class AbpDataProtectionOptions
{
/// <summary>
/// 是否启用数据审计
/// 默认: true
/// </summary>
public bool IsEnabled { get; set; }
/// <summary>
/// 权限主体
/// </summary>
public IList<IDataAccessSubjectContributor> SubjectContributors { get; set; }
/// <summary>
/// 过滤字段关键字
/// </summary>
public IDictionary<string, IDataAccessKeywordContributor> KeywordContributors { get; set; }
/// <summary>
/// 数据操作
/// </summary>
public IDictionary<DataAccessFilterOperate, IDataAccessOperateContributor> OperateContributors { get; set; }
/// <summary>
/// 忽略审计字段列表
/// </summary>
public IList<string> IgnoreAuditedProperties { get; set; }
public AbpDataProtectionOptions()
{
IsEnabled = true;
SubjectContributors = new List<IDataAccessSubjectContributor>();
KeywordContributors = new Dictionary<string, IDataAccessKeywordContributor>();
OperateContributors = new Dictionary<DataAccessFilterOperate, IDataAccessOperateContributor>();
IgnoreAuditedProperties = new List<string>
{
nameof(IEntity<Guid>.Id),
nameof(IAuditedObject.LastModifierId),
nameof(IAuditedObject.LastModificationTime),
nameof(IAuditedObject.CreatorId),
nameof(IAuditedObject.CreationTime),
nameof(IDeletionAuditedObject.IsDeleted),
nameof(IDeletionAuditedObject.DeleterId),
nameof(IDeletionAuditedObject.DeletionTime),
nameof(IMultiTenant.TenantId),
nameof(IHasEntityVersion.EntityVersion),
nameof(IHasConcurrencyStamp.ConcurrencyStamp),
nameof(IHasExtraProperties.ExtraProperties),
};
}
}

30
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessCacheItem.cs

@ -1,30 +0,0 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessCacheItem
{
/// <summary>
/// 实体类型全名
/// </summary>
public string EntityTypeFullName { get; set; }
/// <summary>
/// 数据访问操作
/// </summary>
public DataAccessOperation Operation { get; set; }
/// <summary>
/// 数据访问角色
/// </summary>
public DataAccessRole Role { get; set; }
/// <summary>
/// 资源访问者
/// </summary>
public string Visitor { get; set; }
/// <summary>
/// 字段访问控制
/// </summary>
public List<DataAccessFiledRule> Fileds { get; set; }
/// <summary>
/// 自定义表达式
/// </summary>
public List<DataAccessExpressionRule> Expressions { get; set; }
}

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

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据访问实体控制
/// </summary>
public class DataAccessEntityRule
{
}

11
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessExpressionRule.cs

@ -1,11 +0,0 @@
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据访问控制规则:自定义表达式
/// </summary>
public class DataAccessExpressionRule
{
/// <summary>
/// 表达式
/// </summary>
public virtual string Expression { get; protected set; }
}

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

@ -1,19 +0,0 @@
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据访问控制规则:字段
/// </summary>
public class DataAccessFiledRule
{
/// <summary>
/// 字段名称
/// </summary>
public virtual string Field { get; protected set; }
public DataAccessFiledRule()
{
}
public DataAccessFiledRule(string field)
{
Field = field;
}
}

11
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessKeywordContributorContext.cs

@ -0,0 +1,11 @@
using System;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessKeywordContributorContext
{
public IServiceProvider ServiceProvider { get; }
public DataAccessKeywordContributorContext(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
}

7
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessOperation.cs

@ -1,7 +0,0 @@
namespace LINGYUN.Abp.DataProtection;
public enum DataAccessOperation
{
Read,
Write,
Delete
}

34
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessOwner.cs

@ -1,34 +0,0 @@
using System;
using System.Linq;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据拥有者
/// </summary>
public class DataAccessOwner : IMayHaveCreator
{
public Guid? CreatorId { get; set; }
public string[] Roles { get; set; }
public string[] OrganizaztionUnits { get; set; }
protected DataAccessOwner()
{
}
public DataAccessOwner(Guid? creatorId, string[] roles, string[] organizaztionUnits)
{
CreatorId = creatorId;
Roles = roles;
OrganizaztionUnits = organizaztionUnits;
}
public bool IsInRole(string[] roles)
{
return Roles != null && Roles.Any(r => roles.Contains(r));
}
public bool IsInOrganizaztionUnit(string[] organizaztionUnits)
{
return OrganizaztionUnits != null && OrganizaztionUnits.Any(ou => organizaztionUnits.Contains(ou));
}
}

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

@ -1,23 +0,0 @@
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据访问角色
/// </summary>
public enum DataAccessRole
{
/// <summary>
/// 所有
/// </summary>
All = 0,
/// <summary>
/// 用户
/// </summary>
User = 1,
/// <summary>
/// 角色
/// </summary>
Role = 2,
/// <summary>
/// 组织机构
/// </summary>
OrganizationUnit = 3,
}

54
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessRule.cs

@ -1,54 +0,0 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据访问控制规则
/// </summary>
public class DataAccessRule
{
/// <summary>
/// 实体类型全名
/// </summary>
public virtual string EntityTypeFullName { get; protected set; }
/// <summary>
/// 数据访问操作
/// </summary>
public virtual DataAccessOperation Operation { get; protected set; }
/// <summary>
/// 数据访问角色
/// </summary>
public virtual DataAccessRole Role { get; protected set; }
/// <summary>
/// 资源访问者
/// </summary>
public virtual string Visitor { get; protected set; }
/// <summary>
/// 字段访问控制
/// </summary>
public virtual List<DataAccessFiledRule> Fileds { get; protected set; }
/// <summary>
/// 自定义表达式
/// </summary>
public virtual List<DataAccessExpressionRule> Expressions { get; protected set; }
protected DataAccessRule()
{
Fileds = [];
Expressions = [];
}
public DataAccessRule(
string entityTypeFullName,
DataAccessOperation operation = DataAccessOperation.Read,
DataAccessRole role = DataAccessRole.All,
string visitor = null,
List<DataAccessFiledRule> fileds = null,
List<DataAccessExpressionRule> expressions = null)
{
EntityTypeFullName = entityTypeFullName;
Operation = operation;
Role = role;
Visitor = visitor;
Fileds = fileds ?? [];
Expressions = expressions ?? [];
}
}

11
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataAccessRuleInfo.cs

@ -1,11 +0,0 @@
using System.Collections.Generic;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessRuleInfo
{
public List<DataAccessRule> Rules { get; }
public DataAccessRuleInfo(List<DataAccessRule> rules)
{
Rules = rules ?? new List<DataAccessRule>();
}
}

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

@ -0,0 +1,18 @@
using System;
namespace LINGYUN.Abp.DataProtection;
public class DataAccessSubjectContributorContext
{
public string EntityTypeFullName { get; }
public DataAccessOperation Operation { get; }
public IServiceProvider ServiceProvider { get; }
public DataAccessSubjectContributorContext(
string entityTypeFullName,
DataAccessOperation operation,
IServiceProvider serviceProvider)
{
EntityTypeFullName = entityTypeFullName;
Operation = operation;
ServiceProvider = serviceProvider;
}
}

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

@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtection;
public class DataAuthorizationService : IDataAuthorizationService, ITransientDependency
{
private readonly static MethodInfo AllMethod = typeof(Enumerable).GetMethod(nameof(Enumerable.All), BindingFlags.Public | BindingFlags.Static);
private readonly IEntityTypeFilterBuilder _entityTypeFilterBuilder;
public DataAuthorizationService(IEntityTypeFilterBuilder entityTypeFilterBuilder)
{
_entityTypeFilterBuilder = entityTypeFilterBuilder;
}
public virtual Task<AuthorizationResult> AuthorizeAsync<TEntity>(DataAccessOperation operation, IEnumerable<TEntity> entities)
{
if (!entities.Any())
{
return Task.FromResult(AuthorizationResult.Success());
}
var exp = _entityTypeFilterBuilder.Build<TEntity>(operation);
return Task.FromResult(entities.All(exp.Compile()) ? AuthorizationResult.Success() : AuthorizationResult.Failed());
}
}

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

@ -0,0 +1,48 @@
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
namespace LINGYUN.Abp.DataProtection;
public class DataProtectedInterceptor : AbpInterceptor, ITransientDependency
{
private readonly IDataFilter _dataFilter;
private readonly AbpDataProtectionOptions _options;
public DataProtectedInterceptor(IDataFilter dataFilter, IOptions<AbpDataProtectionOptions> options)
{
_dataFilter = dataFilter;
_options = options.Value;
}
public async override Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (ShouldDisableDataProtected(invocation, _options))
{
using (_dataFilter.Disable<IDataProtected>())
{
await invocation.ProceedAsync();
return;
}
}
await invocation.ProceedAsync();
}
protected virtual bool ShouldDisableDataProtected(
IAbpMethodInvocation invocation,
AbpDataProtectionOptions options)
{
if (!options.IsEnabled)
{
return true;
}
if (invocation.Method.IsDefined(typeof(DisableDataProtectedAttribute), true))
{
return true;
}
return false;
}
}

35
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/DataProtectedInterceptorRegistrar.cs

@ -0,0 +1,35 @@
using System;
using System.Linq;
using System.Reflection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
namespace LINGYUN.Abp.DataProtection;
public static class DataProtectedInterceptorRegistrar
{
public static void RegisterIfNeeded(IOnServiceRegistredContext context)
{
if (ShouldIntercept(context.ImplementationType))
{
context.Interceptors.TryAdd<DataProtectedInterceptor>();
}
}
private static bool ShouldIntercept(Type type)
{
return !DynamicProxyIgnoreTypes.Contains(type) &&
(typeof(IDataProtectedEnabled).IsAssignableFrom(type) || type.IsDefined(typeof(DataProtectedAttribute), true) || AnyMethodHasAuthorizeAttribute(type));
}
private static bool AnyMethodHasAuthorizeAttribute(Type implementationType)
{
return implementationType
.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Any(HasAuthorizeAttribute);
}
private static bool HasAuthorizeAttribute(MemberInfo methodInfo)
{
return methodInfo.IsDefined(typeof(DataProtectedAttribute), true);
}
}

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

@ -0,0 +1,141 @@
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.DataProtection;
public class EntityPropertyResultBuilder : IEntityPropertyResultBuilder, ITransientDependency
{
private readonly IDataFilter _dataFilter;
private readonly IServiceProvider _serviceProvider;
private readonly AbpDataProtectionOptions _options;
public EntityPropertyResultBuilder(
IDataFilter dataFilter,
IServiceProvider serviceProvider,
IOptions<AbpDataProtectionOptions> options)
{
_options = options.Value;
_dataFilter = dataFilter;
_serviceProvider = serviceProvider;
}
public virtual LambdaExpression Build(Type entityType, DataAccessOperation operation)
{
// Func<TEntity, TEntity>
var func = typeof(Func<,>).MakeGenericType(entityType, entityType);
var param = Expression.Parameter(entityType, "e");
LambdaExpression selector = Expression.Lambda(param, param);
if (!ShouldApplyFilter(entityType, operation))
{
return selector;
}
var typeName = entityType.FullName;
var allowProperties = new List<string>();
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors)
{
var properties = contributor.GetAllowProperties(subjectContext);
allowProperties.AddIfNotContains(properties);
}
// 默认实体相关标识需要带上, 否则无法返回查询结果
allowProperties.AddIfNotContains(_options.IgnoreAuditedProperties);
if (!allowProperties.Any())
{
return selector;
}
var memberBindings = new List<MemberBinding>();
foreach (var propertyName in allowProperties)
{
var propertyInfo = entityType.GetProperty(propertyName);
if (propertyInfo != null)
{
var propertyExpression = Expression.Property(param, propertyInfo);
memberBindings.Add(Expression.Bind(propertyInfo, propertyExpression));
}
}
var newExpression = Expression.New(entityType);
var memberInitExpression = Expression.MemberInit(newExpression, memberBindings);
return Expression.Lambda(func, memberInitExpression, param);
}
public virtual Expression<Func<TEntity, TEntity>> Build<TEntity>(DataAccessOperation operation)
{
var entityType = typeof(TEntity);
Expression<Func<TEntity, TEntity>> selector = e => e;
if (!ShouldApplyFilter(entityType, operation))
{
return selector;
}
var typeName = typeof(TEntity).FullName;
var allowProperties = new List<string>();
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors)
{
var properties = contributor.GetAllowProperties(subjectContext);
allowProperties.AddIfNotContains(properties);
}
// 默认实体相关标识需要带上, 否则无法返回查询结果
allowProperties.AddIfNotContains(_options.IgnoreAuditedProperties);
if (!allowProperties.Any())
{
return selector;
}
var param = Expression.Parameter(typeof(TEntity), "e");
var memberBindings = new List<MemberBinding>();
foreach (var propertyName in allowProperties)
{
var propertyInfo = typeof(TEntity).GetProperty(propertyName);
if (propertyInfo != null)
{
var propertyExpression = Expression.Property(param, propertyInfo);
memberBindings.Add(Expression.Bind(propertyInfo, propertyExpression));
}
}
var newExpression = Expression.New(typeof(TEntity));
var memberInitExpression = Expression.MemberInit(newExpression, memberBindings);
return Expression.Lambda<Func<TEntity, TEntity>>(memberInitExpression, param);
}
private bool ShouldApplyFilter(Type entityType, DataAccessOperation operation)
{
if (!_dataFilter.IsEnabled<IDataProtected>())
{
return false;
}
if (entityType.IsDefined(typeof(DisableDataProtectedAttribute), true))
{
return false;
}
var dataProtected = entityType.GetCustomAttribute<DataProtectedAttribute>();
if (dataProtected != null && dataProtected.Operation != operation)
{
return false;
}
return true;
}
}

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

@ -0,0 +1,326 @@
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Nodes;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtection;
public class EntityTypeFilterBuilder : IEntityTypeFilterBuilder, ITransientDependency
{
private readonly IDataFilter _dataFilter;
private readonly IServiceProvider _serviceProvider;
private readonly AbpDataProtectionOptions _options;
public EntityTypeFilterBuilder(
IDataFilter dataFilter,
IServiceProvider serviceProvider,
IOptions<AbpDataProtectionOptions> options)
{
_options = options.Value;
_dataFilter = dataFilter;
_serviceProvider = serviceProvider;
}
public virtual LambdaExpression Build(Type entityType, DataAccessOperation operation, DataAccessFilterGroup group = null)
{
// Func<TEntity, bool>
var func = typeof(Func<,>).MakeGenericType(entityType, typeof(bool));
// e => e
var param = Expression.Parameter(entityType, "e");
// => true
var trueExp = Expression.Constant(true);
// Expression<Func<TEntity, bool>> exp = e => true;
var exp = Expression.Lambda(func, trueExp, param);
if (!ShouldApplyFilter(entityType, operation))
{
return exp;
}
if (group != null)
{
exp = GetExpression(entityType, group);
}
var typeName = entityType.FullName;
var subjectFilterGroups = new List<DataAccessFilterGroup>();
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors)
{
var subjectFilterGroup = contributor.GetFilterGroups(subjectContext);
subjectFilterGroups.AddRange(subjectFilterGroup);
}
LambdaExpression subExp = null;
foreach (var subGroup in subjectFilterGroups)
{
subExp = subExp == null ? GetExpression(entityType, subGroup) : subExp.OrElse(func, GetExpression(entityType, subGroup));
}
if (subExp == null)
{
return exp;
}
if (group == null)
{
return subExp;
}
exp = subExp.AndAlso(func, exp);
return exp;
}
public virtual Expression<Func<TEntity, bool>> Build<TEntity>(DataAccessOperation operation, DataAccessFilterGroup group = null)
{
var entityType = typeof(TEntity);
Expression<Func<TEntity, bool>> exp = _ => true;
if (!ShouldApplyFilter(entityType, operation))
{
return exp;
}
if (group != null)
{
exp = GetExpression<TEntity>(group);
}
var typeName = typeof(TEntity).FullName;
var subjectFilterGroups = new List<DataAccessFilterGroup>();
var subjectContext = new DataAccessSubjectContributorContext(typeName, operation, _serviceProvider);
foreach (var contributor in _options.SubjectContributors)
{
var subjectFilterGroup = contributor.GetFilterGroups(subjectContext);
subjectFilterGroups.AddRange(subjectFilterGroup);
}
Expression<Func<TEntity, bool>> subExp = null;
foreach ( var subGroup in subjectFilterGroups)
{
subExp = subExp == null ? GetExpression<TEntity>(subGroup) : subExp.Or(GetExpression<TEntity>(subGroup));
}
if (subExp == null)
{
return exp;
}
if (group == null)
{
return subExp;
}
exp = subExp.And(exp);
return exp;
}
protected virtual Expression<Func<TEntity, bool>> GetExpression<TEntity>(DataAccessFilterGroup group)
{
Check.NotNull(group, nameof(group));
var param = Expression.Parameter(typeof(TEntity), "e");
var body = GetExpressionBody(param, group);
var expression = Expression.Lambda<Func<TEntity, bool>>(body, param);
return expression;
}
protected virtual LambdaExpression GetExpression(Type entityType, DataAccessFilterGroup group)
{
Check.NotNull(group, nameof(group));
var func = typeof(Func<,>).MakeGenericType(entityType, typeof(bool));
var param = Expression.Parameter(entityType, "e");
var body = GetExpressionBody(param, group);
var expression = Expression.Lambda(func, body, param);
return expression;
}
protected virtual Expression<Func<TEntity, bool>> GetExpression<TEntity>(DataAccessFilterRule rule)
{
Check.NotNull(rule, nameof(rule));
var param = Expression.Parameter(typeof(TEntity), "e");
var body = GetExpressionBody(param, rule);
var expression = Expression.Lambda<Func<TEntity, bool>>(body, param);
return expression;
}
protected virtual LambdaExpression GetExpression(Type entityType, DataAccessFilterRule rule)
{
Check.NotNull(rule, nameof(rule));
var func = typeof(Func<,>).MakeGenericType(entityType, typeof(bool));
var param = Expression.Parameter(entityType, "e");
var body = GetExpressionBody(param, rule);
var expression = Expression.Lambda(func, body, param);
return expression;
}
private Expression GetExpressionBody(ParameterExpression param, DataAccessFilterGroup group)
{
Check.NotNull(param, nameof(param));
if (group == null || (!group.Rules.Any() && !group.Groups.Any()))
{
return Expression.Constant(true);
}
var bodies = new List<Expression>();
bodies.AddRange(group.Rules.Select(rule => GetExpressionBody(param, rule)));
bodies.AddRange(group.Groups.Select(subGroup => GetExpressionBody(param, subGroup)));
return group.Logic switch {
DataAccessFilterLogic.And => bodies.Aggregate(Expression.AndAlso),
DataAccessFilterLogic.Or => bodies.Aggregate(Expression.OrElse),
_ => throw new InvalidOperationException($"Not allowed filter logic: {group.Logic}")
};
}
private Expression GetExpressionBody(ParameterExpression param, DataAccessFilterRule rule)
{
if (!_options.OperateContributors.TryGetValue(rule.Operate, out var contributor))
{
throw new InvalidOperationException($"Invalid data permission operator {rule.Operate}");
}
if (rule == null)
{
return Expression.Constant(true);
}
var expression = GetPropertyLambdaExpression(param, rule);
if (expression == null)
{
return Expression.Constant(true);
}
var constant = ChangeTypeToExpression(rule, expression.Body.Type);
return rule.IsLeft ? contributor.BuildExpression(constant, expression.Body) : contributor.BuildExpression(expression.Body, constant);
}
private static LambdaExpression GetPropertyLambdaExpression(ParameterExpression param, DataAccessFilterRule rule)
{
var propertyNames = rule.Field.Split('.');
Expression propertyAccess = param;
var type = param.Type;
for (var index = 0; index < propertyNames.Length; index++)
{
var propertyName = propertyNames[index];
var property = type.GetProperty(propertyName);
if (property == null)
{
throw new InvalidOperationException(
$"The specified property '{rule.Field}' does not exist in type '{type.FullName}'");
}
type = property.PropertyType;
if (index == propertyNames.Length - 1)
{
if (!CheckFilterRule(type, rule))
{
return null;
}
}
propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
}
return Expression.Lambda(propertyAccess, param);
}
private Expression ChangeTypeToExpression(DataAccessFilterRule rule, Type conversionType)
{
if (_options.KeywordContributors.TryGetValue(rule.Value?.ToString() ?? "", out var contributor))
{
var context = new DataAccessKeywordContributorContext(_serviceProvider);
var keyValue = contributor.Contribute(context);
var value = CastTo(keyValue, conversionType);
return Expression.Constant(value, conversionType);
}
else
{
if (rule.Value is JsonElement element)
{
var valueArray = Array.CreateInstance(conversionType, element.GetArrayLength());
var index = 0;
foreach (var node in element.EnumerateArray())
{
var value = CastTo(node.ToString(), conversionType);
valueArray.SetValue(value, index);
index++;
}
var arrayType = typeof(IEnumerable<>).MakeGenericType(conversionType);
return Expression.Constant(valueArray, arrayType);
}
var valueType = rule.Value.GetType();
if (valueType.IsArrayOrListType())
{
var arrayType = typeof(IEnumerable<>).MakeGenericType(conversionType);
return Expression.Constant(rule.Value, arrayType);
}
else
{
var value = CastTo(rule.Value, conversionType);
return Expression.Constant(value, conversionType);
}
}
}
private bool ShouldApplyFilter(Type entityType, DataAccessOperation operation)
{
if (!_dataFilter.IsEnabled<IDataProtected>())
{
return false;
}
if (entityType.IsDefined(typeof(DisableDataProtectedAttribute), true))
{
return false;
}
var dataProtected = entityType.GetCustomAttribute<DataProtectedAttribute>();
if (dataProtected != null && dataProtected.Operation != operation)
{
return false;
}
return true;
}
private static bool CheckFilterRule(Type type, DataAccessFilterRule rule)
{
if (rule.Value == null || rule.Value.ToString() == string.Empty)
{
rule.Value = null;
}
return rule.Value switch {
null when (type == typeof(string) || type.IsNullableType()) =>
rule.Operate == DataAccessFilterOperate.Equal || rule.Operate == DataAccessFilterOperate.NotEqual,
null => !type.IsValueType,
_ => true
};
}
private static object CastTo(object value, Type conversionType)
{
if (conversionType == typeof(Guid) || conversionType == typeof(Guid?))
{
return TypeDescriptor.GetConverter(conversionType).ConvertFromInvariantString(value.ToString()!)!;
}
return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture);
}
}

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

@ -1,8 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace LINGYUN.Abp.DataProtection;
public interface IDataAccessCache
{
}

6
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/IDataAccessKeywordContributor.cs

@ -0,0 +1,6 @@
namespace LINGYUN.Abp.DataProtection;
public interface IDataAccessKeywordContributor
{
string Keyword { get; }
object Contribute(DataAccessKeywordContributorContext context);
}

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

@ -0,0 +1,8 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection;
public interface IDataAccessOperateContributor
{
DataAccessFilterOperate Operate { get; }
Expression BuildExpression(Expression left, Expression right);
}

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

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

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

@ -0,0 +1,19 @@
using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 数据权限验证服务
/// </summary>
public interface IDataAuthorizationService
{
/// <summary>
/// 验证操作实体数据权限
/// </summary>
/// <param name="operation">数据权限操作</param>
/// <param name="entities">检查实体列表</param>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <returns></returns>
Task<AuthorizationResult> AuthorizeAsync<TEntity>(DataAccessOperation operation, IEnumerable<TEntity> entities);
}

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

@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization;
using Volo.Abp.Domain.Entities;
namespace LINGYUN.Abp.DataProtection;
public static class IDataAuthorizationServiceExtensions
{
public static async Task CheckAsync<TEntity>(this IDataAuthorizationService dataAuthorizationService, DataAccessOperation operation, IEnumerable<TEntity> entities)
{
var result = await dataAuthorizationService.AuthorizeAsync(operation, entities);
if (!result.Succeeded)
{
var entityKeys = entities.Select(x => x.ToString()).JoinAsString(";");
throw new AbpAuthorizationException(
$"The {operation} operation with entity type {typeof(Entity)} identified as {entityKeys} is not allowed!");
}
}
}

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

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.DataProtection;
public interface IDataProtectedResourceStore
{
void Set(DataAccessResource resource);
void Remove(DataAccessResource resource);
DataAccessResource Get(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation);
}

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

@ -0,0 +1,8 @@
using System.Linq;
using System.Threading.Tasks;
namespace LINGYUN.Abp.DataProtection;
public interface IDataProtectionRepository<TEntity> : IDataProtectedEnabled
{
Task<IQueryable<TEntity>> GetQueryableAsync();
}

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

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

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

@ -0,0 +1,20 @@
using System;
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection;
/// <summary>
/// 实体过滤条件构造器
/// </summary>
public interface IEntityTypeFilterBuilder
{
/// <summary>
/// 获取实体的查询过滤表达式
/// </summary>
/// <param name="operation">数据权限操作</param>
/// <param name="group">查询条件组</param>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <returns></returns>
Expression<Func<TEntity, bool>> Build<TEntity>(DataAccessOperation operation, DataAccessFilterGroup group = null);
LambdaExpression Build(Type entityType, DataAccessOperation operation, DataAccessFilterGroup group = null);
}

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

@ -1,5 +0,0 @@
namespace LINGYUN.Abp.DataProtection;
public interface IHasDataAccess
{
public DataAccessOwner Owner { get; }
}

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

@ -0,0 +1,37 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Concurrent;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.DataProtection;
[Dependency(ServiceLifetime.Singleton, TryRegister = true)]
public class InMemoryDataProtectedResourceStore : IDataProtectedResourceStore
{
private readonly static ConcurrentDictionary<string, DataAccessResource> _cache = new ConcurrentDictionary<string, DataAccessResource>();
public DataAccessResource Get(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation)
{
var key = NormalizeKey(subjectName, subjectId, entityTypeFullName, operation);
if (_cache.TryGetValue(key, out var resource))
{
return resource;
}
return null;
}
public void Remove(DataAccessResource resource)
{
var key = NormalizeKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation);
_cache.TryRemove(key, out var _);
}
public void Set(DataAccessResource resource)
{
var key = NormalizeKey(resource.SubjectName, resource.SubjectId, resource.EntityTypeFullName, resource.Operation);
_cache.TryAdd(key, resource);
}
private static string NormalizeKey(string subjectName, string subjectId, string entityTypeFullName, DataAccessOperation operation)
{
return $"{subjectName}_{subjectId}_{entityTypeFullName}_{operation}";
}
}

15
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Keywords/DataAccessCurrentUserContributor.cs

@ -0,0 +1,15 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.Keywords;
public class DataAccessCurrentUserContributor : IDataAccessKeywordContributor
{
public const string Name = "@CurrentUser";
public string Keyword => Name;
public object Contribute(DataAccessKeywordContributorContext context)
{
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
return currentUser.Id;
}
}

33
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessContainsContributor.cs

@ -0,0 +1,33 @@
using System;
using System.Linq;
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessContainsContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.Contains;
public Expression BuildExpression(Expression left, Expression right)
{
if (left.Type == typeof(string))
{
return Expression.Call(left,
typeof(string).GetMethod("Contains", new[] { typeof(string) })
?? throw new InvalidOperationException("The method named \"Contains\" does not exist"),
right);
}
if (left.Type.IsArrayOrListType())
{
var method = typeof(Enumerable).GetMethods().Where(x => x.Name == "Contains").FirstOrDefault();
var methodType = method?.MakeGenericMethod(left.Type.GetGenericArguments()[0]);
return Expression.Call(
null,
methodType ?? throw new InvalidOperationException("The method named \"Contains\" does not exist"),
left,
right);
}
throw new NotSupportedException("\"Contains\" only supports data of string or array type!");
}
}

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

@ -0,0 +1,20 @@
using System;
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessEndsWithContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.EndsWith;
public Expression BuildExpression(Expression left, Expression right)
{
if (left.Type != typeof(string))
{
throw new NotSupportedException("\"EndsWith\" only supports data of string type!");
}
return Expression.Call(left,
typeof(string).GetMethod("EndsWith", new[] { typeof(string) })
?? throw new InvalidOperationException("The method named \"EndsWith\" does not exist!"),
right);
}
}

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

@ -0,0 +1,12 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessEqualContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.Equal;
public Expression BuildExpression(Expression left, Expression right)
{
return Expression.Equal(left, right);
}
}

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

@ -0,0 +1,12 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessGreaterContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.Greater;
public Expression BuildExpression(Expression left, Expression right)
{
return Expression.GreaterThan(left, right);
}
}

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

@ -0,0 +1,12 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessGreaterOrEqualContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.GreaterOrEqual;
public Expression BuildExpression(Expression left, Expression right)
{
return Expression.GreaterThanOrEqual(left, right);
}
}

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

@ -0,0 +1,12 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessLessContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.Less;
public Expression BuildExpression(Expression left, Expression right)
{
return Expression.LessThan(left, right);
}
}

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

@ -0,0 +1,12 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessLessOrEqualContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.LessOrEqual;
public Expression BuildExpression(Expression left, Expression right)
{
return Expression.LessThanOrEqual(left, right);
}
}

37
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/LINGYUN/Abp/DataProtection/Operations/DataAccessNotContainsContributor.cs

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessNotContainsContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.NotContains;
public Expression BuildExpression(Expression left, Expression right)
{
if (left.Type == typeof(string))
{
// string.Contains(string);
return Expression.Not(Expression.Call(left,
typeof(string).GetMethod("Contains", new[] { typeof(string) })
?? throw new InvalidOperationException("The method named \"NotContains\" does not exist"),
right));
}
if (left.Type.IsArrayOrListType())
{
// IEnumerable<T>.Contains(T);
var method = typeof(Enumerable).GetMethods().Where(x => x.Name == "Contains").FirstOrDefault();
var methodType = method?.MakeGenericMethod(left.Type.GetGenericArguments()[0]);
return Expression.Not(Expression.Call(
null,
methodType ?? throw new InvalidOperationException("The method named \"NotContains\" does not exist"),
left,
right));
}
throw new NotSupportedException("\"NotContains\" only supports data of string or array type!");
}
}

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

@ -0,0 +1,12 @@
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessNotEqualContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.NotEqual;
public Expression BuildExpression(Expression left, Expression right)
{
return Expression.NotEqual(left, right);
}
}

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

@ -0,0 +1,20 @@
using System;
using System.Linq.Expressions;
namespace LINGYUN.Abp.DataProtection.Operations;
public class DataAccessStartsWithContributor : IDataAccessOperateContributor
{
public DataAccessFilterOperate Operate => DataAccessFilterOperate.StartsWith;
public Expression BuildExpression(Expression left, Expression right)
{
if (left.Type != typeof(string))
{
throw new NotSupportedException("\"StartsWith\" only supports data of string type!");
}
return Expression.Call(left,
typeof(string).GetMethod("StartsWith", new[] { typeof(string) })
?? throw new InvalidOperationException("The method named \"StartsWith\" does not exist!"),
right);
}
}

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

@ -0,0 +1,52 @@
using LINGYUN.Abp.Authorization.Permissions;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.Subjects;
public class DataAccessOrganizationUnitContributor : IDataAccessSubjectContributor
{
public string Name => OrganizationUnitPermissionValueProvider.ProviderName;
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context)
{
var groups = new List<DataAccessFilterGroup>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
{
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var orgCodes = currentUser.FindOrganizationUnits();
foreach (var orgCode in orgCodes)
{
var resource = resourceStore.Get(Name, orgCode, context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null)
{
groups.Add(resource.FilterGroup);
}
}
}
return groups;
}
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context)
{
var allowProperties = new List<string>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
{
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var orgCodes = currentUser.FindOrganizationUnits();
foreach (var orgCode in orgCodes)
{
var resource = resourceStore.Get(Name, orgCode, context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true)
{
allowProperties.AddIfNotContains(resource.AllowProperties);
}
}
}
return allowProperties;
}
}

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

@ -0,0 +1,52 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.Subjects;
public class DataAccessRoleNameContributor : IDataAccessSubjectContributor
{
public string Name => RolePermissionValueProvider.ProviderName;
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context)
{
var groups = new List<DataAccessFilterGroup>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
{
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var roles = currentUser.Roles;
foreach (var role in roles)
{
var resource = resourceStore.Get(Name, role, context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null)
{
groups.Add(resource.FilterGroup);
}
}
}
return groups;
}
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context)
{
var allowProperties = new List<string>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
{
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var roles = currentUser.Roles;
foreach (var role in roles)
{
var resource = resourceStore.Get(Name, role, context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true)
{
allowProperties.AddIfNotContains(resource.AllowProperties);
}
}
}
return allowProperties;
}
}

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

@ -0,0 +1,44 @@
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Users;
namespace LINGYUN.Abp.DataProtection.Subjects;
public class DataAccessUserIdContributor : IDataAccessSubjectContributor
{
public string Name => UserPermissionValueProvider.ProviderName;
public virtual List<DataAccessFilterGroup> GetFilterGroups(DataAccessSubjectContributorContext context)
{
var groups = new List<DataAccessFilterGroup>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
{
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var resource = resourceStore.Get(Name, currentUser.Id.ToString(), context.EntityTypeFullName, context.Operation);
if (resource?.FilterGroup != null)
{
groups.Add(resource.FilterGroup);
}
}
return groups;
}
public virtual List<string> GetAllowProperties(DataAccessSubjectContributorContext context)
{
var allowProperties = new List<string>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
if (currentUser.IsAuthenticated)
{
var resourceStore = context.ServiceProvider.GetRequiredService<IDataProtectedResourceStore>();
var resource = resourceStore.Get(Name, currentUser.Id.ToString(), context.EntityTypeFullName, context.Operation);
if (resource?.AllowProperties.Any() == true)
{
allowProperties.AddIfNotContains(resource.AllowProperties);
}
}
return allowProperties;
}
}

73
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Linq/Expressions/ExpressionFuncExtender.cs

@ -0,0 +1,73 @@
namespace System.Linq.Expressions;
internal static class ExpressionFuncExtender
{
internal static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second,
Func<Expression, Expression, Expression> merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] })
.ToDictionary(p => p.s, p => p.f);
// replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
// apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
internal static LambdaExpression Compose(this LambdaExpression first,
Type delegateType,
LambdaExpression second,
Func<Expression, Expression, Expression> merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] })
.ToDictionary(p => p.s, p => p.f);
// replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
// apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda(delegateType, merge(first.Body, secondBody), first.Parameters);
}
/// <summary>
/// Combines two given expressions by using the AND semantics.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="first">The first part of the expression.</param>
/// <param name="second">The second part of the expression.</param>
/// <returns>The combined expression.</returns>
public static LambdaExpression AndAlso(this LambdaExpression first,
Type delegateType,
LambdaExpression second)
{
return first.Compose(delegateType, second, Expression.AndAlso);
}
public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> first,
Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.AndAlso);
}
/// <summary>
/// Combines two given expressions by using the OR semantics.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="first">The first part of the expression.</param>
/// <param name="second">The second part of the expression.</param>
/// <returns>The combined expression.</returns>
public static LambdaExpression OrElse(this LambdaExpression first,
Type delegateType,
LambdaExpression second)
{
return first.Compose(delegateType, second, Expression.OrElse);
}
public static Expression<Func<T, bool>> OrElse<T>(this Expression<Func<T, bool>> first,
Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.OrElse);
}
}

30
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Linq/Expressions/ExpressionFuncExtensions.cs

@ -0,0 +1,30 @@
namespace System.Linq.Expressions;
public static class ExpressionFuncExtensions
{
public static Expression<Func<T, bool>> AndIf<T>(
this Expression<Func<T, bool>> first,
bool condition,
Expression<Func<T, bool>> second)
{
if (condition)
{
return ExpressionFuncExtender.AndAlso(first, second);
}
return first;
}
public static Expression<Func<T, bool>> OrIf<T>(
this Expression<Func<T, bool>> first,
bool condition,
Expression<Func<T, bool>> second)
{
if (condition)
{
return ExpressionFuncExtender.OrElse(first, second);
}
return first;
}
}

28
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Linq/Expressions/ParameterRebinder.cs

@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace System.Linq.Expressions;
internal class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> _map;
internal ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
_map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
internal static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map,
Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
if (_map.TryGetValue(p, out var replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}

16
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/Reflection/NullableTypeExtensions.cs

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

28
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/System/TypeExtensions.cs

@ -0,0 +1,28 @@
using System.Collections;
namespace System;
internal static class TypeExtensions
{
public static bool IsArrayOrListType(this Type type)
{
if (type.IsArray)
{
return true;
}
if (type.IsGenericType)
{
if (typeof(IList).IsAssignableFrom(type))
{
return true;
}
if (typeof(IEnumerable).IsAssignableFrom(type))
{
return true;
}
}
return false;
}
}

24
aspnet-core/framework/data-protection/LINGYUN.Abp.DataProtection/Volo/Abp/Uow/IUnitOfWorkDataAccessExtensions.cs

@ -1,24 +0,0 @@
using LINGYUN.Abp.DataProtection;
namespace Volo.Abp.Uow;
public static class IUnitOfWorkDataAccessExtensions
{
private const string DataAccessRuleKey = "LINGYUN.Abp.DataProtection.DataAccess";
public static IUnitOfWork SetAccessRuleInfo(
this IUnitOfWork unitOfWork,
DataAccessRuleInfo dataAccessRuleInfo)
{
unitOfWork.RemoveItem(DataAccessRuleKey);
unitOfWork.AddItem(DataAccessRuleKey, dataAccessRuleInfo);
return unitOfWork;
}
public static DataAccessRuleInfo GetAccessRuleInfo(
this IUnitOfWork unitOfWork)
{
return unitOfWork.GetItemOrDefault<DataAccessRuleInfo>(DataAccessRuleKey)
?? new DataAccessRuleInfo(null);
}
}

5
aspnet-core/framework/localization/LINGYUN.Abp.AspNetCore.Mvc.Localization/LINGYUN/Abp/AspNetCore/Mvc/Localization/LanguageAppService.cs

@ -1,17 +1,12 @@
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Localization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Dynamic.Core; using System.Linq.Dynamic.Core;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Localization.External;
namespace LINGYUN.Abp.AspNetCore.Mvc.Localization namespace LINGYUN.Abp.AspNetCore.Mvc.Localization
{ {

4
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/BackendAdminMigrationsDbContext.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore;
using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; using LINGYUN.Abp.TextTemplating.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data; using Volo.Abp.Data;
@ -27,5 +28,6 @@ public class BackendAdminMigrationsDbContext : AbpDbContext<BackendAdminMigratio
modelBuilder.ConfigureFeatureManagement(); modelBuilder.ConfigureFeatureManagement();
modelBuilder.ConfigureSettingManagement(); modelBuilder.ConfigureSettingManagement();
modelBuilder.ConfigurePermissionManagement(); modelBuilder.ConfigurePermissionManagement();
modelBuilder.ConfigureDataProtectionManagement();
} }
} }

2
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/BackendAdminMigrationsEntityFrameworkCoreModule.cs

@ -1,4 +1,5 @@
using LINGYUN.Abp.Data.DbMigrator; using LINGYUN.Abp.Data.DbMigrator;
using LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore;
using LINGYUN.Abp.Saas.EntityFrameworkCore; using LINGYUN.Abp.Saas.EntityFrameworkCore;
using LINGYUN.Abp.TextTemplating.EntityFrameworkCore; using LINGYUN.Abp.TextTemplating.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -13,6 +14,7 @@ namespace LY.MicroService.BackendAdmin.EntityFrameworkCore;
[DependsOn( [DependsOn(
typeof(AbpSaasEntityFrameworkCoreModule), typeof(AbpSaasEntityFrameworkCoreModule),
typeof(AbpSettingManagementEntityFrameworkCoreModule), typeof(AbpSettingManagementEntityFrameworkCoreModule),
typeof(AbpDataProtectionManagementEntityFrameworkCoreModule),
typeof(AbpPermissionManagementEntityFrameworkCoreModule), typeof(AbpPermissionManagementEntityFrameworkCoreModule),
typeof(AbpFeatureManagementEntityFrameworkCoreModule), typeof(AbpFeatureManagementEntityFrameworkCoreModule),
typeof(AbpTextTemplatingEntityFrameworkCoreModule), typeof(AbpTextTemplatingEntityFrameworkCoreModule),

1
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/LY.MicroService.BackendAdmin.EntityFrameworkCore.csproj

@ -21,6 +21,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\framework\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" /> <ProjectReference Include="..\..\framework\common\LINGYUN.Abp.Data.DbMigrator\LINGYUN.Abp.Data.DbMigrator.csproj" />
<ProjectReference Include="..\..\modules\data-protection\LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore\LINGYUN.Abp.DataProtectionManagement.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\saas\LINGYUN.Abp.Saas.EntityFrameworkCore\LINGYUN.Abp.Saas.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\modules\text-templating\LINGYUN.Abp.TextTemplating.EntityFrameworkCore\LINGYUN.Abp.TextTemplating.EntityFrameworkCore.csproj" /> <ProjectReference Include="..\..\modules\text-templating\LINGYUN.Abp.TextTemplating.EntityFrameworkCore\LINGYUN.Abp.TextTemplating.EntityFrameworkCore.csproj" />
</ItemGroup> </ItemGroup>

932
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515073346_Add-Data-Protected-Module.Designer.cs

@ -0,0 +1,932 @@
// <auto-generated />
using System;
using LY.MicroService.BackendAdmin.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.Abp.EntityFrameworkCore;
#nullable disable
namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
{
[DbContext(typeof(BackendAdminMigrationsDbContext))]
[Migration("20240515073346_Add-Data-Protected-Module")]
partial class AddDataProtectedModule
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "8.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.Property<Guid>("TypeInfoId")
.HasColumnType("char(36)");
b.Property<string>("ValueRange")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("ValueRange");
b.HasKey("Id");
b.HasIndex("TypeInfoId", "TypeFullName");
b.ToTable("AbpAuthEntityProperties", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAuditEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.HasKey("Id");
b.HasIndex("TypeFullName");
b.ToTable("AbpAuthEntitites", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<string>("OrgCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("OrgCode");
b.Property<Guid>("OrgId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthOrganizationUnitEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<Guid>("RoleId")
.HasColumnType("char(36)");
b.Property<string>("RoleName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("RoleName");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthRoleEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Editions.Edition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("char(36)")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.HasKey("Id");
b.HasIndex("DisplayName");
b.ToTable("AbpEditions", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("char(36)")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<DateTime?>("DisableTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("EditionId")
.HasColumnType("char(36)");
b.Property<DateTime?>("EnableTime")
.HasColumnType("datetime(6)");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("NormalizedName")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.HasKey("Id");
b.HasIndex("EditionId");
b.HasIndex("Name");
b.HasIndex("NormalizedName");
b.ToTable("AbpTenants", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.TenantConnectionString", b =>
{
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.HasKey("TenantId", "Name");
b.ToTable("AbpTenantConnectionStrings", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.TextTemplating.TextTemplate", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Content")
.HasMaxLength(1048576)
.HasColumnType("longtext")
.HasColumnName("Content");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Culture")
.HasMaxLength(30)
.HasColumnType("varchar(30)")
.HasColumnName("Culture");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("DisplayName");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("Name");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
.HasDatabaseName("IX_Tenant_Text_Template_Name");
b.ToTable("AbpTextTemplates", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.TextTemplating.TextTemplateDefinition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("DefaultCultureName")
.HasMaxLength(30)
.HasColumnType("varchar(30)")
.HasColumnName("DefaultCultureName");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsInlineLocalized")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsLayout")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsStatic")
.HasColumnType("tinyint(1)");
b.Property<string>("Layout")
.HasMaxLength(60)
.HasColumnType("varchar(60)")
.HasColumnName("Layout");
b.Property<string>("LocalizationResourceName")
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("LocalizationResourceName");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("Name");
b.Property<string>("RenderEngine")
.HasMaxLength(30)
.HasColumnType("varchar(30)")
.HasColumnName("RenderEngine");
b.HasKey("Id");
b.ToTable("AbpTextTemplateDefinitions", (string)null);
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowedProviders")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("DefaultValue")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("Description")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("GroupName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<bool>("IsAvailableToHost")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsVisibleToClients")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ParentName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ValueType")
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.HasKey("Id");
b.HasIndex("GroupName");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpFeatures", (string)null);
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureGroupDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpFeatureGroups", (string)null);
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey")
.IsUnique();
b.ToTable("AbpFeatureValues", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("GroupName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<byte>("MultiTenancySide")
.HasColumnType("tinyint unsigned");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ParentName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("Providers")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("StateCheckers")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("GroupName");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpPermissions", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey")
.IsUnique();
b.ToTable("AbpPermissionGrants", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpPermissionGroups", (string)null);
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey")
.IsUnique();
b.ToTable("AbpSettings", (string)null);
});
modelBuilder.Entity("Volo.Abp.SettingManagement.SettingDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DefaultValue")
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.Property<string>("Description")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsEncrypted")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsInherited")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsVisibleToClients")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("Providers")
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpSettingDefinitions", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "TypeInfo")
.WithMany("Properties")
.HasForeignKey("TypeInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.HasOne("LINGYUN.Abp.Saas.Editions.Edition", "Edition")
.WithMany()
.HasForeignKey("EditionId");
b.Navigation("Edition");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.TenantConnectionString", b =>
{
b.HasOne("LINGYUN.Abp.Saas.Tenants.Tenant", null)
.WithMany("ConnectionStrings")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Navigation("Properties");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.Navigation("ConnectionStrings");
});
#pragma warning restore 612, 618
}
}
}

179
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515073346_Add-Data-Protected-Module.cs

@ -0,0 +1,179 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
{
/// <inheritdoc />
public partial class AddDataProtectedModule : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AbpAuthEntitites",
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"),
TypeFullName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
IsAuditEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
ExtraProperties = table.Column<string>(type: "longtext", 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"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthEntitites", x => x.Id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpAuthEntityProperties",
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"),
TypeFullName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ValueRange = table.Column<string>(type: "varchar(512)", maxLength: 512, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
TypeInfoId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthEntityProperties", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthEntityProperties_AbpAuthEntitites_TypeInfoId",
column: x => x.TypeInfoId,
principalTable: "AbpAuthEntitites",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpAuthOrganizationUnitEntityRules",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrgId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
OrgCode = table.Column<string>(type: "varchar(128)", maxLength: 128, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ExtraProperties = table.Column<string>(type: "longtext", 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"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
Operation = table.Column<int>(type: "int", nullable: false),
FilterGroup = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EntityTypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
EntityTypeFullName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthOrganizationUnitEntityRules", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthOrganizationUnitEntityRules_AbpAuthEntitites_EntityTy~",
column: x => x.EntityTypeId,
principalTable: "AbpAuthEntitites",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AbpAuthRoleEntityRules",
columns: table => new
{
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
RoleId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
RoleName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ExtraProperties = table.Column<string>(type: "longtext", 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"),
LastModificationTime = table.Column<DateTime>(type: "datetime(6)", nullable: true),
LastModifierId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
TenantId = table.Column<Guid>(type: "char(36)", nullable: true, collation: "ascii_general_ci"),
IsEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
Operation = table.Column<int>(type: "int", nullable: false),
FilterGroup = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EntityTypeId = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
EntityTypeFullName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AbpAuthRoleEntityRules", x => x.Id);
table.ForeignKey(
name: "FK_AbpAuthRoleEntityRules_AbpAuthEntitites_EntityTypeId",
column: x => x.EntityTypeId,
principalTable: "AbpAuthEntitites",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthEntitites_TypeFullName",
table: "AbpAuthEntitites",
column: "TypeFullName");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthEntityProperties_TypeInfoId_TypeFullName",
table: "AbpAuthEntityProperties",
columns: new[] { "TypeInfoId", "TypeFullName" });
migrationBuilder.CreateIndex(
name: "IX_AbpAuthOrganizationUnitEntityRules_EntityTypeId",
table: "AbpAuthOrganizationUnitEntityRules",
column: "EntityTypeId");
migrationBuilder.CreateIndex(
name: "IX_AbpAuthRoleEntityRules_EntityTypeId",
table: "AbpAuthRoleEntityRules",
column: "EntityTypeId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AbpAuthEntityProperties");
migrationBuilder.DropTable(
name: "AbpAuthOrganizationUnitEntityRules");
migrationBuilder.DropTable(
name: "AbpAuthRoleEntityRules");
migrationBuilder.DropTable(
name: "AbpAuthEntitites");
}
}
}

942
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515092715_Add-Allow-Properties.Designer.cs

@ -0,0 +1,942 @@
// <auto-generated />
using System;
using LY.MicroService.BackendAdmin.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.Abp.EntityFrameworkCore;
#nullable disable
namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
{
[DbContext(typeof(BackendAdminMigrationsDbContext))]
[Migration("20240515092715_Add-Allow-Properties")]
partial class AddAllowProperties
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "8.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.Property<Guid>("TypeInfoId")
.HasColumnType("char(36)");
b.Property<string>("ValueRange")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("ValueRange");
b.HasKey("Id");
b.HasIndex("TypeInfoId", "TypeFullName");
b.ToTable("AbpAuthEntityProperties", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAuditEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.HasKey("Id");
b.HasIndex("TypeFullName");
b.ToTable("AbpAuthEntitites", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowProperties")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("AllowProperties");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<string>("OrgCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("OrgCode");
b.Property<Guid>("OrgId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthOrganizationUnitEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowProperties")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("AllowProperties");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<Guid>("RoleId")
.HasColumnType("char(36)");
b.Property<string>("RoleName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("RoleName");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthRoleEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Editions.Edition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("char(36)")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.HasKey("Id");
b.HasIndex("DisplayName");
b.ToTable("AbpEditions", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnType("char(36)")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<DateTime?>("DisableTime")
.HasColumnType("datetime(6)");
b.Property<Guid?>("EditionId")
.HasColumnType("char(36)");
b.Property<DateTime?>("EnableTime")
.HasColumnType("datetime(6)");
b.Property<int>("EntityVersion")
.HasColumnType("int");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("NormalizedName")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.HasKey("Id");
b.HasIndex("EditionId");
b.HasIndex("Name");
b.HasIndex("NormalizedName");
b.ToTable("AbpTenants", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.TenantConnectionString", b =>
{
b.Property<Guid>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("Name")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.HasKey("TenantId", "Name");
b.ToTable("AbpTenantConnectionStrings", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.TextTemplating.TextTemplate", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Content")
.HasMaxLength(1048576)
.HasColumnType("longtext")
.HasColumnName("Content");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Culture")
.HasMaxLength(30)
.HasColumnType("varchar(30)")
.HasColumnName("Culture");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("DisplayName");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("Name");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name")
.HasDatabaseName("IX_Tenant_Text_Template_Name");
b.ToTable("AbpTextTemplates", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.TextTemplating.TextTemplateDefinition", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<string>("DefaultCultureName")
.HasMaxLength(30)
.HasColumnType("varchar(30)")
.HasColumnName("DefaultCultureName");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsInlineLocalized")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsLayout")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsStatic")
.HasColumnType("tinyint(1)");
b.Property<string>("Layout")
.HasMaxLength(60)
.HasColumnType("varchar(60)")
.HasColumnName("Layout");
b.Property<string>("LocalizationResourceName")
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("LocalizationResourceName");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("Name");
b.Property<string>("RenderEngine")
.HasMaxLength(30)
.HasColumnType("varchar(30)")
.HasColumnName("RenderEngine");
b.HasKey("Id");
b.ToTable("AbpTextTemplateDefinitions", (string)null);
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowedProviders")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("DefaultValue")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("Description")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("GroupName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<bool>("IsAvailableToHost")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsVisibleToClients")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ParentName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ValueType")
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.HasKey("Id");
b.HasIndex("GroupName");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpFeatures", (string)null);
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureGroupDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpFeatureGroups", (string)null);
});
modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey")
.IsUnique();
b.ToTable("AbpFeatureValues", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("GroupName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<byte>("MultiTenancySide")
.HasColumnType("tinyint unsigned");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ParentName")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("Providers")
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("StateCheckers")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.HasKey("Id");
b.HasIndex("GroupName");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpPermissions", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey")
.IsUnique();
b.ToTable("AbpPermissionGrants", (string)null);
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpPermissionGroups", (string)null);
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("ProviderKey")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("ProviderName")
.HasMaxLength(64)
.HasColumnType("varchar(64)");
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey")
.IsUnique();
b.ToTable("AbpSettings", (string)null);
});
modelBuilder.Entity("Volo.Abp.SettingManagement.SettingDefinitionRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DefaultValue")
.HasMaxLength(2048)
.HasColumnType("varchar(2048)");
b.Property<string>("Description")
.HasMaxLength(512)
.HasColumnType("varchar(512)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<string>("ExtraProperties")
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsEncrypted")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsInherited")
.HasColumnType("tinyint(1)");
b.Property<bool>("IsVisibleToClients")
.HasColumnType("tinyint(1)");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)");
b.Property<string>("Providers")
.HasMaxLength(1024)
.HasColumnType("varchar(1024)");
b.HasKey("Id");
b.HasIndex("Name")
.IsUnique();
b.ToTable("AbpSettingDefinitions", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "TypeInfo")
.WithMany("Properties")
.HasForeignKey("TypeInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.HasOne("LINGYUN.Abp.Saas.Editions.Edition", "Edition")
.WithMany()
.HasForeignKey("EditionId");
b.Navigation("Edition");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.TenantConnectionString", b =>
{
b.HasOne("LINGYUN.Abp.Saas.Tenants.Tenant", null)
.WithMany("ConnectionStrings")
.HasForeignKey("TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Navigation("Properties");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{
b.Navigation("ConnectionStrings");
});
#pragma warning restore 612, 618
}
}
}

42
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/20240515092715_Add-Allow-Properties.cs

@ -0,0 +1,42 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
{
/// <inheritdoc />
public partial class AddAllowProperties : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "AllowProperties",
table: "AbpAuthRoleEntityRules",
type: "varchar(512)",
maxLength: 512,
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<string>(
name: "AllowProperties",
table: "AbpAuthOrganizationUnitEntityRules",
type: "varchar(512)",
maxLength: 512,
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AllowProperties",
table: "AbpAuthRoleEntityRules");
migrationBuilder.DropColumn(
name: "AllowProperties",
table: "AbpAuthOrganizationUnitEntityRules");
}
}
}

289
aspnet-core/migrations/LY.MicroService.BackendAdmin.EntityFrameworkCore/Migrations/BackendAdminMigrationsDbContextModelSnapshot.cs

@ -21,6 +21,257 @@ namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
.HasAnnotation("ProductVersion", "8.0.0") .HasAnnotation("ProductVersion", "8.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.Property<Guid>("TypeInfoId")
.HasColumnType("char(36)");
b.Property<string>("ValueRange")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("ValueRange");
b.HasKey("Id");
b.HasIndex("TypeInfoId", "TypeFullName");
b.ToTable("AbpAuthEntityProperties", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("DisplayName");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsAuditEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(64)
.HasColumnType("varchar(64)")
.HasColumnName("Name");
b.Property<string>("TypeFullName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("TypeFullName");
b.HasKey("Id");
b.HasIndex("TypeFullName");
b.ToTable("AbpAuthEntitites", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowProperties")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("AllowProperties");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<string>("OrgCode")
.IsRequired()
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("OrgCode");
b.Property<Guid>("OrgId")
.HasColumnType("char(36)");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthOrganizationUnitEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<string>("AllowProperties")
.HasMaxLength(512)
.HasColumnType("varchar(512)")
.HasColumnName("AllowProperties");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasMaxLength(40)
.HasColumnType("varchar(40)")
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("EntityTypeFullName")
.HasColumnType("longtext");
b.Property<Guid>("EntityTypeId")
.HasColumnType("char(36)");
b.Property<string>("ExtraProperties")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("ExtraProperties");
b.Property<string>("FilterGroup")
.HasColumnType("longtext")
.HasColumnName("FilterGroup");
b.Property<bool>("IsEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnType("char(36)")
.HasColumnName("LastModifierId");
b.Property<int>("Operation")
.HasColumnType("int");
b.Property<Guid>("RoleId")
.HasColumnType("char(36)");
b.Property<string>("RoleName")
.IsRequired()
.HasMaxLength(256)
.HasColumnType("varchar(256)")
.HasColumnName("RoleName");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)")
.HasColumnName("TenantId");
b.HasKey("Id");
b.HasIndex("EntityTypeId");
b.ToTable("AbpAuthRoleEntityRules", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Editions.Edition", b => modelBuilder.Entity("LINGYUN.Abp.Saas.Editions.Edition", b =>
{ {
b.Property<Guid>("Id") b.Property<Guid>("Id")
@ -622,6 +873,39 @@ namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
b.ToTable("AbpSettingDefinitions", (string)null); b.ToTable("AbpSettingDefinitions", (string)null);
}); });
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityPropertyInfo", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "TypeInfo")
.WithMany("Properties")
.HasForeignKey("TypeInfoId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("TypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.OrganizationUnitEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.RoleEntityRule", b =>
{
b.HasOne("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", "EntityTypeInfo")
.WithMany()
.HasForeignKey("EntityTypeId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("EntityTypeInfo");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b => modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{ {
b.HasOne("LINGYUN.Abp.Saas.Editions.Edition", "Edition") b.HasOne("LINGYUN.Abp.Saas.Editions.Edition", "Edition")
@ -640,6 +924,11 @@ namespace LY.MicroService.BackendAdmin.EntityFrameworkCore.Migrations
.IsRequired(); .IsRequired();
}); });
modelBuilder.Entity("LINGYUN.Abp.DataProtectionManagement.EntityTypeInfo", b =>
{
b.Navigation("Properties");
});
modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b => modelBuilder.Entity("LINGYUN.Abp.Saas.Tenants.Tenant", b =>
{ {
b.Navigation("ConnectionStrings"); b.Navigation("ConnectionStrings");

49
aspnet-core/migrations/LY.MicroService.Platform.EntityFrameworkCore/PlatformDbMigrationEventHandler.cs

@ -1,5 +1,4 @@
using LINGYUN.Abp.Saas.Features; using LINGYUN.Abp.Saas.Tenants;
using LINGYUN.Abp.Saas.Tenants;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -53,37 +52,31 @@ public class PlatformDbMigrationEventHandler :
var hostDefaultConnectionString = Configuration.GetConnectionString(ConnectionStrings.DefaultConnectionStringName); var hostDefaultConnectionString = Configuration.GetConnectionString(ConnectionStrings.DefaultConnectionStringName);
using (CurrentTenant.Change(eventData.Id)) using (CurrentTenant.Change(eventData.Id))
{ {
// 租户删除时的资源回收策略 // 需要回收策略为回收且存在默认连接字符串且默认连接字符串与宿主不同
var strategyFeature = await FeatureChecker.GetOrNullAsync(SaasFeatureNames.Tenant.RecycleStrategy); if (eventData.Strategy == RecycleStrategy.Recycle && !eventData.DefaultConnectionString.IsNullOrWhiteSpace())
if (!strategyFeature.IsNullOrWhiteSpace() && Enum.TryParse<RecycleStrategy>(strategyFeature, out var strategy))
{ {
// 需要回收策略为回收且存在默认连接字符串且默认连接字符串与宿主不同 var hostConnection = new DbConnectionStringBuilder()
if (strategy == RecycleStrategy.Recycle && !eventData.DefaultConnectionString.IsNullOrWhiteSpace())
{ {
var hostConnection = new DbConnectionStringBuilder() ConnectionString = hostDefaultConnectionString,
{ };
ConnectionString = hostDefaultConnectionString, var tenantConnection = new DbConnectionStringBuilder()
}; {
var tenantConnection = new DbConnectionStringBuilder() ConnectionString = eventData.DefaultConnectionString,
{ };
ConnectionString = eventData.DefaultConnectionString, if (hostConnection.EquivalentTo(tenantConnection))
}; {
if (hostConnection.EquivalentTo(tenantConnection)) return;
{ }
return;
}
using var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true); using var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true);
var buildr = new DbContextOptionsBuilder(); var buildr = new DbContextOptionsBuilder();
buildr.UseMySql(eventData.DefaultConnectionString, ServerVersion.AutoDetect(eventData.DefaultConnectionString)); buildr.UseMySql(eventData.DefaultConnectionString, ServerVersion.AutoDetect(eventData.DefaultConnectionString));
await using var dbConnection = new DbContext(buildr.Options); await using var dbConnection = new DbContext(buildr.Options);
if ((await dbConnection.Database.GetAppliedMigrationsAsync()).Any()) if ((await dbConnection.Database.GetAppliedMigrationsAsync()).Any())
{ {
await dbConnection.Database.EnsureDeletedAsync(); await dbConnection.Database.EnsureDeletedAsync();
}
} }
} }
} }
} }
} }

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

Loading…
Cancel
Save