From a042fd10f18384532a6de3f6b356ed09aaea4dda Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Wed, 25 Oct 2017 21:26:09 -0400 Subject: [PATCH] apis for purging user vault --- src/Api/Controllers/CiphersController.cs | 7 ++++ src/Core/Repositories/ICipherRepository.cs | 1 + .../SqlServer/CipherRepository.cs | 11 ++++++ src/Sql/Sql.sqlproj | 1 + .../Cipher_DeleteByUserId.sql | 28 +++++++++++++++ .../2017-10-25_00_OrgUserUpdates.sql | 36 +++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 src/Sql/dbo/Stored Procedures/Cipher_DeleteByUserId.sql diff --git a/src/Api/Controllers/CiphersController.cs b/src/Api/Controllers/CiphersController.cs index 37482fb3d7..d0f8c011eb 100644 --- a/src/Api/Controllers/CiphersController.cs +++ b/src/Api/Controllers/CiphersController.cs @@ -353,6 +353,13 @@ namespace Bit.Api.Controllers string.IsNullOrWhiteSpace(model.FolderId) ? (Guid?)null : new Guid(model.FolderId), userId); } + [HttpPost("purge")] + public async Task PostPurge() + { + var userId = _userService.GetProperUserId(User).Value; + await _cipherRepository.DeleteByUserIdAsync(userId); + } + [HttpPost("{id}/attachment")] [DisableFormValueModelBinding] public async Task PostAttachment(string id) diff --git a/src/Core/Repositories/ICipherRepository.cs b/src/Core/Repositories/ICipherRepository.cs index 133a6ab263..4b204f072d 100644 --- a/src/Core/Repositories/ICipherRepository.cs +++ b/src/Core/Repositories/ICipherRepository.cs @@ -25,6 +25,7 @@ namespace Bit.Core.Repositories Task DeleteAttachmentAsync(Guid cipherId, string attachmentId); Task DeleteAsync(IEnumerable ids, Guid userId); Task MoveAsync(IEnumerable ids, Guid? folderId, Guid userId); + Task DeleteByUserIdAsync(Guid userId); Task UpdateUserKeysAndCiphersAsync(User user, IEnumerable ciphers, IEnumerable folders); Task CreateAsync(IEnumerable ciphers, IEnumerable folders); Task CreateAsync(IEnumerable ciphers, IEnumerable collections, diff --git a/src/Core/Repositories/SqlServer/CipherRepository.cs b/src/Core/Repositories/SqlServer/CipherRepository.cs index 9a1d999742..0481689cba 100644 --- a/src/Core/Repositories/SqlServer/CipherRepository.cs +++ b/src/Core/Repositories/SqlServer/CipherRepository.cs @@ -235,6 +235,17 @@ namespace Bit.Core.Repositories.SqlServer } } + public async Task DeleteByUserIdAsync(Guid userId) + { + using(var connection = new SqlConnection(ConnectionString)) + { + var results = await connection.ExecuteAsync( + $"[{Schema}].[Cipher_DeleteByUserId]", + new { UserId = userId }, + commandType: CommandType.StoredProcedure); + } + } + public Task UpdateUserKeysAndCiphersAsync(User user, IEnumerable ciphers, IEnumerable folders) { using(var connection = new SqlConnection(ConnectionString)) diff --git a/src/Sql/Sql.sqlproj b/src/Sql/Sql.sqlproj index 942f5b89f9..08040a0c30 100644 --- a/src/Sql/Sql.sqlproj +++ b/src/Sql/Sql.sqlproj @@ -213,5 +213,6 @@ + \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/Cipher_DeleteByUserId.sql b/src/Sql/dbo/Stored Procedures/Cipher_DeleteByUserId.sql new file mode 100644 index 0000000000..2718234562 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/Cipher_DeleteByUserId.sql @@ -0,0 +1,28 @@ +CREATE PROCEDURE [dbo].[Cipher_DeleteByUserId] + @UserId AS UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + DECLARE @BatchSize INT = 100 + + -- Delete ciphers + WHILE @BatchSize > 0 + BEGIN + BEGIN TRANSACTION Cipher_DeleteByUserId_Ciphers + + DELETE TOP(@BatchSize) + FROM + [dbo].[Cipher] + WHERE + [UserId] = @UserId + + SET @BatchSize = @@ROWCOUNT + + COMMIT TRANSACTION Cipher_DeleteByUserId_Ciphers + END + + -- Cleanup user + EXEC [dbo].[User_UpdateStorage] @UserId + EXEC [dbo].[User_BumpAccountRevisionDate] @UserId +END \ No newline at end of file diff --git a/util/Setup/DbScripts/2017-10-25_00_OrgUserUpdates.sql b/util/Setup/DbScripts/2017-10-25_00_OrgUserUpdates.sql index f6d8ba3696..b4a1b4d34b 100644 --- a/util/Setup/DbScripts/2017-10-25_00_OrgUserUpdates.sql +++ b/util/Setup/DbScripts/2017-10-25_00_OrgUserUpdates.sql @@ -294,3 +294,39 @@ BEGIN [Id] = @Id END GO + +IF OBJECT_ID('[dbo].[Cipher_DeleteByUserId]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[Cipher_DeleteByUserId] +END +GO + +CREATE PROCEDURE [dbo].[Cipher_DeleteByUserId] + @UserId AS UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + DECLARE @BatchSize INT = 100 + + -- Delete ciphers + WHILE @BatchSize > 0 + BEGIN + BEGIN TRANSACTION Cipher_DeleteByUserId_Ciphers + + DELETE TOP(@BatchSize) + FROM + [dbo].[Cipher] + WHERE + [UserId] = @UserId + + SET @BatchSize = @@ROWCOUNT + + COMMIT TRANSACTION Cipher_DeleteByUserId_Ciphers + END + + -- Cleanup user + EXEC [dbo].[User_UpdateStorage] @UserId + EXEC [dbo].[User_BumpAccountRevisionDate] @UserId +END +GO