mirror of
https://github.com/bitwarden/server.git
synced 2025-02-16 01:51:21 +01:00
[Soft-Delete] Simplify the data-tier, removed extra sprocs and reuse update
This commit is contained in:
parent
f6044f0d00
commit
d07f27f274
@ -32,9 +32,7 @@ namespace Bit.Core.Repositories
|
||||
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Folder> folders);
|
||||
Task CreateAsync(IEnumerable<Cipher> ciphers, IEnumerable<Collection> collections,
|
||||
IEnumerable<CollectionCipher> collectionCiphers);
|
||||
Task SoftDeleteAsync(Cipher obj);
|
||||
Task SoftDeleteAsync(IEnumerable<Guid> ids, Guid userId);
|
||||
Task RestoreAsync(Cipher obj);
|
||||
Task RestoreAsync(IEnumerable<Guid> ids, Guid userId);
|
||||
}
|
||||
}
|
||||
|
@ -577,17 +577,6 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SoftDeleteAsync(Cipher obj)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.ExecuteAsync(
|
||||
$"[{Schema}].[Cipher_SoftDeleteById]",
|
||||
new { obj.Id },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SoftDeleteAsync(IEnumerable<Guid> ids, Guid userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
@ -599,17 +588,6 @@ namespace Bit.Core.Repositories.SqlServer
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RestoreAsync(Cipher obj)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
{
|
||||
var results = await connection.ExecuteAsync(
|
||||
$"[{Schema}].[Cipher_RestoreById]",
|
||||
new { obj.Id },
|
||||
commandType: CommandType.StoredProcedure);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RestoreAsync(IEnumerable<Guid> ids, Guid userId)
|
||||
{
|
||||
using (var connection = new SqlConnection(ConnectionString))
|
||||
|
@ -671,7 +671,16 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("You do not have permissions to soft delete this.");
|
||||
}
|
||||
|
||||
await _cipherRepository.SoftDeleteAsync(cipher);
|
||||
if (cipher.DeletedDate.HasValue)
|
||||
{
|
||||
// Already soft-deleted, we can safely ignore this
|
||||
return;
|
||||
}
|
||||
|
||||
cipher.DeletedDate = DateTime.UtcNow;
|
||||
cipher.RevisionDate = DateTime.UtcNow;
|
||||
|
||||
await _cipherRepository.UpsertAsync(cipher);
|
||||
await _eventService.LogCipherEventAsync(cipher, EventType.Cipher_SoftDeleted);
|
||||
|
||||
// push
|
||||
@ -704,7 +713,16 @@ namespace Bit.Core.Services
|
||||
throw new BadRequestException("You do not have permissions to delete this.");
|
||||
}
|
||||
|
||||
await _cipherRepository.RestoreAsync(cipher);
|
||||
if (!cipher.DeletedDate.HasValue)
|
||||
{
|
||||
// Already restored, we can safely ignore this
|
||||
return;
|
||||
}
|
||||
|
||||
cipher.DeletedDate = null;
|
||||
cipher.RevisionDate = DateTime.UtcNow;
|
||||
|
||||
await _cipherRepository.UpsertAsync(cipher);
|
||||
await _eventService.LogCipherEventAsync(cipher, EventType.Cipher_Restored);
|
||||
|
||||
// push
|
||||
|
@ -262,8 +262,6 @@
|
||||
<Build Include="dbo\Stored Procedures\Policy_ReadByOrganizationIdType.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Policy_ReadByUserId.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Cipher_Restore.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Cipher_RestoreById.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Cipher_SoftDelete.sql" />
|
||||
<Build Include="dbo\Stored Procedures\Cipher_SoftDeleteById.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -13,7 +13,7 @@
|
||||
@Favorite BIT,
|
||||
@Edit BIT, -- not used
|
||||
@OrganizationUseTotp BIT, -- not used
|
||||
@DeletedDate DATETIME2(7) -- not used
|
||||
@DeletedDate DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -31,7 +31,8 @@ BEGIN
|
||||
[Favorites],
|
||||
[Folders],
|
||||
[CreationDate],
|
||||
[RevisionDate]
|
||||
[RevisionDate],
|
||||
[DeletedDate]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@ -43,7 +44,8 @@ BEGIN
|
||||
CASE WHEN @Favorite = 1 THEN CONCAT('{', @UserIdKey, ':true}') ELSE NULL END,
|
||||
CASE WHEN @FolderId IS NOT NULL THEN CONCAT('{', @UserIdKey, ':"', @FolderId, '"', '}') ELSE NULL END,
|
||||
@CreationDate,
|
||||
@RevisionDate
|
||||
@RevisionDate,
|
||||
@DeletedDate
|
||||
)
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
|
@ -13,7 +13,7 @@
|
||||
@Favorite BIT,
|
||||
@Edit BIT, -- not used
|
||||
@OrganizationUseTotp BIT, -- not used
|
||||
@DeletedDate DATETIME2(7), -- not used
|
||||
@DeletedDate DATETIME2(7),
|
||||
@CollectionIds AS [dbo].[GuidIdArray] READONLY
|
||||
AS
|
||||
BEGIN
|
||||
|
@ -13,7 +13,7 @@
|
||||
@Favorite BIT,
|
||||
@Edit BIT, -- not used
|
||||
@OrganizationUseTotp BIT, -- not used
|
||||
@DeletedDate DATETIME2(2) -- not used
|
||||
@DeletedDate DATETIME2(2)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -47,7 +47,8 @@ BEGIN
|
||||
JSON_MODIFY([Favorites], @UserIdPath, NULL)
|
||||
END,
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[DeletedDate] = @DeletedDate
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7) -- not used
|
||||
@DeletedDate DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -25,7 +25,8 @@ BEGIN
|
||||
[Folders],
|
||||
[Attachments],
|
||||
[CreationDate],
|
||||
[RevisionDate]
|
||||
[RevisionDate],
|
||||
[DeletedDate]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@ -38,7 +39,8 @@ BEGIN
|
||||
@Folders,
|
||||
@Attachments,
|
||||
@CreationDate,
|
||||
@RevisionDate
|
||||
@RevisionDate,
|
||||
@DeletedDate
|
||||
)
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
|
@ -9,7 +9,7 @@
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7), -- not used
|
||||
@DeletedDate DATETIME2(7),
|
||||
@CollectionIds AS [dbo].[GuidIdArray] READONLY
|
||||
AS
|
||||
BEGIN
|
||||
|
@ -1,34 +0,0 @@
|
||||
CREATE PROCEDURE [dbo].[Cipher_RestoreById]
|
||||
@Id UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
DECLARE @UserId UNIQUEIDENTIFIER
|
||||
DECLARE @OrganizationId UNIQUEIDENTIFIER
|
||||
|
||||
SELECT TOP 1
|
||||
@UserId = [UserId],
|
||||
@OrganizationId = [OrganizationId]
|
||||
FROM
|
||||
[dbo].[Cipher]
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
UPDATE
|
||||
[dbo].[Cipher]
|
||||
SET
|
||||
[DeletedDate] = NULL,
|
||||
[RevisionDate] = GETUTCDATE()
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId
|
||||
END
|
||||
ELSE IF @UserId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDate] @UserId
|
||||
END
|
||||
END
|
@ -1,35 +0,0 @@
|
||||
CREATE PROCEDURE [dbo].[Cipher_SoftDeleteById]
|
||||
@Id UNIQUEIDENTIFIER
|
||||
WITH RECOMPILE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
DECLARE @UserId UNIQUEIDENTIFIER
|
||||
DECLARE @OrganizationId UNIQUEIDENTIFIER
|
||||
|
||||
SELECT TOP 1
|
||||
@UserId = [UserId],
|
||||
@OrganizationId = [OrganizationId]
|
||||
FROM
|
||||
[dbo].[Cipher]
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
UPDATE
|
||||
[dbo].[Cipher]
|
||||
SET
|
||||
[DeletedDate] = SYSUTCDATETIME(),
|
||||
[RevisionDate] = GETUTCDATE()
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId
|
||||
END
|
||||
ELSE IF @UserId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDate] @UserId
|
||||
END
|
||||
END
|
@ -9,7 +9,7 @@
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7) -- not used
|
||||
@DeletedDate DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -25,7 +25,8 @@ BEGIN
|
||||
[Folders] = @Folders,
|
||||
[Attachments] = @Attachments,
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[DeletedDate] = @DeletedDate
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7), -- not used
|
||||
@DeletedDate DATETIME2(7),
|
||||
@CollectionIds AS [dbo].[GuidIdArray] READONLY
|
||||
AS
|
||||
BEGIN
|
||||
@ -34,9 +34,9 @@ BEGIN
|
||||
[OrganizationId] = @OrganizationId,
|
||||
[Data] = @Data,
|
||||
[Attachments] = @Attachments,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[DeletedDate] = @DeletedDate
|
||||
-- No need to update CreationDate, Favorites, Folders, or Type since that data will not change
|
||||
-- Do not update DeletedDate because that is a separate atomic action
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
|
@ -2,8 +2,9 @@
|
||||
* Revert [Cipher] deletes/gets to original versions
|
||||
* - No longer needs to have the deleted flag on reads (always read all)
|
||||
* - No longer needs to have the permanent flag on deletes (they just are)
|
||||
* + Added ability to restore a soft-deleted cipher
|
||||
* + Added DeletedDate value to updates/create sprocs
|
||||
* + Added ability to bulk soft-delete a cipher
|
||||
* + Added ability to bulk restore a soft-deleted cipher
|
||||
* + Added DeletedDate value to updates/create sprocs (individual records)
|
||||
*/
|
||||
IF OBJECT_ID('[dbo].[Cipher_Restore]') IS NOT NULL
|
||||
BEGIN
|
||||
@ -75,41 +76,6 @@ BEGIN
|
||||
DROP PROCEDURE [dbo].[Cipher_RestoreById];
|
||||
END
|
||||
GO
|
||||
CREATE PROCEDURE [dbo].[Cipher_RestoreById]
|
||||
@Id UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
DECLARE @UserId UNIQUEIDENTIFIER
|
||||
DECLARE @OrganizationId UNIQUEIDENTIFIER
|
||||
|
||||
SELECT TOP 1
|
||||
@UserId = [UserId],
|
||||
@OrganizationId = [OrganizationId]
|
||||
FROM
|
||||
[dbo].[Cipher]
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
UPDATE
|
||||
[dbo].[Cipher]
|
||||
SET
|
||||
[DeletedDate] = NULL,
|
||||
[RevisionDate] = GETUTCDATE()
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId
|
||||
END
|
||||
ELSE IF @UserId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDate] @UserId
|
||||
END
|
||||
END
|
||||
GO
|
||||
|
||||
IF OBJECT_ID('[dbo].[CipherDetails_ReadByUserId]') IS NOT NULL
|
||||
BEGIN
|
||||
@ -398,42 +364,6 @@ BEGIN
|
||||
DROP PROCEDURE [dbo].[Cipher_SoftDeleteById];
|
||||
END
|
||||
GO
|
||||
CREATE PROCEDURE [dbo].[Cipher_SoftDeleteById]
|
||||
@Id UNIQUEIDENTIFIER
|
||||
WITH RECOMPILE
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
DECLARE @UserId UNIQUEIDENTIFIER
|
||||
DECLARE @OrganizationId UNIQUEIDENTIFIER
|
||||
|
||||
SELECT TOP 1
|
||||
@UserId = [UserId],
|
||||
@OrganizationId = [OrganizationId]
|
||||
FROM
|
||||
[dbo].[Cipher]
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
UPDATE
|
||||
[dbo].[Cipher]
|
||||
SET
|
||||
[DeletedDate] = SYSUTCDATETIME(),
|
||||
[RevisionDate] = GETUTCDATE()
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId
|
||||
END
|
||||
ELSE IF @UserId IS NOT NULL
|
||||
BEGIN
|
||||
EXEC [dbo].[User_BumpAccountRevisionDate] @UserId
|
||||
END
|
||||
END
|
||||
GO
|
||||
|
||||
IF OBJECT_ID('[dbo].[Cipher_Create]') IS NOT NULL
|
||||
BEGIN
|
||||
@ -451,7 +381,7 @@ CREATE PROCEDURE [dbo].[Cipher_Create]
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7) -- not used
|
||||
@DeletedDate DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -467,7 +397,8 @@ BEGIN
|
||||
[Folders],
|
||||
[Attachments],
|
||||
[CreationDate],
|
||||
[RevisionDate]
|
||||
[RevisionDate],
|
||||
[DeletedDate]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@ -480,7 +411,8 @@ BEGIN
|
||||
@Folders,
|
||||
@Attachments,
|
||||
@CreationDate,
|
||||
@RevisionDate
|
||||
@RevisionDate,
|
||||
@DeletedDate
|
||||
)
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
@ -514,7 +446,7 @@ CREATE PROCEDURE [dbo].[CipherDetails_Create]
|
||||
@Favorite BIT,
|
||||
@Edit BIT, -- not used
|
||||
@OrganizationUseTotp BIT, -- not used
|
||||
@DeletedDate DATETIME2(7) -- not used
|
||||
@DeletedDate DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -532,7 +464,8 @@ BEGIN
|
||||
[Favorites],
|
||||
[Folders],
|
||||
[CreationDate],
|
||||
[RevisionDate]
|
||||
[RevisionDate],
|
||||
[DeletedDate]
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
@ -544,7 +477,8 @@ BEGIN
|
||||
CASE WHEN @Favorite = 1 THEN CONCAT('{', @UserIdKey, ':true}') ELSE NULL END,
|
||||
CASE WHEN @FolderId IS NOT NULL THEN CONCAT('{', @UserIdKey, ':"', @FolderId, '"', '}') ELSE NULL END,
|
||||
@CreationDate,
|
||||
@RevisionDate
|
||||
@RevisionDate,
|
||||
@DeletedDate
|
||||
)
|
||||
|
||||
IF @OrganizationId IS NOT NULL
|
||||
@ -574,7 +508,7 @@ CREATE PROCEDURE [dbo].[Cipher_CreateWithCollections]
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7), -- not used
|
||||
@DeletedDate DATETIME2(7),
|
||||
@CollectionIds AS [dbo].[GuidIdArray] READONLY
|
||||
AS
|
||||
BEGIN
|
||||
@ -608,7 +542,7 @@ CREATE PROCEDURE [dbo].[CipherDetails_CreateWithCollections]
|
||||
@Favorite BIT,
|
||||
@Edit BIT, -- not used
|
||||
@OrganizationUseTotp BIT, -- not used
|
||||
@DeletedDate DATETIME2(7), -- not used
|
||||
@DeletedDate DATETIME2(7),
|
||||
@CollectionIds AS [dbo].[GuidIdArray] READONLY
|
||||
AS
|
||||
BEGIN
|
||||
@ -638,7 +572,7 @@ CREATE PROCEDURE [dbo].[Cipher_Update]
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7) -- not used
|
||||
@DeletedDate DATETIME2(7)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -654,7 +588,8 @@ BEGIN
|
||||
[Folders] = @Folders,
|
||||
[Attachments] = @Attachments,
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[DeletedDate] = @DeletedDate
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
@ -685,7 +620,7 @@ CREATE PROCEDURE [dbo].[Cipher_UpdateWithCollections]
|
||||
@Attachments NVARCHAR(MAX),
|
||||
@CreationDate DATETIME2(7),
|
||||
@RevisionDate DATETIME2(7),
|
||||
@DeletedDate DATETIME2(7), -- not used
|
||||
@DeletedDate DATETIME2(7),
|
||||
@CollectionIds AS [dbo].[GuidIdArray] READONLY
|
||||
AS
|
||||
BEGIN
|
||||
@ -710,9 +645,9 @@ BEGIN
|
||||
[OrganizationId] = @OrganizationId,
|
||||
[Data] = @Data,
|
||||
[Attachments] = @Attachments,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[DeletedDate] = @DeletedDate
|
||||
-- No need to update CreationDate, Favorites, Folders, or Type since that data will not change
|
||||
-- Do not update DeletedDate because that is a separate atomic action
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
@ -750,7 +685,7 @@ CREATE PROCEDURE [dbo].[CipherDetails_Update]
|
||||
@Favorite BIT,
|
||||
@Edit BIT, -- not used
|
||||
@OrganizationUseTotp BIT, -- not used
|
||||
@DeletedDate DATETIME2(2) -- not used
|
||||
@DeletedDate DATETIME2(2)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
@ -784,7 +719,8 @@ BEGIN
|
||||
JSON_MODIFY([Favorites], @UserIdPath, NULL)
|
||||
END,
|
||||
[CreationDate] = @CreationDate,
|
||||
[RevisionDate] = @RevisionDate
|
||||
[RevisionDate] = @RevisionDate,
|
||||
[DeletedDate] = @DeletedDate
|
||||
WHERE
|
||||
[Id] = @Id
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user