Skip to content

Commit 3debb5e

Browse files
committed
Merge branch 'main' into ac/pm-18235/add-personalownershippolicyrequirement
# Conflicts: # src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyServiceCollectionExtensions.cs # src/Core/Tools/ImportFeatures/ImportCiphersCommand.cs # test/Core.Test/Vault/Services/CipherServiceTests.cs
2 parents 99e4e06 + 6510f2a commit 3debb5e

File tree

267 files changed

+24543
-3341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

267 files changed

+24543
-3341
lines changed

.devcontainer/bitwarden_common/docker-compose.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
bitwarden_server:
53
image: mcr.microsoft.com/devcontainers/dotnet:8.0
@@ -13,7 +11,8 @@ services:
1311
platform: linux/amd64
1412
restart: unless-stopped
1513
env_file:
16-
../../dev/.env
14+
- path: ../../dev/.env
15+
required: false
1716
environment:
1817
ACCEPT_EULA: "Y"
1918
MSSQL_PID: Developer

.devcontainer/community_dev/postCreateCommand.sh

+7-1
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,10 @@ Proceed? [y/N] " response
5151
}
5252

5353
# main
54-
one_time_setup
54+
if [[ -z "${CODESPACES}" ]]; then
55+
one_time_setup
56+
else
57+
# Ignore interactive elements when running in codespaces since they are not supported there
58+
# TODO Write codespaces specific instructions and link here
59+
echo "Running in codespaces, follow instructions here: https://contributing.bitwarden.com/getting-started/server/guide/ to continue the setup"
60+
fi

.devcontainer/internal_dev/docker-compose.override.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
bitwarden_storage:
53
image: mcr.microsoft.com/azure-storage/azurite:latest

.devcontainer/internal_dev/postCreateCommand.sh

+7-1
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,10 @@ install_stripe_cli() {
8989
}
9090

9191
# main
92-
one_time_setup
92+
if [[ -z "${CODESPACES}" ]]; then
93+
one_time_setup
94+
else
95+
# Ignore interactive elements when running in codespaces since they are not supported there
96+
# TODO Write codespaces specific instructions and link here
97+
echo "Running in codespaces, follow instructions here: https://contributing.bitwarden.com/getting-started/server/guide/ to continue the setup"
98+
fi

.github/workflows/test-database.yml

+1-19
Original file line numberDiff line numberDiff line change
@@ -32,28 +32,10 @@ on:
3232
- "src/**/Entities/**/*.cs" # Database entity definitions
3333

3434
jobs:
35-
check-test-secrets:
36-
name: Check for test secrets
37-
runs-on: ubuntu-22.04
38-
outputs:
39-
available: ${{ steps.check-test-secrets.outputs.available }}
40-
permissions:
41-
contents: read
42-
43-
steps:
44-
- name: Check
45-
id: check-test-secrets
46-
run: |
47-
if [ "${{ secrets.CODECOV_TOKEN }}" != '' ]; then
48-
echo "available=true" >> $GITHUB_OUTPUT;
49-
else
50-
echo "available=false" >> $GITHUB_OUTPUT;
51-
fi
5235

5336
test:
5437
name: Run tests
5538
runs-on: ubuntu-22.04
56-
needs: check-test-secrets
5739
steps:
5840
- name: Check out repo
5941
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -167,7 +149,7 @@ jobs:
167149

168150
- name: Report test results
169151
uses: dorny/test-reporter@31a54ee7ebcacc03a09ea97a7e5465a47b84aea5 # v1.9.1
170-
if: ${{ needs.check-test-secrets.outputs.available == 'true' && !cancelled() }}
152+
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }}
171153
with:
172154
name: Test Results
173155
path: "**/*-test-results.trx"

.github/workflows/test.yml

+1-19
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,11 @@ env:
1313
_AZ_REGISTRY: "bitwardenprod.azurecr.io"
1414

1515
jobs:
16-
check-test-secrets:
17-
name: Check for test secrets
18-
runs-on: ubuntu-22.04
19-
outputs:
20-
available: ${{ steps.check-test-secrets.outputs.available }}
21-
permissions:
22-
contents: read
23-
24-
steps:
25-
- name: Check
26-
id: check-test-secrets
27-
run: |
28-
if [ "${{ secrets.CODECOV_TOKEN }}" != '' ]; then
29-
echo "available=true" >> $GITHUB_OUTPUT;
30-
else
31-
echo "available=false" >> $GITHUB_OUTPUT;
32-
fi
3316

