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

Updated to use new pricing client. Supressed null dereference errors.

This commit is contained in:
jrmccannon 2025-03-05 15:48:12 -06:00
parent f8c08de2db
commit 6f7b0b3e0e
No known key found for this signature in database
GPG Key ID: CF03F3DB01CE96A6
3 changed files with 39 additions and 13 deletions

View File

@ -1,9 +1,12 @@
#nullable enable #nullable enable
using Bit.Core; using Bit.Core;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
using Bit.Core.Billing.Pricing;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Commands; using Bit.Core.Models.Commands;
@ -24,7 +27,9 @@ public class PostUserCommand(
IScimContext scimContext, IScimContext scimContext,
IFeatureService featureService, IFeatureService featureService,
IInviteOrganizationUsersCommand inviteOrganizationUsersCommand, IInviteOrganizationUsersCommand inviteOrganizationUsersCommand,
TimeProvider timeProvider) TimeProvider timeProvider,
IPricingClient pricingClient,
ILogger<PostUserCommand> logger)
: IPostUserCommand : IPostUserCommand
{ {
public async Task<OrganizationUserUserDetails?> PostUserAsync(Guid organizationId, ScimUserRequestModel model) public async Task<OrganizationUserUserDetails?> PostUserAsync(Guid organizationId, ScimUserRequestModel model)
@ -54,16 +59,18 @@ public class PostUserCommand(
} }
var organization = await organizationRepository.GetByIdAsync(organizationId); var organization = await organizationRepository.GetByIdAsync(organizationId);
if (organization == null)
{
throw new NotFoundException();
}
var hasStandaloneSecretsManager = await paymentService.HasSecretsManagerStandalone(organization); var hasStandaloneSecretsManager = await paymentService.HasSecretsManagerStandalone(organization);
invite.AccessSecretsManager = hasStandaloneSecretsManager; invite.AccessSecretsManager = hasStandaloneSecretsManager;
if (featureService.IsEnabled(FeatureFlagKeys.ScimInviteUserOptimization)) if (featureService.IsEnabled(FeatureFlagKeys.ScimInviteUserOptimization))
{ {
return await InviteScimOrganizationUserAsync(model.ToRequest( return await InviteScimOrganizationUserAsync(model, organization, scimProvider, hasStandaloneSecretsManager);
scimProvider: scimProvider,
hasSecretsManager: hasStandaloneSecretsManager,
organization: new OrganizationDto(organization),
performedAt: timeProvider.GetUtcNow()));
} }
var invitedOrgUser = await organizationService.InviteUserAsync(organizationId, invitingUserId: null, EventSystemUser.SCIM, var invitedOrgUser = await organizationService.InviteUserAsync(organizationId, invitingUserId: null, EventSystemUser.SCIM,
@ -73,8 +80,22 @@ public class PostUserCommand(
return orgUser; return orgUser;
} }
private async Task<OrganizationUserUserDetails?> InviteScimOrganizationUserAsync(InviteScimOrganizationUserRequest request) private async Task<OrganizationUserUserDetails?> InviteScimOrganizationUserAsync(ScimUserRequestModel model, Organization organization, ScimProviderType scimProvider, bool hasStandaloneSecretsManager)
{ {
var plan = await pricingClient.GetPlan(organization.PlanType);
if (plan == null)
{
logger.LogError("Plan {planType} not found for organization {organizationId}", organization.PlanType, organization.Id);
return null;
}
var request = model.ToRequest(
scimProvider: scimProvider,
hasSecretsManager: hasStandaloneSecretsManager,
organization: new OrganizationDto(organization, plan),
performedAt: timeProvider.GetUtcNow());
var result = await inviteOrganizationUsersCommand.InviteScimOrganizationUserAsync(request); var result = await inviteOrganizationUsersCommand.InviteScimOrganizationUserAsync(request);
if (result is not Success<ScimInviteOrganizationUsersResponse> successfulResponse) if (result is not Success<ScimInviteOrganizationUsersResponse> successfulResponse)

View File

@ -21,16 +21,21 @@ public record OrganizationDto
} }
public OrganizationDto(Organization organization)
public OrganizationDto(Organization organization, Plan plan)
{ {
OrganizationId = organization.Id; OrganizationId = organization.Id;
Seats = organization.Seats; Seats = organization.Seats;
MaxAutoScaleSeats = organization.MaxAutoscaleSeats; MaxAutoScaleSeats = organization.MaxAutoscaleSeats;
SmSeats = organization.SmSeats; SmSeats = organization.SmSeats;
SmMaxAutoScaleSeats = organization.MaxAutoscaleSmSeats; SmMaxAutoScaleSeats = organization.MaxAutoscaleSmSeats;
Plan = StaticStore.GetPlan(organization.PlanType); Plan = plan;
GatewayCustomerId = organization.GatewayCustomerId; GatewayCustomerId = organization.GatewayCustomerId;
GatewaySubscriptionId = organization.GatewaySubscriptionId; GatewaySubscriptionId = organization.GatewaySubscriptionId;
UseSecretsManager = organization.UseSecretsManager; UseSecretsManager = organization.UseSecretsManager;
} }
public OrganizationDto(Organization organization) : this(organization, StaticStore.GetPlan(organization.PlanType))
{
}
} }

View File

@ -94,7 +94,7 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
.Select(MapToDataModel(request.PerformedAt)) .Select(MapToDataModel(request.PerformedAt))
.ToArray(); .ToArray();
var organization = await organizationRepository.GetByIdAsync(validatedRequest.Value.Organization.OrganizationId); var organization = await organizationRepository.GetByIdAsync(validatedRequest!.Value.Organization.OrganizationId);
try try
{ {
await organizationUserRepository.CreateManyAsync(organizationUserCollection); await organizationUserRepository.CreateManyAsync(organizationUserCollection);
@ -142,7 +142,7 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
{ {
if (valid.Value.SecretsManagerSubscriptionUpdate.SeatsRequiredToAdd < 0) if (valid.Value.SecretsManagerSubscriptionUpdate.SeatsRequiredToAdd < 0)
{ {
var updateRevert = new SecretsManagerSubscriptionUpdate(organization, false) var updateRevert = new SecretsManagerSubscriptionUpdate(organization, valid.Value.Organization.Plan, false)
{ {
SmSeats = valid.Value.SecretsManagerSubscriptionUpdate.Seats SmSeats = valid.Value.SecretsManagerSubscriptionUpdate.Seats
}; };
@ -185,7 +185,7 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
.Distinct(); .Distinct();
await mailService.SendOrganizationMaxSeatLimitReachedEmailAsync(organization, await mailService.SendOrganizationMaxSeatLimitReachedEmailAsync(organization,
valid.Value.PasswordManagerSubscriptionUpdate.MaxAutoScaleSeats.Value, ownerEmails); valid.Value.PasswordManagerSubscriptionUpdate.MaxAutoScaleSeats.Value!, ownerEmails);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -200,7 +200,7 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
return; return;
} }
var subscriptionUpdate = new SecretsManagerSubscriptionUpdate(organization, true) var subscriptionUpdate = new SecretsManagerSubscriptionUpdate(organization, valid.Value.Organization.Plan, true)
.AdjustSeats(valid.Value.SecretsManagerSubscriptionUpdate.SeatsRequiredToAdd); .AdjustSeats(valid.Value.SecretsManagerSubscriptionUpdate.SeatsRequiredToAdd);
await updateSecretsManagerSubscriptionCommand.UpdateSubscriptionAsync(subscriptionUpdate); await updateSecretsManagerSubscriptionCommand.UpdateSubscriptionAsync(subscriptionUpdate);