From 8684b9c8e5899971a73c32426fb2ec9203568791 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 10 Jul 2017 22:08:52 -0400 Subject: [PATCH] recompute full storage each time --- .../Repositories/IOrganizationRepository.cs | 2 +- src/Core/Repositories/IUserRepository.cs | 2 +- .../SqlServer/OrganizationRepository.cs | 4 +-- .../Repositories/SqlServer/UserRepository.cs | 4 +-- .../Services/Implementations/CipherService.cs | 9 +++--- .../Cipher_DeleteAttachment.sql | 11 ++----- .../Cipher_UpdateAttachment.sql | 5 ++-- .../Cipher_UpdateWithCollections.sql | 26 ++-------------- .../Organization_UpdateStorage.sql | 30 ++++++++++++++++--- .../Stored Procedures/User_UpdateStorage.sql | 30 ++++++++++++++++--- 10 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/Core/Repositories/IOrganizationRepository.cs b/src/Core/Repositories/IOrganizationRepository.cs index 826084c9a..3edf16606 100644 --- a/src/Core/Repositories/IOrganizationRepository.cs +++ b/src/Core/Repositories/IOrganizationRepository.cs @@ -8,6 +8,6 @@ namespace Bit.Core.Repositories public interface IOrganizationRepository : IRepository { Task> GetManyByUserIdAsync(Guid userId); - Task UpdateStorageAsync(Guid id, long storageIncrease); + Task UpdateStorageAsync(Guid id); } } diff --git a/src/Core/Repositories/IUserRepository.cs b/src/Core/Repositories/IUserRepository.cs index 57a945cf6..1dc773b22 100644 --- a/src/Core/Repositories/IUserRepository.cs +++ b/src/Core/Repositories/IUserRepository.cs @@ -9,6 +9,6 @@ namespace Bit.Core.Repositories Task GetByEmailAsync(string email); Task GetPublicKeyAsync(Guid id); Task GetAccountRevisionDateAsync(Guid id); - Task UpdateStorageAsync(Guid id, long storageIncrease); + Task UpdateStorageAsync(Guid id); } } diff --git a/src/Core/Repositories/SqlServer/OrganizationRepository.cs b/src/Core/Repositories/SqlServer/OrganizationRepository.cs index a5b151002..e5fe47102 100644 --- a/src/Core/Repositories/SqlServer/OrganizationRepository.cs +++ b/src/Core/Repositories/SqlServer/OrganizationRepository.cs @@ -32,13 +32,13 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task UpdateStorageAsync(Guid id, long storageIncrease) + public async Task UpdateStorageAsync(Guid id) { using(var connection = new SqlConnection(ConnectionString)) { await connection.ExecuteAsync( "[dbo].[Organization_UpdateStorage]", - new { Id = id, StorageIncrease = storageIncrease }, + new { Id = id }, commandType: CommandType.StoredProcedure, commandTimeout: 180); } diff --git a/src/Core/Repositories/SqlServer/UserRepository.cs b/src/Core/Repositories/SqlServer/UserRepository.cs index 33a489812..ed3d92a27 100644 --- a/src/Core/Repositories/SqlServer/UserRepository.cs +++ b/src/Core/Repositories/SqlServer/UserRepository.cs @@ -79,13 +79,13 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task UpdateStorageAsync(Guid id, long storageIncrease) + public async Task UpdateStorageAsync(Guid id) { using(var connection = new SqlConnection(ConnectionString)) { await connection.ExecuteAsync( $"[{Schema}].[{Table}_UpdateStorage]", - new { Id = id, StorageIncrease = storageIncrease }, + new { Id = id }, commandType: CommandType.StoredProcedure, commandTimeout: 180); } diff --git a/src/Core/Services/Implementations/CipherService.cs b/src/Core/Services/Implementations/CipherService.cs index 08f2b0f32..8b0bc9f70 100644 --- a/src/Core/Services/Implementations/CipherService.cs +++ b/src/Core/Services/Implementations/CipherService.cs @@ -302,7 +302,6 @@ namespace Bit.Core.Services { var attachments = cipher.GetAttachments(); var hasAttachments = (attachments?.Count ?? 0) > 0; - var storageAdjustment = attachments?.Sum(a => a.Value.Size) ?? 0; var updatedCipher = false; var migratedAttachments = false; @@ -329,8 +328,8 @@ namespace Bit.Core.Services throw new BadRequestException("This organization cannot use attachments."); } - var storageBytesRemaining = org.StorageBytesRemaining(); - if(storageBytesRemaining < storageAdjustment) + var storageAdjustment = attachments?.Sum(a => a.Value.Size) ?? 0; + if(org.StorageBytesRemaining() < storageAdjustment) { throw new BadRequestException("Not enough storage available for this organization."); } @@ -367,8 +366,8 @@ namespace Bit.Core.Services if(updatedCipher) { - await _userRepository.UpdateStorageAsync(sharingUserId, storageAdjustment); - await _organizationRepository.UpdateStorageAsync(organizationId, -1 * storageAdjustment); + await _userRepository.UpdateStorageAsync(sharingUserId); + await _organizationRepository.UpdateStorageAsync(organizationId); } foreach(var attachment in attachments) diff --git a/src/Sql/dbo/Stored Procedures/Cipher_DeleteAttachment.sql b/src/Sql/dbo/Stored Procedures/Cipher_DeleteAttachment.sql index f3b2f9781..69e6f2d92 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_DeleteAttachment.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_DeleteAttachment.sql @@ -8,21 +8,16 @@ BEGIN DECLARE @AttachmentIdKey VARCHAR(50) = CONCAT('"', @AttachmentId, '"') DECLARE @AttachmentIdPath VARCHAR(50) = CONCAT('$.', @AttachmentIdKey) - DECLARE @Attachments NVARCHAR(MAX) DECLARE @UserId UNIQUEIDENTIFIER DECLARE @OrganizationId UNIQUEIDENTIFIER SELECT @UserId = [UserId], - @OrganizationId = [OrganizationId], - @Attachments = [Attachments] + @OrganizationId = [OrganizationId] FROM [dbo].[Cipher] WHERE [Id] = @Id - DECLARE @AttachmentData NVARCHAR(MAX) = JSON_QUERY(@Attachments, @AttachmentIdPath) - DECLARE @Size BIGINT = (CAST(JSON_VALUE(@AttachmentData, '$.Size') AS BIGINT) * -1) - UPDATE [dbo].[Cipher] SET @@ -32,12 +27,12 @@ BEGIN IF @OrganizationId IS NOT NULL BEGIN - EXEC [dbo].[Organization_UpdateStorage] @OrganizationId, @Size + EXEC [dbo].[Organization_UpdateStorage] @OrganizationId EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId END ELSE IF @UserId IS NOT NULL BEGIN - EXEC [dbo].[User_UpdateStorage] @UserId, @Size + EXEC [dbo].[User_UpdateStorage] @UserId EXEC [dbo].[User_BumpAccountRevisionDate] @UserId END END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/Cipher_UpdateAttachment.sql b/src/Sql/dbo/Stored Procedures/Cipher_UpdateAttachment.sql index c12748e33..2461639b2 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_UpdateAttachment.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_UpdateAttachment.sql @@ -10,7 +10,6 @@ BEGIN DECLARE @AttachmentIdKey VARCHAR(50) = CONCAT('"', @AttachmentId, '"') DECLARE @AttachmentIdPath VARCHAR(50) = CONCAT('$.', @AttachmentIdKey) - DECLARE @Size BIGINT = CAST(JSON_VALUE(@AttachmentData, '$.Size') AS BIGINT) UPDATE [dbo].[Cipher] @@ -27,12 +26,12 @@ BEGIN IF @OrganizationId IS NOT NULL BEGIN - EXEC [dbo].[Organization_UpdateStorage] @OrganizationId, @Size + EXEC [dbo].[Organization_UpdateStorage] @OrganizationId EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId END ELSE IF @UserId IS NOT NULL BEGIN - EXEC [dbo].[User_UpdateStorage] @UserId, @Size + EXEC [dbo].[User_UpdateStorage] @UserId EXEC [dbo].[User_BumpAccountRevisionDate] @UserId END END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql b/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql index d29f42a43..24d89e18e 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql @@ -14,26 +14,6 @@ AS BEGIN SET NOCOUNT ON - DECLARE @CipherAttachments NVARCHAR(MAX) - SELECT - @CipherAttachments = [Attachments] - FROM - [dbo].[Cipher] - WHERE [Id] = @Id - - DECLARE @Size BIGINT - DECLARE @SizeDec BIGINT - - IF @CipherAttachments IS NOT NULL - BEGIN - SELECT - @Size = SUM(CAST(JSON_VALUE(value,'$.Size') AS BIGINT)) - FROM - OPENJSON(@CipherAttachments) - - SET @SizeDec = @Size * -1 - END - UPDATE [dbo].[Cipher] SET @@ -87,10 +67,10 @@ BEGIN WHERE [Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) - IF ISNULL(@Size, 0) > 0 + IF @Attachments IS NOT NULL BEGIN - EXEC [dbo].[Organization_UpdateStorage] @OrganizationId, @Size - EXEC [dbo].[User_UpdateStorage] @UserId, @SizeDec + EXEC [dbo].[Organization_UpdateStorage] @OrganizationId + EXEC [dbo].[User_UpdateStorage] @UserId END EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId diff --git a/src/Sql/dbo/Stored Procedures/Organization_UpdateStorage.sql b/src/Sql/dbo/Stored Procedures/Organization_UpdateStorage.sql index 675f5d722..17e8c8e35 100644 --- a/src/Sql/dbo/Stored Procedures/Organization_UpdateStorage.sql +++ b/src/Sql/dbo/Stored Procedures/Organization_UpdateStorage.sql @@ -1,15 +1,37 @@ CREATE PROCEDURE [dbo].[Organization_UpdateStorage] - @Id UNIQUEIDENTIFIER, - @StorageIncrease BIGINT - + @Id UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON + DECLARE @Storage BIGINT + + ;WITH [CTE] AS ( + SELECT + [Id], + ( + SELECT + SUM(CAST(JSON_VALUE(value,'$.Size') AS BIGINT)) + FROM + OPENJSON([Attachments]) + ) [Size] + FROM + [dbo].[Cipher] + ) + SELECT + @Storage = SUM([CTE].[Size]) + FROM + [dbo].[Cipher] C + LEFT JOIN + [CTE] ON C.[Id] = [CTE].[Id] + WHERE + C.[OrganizationId] = @Id + AND C.[Attachments] IS NOT NULL + UPDATE [dbo].[Organization] SET - [Storage] = ISNULL([Storage], 0) + @StorageIncrease, + [Storage] = @Storage, [RevisionDate] = GETUTCDATE() WHERE [Id] = @Id diff --git a/src/Sql/dbo/Stored Procedures/User_UpdateStorage.sql b/src/Sql/dbo/Stored Procedures/User_UpdateStorage.sql index 63d1b46de..c30e4d884 100644 --- a/src/Sql/dbo/Stored Procedures/User_UpdateStorage.sql +++ b/src/Sql/dbo/Stored Procedures/User_UpdateStorage.sql @@ -1,15 +1,37 @@ CREATE PROCEDURE [dbo].[User_UpdateStorage] - @Id UNIQUEIDENTIFIER, - @StorageIncrease BIGINT - + @Id UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON + DECLARE @Storage BIGINT + + ;WITH [CTE] AS ( + SELECT + [Id], + ( + SELECT + SUM(CAST(JSON_VALUE(value,'$.Size') AS BIGINT)) + FROM + OPENJSON([Attachments]) + ) [Size] + FROM + [dbo].[Cipher] + ) + SELECT + @Storage = SUM([CTE].[Size]) + FROM + [dbo].[Cipher] C + LEFT JOIN + [CTE] ON C.[Id] = [CTE].[Id] + WHERE + C.[UserId] = @Id + AND C.[Attachments] IS NOT NULL + UPDATE [dbo].[User] SET - [Storage] = ISNULL([Storage], 0) + @StorageIncrease, + [Storage] = @Storage, [RevisionDate] = GETUTCDATE() WHERE [Id] = @Id