From 479f2bdecef0c782299f6b4b179784ba860b2b1d Mon Sep 17 00:00:00 2001 From: colin Date: Mon, 3 Mar 2025 21:02:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(gdpr):=20=E5=A2=9E=E5=8A=A0=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E7=AB=AF=E4=BB=A3=E7=90=86=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbpGdprIdentityUserDataProvider.cs | 22 +- .../Gdpr/GdprRequestClientProxy.Generated.cs | 67 ++++ .../Abp/Gdpr/GdprRequestClientProxy.cs | 7 + .../ClientProxies/gdpr-generate-proxy.json | 362 ++++++++++++++++++ .../FodyWeavers.xml | 3 + .../FodyWeavers.xsd | 30 ++ .../LINGYUN.Abp.Gdpr.HttpApi.Client.csproj | 32 ++ .../Abp/Gdpr/AbpGdprHttpApiClientModule.cs | 24 ++ 8 files changed, 538 insertions(+), 9 deletions(-) create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.Generated.cs create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.cs create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/gdpr-generate-proxy.json create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xml create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xsd create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN.Abp.Gdpr.HttpApi.Client.csproj create mode 100644 aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN/Abp/Gdpr/AbpGdprHttpApiClientModule.cs diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.Domain.Identity/LINGYUN/Abp/Gdpr/Identity/AbpGdprIdentityUserDataProvider.cs b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.Domain.Identity/LINGYUN/Abp/Gdpr/Identity/AbpGdprIdentityUserDataProvider.cs index 604440e0b..7f0cbc367 100644 --- a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.Domain.Identity/LINGYUN/Abp/Gdpr/Identity/AbpGdprIdentityUserDataProvider.cs +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.Domain.Identity/LINGYUN/Abp/Gdpr/Identity/AbpGdprIdentityUserDataProvider.cs @@ -3,7 +3,6 @@ using Microsoft.Extensions.DependencyInjection; using System.Threading.Tasks; using Volo.Abp.Auditing; using Volo.Abp.Domain.ChangeTracking; -using Volo.Abp.Domain.Repositories; using Volo.Abp.Gdpr; using Volo.Abp.Identity; using Volo.Abp.Users; @@ -21,31 +20,36 @@ public class AbpGdprIdentityUserDataProvider: GdprUserDataProviderBase public async override Task DeleteAsync(GdprDeleteUserDataContext context) { - var identityUserRepository = context.ServiceProvider.GetRequiredService(); var identityUserManager = context.ServiceProvider.GetRequiredService(); var identityUser = await identityUserManager.GetByIdAsync(context.UserId); identityUser.Name = ""; identityUser.Surname = ""; - identityUser.SetIsActive(false); - - await identityUserRepository.EnsureCollectionLoadedAsync(identityUser, u => u.Claims); - - identityUser.Claims.Clear(); // TODO: 应设置为空字符串, 但是abp框架不允许Email为空 (await identityUserManager.SetEmailAsync(identityUser, $"{identityUser.UserName}@abp.io")).CheckErrors(); (await identityUserManager.SetPhoneNumberAsync(identityUser, "")).CheckErrors(); + // 清理身份标识 + var userClaims = await identityUserManager.GetClaimsAsync(identityUser); + (await identityUserManager.RemoveClaimsAsync(identityUser, userClaims)).CheckErrors(); + + // TODO: 是否需要清理第三方关联账户? + //var userLogins = await identityUserManager.GetLoginsAsync(identityUser); + //foreach (var userLogin in userLogins) + //{ + // (await identityUserManager.RemoveLoginAsync(identityUser, userLogin.LoginProvider, userLogin.ProviderKey)).CheckErrors(); + //} + (await identityUserManager.UpdateAsync(identityUser)).CheckErrors(); } [DisableEntityChangeTracking] public async override Task PorepareAsync(GdprPrepareUserDataContext context) { - var identityUserRepository = context.ServiceProvider.GetRequiredService(); - var identityUser = await identityUserRepository.GetAsync(context.UserId); + var identityUserManager = context.ServiceProvider.GetRequiredService(); + var identityUser = await identityUserManager.GetByIdAsync(context.UserId); var gdprDataInfo = new GdprDataInfo { diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.Generated.cs b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.Generated.cs new file mode 100644 index 000000000..72412accd --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.Generated.cs @@ -0,0 +1,67 @@ +// This file is automatically generated by ABP framework to use MVC Controllers from CSharp +using LINGYUN.Abp.Gdpr; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Content; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Client.ClientProxying; +using Volo.Abp.Http.Modeling; + +// ReSharper disable once CheckNamespace +namespace LINGYUN.Abp.Gdpr; + +[Dependency(ReplaceServices = true)] +[ExposeServices(typeof(IGdprRequestAppService), typeof(GdprRequestClientProxy))] +public partial class GdprRequestClientProxy : ClientProxyBase, IGdprRequestAppService +{ + public virtual async Task DeleteAsync(Guid id) + { + await RequestAsync(nameof(DeleteAsync), new ClientProxyRequestTypeValue + { + { typeof(Guid), id } + }); + } + + public virtual async Task DeletePersonalAccountAsync() + { + await RequestAsync(nameof(DeletePersonalAccountAsync)); + } + + public virtual async Task DeletePersonalDataAsync() + { + await RequestAsync(nameof(DeletePersonalDataAsync)); + } + + public virtual async Task GetAsync(Guid id) + { + return await RequestAsync(nameof(GetAsync), new ClientProxyRequestTypeValue + { + { typeof(Guid), id } + }); + } + + public virtual async Task> GetListAsync(GdprRequestGetListInput input) + { + return await RequestAsync>(nameof(GetListAsync), new ClientProxyRequestTypeValue + { + { typeof(GdprRequestGetListInput), input } + }); + } + + public virtual async Task DownloadPersonalDataAsync(Guid requestId) + { + return await RequestAsync(nameof(DownloadPersonalDataAsync), new ClientProxyRequestTypeValue + { + { typeof(Guid), requestId } + }); + } + + public virtual async Task PreparePersonalDataAsync() + { + await RequestAsync(nameof(PreparePersonalDataAsync)); + } +} diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.cs b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.cs new file mode 100644 index 000000000..d100d2f73 --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/LINGYUN/Abp/Gdpr/GdprRequestClientProxy.cs @@ -0,0 +1,7 @@ +// This file is part of GdprRequestClientProxy, you can customize it here +// ReSharper disable once CheckNamespace +namespace LINGYUN.Abp.Gdpr; + +public partial class GdprRequestClientProxy +{ +} diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/gdpr-generate-proxy.json b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/gdpr-generate-proxy.json new file mode 100644 index 000000000..504477dc9 --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/ClientProxies/gdpr-generate-proxy.json @@ -0,0 +1,362 @@ +{ + "modules": { + "gdpr": { + "rootPath": "gdpr", + "remoteServiceName": "Gdpr", + "controllers": { + "LINGYUN.Abp.Gdpr.GdprRequestController": { + "controllerName": "GdprRequest", + "controllerGroupName": "GdprRequest", + "isRemoteService": true, + "isIntegrationService": false, + "apiVersion": null, + "type": "LINGYUN.Abp.Gdpr.GdprRequestController", + "interfaces": [ + { + "type": "LINGYUN.Abp.Gdpr.IGdprRequestAppService", + "name": "IGdprRequestAppService", + "methods": [ + { + "name": "GetAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "LINGYUN.Abp.Gdpr.GdprRequestDto", + "typeSimple": "LINGYUN.Abp.Gdpr.GdprRequestDto" + } + }, + { + "name": "GetListAsync", + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "LINGYUN.Abp.Gdpr.GdprRequestGetListInput, LINGYUN.Abp.Gdpr.Application.Contracts", + "type": "LINGYUN.Abp.Gdpr.GdprRequestGetListInput", + "typeSimple": "LINGYUN.Abp.Gdpr.GdprRequestGetListInput", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + } + }, + { + "name": "DownloadPersonalDataAsync", + "parametersOnMethod": [ + { + "name": "requestId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "Volo.Abp.Content.IRemoteStreamContent", + "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" + } + }, + { + "name": "DeleteAsync", + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "PreparePersonalDataAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "DeletePersonalDataAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + }, + { + "name": "DeletePersonalAccountAsync", + "parametersOnMethod": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + } + } + ] + } + ], + "actions": { + "DeleteAsyncById": { + "uniqueName": "DeleteAsyncById", + "name": "DeleteAsync", + "httpMethod": "DELETE", + "url": "api/gdpr/requests/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "jsonName": null, + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + }, + "DeletePersonalAccountAsync": { + "uniqueName": "DeletePersonalAccountAsync", + "name": "DeletePersonalAccountAsync", + "httpMethod": "DELETE", + "url": "api/gdpr/requests/personal-account", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + }, + "DeletePersonalDataAsync": { + "uniqueName": "DeletePersonalDataAsync", + "name": "DeletePersonalDataAsync", + "httpMethod": "DELETE", + "url": "api/gdpr/requests/personal-data", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + }, + "GetAsyncById": { + "uniqueName": "GetAsyncById", + "name": "GetAsync", + "httpMethod": "GET", + "url": "api/gdpr/requests/{id}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "id", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "id", + "name": "id", + "jsonName": null, + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "LINGYUN.Abp.Gdpr.GdprRequestDto", + "typeSimple": "LINGYUN.Abp.Gdpr.GdprRequestDto" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + }, + "GetListAsyncByInput": { + "uniqueName": "GetListAsyncByInput", + "name": "GetListAsync", + "httpMethod": "GET", + "url": "api/gdpr/requests", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "LINGYUN.Abp.Gdpr.GdprRequestGetListInput, LINGYUN.Abp.Gdpr.Application.Contracts", + "type": "LINGYUN.Abp.Gdpr.GdprRequestGetListInput", + "typeSimple": "LINGYUN.Abp.Gdpr.GdprRequestGetListInput", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "CreationTime", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "ReadyTime", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "Sorting", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "SkipCount", + "jsonName": null, + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + }, + { + "nameOnMethod": "input", + "name": "MaxResultCount", + "jsonName": null, + "type": "System.Int32", + "typeSimple": "number", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "input" + } + ], + "returnValue": { + "type": "Volo.Abp.Application.Dtos.PagedResultDto", + "typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + }, + "DownloadPersonalDataAsyncByRequestId": { + "uniqueName": "DownloadPersonalDataAsyncByRequestId", + "name": "DownloadPersonalDataAsync", + "httpMethod": "GET", + "url": "api/gdpr/requests/personal-data/download/{requestId}", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "requestId", + "typeAsString": "System.Guid, System.Private.CoreLib", + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "requestId", + "name": "requestId", + "jsonName": null, + "type": "System.Guid", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": [], + "bindingSourceId": "Path", + "descriptorName": "" + } + ], + "returnValue": { + "type": "Volo.Abp.Content.IRemoteStreamContent", + "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + }, + "PreparePersonalDataAsync": { + "uniqueName": "PreparePersonalDataAsync", + "name": "PreparePersonalDataAsync", + "httpMethod": "POST", + "url": "api/gdpr/requests/personal-data/prepare", + "supportedVersions": [], + "parametersOnMethod": [], + "parameters": [], + "returnValue": { + "type": "System.Void", + "typeSimple": "System.Void" + }, + "allowAnonymous": false, + "implementFrom": "LINGYUN.Abp.Gdpr.IGdprRequestAppService" + } + } + } + } + } + }, + "types": {} +} \ No newline at end of file diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xml b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xsd b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xsd new file mode 100644 index 000000000..3f3946e28 --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN.Abp.Gdpr.HttpApi.Client.csproj b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN.Abp.Gdpr.HttpApi.Client.csproj new file mode 100644 index 000000000..ae1c2def6 --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN.Abp.Gdpr.HttpApi.Client.csproj @@ -0,0 +1,32 @@ + + + + + + + netstandard2.0;netstandard2.1;net8.0;net9.0 + LINGYUN.Abp.Gdpr.HttpApi.Client + LINGYUN.Abp.Gdpr.HttpApi.Client + false + false + false + + + + + + + + + + + + + + + + + + + + diff --git a/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN/Abp/Gdpr/AbpGdprHttpApiClientModule.cs b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN/Abp/Gdpr/AbpGdprHttpApiClientModule.cs new file mode 100644 index 000000000..d9c69640e --- /dev/null +++ b/aspnet-core/modules/gdpr/LINGYUN.Abp.Gdpr.HttpApi.Client/LINGYUN/Abp/Gdpr/AbpGdprHttpApiClientModule.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; +using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; + +namespace LINGYUN.Abp.Gdpr; + +[DependsOn( + typeof(AbpGdprApplicationContractsModule), + typeof(AbpHttpClientModule))] +public class AbpGdprHttpApiClientModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddStaticHttpClientProxies( + typeof(AbpGdprApplicationContractsModule).Assembly, + GdprRemoteServiceConsts.RemoteServiceName); + + Configure(options => + { + options.FileSets.AddEmbedded(); + }); + } +}