mirror of
https://github.com/bitwarden/server.git
synced 2025-06-30 15:42:48 -05:00
[AC-2206] Fix assigning Manage access to default collection (#3799)
* Fix assigning Manage access to default collection The previous implementation did not work when creating an org as a provider because the ownerId is null in OrganizationService.SignUp. Added a null check and handled assigning access in ProviderService instead. * Tweaks
This commit is contained in:
@ -20,8 +20,17 @@ public interface IOrganizationService
|
||||
Task AutoAddSeatsAsync(Organization organization, int seatsToAdd, DateTime? prorationDate = null);
|
||||
Task<string> AdjustSeatsAsync(Guid organizationId, int seatAdjustment, DateTime? prorationDate = null);
|
||||
Task VerifyBankAsync(Guid organizationId, int amount1, int amount2);
|
||||
Task<Tuple<Organization, OrganizationUser>> SignUpAsync(OrganizationSignup organizationSignup, bool provider = false);
|
||||
Task<Tuple<Organization, OrganizationUser>> SignUpAsync(OrganizationLicense license, User owner,
|
||||
/// <summary>
|
||||
/// Create a new organization in a cloud environment
|
||||
/// </summary>
|
||||
/// <returns>A tuple containing the new organization, the initial organizationUser (if any) and the default collection (if any)</returns>
|
||||
#nullable enable
|
||||
Task<(Organization organization, OrganizationUser? organizationUser, Collection? defaultCollection)> SignUpAsync(OrganizationSignup organizationSignup, bool provider = false);
|
||||
#nullable disable
|
||||
/// <summary>
|
||||
/// Create a new organization on a self-hosted instance
|
||||
/// </summary>
|
||||
Task<(Organization organization, OrganizationUser organizationUser)> SignUpAsync(OrganizationLicense license, User owner,
|
||||
string ownerKey, string collectionName, string publicKey, string privateKey);
|
||||
Task DeleteAsync(Organization organization);
|
||||
Task EnableAsync(Guid organizationId, DateTime? expirationDate);
|
||||
|
@ -424,7 +424,7 @@ public class OrganizationService : IOrganizationService
|
||||
/// <summary>
|
||||
/// Create a new organization in a cloud environment
|
||||
/// </summary>
|
||||
public async Task<Tuple<Organization, OrganizationUser>> SignUpAsync(OrganizationSignup signup,
|
||||
public async Task<(Organization organization, OrganizationUser organizationUser, Collection defaultCollection)> SignUpAsync(OrganizationSignup signup,
|
||||
bool provider = false)
|
||||
{
|
||||
var plan = StaticStore.GetPlan(signup.Plan);
|
||||
@ -552,7 +552,7 @@ public class OrganizationService : IOrganizationService
|
||||
/// <summary>
|
||||
/// Create a new organization on a self-hosted instance
|
||||
/// </summary>
|
||||
public async Task<Tuple<Organization, OrganizationUser>> SignUpAsync(
|
||||
public async Task<(Organization organization, OrganizationUser organizationUser)> SignUpAsync(
|
||||
OrganizationLicense license, User owner, string ownerKey, string collectionName, string publicKey,
|
||||
string privateKey)
|
||||
{
|
||||
@ -633,14 +633,14 @@ public class OrganizationService : IOrganizationService
|
||||
Directory.CreateDirectory(dir);
|
||||
await using var fs = new FileStream(Path.Combine(dir, $"{organization.Id}.json"), FileMode.Create);
|
||||
await JsonSerializer.SerializeAsync(fs, license, JsonHelpers.Indented);
|
||||
return result;
|
||||
return (result.organization, result.organizationUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private helper method to create a new organization.
|
||||
/// This is common code used by both the cloud and self-hosted methods.
|
||||
/// </summary>
|
||||
private async Task<Tuple<Organization, OrganizationUser>> SignUpAsync(Organization organization,
|
||||
private async Task<(Organization organization, OrganizationUser organizationUser, Collection defaultCollection)> SignUpAsync(Organization organization,
|
||||
Guid ownerId, string ownerKey, string collectionName, bool withPayment)
|
||||
{
|
||||
try
|
||||
@ -655,6 +655,8 @@ public class OrganizationService : IOrganizationService
|
||||
});
|
||||
await _applicationCacheService.UpsertOrganizationAbilityAsync(organization);
|
||||
|
||||
// ownerId == default if the org is created by a provider - in this case it's created without an
|
||||
// owner and the first owner is immediately invited afterwards
|
||||
OrganizationUser orgUser = null;
|
||||
if (ownerId != default)
|
||||
{
|
||||
@ -683,9 +685,10 @@ public class OrganizationService : IOrganizationService
|
||||
await _pushNotificationService.PushSyncOrgKeysAsync(ownerId);
|
||||
}
|
||||
|
||||
Collection defaultCollection = null;
|
||||
if (!string.IsNullOrWhiteSpace(collectionName))
|
||||
{
|
||||
var defaultCollection = new Collection
|
||||
defaultCollection = new Collection
|
||||
{
|
||||
Name = collectionName,
|
||||
OrganizationId = organization.Id,
|
||||
@ -695,7 +698,7 @@ public class OrganizationService : IOrganizationService
|
||||
|
||||
// If using Flexible Collections, give the owner Can Manage access over the default collection
|
||||
List<CollectionAccessSelection> defaultOwnerAccess = null;
|
||||
if (organization.FlexibleCollections)
|
||||
if (orgUser != null && organization.FlexibleCollections)
|
||||
{
|
||||
defaultOwnerAccess =
|
||||
[new CollectionAccessSelection { Id = orgUser.Id, HidePasswords = false, ReadOnly = false, Manage = true }];
|
||||
@ -704,7 +707,7 @@ public class OrganizationService : IOrganizationService
|
||||
await _collectionRepository.CreateAsync(defaultCollection, null, defaultOwnerAccess);
|
||||
}
|
||||
|
||||
return new Tuple<Organization, OrganizationUser>(organization, orgUser);
|
||||
return (organization, orgUser, defaultCollection);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
Reference in New Issue
Block a user