Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-11162] Assign to Collection Permission Update #4844

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 55 additions & 2 deletions src/Api/Vault/Controllers/CiphersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,59 @@

return false;
}

/// <summary>
/// TODO: Move this to its own authorization handler or equivalent service - AC-2062
/// </summary>
private async Task<bool> CanModifyCipherCollectionsAsync(Guid organizationId, IEnumerable<Guid> cipherIds)
{
// If the user can edit all ciphers for the organization, just check they all belong to the org
if (await CanEditAllCiphersAsync(organizationId))
{
// TODO: This can likely be optimized to only query the requested ciphers and then checking they belong to the org
var orgCiphers = (await _cipherRepository.GetManyByOrganizationIdAsync(organizationId)).ToDictionary(c => c.Id);

// Ensure all requested ciphers are in orgCiphers
if (cipherIds.Any(c => !orgCiphers.ContainsKey(c)))
{
return false;
}

return true;
}

// The user cannot access any ciphers for the organization, we're done
if (!await CanAccessOrganizationCiphersAsync(organizationId))
{
return false;
}

var userId = _userService.GetProperUserId(User).Value;
// Select all editable ciphers for this user belonging to the organization
var editableOrgCipherList = (await _cipherRepository.GetManyByUserIdAsync(userId, true))
.Where(c => c.OrganizationId == organizationId && c.UserId == null && c.Edit && c.ViewPassword).ToList();

// Special case for unassigned ciphers
if (await CanAccessUnassignedCiphersAsync(organizationId))
{
var unassignedCiphers =
(await _cipherRepository.GetManyUnassignedOrganizationDetailsByOrganizationIdAsync(
organizationId));

// Users that can access unassigned ciphers can also edit them
editableOrgCipherList.AddRange(unassignedCiphers.Select(c => new CipherDetails(c) { Edit = true }));
}

var editableOrgCiphers = editableOrgCipherList
.ToDictionary(c => c.Id);

if (cipherIds.Any(c => !editableOrgCiphers.ContainsKey(c)))
{
return false;
}

return true;
}

/// <summary>
/// TODO: Move this to its own authorization handler or equivalent service - AC-2062
Expand Down Expand Up @@ -576,9 +629,9 @@
var userId = _userService.GetProperUserId(User).Value;
var cipher = await GetByIdAsync(id, userId);
if (cipher == null || !cipher.OrganizationId.HasValue ||
!await _currentContext.OrganizationUser(cipher.OrganizationId.Value))
!await _currentContext.OrganizationUser(cipher.OrganizationId.Value) || !cipher.ViewPassword)
{
throw new NotFoundException();

Check failure on line 634 in src/Api/Vault/Controllers/CiphersController.cs

View workflow job for this annotation

GitHub Actions / Test Results

Bit.Api.Test.Controllers.CiphersControllerTests ► PutCollections_vNextReturnOptionalDetailsCipherUnavailableFalse(id: ea25d680-bb38-4c40-8c50-ccba1e73b0c5, model: CipherCollectionsRequestModel { CollectionIds = [···] }, userId: 1a1ae58a-1268-4d3f-8c5f-...

Failed test found in: test/Api.Test/TestResults/oss-test-results.trx Error: Bit.Core.Exceptions.NotFoundException : Exception of type 'Bit.Core.Exceptions.NotFoundException' was thrown.
Raw output
Bit.Core.Exceptions.NotFoundException : Exception of type 'Bit.Core.Exceptions.NotFoundException' was thrown.
   at Bit.Api.Vault.Controllers.CiphersController.PutCollections_vNext(Guid id, CipherCollectionsRequestModel model) in /home/runner/work/server/server/src/Api/Vault/Controllers/CiphersController.cs:line 634
   at Bit.Api.Test.Controllers.CiphersControllerTests.PutCollections_vNextReturnOptionalDetailsCipherUnavailableFalse(Guid id, CipherCollectionsRequestModel model, Guid userId, SutProvider`1 sutProvider) in /home/runner/work/server/server/test/Api.Test/Vault/Controllers/CiphersControllerTests.cs:line 94
--- End of stack trace from previous location ---

Check failure on line 634 in src/Api/Vault/Controllers/CiphersController.cs

View workflow job for this annotation

GitHub Actions / Test Results

Bit.Api.Test.Controllers.CiphersControllerTests ► PutCollections_vNextReturnOptionalDetailsCipherUnavailableTrue(id: 27c431ee-8901-4299-8600-1c1395ca50a7, model: CipherCollectionsRequestModel { CollectionIds = [···] }, userId: 4537a257-4889-4e96-8676-8...

Failed test found in: test/Api.Test/TestResults/oss-test-results.trx Error: Bit.Core.Exceptions.NotFoundException : Exception of type 'Bit.Core.Exceptions.NotFoundException' was thrown.
Raw output
Bit.Core.Exceptions.NotFoundException : Exception of type 'Bit.Core.Exceptions.NotFoundException' was thrown.
   at Bit.Api.Vault.Controllers.CiphersController.PutCollections_vNext(Guid id, CipherCollectionsRequestModel model) in /home/runner/work/server/server/src/Api/Vault/Controllers/CiphersController.cs:line 634
   at Bit.Api.Test.Controllers.CiphersControllerTests.PutCollections_vNextReturnOptionalDetailsCipherUnavailableTrue(Guid id, CipherCollectionsRequestModel model, Guid userId, SutProvider`1 sutProvider) in /home/runner/work/server/server/test/Api.Test/Vault/Controllers/CiphersControllerTests.cs:line 109
--- End of stack trace from previous location ---

Check failure on line 634 in src/Api/Vault/Controllers/CiphersController.cs

View workflow job for this annotation

GitHub Actions / Test Results

Bit.Api.Test.Controllers.CiphersControllerTests ► PutCollections_vNextShouldSaveUpdatedCipher(id: d5bf0129-21b3-44f1-8954-11262f11b68c, model: CipherCollectionsRequestModel { CollectionIds = [···] }, userId: 653944ba-4f0d-43ac-a3c6-6652bd1410b7, sutPro...

Failed test found in: test/Api.Test/TestResults/oss-test-results.trx Error: Bit.Core.Exceptions.NotFoundException : Exception of type 'Bit.Core.Exceptions.NotFoundException' was thrown.
Raw output
Bit.Core.Exceptions.NotFoundException : Exception of type 'Bit.Core.Exceptions.NotFoundException' was thrown.
   at Bit.Api.Vault.Controllers.CiphersController.PutCollections_vNext(Guid id, CipherCollectionsRequestModel model) in /home/runner/work/server/server/src/Api/Vault/Controllers/CiphersController.cs:line 634
   at Bit.Api.Test.Controllers.CiphersControllerTests.PutCollections_vNextShouldSaveUpdatedCipher(Guid id, CipherCollectionsRequestModel model, Guid userId, SutProvider`1 sutProvider) in /home/runner/work/server/server/test/Api.Test/Vault/Controllers/CiphersControllerTests.cs:line 80
--- End of stack trace from previous location ---
}

await _cipherService.SaveCollectionsAsync(cipher,
Expand Down Expand Up @@ -626,7 +679,7 @@
[HttpPost("bulk-collections")]
public async Task PostBulkCollections([FromBody] CipherBulkUpdateCollectionsRequestModel model)
{
if (!await CanEditCiphersAsync(model.OrganizationId, model.CipherIds) ||
if (!await CanModifyCipherCollectionsAsync(model.OrganizationId, model.CipherIds) ||
!await CanEditItemsInCollections(model.OrganizationId, model.CollectionIds))
{
throw new NotFoundException();
Expand Down
Loading