mirror of
https://github.com/bitwarden/server.git
synced 2025-06-24 12:48:48 -05:00
[PM-22503] Fix manage cipher permission (#5972)
* Added new tests to validate that the ciphers are being grouped and filtered correctly when assigned to multiple collections and changing order of grouping properties.
This commit is contained in:
parent
cdfe51f9d6
commit
d2410747d0
@ -98,7 +98,10 @@ public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
|
||||
|
||||
return results
|
||||
.GroupBy(c => c.Id)
|
||||
.Select(g => g.OrderByDescending(og => og.Edit).ThenByDescending(og => og.ViewPassword).First())
|
||||
.Select(g =>
|
||||
g.OrderByDescending(og => og.Manage)
|
||||
.ThenByDescending(og => og.Edit)
|
||||
.ThenByDescending(og => og.ViewPassword).First())
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
@ -457,7 +457,7 @@ public class CipherRepository : Repository<Core.Vault.Entities.Cipher, Cipher, G
|
||||
using (var scope = ServiceScopeFactory.CreateScope())
|
||||
{
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
IQueryable<CipherDetails> cipherDetailsView = withOrganizations ?
|
||||
var cipherDetailsView = withOrganizations ?
|
||||
new UserCipherDetailsQuery(userId).Run(dbContext) :
|
||||
new CipherDetailsQuery(userId).Run(dbContext);
|
||||
if (!withOrganizations)
|
||||
@ -485,8 +485,15 @@ public class CipherRepository : Repository<Core.Vault.Entities.Cipher, Cipher, G
|
||||
Key = c.Key
|
||||
};
|
||||
}
|
||||
|
||||
var ciphers = await cipherDetailsView.ToListAsync();
|
||||
return ciphers;
|
||||
|
||||
return ciphers.GroupBy(c => c.Id)
|
||||
.Select(g => g.OrderByDescending(c => c.Manage)
|
||||
.ThenByDescending(c => c.Edit)
|
||||
.ThenByDescending(c => c.ViewPassword)
|
||||
.First())
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -571,6 +571,65 @@ public class CipherRepositoryTests
|
||||
Assert.True(personalDetails.Manage, "Personal ciphers should always have Manage permission");
|
||||
}
|
||||
|
||||
[DatabaseTheory, DatabaseData]
|
||||
public async Task GetManyByUserIdAsync_WhenOneCipherIsAssignedToTwoCollectionsWithDifferentPermissions_MostPrivilegedAccessIsReturnedOnTheCipher(
|
||||
ICipherRepository cipherRepository,
|
||||
IUserRepository userRepository,
|
||||
ICollectionCipherRepository collectionCipherRepository,
|
||||
ICollectionRepository collectionRepository,
|
||||
IOrganizationRepository organizationRepository,
|
||||
IOrganizationUserRepository organizationUserRepository)
|
||||
{
|
||||
//Arrange
|
||||
var (user, organization, orgUser) = await CreateTestUserAndOrganization(userRepository, organizationRepository, organizationUserRepository);
|
||||
|
||||
var cipher = await cipherRepository.CreateAsync(new Cipher
|
||||
{
|
||||
Type = CipherType.Login,
|
||||
OrganizationId = organization.Id,
|
||||
Data = ""
|
||||
});
|
||||
|
||||
var managedPermissionsCollection = await collectionRepository.CreateAsync(new Collection
|
||||
{
|
||||
Name = "Managed",
|
||||
OrganizationId = organization.Id
|
||||
});
|
||||
|
||||
var unmanagedPermissionsCollection = await collectionRepository.CreateAsync(new Collection
|
||||
{
|
||||
Name = "Unmanaged",
|
||||
OrganizationId = organization.Id
|
||||
});
|
||||
await collectionCipherRepository.UpdateCollectionsForAdminAsync(cipher.Id, organization.Id,
|
||||
[managedPermissionsCollection.Id, unmanagedPermissionsCollection.Id]);
|
||||
|
||||
await collectionRepository.UpdateUsersAsync(managedPermissionsCollection.Id, new List<CollectionAccessSelection>
|
||||
{
|
||||
new() { Id = orgUser.Id, HidePasswords = false, ReadOnly = false, Manage = true }
|
||||
});
|
||||
|
||||
await collectionRepository.UpdateUsersAsync(unmanagedPermissionsCollection.Id, new List<CollectionAccessSelection>
|
||||
{
|
||||
new() { Id = orgUser.Id, HidePasswords = false, ReadOnly = false, Manage = false }
|
||||
});
|
||||
|
||||
// Act
|
||||
var ciphers = await cipherRepository.GetManyByUserIdAsync(user.Id);
|
||||
|
||||
// Assert
|
||||
Assert.Single(ciphers);
|
||||
var deletableCipher = ciphers.SingleOrDefault(x => x.Id == cipher.Id);
|
||||
Assert.NotNull(deletableCipher);
|
||||
Assert.True(deletableCipher.Manage);
|
||||
|
||||
// Annul
|
||||
await cipherRepository.DeleteAsync(cipher);
|
||||
await organizationUserRepository.DeleteAsync(orgUser);
|
||||
await organizationRepository.DeleteAsync(organization);
|
||||
await userRepository.DeleteAsync(user);
|
||||
}
|
||||
|
||||
private async Task<(User user, Organization org, OrganizationUser orgUser)> CreateTestUserAndOrganization(
|
||||
IUserRepository userRepository,
|
||||
IOrganizationRepository organizationRepository,
|
||||
|
Loading…
x
Reference in New Issue
Block a user