3417
testing:
3518
name: Run tests
3619
if: ${{ startsWith(github.head_ref, 'version_bump_') == false }}
3720
runs-on: ubuntu-22.04
38-
needs: check-test-secrets
3921
permissions:
4022
checks: write
4123
contents: read
@@ -69,7 +51,7 @@ jobs:
6951

7052
- name: Report test results
7153
uses: dorny/test-reporter@31a54ee7ebcacc03a09ea97a7e5465a47b84aea5 # v1.9.1
72-
if: ${{ needs.check-test-secrets.outputs.available == 'true' && !cancelled() }}
54+
if: ${{ github.event.pull_request.head.repo.full_name == github.repository && !cancelled() }}
7355
with:
7456
name: Test Results
7557
path: "**/*-test-results.trx"

Directory.Build.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
55

6-
<Version>2025.2.1</Version>
6+
<Version>2025.3.0</Version>
77

88
<RootNamespace>Bit.$(MSBuildProjectName)</RootNamespace>
99
<ImplicitUsings>enable</ImplicitUsings>

bitwarden_license/src/Commercial.Core/AdminConsole/Providers/RemoveOrganizationFromProviderCommand.cs

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
using Bit.Core.AdminConsole.Repositories;
66
using Bit.Core.Billing.Constants;
77
using Bit.Core.Billing.Extensions;
8+
using Bit.Core.Billing.Pricing;
89
using Bit.Core.Billing.Services;
910
using Bit.Core.Enums;
1011
using Bit.Core.Exceptions;
1112
using Bit.Core.Repositories;
1213
using Bit.Core.Services;
13-
using Bit.Core.Utilities;
1414
using Stripe;
1515

1616
namespace Bit.Commercial.Core.AdminConsole.Providers;
@@ -27,6 +27,7 @@ public class RemoveOrganizationFromProviderCommand : IRemoveOrganizationFromProv
2727
private readonly IProviderBillingService _providerBillingService;
2828
private readonly ISubscriberService _subscriberService;
2929
private readonly IHasConfirmedOwnersExceptQuery _hasConfirmedOwnersExceptQuery;
30+
private readonly IPricingClient _pricingClient;
3031

3132
public RemoveOrganizationFromProviderCommand(
3233
IEventService eventService,
@@ -38,7 +39,8 @@ public RemoveOrganizationFromProviderCommand(
3839
IFeatureService featureService,
3940
IProviderBillingService providerBillingService,
4041
ISubscriberService subscriberService,
41-
IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery)
42+
IHasConfirmedOwnersExceptQuery hasConfirmedOwnersExceptQuery,
43+
IPricingClient pricingClient)
4244
{
4345
_eventService = eventService;
4446
_mailService = mailService;
@@ -50,6 +52,7 @@ public RemoveOrganizationFromProviderCommand(
5052
_providerBillingService = providerBillingService;
5153
_subscriberService = subscriberService;
5254
_hasConfirmedOwnersExceptQuery = hasConfirmedOwnersExceptQuery;
55+
_pricingClient = pricingClient;
5356
}
5457

5558
public async Task RemoveOrganizationFromProvider(
@@ -110,7 +113,7 @@ private async Task ResetOrganizationBillingAsync(
110113
Email = organization.BillingEmail
111114
});
112115

113-
var plan = StaticStore.GetPlan(organization.PlanType).PasswordManager;
116+
var plan = await _pricingClient.GetPlanOrThrow(organization.PlanType);
114117

115118
var subscriptionCreateOptions = new SubscriptionCreateOptions
116119
{
@@ -124,7 +127,7 @@ private async Task ResetOrganizationBillingAsync(
124127
},
125128
OffSession = true,
126129
ProrationBehavior = StripeConstants.ProrationBehavior.CreateProrations,
127-
Items = [new SubscriptionItemOptions { Price = plan.StripeSeatPlanId, Quantity = organization.Seats }]
130+
Items = [new SubscriptionItemOptions { Price = plan.PasswordManager.StripeSeatPlanId, Quantity = organization.Seats }]
128131
};
129132

130133
var subscription = await _stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);

bitwarden_license/src/Commercial.Core/AdminConsole/Services/ProviderService.cs

