1
0
mirror of https://github.com/bitwarden/server synced 2026-02-21 03:43:44 +00:00

chore: [PM-29055] remove pm-25379-use-new-organization-metadata-structure feature flag (#6966)

Remove the fully-released feature flag and clean up the old code path:
- Remove flag constant from FeatureFlagKeys
- Remove [RequireFeature] gate from VNext billing controllers
- Remove old GetMetadataAsync endpoint from OrganizationBillingController
- Remove GetMetadata from IOrganizationBillingService and implementation
- Remove IsOnSecretsManagerStandalone private helper
- Remove associated tests
This commit is contained in:
Alex Morask
2026-02-18 09:06:06 -06:00
committed by GitHub
parent 8fefae98e4
commit 2ce98277b4
8 changed files with 0 additions and 260 deletions

View File

@@ -21,25 +21,6 @@ public class OrganizationBillingController(
IStripePaymentService paymentService,
IPaymentHistoryService paymentHistoryService) : BaseBillingController
{
// TODO: Remove when pm-25379-use-new-organization-metadata-structure is removed.
[HttpGet("metadata")]
public async Task<IResult> GetMetadataAsync([FromRoute] Guid organizationId)
{
if (!await currentContext.OrganizationUser(organizationId))
{
return Error.Unauthorized();
}
var metadata = await organizationBillingService.GetMetadata(organizationId);
if (metadata == null)
{
return Error.NotFound();
}
return TypedResults.Ok(metadata);
}
// TODO: Migrate to Query / OrganizationBillingVNextController
[HttpGet("history")]
public async Task<IResult> GetHistoryAsync([FromRoute] Guid organizationId)

View File

@@ -4,7 +4,6 @@ using Bit.Api.Billing.Attributes;
using Bit.Api.Billing.Models.Requests.Payment;
using Bit.Api.Billing.Models.Requests.Subscriptions;
using Bit.Api.Billing.Models.Requirements;
using Bit.Core;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Commands;
using Bit.Core.Billing.Organizations.Queries;
@@ -117,7 +116,6 @@ public class OrganizationBillingVNextController(
[Authorize<MemberOrProviderRequirement>]
[HttpGet("metadata")]
[RequireFeature(FeatureFlagKeys.PM25379_UseNewOrganizationMetadataStructure)]
[InjectOrganization]
public async Task<IResult> GetMetadataAsync(
[BindNever] Organization organization)

View File

@@ -1,7 +1,6 @@
using Bit.Api.AdminConsole.Authorization;
using Bit.Api.AdminConsole.Authorization.Requirements;
using Bit.Api.Billing.Attributes;
using Bit.Core;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Organizations.Queries;
using Bit.Core.Utilities;
@@ -19,7 +18,6 @@ public class SelfHostedOrganizationBillingVNextController(
{
[Authorize<MemberOrProviderRequirement>]
[HttpGet("metadata")]
[RequireFeature(FeatureFlagKeys.PM25379_UseNewOrganizationMetadataStructure)]
[InjectOrganization]
public async Task<IResult> GetMetadataAsync([BindNever] Organization organization)
{

View File

@@ -26,13 +26,6 @@ public interface IOrganizationBillingService
/// </example>
Task Finalize(OrganizationSale sale);
/// <summary>
/// Retrieve metadata about the organization represented bsy the provided <paramref name="organizationId"/>.
/// </summary>
/// <param name="organizationId">The ID of the organization to retrieve metadata for.</param>
/// <returns>An <see cref="OrganizationMetadata"/> record.</returns>
Task<OrganizationMetadata?> GetMetadata(Guid organizationId);
/// <summary>
/// Updates the provided <paramref name="organization"/>'s payment source and tax information.
/// If the <paramref name="organization"/> does not have a Stripe <see cref="Stripe.Customer"/>, this method will create one using the provided

View File

@@ -54,52 +54,6 @@ public class OrganizationBillingService(
}
}
public async Task<OrganizationMetadata?> GetMetadata(Guid organizationId)
{
var organization = await organizationRepository.GetByIdAsync(organizationId);
if (organization == null)
{
return null;
}
if (globalSettings.SelfHosted)
{
return OrganizationMetadata.Default;
}
var orgOccupiedSeats = await organizationRepository.GetOccupiedSeatCountByOrganizationIdAsync(organization.Id);
if (string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
{
return OrganizationMetadata.Default with
{
OrganizationOccupiedSeats = orgOccupiedSeats.Total
};
}
var customer = await subscriberService.GetCustomer(organization);
var subscription = await subscriberService.GetSubscription(organization, new SubscriptionGetOptions
{
Expand = ["discounts.coupon.applies_to"]
});
if (customer == null || subscription == null)
{
return OrganizationMetadata.Default with
{
OrganizationOccupiedSeats = orgOccupiedSeats.Total
};
}
var isOnSecretsManagerStandalone = await IsOnSecretsManagerStandalone(organization, customer, subscription);
return new OrganizationMetadata(
isOnSecretsManagerStandalone,
orgOccupiedSeats.Total);
}
public async Task UpdatePaymentMethod(
Organization organization,
TokenizedPaymentSource tokenizedPaymentSource,
@@ -565,38 +519,6 @@ public class OrganizationBillingService(
return customer;
}
private async Task<bool> IsOnSecretsManagerStandalone(
Organization organization,
Customer? customer,
Subscription? subscription)
{
if (customer == null || subscription == null)
{
return false;
}
var plan = await pricingClient.GetPlanOrThrow(organization.PlanType);
if (!plan.SupportsSecretsManager)
{
return false;
}
var coupon = subscription.Discounts?.FirstOrDefault(discount =>
discount.Coupon?.Id == StripeConstants.CouponIDs.SecretsManagerStandalone)?.Coupon;
if (coupon == null)
{
return false;
}
var subscriptionProductIds = subscription.Items.Data.Select(item => item.Plan.ProductId);
var couponAppliesTo = coupon.AppliesTo?.Products;
return subscriptionProductIds.Intersect(couponAppliesTo ?? []).Any();
}
private async Task UpdateMissingPaymentMethodBehaviourAsync(Organization organization)
{
var subscription = await subscriberService.GetSubscriptionOrThrow(organization);

View File

@@ -182,7 +182,6 @@ public static class FeatureFlagKeys
/* Billing Team */
public const string TrialPayment = "PM-8163-trial-payment";
public const string PM25379_UseNewOrganizationMetadataStructure = "pm-25379-use-new-organization-metadata-structure";
public const string PM24032_NewNavigationPremiumUpgradeButton = "pm-24032-new-navigation-premium-upgrade-button";
public const string PM23713_PremiumBadgeOpensNewPremiumUpgradeDialog = "pm-23713-premium-badge-opens-new-premium-upgrade-dialog";
public const string PM26793_FetchPremiumPriceFromPricingService = "pm-26793-fetch-premium-price-from-pricing-service";