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:
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user