From 53caacb8704196d2309aad320353d1d4036c5664 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 23 Aug 2018 23:46:18 -0400 Subject: [PATCH] fix availablecollections queries for groups join --- .../Cipher_UpdateWithCollections.sql | 2 +- .../CollectionCipher_UpdateCollections.sql | 2 +- ...tionCipher_UpdateCollectionsForCiphers.sql | 2 +- .../Setup/DbScripts/2018-08-14_00_UserKdf.sql | 248 ++++++++++++++++++ 4 files changed, 251 insertions(+), 3 deletions(-) diff --git a/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql b/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql index ebdd3a3de1..15e7cc388b 100644 --- a/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql +++ b/src/Sql/dbo/Stored Procedures/Cipher_UpdateWithCollections.sql @@ -34,7 +34,7 @@ BEGIN LEFT JOIN [dbo].[Group] G ON G.[Id] = GU.[GroupId] LEFT JOIN - [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[GroupId] = GU.[GroupId] + [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] WHERE O.[Id] = @OrganizationId AND O.[Enabled] = 1 diff --git a/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollections.sql b/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollections.sql index 8951c08d06..cdefe8b1ce 100644 --- a/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollections.sql +++ b/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollections.sql @@ -31,7 +31,7 @@ BEGIN LEFT JOIN [dbo].[Group] G ON G.[Id] = GU.[GroupId] LEFT JOIN - [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[GroupId] = GU.[GroupId] + [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] WHERE O.[Id] = @OrgId AND O.[Enabled] = 1 diff --git a/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollectionsForCiphers.sql b/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollectionsForCiphers.sql index 4e0dccd646..0bcb0860f1 100644 --- a/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollectionsForCiphers.sql +++ b/src/Sql/dbo/Stored Procedures/CollectionCipher_UpdateCollectionsForCiphers.sql @@ -27,7 +27,7 @@ BEGIN LEFT JOIN [dbo].[Group] G ON G.[Id] = GU.[GroupId] LEFT JOIN - [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[GroupId] = GU.[GroupId] + [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] WHERE O.[Id] = @OrganizationId AND O.[Enabled] = 1 diff --git a/util/Setup/DbScripts/2018-08-14_00_UserKdf.sql b/util/Setup/DbScripts/2018-08-14_00_UserKdf.sql index 50b0a3f05a..16ec439037 100644 --- a/util/Setup/DbScripts/2018-08-14_00_UserKdf.sql +++ b/util/Setup/DbScripts/2018-08-14_00_UserKdf.sql @@ -245,3 +245,251 @@ BEGIN [Email] = @Email END GO + +IF OBJECT_ID('[dbo].[Cipher_UpdateWithCollections]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[Cipher_UpdateWithCollections] +END +GO + +CREATE PROCEDURE [dbo].[Cipher_UpdateWithCollections] + @Id UNIQUEIDENTIFIER, + @UserId UNIQUEIDENTIFIER, + @OrganizationId UNIQUEIDENTIFIER, + @Type TINYINT, + @Data NVARCHAR(MAX), + @Favorites NVARCHAR(MAX), + @Folders NVARCHAR(MAX), + @Attachments NVARCHAR(MAX), + @CreationDate DATETIME2(7), + @RevisionDate DATETIME2(7), + @CollectionIds AS [dbo].[GuidIdArray] READONLY +AS +BEGIN + SET NOCOUNT ON + + CREATE TABLE #AvailableCollections ( + [Id] UNIQUEIDENTIFIER + ) + + INSERT INTO #AvailableCollections + SELECT + C.[Id] + FROM + [dbo].[Collection] C + INNER JOIN + [Organization] O ON O.[Id] = C.[OrganizationId] + INNER JOIN + [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId + LEFT JOIN + [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id] + LEFT JOIN + [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] + LEFT JOIN + [dbo].[Group] G ON G.[Id] = GU.[GroupId] + LEFT JOIN + [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] + WHERE + O.[Id] = @OrganizationId + AND O.[Enabled] = 1 + AND OU.[Status] = 2 -- Confirmed + AND ( + OU.[AccessAll] = 1 + OR CU.[ReadOnly] = 0 + OR G.[AccessAll] = 1 + OR CG.[ReadOnly] = 0 + ) + + IF (SELECT COUNT(1) FROM #AvailableCollections) < 1 + BEGIN + -- No writable collections available to share with in this organization. + SELECT -1 -- -1 = Failure + RETURN + END + + UPDATE + [dbo].[Cipher] + SET + [UserId] = NULL, + [OrganizationId] = @OrganizationId, + [Data] = @Data, + [Attachments] = @Attachments, + [RevisionDate] = @RevisionDate + -- No need to update CreationDate, Favorites, Folders, or Type since that data will not change + WHERE + [Id] = @Id + + INSERT INTO [dbo].[CollectionCipher] + ( + [CollectionId], + [CipherId] + ) + SELECT + [Id], + @Id + FROM + @CollectionIds + WHERE + [Id] IN (SELECT [Id] FROM #AvailableCollections) + + IF @Attachments IS NOT NULL + BEGIN + EXEC [dbo].[Organization_UpdateStorage] @OrganizationId + EXEC [dbo].[User_UpdateStorage] @UserId + END + + EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId + + SELECT 0 -- 0 = Success +END +GO + +IF OBJECT_ID('[dbo].[CollectionCipher_UpdateCollections]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[CollectionCipher_UpdateCollections] +END +GO + +CREATE PROCEDURE [dbo].[CollectionCipher_UpdateCollections] + @CipherId UNIQUEIDENTIFIER, + @UserId UNIQUEIDENTIFIER, + @CollectionIds AS [dbo].[GuidIdArray] READONLY +AS +BEGIN + SET NOCOUNT ON + + DECLARE @OrgId UNIQUEIDENTIFIER = ( + SELECT TOP 1 + [OrganizationId] + FROM + [dbo].[Cipher] + WHERE + [Id] = @CipherId + ) + + ;WITH [AvailableCollectionsCTE] AS( + SELECT + C.[Id] + FROM + [dbo].[Collection] C + INNER JOIN + [Organization] O ON O.[Id] = C.[OrganizationId] + INNER JOIN + [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId + LEFT JOIN + [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id] + LEFT JOIN + [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] + LEFT JOIN + [dbo].[Group] G ON G.[Id] = GU.[GroupId] + LEFT JOIN + [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] + WHERE + O.[Id] = @OrgId + AND O.[Enabled] = 1 + AND OU.[Status] = 2 -- Confirmed + AND ( + OU.[AccessAll] = 1 + OR CU.[ReadOnly] = 0 + OR G.[AccessAll] = 1 + OR CG.[ReadOnly] = 0 + ) + ) + MERGE + [dbo].[CollectionCipher] AS [Target] + USING + @CollectionIds AS [Source] + ON + [Target].[CollectionId] = [Source].[Id] + AND [Target].[CipherId] = @CipherId + WHEN NOT MATCHED BY TARGET + AND [Source].[Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) THEN + INSERT VALUES + ( + [Source].[Id], + @CipherId + ) + WHEN NOT MATCHED BY SOURCE + AND [Target].[CipherId] = @CipherId + AND [Target].[CollectionId] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) THEN + DELETE + ; + + IF @OrgId IS NOT NULL + BEGIN + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrgId + END +END +GO + +IF OBJECT_ID('[dbo].[CollectionCipher_UpdateCollectionsForCiphers]') IS NOT NULL +BEGIN + DROP PROCEDURE [dbo].[CollectionCipher_UpdateCollectionsForCiphers] +END +GO + +CREATE PROCEDURE [dbo].[CollectionCipher_UpdateCollectionsForCiphers] + @CipherIds AS [dbo].[GuidIdArray] READONLY, + @OrganizationId UNIQUEIDENTIFIER, + @UserId UNIQUEIDENTIFIER, + @CollectionIds AS [dbo].[GuidIdArray] READONLY +AS +BEGIN + SET NOCOUNT ON + + CREATE TABLE #AvailableCollections ( + [Id] UNIQUEIDENTIFIER + ) + + INSERT INTO #AvailableCollections + SELECT + C.[Id] + FROM + [dbo].[Collection] C + INNER JOIN + [Organization] O ON O.[Id] = C.[OrganizationId] + INNER JOIN + [dbo].[OrganizationUser] OU ON OU.[OrganizationId] = O.[Id] AND OU.[UserId] = @UserId + LEFT JOIN + [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = OU.[Id] + LEFT JOIN + [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] + LEFT JOIN + [dbo].[Group] G ON G.[Id] = GU.[GroupId] + LEFT JOIN + [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] + WHERE + O.[Id] = @OrganizationId + AND O.[Enabled] = 1 + AND OU.[Status] = 2 -- Confirmed + AND ( + OU.[AccessAll] = 1 + OR CU.[ReadOnly] = 0 + OR G.[AccessAll] = 1 + OR CG.[ReadOnly] = 0 + ) + + IF (SELECT COUNT(1) FROM #AvailableCollections) < 1 + BEGIN + -- No writable collections available to share with in this organization. + RETURN + END + + INSERT INTO [dbo].[CollectionCipher] + ( + [CollectionId], + [CipherId] + ) + SELECT + [Collection].[Id], + [Cipher].[Id] + FROM + @CollectionIds [Collection] + INNER JOIN + @CipherIds [Cipher] ON 1 = 1 + WHERE + [Collection].[Id] IN (SELECT [Id] FROM #AvailableCollections) + + EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId +END +GO