+15-11
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Bit.Core.AdminConsole.Repositories;
99
using Bit.Core.AdminConsole.Services;
1010
using Bit.Core.Billing.Enums;
11+
using Bit.Core.Billing.Pricing;
1112
using Bit.Core.Billing.Services;
1213
using Bit.Core.Context;
1314
using Bit.Core.Entities;
@@ -50,6 +51,7 @@ public class ProviderService : IProviderService
5051
private readonly IDataProtectorTokenFactory<ProviderDeleteTokenable> _providerDeleteTokenDataFactory;
5152
private readonly IApplicationCacheService _applicationCacheService;
5253
private readonly IProviderBillingService _providerBillingService;
54+
private readonly IPricingClient _pricingClient;
5355

5456
public ProviderService(IProviderRepository providerRepository, IProviderUserRepository providerUserRepository,
5557
IProviderOrganizationRepository providerOrganizationRepository, IUserRepository userRepository,
@@ -58,7 +60,7 @@ public ProviderService(IProviderRepository providerRepository, IProviderUserRepo
5860
IOrganizationRepository organizationRepository, GlobalSettings globalSettings,
5961
ICurrentContext currentContext, IStripeAdapter stripeAdapter, IFeatureService featureService,
6062
IDataProtectorTokenFactory<ProviderDeleteTokenable> providerDeleteTokenDataFactory,
61-
IApplicationCacheService applicationCacheService, IProviderBillingService providerBillingService)
63+
IApplicationCacheService applicationCacheService, IProviderBillingService providerBillingService, IPricingClient pricingClient)
6264
{
6365
_providerRepository = providerRepository;
6466
_providerUserRepository = providerUserRepository;
@@ -77,6 +79,7 @@ public ProviderService(IProviderRepository providerRepository, IProviderUserRepo
7779
_providerDeleteTokenDataFactory = providerDeleteTokenDataFactory;
7880
_applicationCacheService = applicationCacheService;
7981
_providerBillingService = providerBillingService;
82+
_pricingClient = pricingClient;
8083
}
8184

8285
public async Task<Provider> CompleteSetupAsync(Provider provider, Guid ownerUserId, string token, string key, TaxInfo taxInfo = null)
@@ -452,30 +455,31 @@ private async Task ApplyProviderPriceRateAsync(Organization organization, Provid
452455

453456
if (!string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
454457
{
455-
var subscriptionItem = await GetSubscriptionItemAsync(organization.GatewaySubscriptionId,
456-
GetStripeSeatPlanId(organization.PlanType));
458+
var plan = await _pricingClient.GetPlanOrThrow(organization.PlanType);
459+
460+
var subscriptionItem = await GetSubscriptionItemAsync(
461+
organization.GatewaySubscriptionId,
462+
plan.PasswordManager.StripeSeatPlanId);
463+
457464
var extractedPlanType = PlanTypeMappings(organization);
465+
var extractedPlan = await _pricingClient.GetPlanOrThrow(extractedPlanType);
466+
458467
if (subscriptionItem != null)
459468
{
460-
await UpdateSubscriptionAsync(subscriptionItem, GetStripeSeatPlanId(extractedPlanType), organization);
469+
await UpdateSubscriptionAsync(subscriptionItem, extractedPlan.PasswordManager.StripeSeatPlanId, organization);
461470
}
462471
}
463472

464473
await _organizationRepository.UpsertAsync(organization);
465474
}
466475

467-
private async Task<Stripe.SubscriptionItem> GetSubscriptionItemAsync(string subscriptionId, string oldPlanId)
476+
private async Task<SubscriptionItem> GetSubscriptionItemAsync(string subscriptionId, string oldPlanId)
468477
{
469478
var subscriptionDetails = await _stripeAdapter.SubscriptionGetAsync(subscriptionId);
470479
return subscriptionDetails.Items.Data.FirstOrDefault(item => item.Price.Id == oldPlanId);
471480
}
472481

473-
private static string GetStripeSeatPlanId(PlanType planType)
474-
{
475-
return StaticStore.GetPlan(planType).PasswordManager.StripeSeatPlanId;
476-
}
477-
478-
private async Task UpdateSubscriptionAsync(Stripe.SubscriptionItem subscriptionItem, string extractedPlanType, Organization organization)
482+
private async Task UpdateSubscriptionAsync(SubscriptionItem subscriptionItem, string extractedPlanType, Organization organization)
479483
{
480484
try
481485
{

0 commit comments

Comments
 (0)