1
0
mirror of https://github.com/bitwarden/server synced 2025-12-15 07:43:54 +00:00

[PM-25463] Work towards complete usage of Payments domain (#6363)

* Use payment domain

* Run dotnet format and remove unused code

* Fix swagger

* Stephon's feedback

* Run dotnet format
This commit is contained in:
Alex Morask
2025-10-01 10:26:39 -05:00
committed by GitHub
parent 7cefca330b
commit 61265c7533
46 changed files with 2988 additions and 1350 deletions

View File

@@ -1,16 +1,8 @@
#nullable enable
using System.Diagnostics;
using Bit.Api.AdminConsole.Models.Request.Organizations;
using Bit.Api.Billing.Models.Requests;
using Bit.Api.Billing.Models.Requests;
using Bit.Api.Billing.Models.Responses;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Organizations.Models;
using Bit.Core.Billing.Organizations.Services;
using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Providers.Services;
using Bit.Core.Billing.Services;
using Bit.Core.Billing.Tax.Models;
using Bit.Core.Context;
using Bit.Core.Repositories;
using Bit.Core.Services;
@@ -28,10 +20,8 @@ public class OrganizationBillingController(
IOrganizationBillingService organizationBillingService,
IOrganizationRepository organizationRepository,
IPaymentService paymentService,
IPricingClient pricingClient,
ISubscriberService subscriberService,
IPaymentHistoryService paymentHistoryService,
IUserService userService) : BaseBillingController
IPaymentHistoryService paymentHistoryService) : BaseBillingController
{
[HttpGet("metadata")]
public async Task<IResult> GetMetadataAsync([FromRoute] Guid organizationId)
@@ -264,71 +254,6 @@ public class OrganizationBillingController(
return TypedResults.Ok();
}
[HttpPost("restart-subscription")]
public async Task<IResult> RestartSubscriptionAsync([FromRoute] Guid organizationId,
[FromBody] OrganizationCreateRequestModel model)
{
var user = await userService.GetUserByPrincipalAsync(User);
if (user == null)
{
throw new UnauthorizedAccessException();
}
if (!await currentContext.EditPaymentMethods(organizationId))
{
return Error.Unauthorized();
}
var organization = await organizationRepository.GetByIdAsync(organizationId);
if (organization == null)
{
return Error.NotFound();
}
var existingPlan = organization.PlanType;
var organizationSignup = model.ToOrganizationSignup(user);
var sale = OrganizationSale.From(organization, organizationSignup);
var plan = await pricingClient.GetPlanOrThrow(model.PlanType);
sale.Organization.PlanType = plan.Type;
sale.Organization.Plan = plan.Name;
sale.SubscriptionSetup.SkipTrial = true;
if (existingPlan == PlanType.Free && organization.GatewaySubscriptionId is not null)
{
sale.Organization.UseTotp = plan.HasTotp;
sale.Organization.UseGroups = plan.HasGroups;
sale.Organization.UseDirectory = plan.HasDirectory;
sale.Organization.SelfHost = plan.HasSelfHost;
sale.Organization.UsersGetPremium = plan.UsersGetPremium;
sale.Organization.UseEvents = plan.HasEvents;
sale.Organization.Use2fa = plan.Has2fa;
sale.Organization.UseApi = plan.HasApi;
sale.Organization.UsePolicies = plan.HasPolicies;
sale.Organization.UseSso = plan.HasSso;
sale.Organization.UseResetPassword = plan.HasResetPassword;
sale.Organization.UseKeyConnector = plan.HasKeyConnector ? organization.UseKeyConnector : false;
sale.Organization.UseScim = plan.HasScim;
sale.Organization.UseCustomPermissions = plan.HasCustomPermissions;
sale.Organization.UseOrganizationDomains = plan.HasOrganizationDomains;
sale.Organization.MaxCollections = plan.PasswordManager.MaxCollections;
}
if (organizationSignup.PaymentMethodType == null || string.IsNullOrEmpty(organizationSignup.PaymentToken))
{
return Error.BadRequest("A payment method is required to restart the subscription.");
}
var org = await organizationRepository.GetByIdAsync(organizationId);
Debug.Assert(org is not null, "This organization has already been found via this same ID, this should be fine.");
var paymentSource = new TokenizedPaymentSource(organizationSignup.PaymentMethodType.Value, organizationSignup.PaymentToken);
var taxInformation = TaxInformation.From(organizationSignup.TaxInfo);
await organizationBillingService.Finalize(sale);
var updatedOrg = await organizationRepository.GetByIdAsync(organizationId);
if (updatedOrg != null)
{
await organizationBillingService.UpdatePaymentMethod(updatedOrg, paymentSource, taxInformation);
}
return TypedResults.Ok();
}
[HttpPost("setup-business-unit")]
[SelfHosted(NotSelfHostedOnly = true)]
public async Task<IResult> SetupBusinessUnitAsync(