1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 16:42:50 -05:00

[AC-1344] Provider users unable to bulk restore vault items for client organizations (#2871)

* [AC-1344] Added method PutRestoreManyAdmin to CiphersController and refactored PutRestoreMany

* [AC-1344] Fixed unit test

* [AC-1344] Removed comment

* [AC-1344] Fixed sql.csproj

* [AC-1344] Added check for empty or null array; added more unit tests
This commit is contained in:
Rui Tomé
2023-08-02 16:22:37 +01:00
committed by GitHub
parent 4a110ad135
commit d94a54516e
10 changed files with 221 additions and 16 deletions

View File

@ -36,5 +36,6 @@ public interface ICipherRepository : IRepository<Cipher, Guid>
Task SoftDeleteAsync(IEnumerable<Guid> ids, Guid userId);
Task SoftDeleteByIdsOrganizationIdAsync(IEnumerable<Guid> ids, Guid organizationId);
Task<DateTime> RestoreAsync(IEnumerable<Guid> ids, Guid userId);
Task<DateTime> RestoreByIdsOrganizationIdAsync(IEnumerable<Guid> ids, Guid organizationId);
Task DeleteDeletedAsync(DateTime deletedDateBefore);
}

View File

@ -35,7 +35,7 @@ public interface ICipherService
Task SoftDeleteAsync(Cipher cipher, Guid deletingUserId, bool orgAdmin = false);
Task SoftDeleteManyAsync(IEnumerable<Guid> cipherIds, Guid deletingUserId, Guid? organizationId = null, bool orgAdmin = false);
Task RestoreAsync(Cipher cipher, Guid restoringUserId, bool orgAdmin = false);
Task RestoreManyAsync(IEnumerable<CipherDetails> ciphers, Guid restoringUserId);
Task<ICollection<CipherOrganizationDetails>> RestoreManyAsync(IEnumerable<Guid> cipherIds, Guid restoringUserId, Guid? organizationId = null, bool orgAdmin = false);
Task UploadFileForExistingAttachmentAsync(Stream stream, Cipher cipher, CipherAttachment.MetaData attachmentId);
Task<AttachmentResponseData> GetAttachmentDownloadDataAsync(Cipher cipher, string attachmentId);
Task<bool> ValidateCipherAttachmentFile(Cipher cipher, CipherAttachment.MetaData attachmentData);

View File

@ -898,13 +898,33 @@ public class CipherService : ICipherService
await _pushService.PushSyncCipherUpdateAsync(cipher, null);
}
public async Task RestoreManyAsync(IEnumerable<CipherDetails> ciphers, Guid restoringUserId)
public async Task<ICollection<CipherOrganizationDetails>> RestoreManyAsync(IEnumerable<Guid> cipherIds, Guid restoringUserId, Guid? organizationId = null, bool orgAdmin = false)
{
var revisionDate = await _cipherRepository.RestoreAsync(ciphers.Select(c => c.Id), restoringUserId);
var events = ciphers.Select(c =>
if (cipherIds == null || !cipherIds.Any())
{
c.RevisionDate = revisionDate;
return new List<CipherOrganizationDetails>();
}
var cipherIdsSet = new HashSet<Guid>(cipherIds);
var restoringCiphers = new List<CipherOrganizationDetails>();
DateTime? revisionDate;
if (orgAdmin && organizationId.HasValue)
{
var ciphers = await _cipherRepository.GetManyOrganizationDetailsByOrganizationIdAsync(organizationId.Value);
restoringCiphers = ciphers.Where(c => cipherIdsSet.Contains(c.Id)).ToList();
revisionDate = await _cipherRepository.RestoreByIdsOrganizationIdAsync(restoringCiphers.Select(c => c.Id), organizationId.Value);
}
else
{
var ciphers = await _cipherRepository.GetManyByUserIdAsync(restoringUserId);
restoringCiphers = ciphers.Where(c => cipherIdsSet.Contains(c.Id) && c.Edit).Select(c => (CipherOrganizationDetails)c).ToList();
revisionDate = await _cipherRepository.RestoreAsync(restoringCiphers.Select(c => c.Id), restoringUserId);
}
var events = restoringCiphers.Select(c =>
{
c.RevisionDate = revisionDate.Value;
c.DeletedDate = null;
return new Tuple<Cipher, EventType, DateTime?>(c, EventType.Cipher_Restored, null);
});
@ -915,6 +935,8 @@ public class CipherService : ICipherService
// push
await _pushService.PushSyncCiphersAsync(restoringUserId);
return restoringCiphers;
}
public async Task<(IEnumerable<CipherOrganizationDetails>, Dictionary<Guid, IGrouping<Guid, CollectionCipher>>)> GetOrganizationCiphers(Guid userId, Guid organizationId)