1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-09 13:42:21 -05:00

[PM-5873 / PM-5932] Fix collection creation by users other than the Organization owner (#3721)

* [AC-2106] Add check for providers and additional check for null response

* [PM-5873] Separated CollectionsController.Post flexible collections logic from non-migrated orgs

---------

Co-authored-by: Shane Melton <smelton@bitwarden.com>
This commit is contained in:
Rui Tomé 2024-01-30 16:18:18 +00:00 committed by GitHub
parent cc2a81ae3f
commit 7180a6618e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -213,12 +213,15 @@ public class CollectionsController : Controller
[HttpPost("")] [HttpPost("")]
public async Task<CollectionResponseModel> Post(Guid orgId, [FromBody] CollectionRequestModel model) public async Task<CollectionResponseModel> Post(Guid orgId, [FromBody] CollectionRequestModel model)
{ {
if (await FlexibleCollectionsIsEnabledAsync(orgId))
{
// New flexible collections logic
return await Post_vNext(orgId, model);
}
var collection = model.ToCollection(orgId); var collection = model.ToCollection(orgId);
var flexibleCollectionsIsEnabled = await FlexibleCollectionsIsEnabledAsync(orgId); var authorized = await CanCreateCollection(orgId, collection.Id) || await CanEditCollectionAsync(orgId, collection.Id);
var authorized = flexibleCollectionsIsEnabled
? (await _authorizationService.AuthorizeAsync(User, collection, BulkCollectionOperations.Create)).Succeeded
: await CanCreateCollection(orgId, collection.Id) || await CanEditCollectionAsync(orgId, collection.Id);
if (!authorized) if (!authorized)
{ {
throw new NotFoundException(); throw new NotFoundException();
@ -229,7 +232,6 @@ public class CollectionsController : Controller
// Pre-flexible collections logic assigned Managers to collections they create // Pre-flexible collections logic assigned Managers to collections they create
var assignUserToCollection = var assignUserToCollection =
!flexibleCollectionsIsEnabled &&
!await _currentContext.EditAnyCollection(orgId) && !await _currentContext.EditAnyCollection(orgId) &&
await _currentContext.EditAssignedCollections(orgId); await _currentContext.EditAssignedCollections(orgId);
var isNewCollection = collection.Id == default; var isNewCollection = collection.Id == default;
@ -251,16 +253,7 @@ public class CollectionsController : Controller
await _collectionService.SaveAsync(collection, groups, users); await _collectionService.SaveAsync(collection, groups, users);
if (!_currentContext.UserId.HasValue) return new CollectionResponseModel(collection);
{
return new CollectionResponseModel(collection);
}
// If we have a user, fetch the collection to get the latest permission details
var userCollectionDetails = await _collectionRepository.GetByIdAsync(collection.Id,
_currentContext.UserId.Value, await FlexibleCollectionsIsEnabledAsync(collection.OrganizationId));
return new CollectionDetailsResponseModel(userCollectionDetails);
} }
[HttpPut("{id}")] [HttpPut("{id}")]
@ -616,6 +609,35 @@ public class CollectionsController : Controller
return responses; return responses;
} }
private async Task<CollectionResponseModel> Post_vNext(Guid orgId, [FromBody] CollectionRequestModel model)
{
var collection = model.ToCollection(orgId);
var authorized = (await _authorizationService.AuthorizeAsync(User, collection, BulkCollectionOperations.Create)).Succeeded;
if (!authorized)
{
throw new NotFoundException();
}
var groups = model.Groups?.Select(g => g.ToSelectionReadOnly());
var users = model.Users?.Select(g => g.ToSelectionReadOnly()).ToList() ?? new List<CollectionAccessSelection>();
await _collectionService.SaveAsync(collection, groups, users);
if (!_currentContext.UserId.HasValue || await _currentContext.ProviderUserForOrgAsync(orgId))
{
return new CollectionResponseModel(collection);
}
// If we have a user, fetch the collection to get the latest permission details
var userCollectionDetails = await _collectionRepository.GetByIdAsync(collection.Id,
_currentContext.UserId.Value, await FlexibleCollectionsIsEnabledAsync(collection.OrganizationId));
return userCollectionDetails == null
? new CollectionResponseModel(collection)
: new CollectionDetailsResponseModel(userCollectionDetails);
}
private async Task<CollectionResponseModel> Put_vNext(Guid id, CollectionRequestModel model) private async Task<CollectionResponseModel> Put_vNext(Guid id, CollectionRequestModel model)
{ {
var collection = await _collectionRepository.GetByIdAsync(id); var collection = await _collectionRepository.GetByIdAsync(id);
@ -629,7 +651,7 @@ public class CollectionsController : Controller
var users = model.Users?.Select(g => g.ToSelectionReadOnly()); var users = model.Users?.Select(g => g.ToSelectionReadOnly());
await _collectionService.SaveAsync(model.ToCollection(collection), groups, users); await _collectionService.SaveAsync(model.ToCollection(collection), groups, users);
if (!_currentContext.UserId.HasValue) if (!_currentContext.UserId.HasValue || await _currentContext.ProviderUserForOrgAsync(collection.OrganizationId))
{ {
return new CollectionResponseModel(collection); return new CollectionResponseModel(collection);
} }
@ -637,7 +659,9 @@ public class CollectionsController : Controller
// If we have a user, fetch the collection details to get the latest permission details for the user // If we have a user, fetch the collection details to get the latest permission details for the user
var updatedCollectionDetails = await _collectionRepository.GetByIdAsync(id, _currentContext.UserId.Value, await FlexibleCollectionsIsEnabledAsync(collection.OrganizationId)); var updatedCollectionDetails = await _collectionRepository.GetByIdAsync(id, _currentContext.UserId.Value, await FlexibleCollectionsIsEnabledAsync(collection.OrganizationId));
return new CollectionDetailsResponseModel(updatedCollectionDetails); return updatedCollectionDetails == null
? new CollectionResponseModel(collection)
: new CollectionDetailsResponseModel(updatedCollectionDetails);
} }
private async Task PutUsers_vNext(Guid id, IEnumerable<SelectionReadOnlyRequestModel> model) private async Task PutUsers_vNext(Guid id, IEnumerable<SelectionReadOnlyRequestModel> model)