From f2a02e040c905633a80e543d30d4ac0a162e3ad3 Mon Sep 17 00:00:00 2001
From: Robyn MacCallum <robyntmaccallum@gmail.com>
Date: Tue, 21 Jun 2022 08:25:54 -0400
Subject: [PATCH] [SG-378] Get and send collectionIds when a cipher is updated
 (#2066)

* Get and send collectionIds when a cipher is updated

* Make Put method parameters Guids instead of strings
---
 src/Api/Controllers/CiphersController.cs           | 14 ++++++++------
 src/Core/Services/Implementations/CipherService.cs | 12 ++----------
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/src/Api/Controllers/CiphersController.cs b/src/Api/Controllers/CiphersController.cs
index c72b8ea270..685473ff36 100644
--- a/src/Api/Controllers/CiphersController.cs
+++ b/src/Api/Controllers/CiphersController.cs
@@ -170,15 +170,16 @@ namespace Bit.Api.Controllers
 
         [HttpPut("{id}")]
         [HttpPost("{id}")]
-        public async Task<CipherResponseModel> Put(string id, [FromBody] CipherRequestModel model)
+        public async Task<CipherResponseModel> Put(Guid id, [FromBody] CipherRequestModel model)
         {
             var userId = _userService.GetProperUserId(User).Value;
-            var cipher = await _cipherRepository.GetByIdAsync(new Guid(id), userId);
+            var cipher = await _cipherRepository.GetByIdAsync(id, userId);
             if (cipher == null)
             {
                 throw new NotFoundException();
             }
 
+            var collectionIds = (await _collectionCipherRepository.GetManyByUserIdCipherIdAsync(userId, id)).Select(c => c.CollectionId).ToList();
             var modelOrgId = string.IsNullOrWhiteSpace(model.OrganizationId) ?
                 (Guid?)null : new Guid(model.OrganizationId);
             if (cipher.OrganizationId != modelOrgId)
@@ -187,7 +188,7 @@ namespace Bit.Api.Controllers
                     "then try again.");
             }
 
-            await _cipherService.SaveDetailsAsync(model.ToCipherDetails(cipher), userId, model.LastKnownRevisionDate);
+            await _cipherService.SaveDetailsAsync(model.ToCipherDetails(cipher), userId, model.LastKnownRevisionDate, collectionIds);
 
             var response = new CipherResponseModel(cipher, _globalSettings);
             return response;
@@ -195,19 +196,20 @@ namespace Bit.Api.Controllers
 
         [HttpPut("{id}/admin")]
         [HttpPost("{id}/admin")]
-        public async Task<CipherMiniResponseModel> PutAdmin(string id, [FromBody] CipherRequestModel model)
+        public async Task<CipherMiniResponseModel> PutAdmin(Guid id, [FromBody] CipherRequestModel model)
         {
             var userId = _userService.GetProperUserId(User).Value;
-            var cipher = await _cipherRepository.GetOrganizationDetailsByIdAsync(new Guid(id));
+            var cipher = await _cipherRepository.GetOrganizationDetailsByIdAsync(id);
             if (cipher == null || !cipher.OrganizationId.HasValue ||
                 !await _currentContext.EditAnyCollection(cipher.OrganizationId.Value))
             {
                 throw new NotFoundException();
             }
 
+            var collectionIds = (await _collectionCipherRepository.GetManyByUserIdCipherIdAsync(userId, id)).Select(c => c.CollectionId).ToList();
             // object cannot be a descendant of CipherDetails, so let's clone it.
             var cipherClone = model.ToCipher(cipher).Clone();
-            await _cipherService.SaveAsync(cipherClone, userId, model.LastKnownRevisionDate, null, true, false);
+            await _cipherService.SaveAsync(cipherClone, userId, model.LastKnownRevisionDate, collectionIds, true, false);
 
             var response = new CipherMiniResponseModel(cipherClone, _globalSettings, cipher.OrganizationUseTotp);
             return response;
diff --git a/src/Core/Services/Implementations/CipherService.cs b/src/Core/Services/Implementations/CipherService.cs
index 485fc83783..663c3a910e 100644
--- a/src/Core/Services/Implementations/CipherService.cs
+++ b/src/Core/Services/Implementations/CipherService.cs
@@ -98,17 +98,13 @@ namespace Bit.Core.Services
             }
             else
             {
-                if (collectionIds != null)
-                {
-                    throw new ArgumentException("Cannot create cipher with collection ids at the same time.");
-                }
                 ValidateCipherLastKnownRevisionDateAsync(cipher, lastKnownRevisionDate);
                 cipher.RevisionDate = DateTime.UtcNow;
                 await _cipherRepository.ReplaceAsync(cipher);
                 await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_Updated);
 
                 // push
-                await _pushService.PushSyncCipherUpdateAsync(cipher, null);
+                await _pushService.PushSyncCipherUpdateAsync(cipher, collectionIds);
             }
         }
 
@@ -156,17 +152,13 @@ namespace Bit.Core.Services
             }
             else
             {
-                if (collectionIds != null)
-                {
-                    throw new ArgumentException("Cannot create cipher with collection ids at the same time.");
-                }
                 ValidateCipherLastKnownRevisionDateAsync(cipher, lastKnownRevisionDate);
                 cipher.RevisionDate = DateTime.UtcNow;
                 await _cipherRepository.ReplaceAsync(cipher);
                 await _eventService.LogCipherEventAsync(cipher, Enums.EventType.Cipher_Updated);
 
                 // push
-                await _pushService.PushSyncCipherUpdateAsync(cipher, null);
+                await _pushService.PushSyncCipherUpdateAsync(cipher, collectionIds);
             }
         }