Skip to content

Commit 0e519bc

Browse files
committed
Changes from Code Review
1 parent 98d5fde commit 0e519bc

5 files changed

Lines changed: 24 additions & 34 deletions

File tree

src/Core/AdminConsole/AbilitiesCache/ExtendedOrganizationAbilityCacheService.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ public class ExtendedOrganizationAbilityCacheService(
1717
IOrganizationRepository organizationRepository)
1818
: IOrganizationAbilityCacheService
1919
{
20-
2120
public async Task<OrganizationAbility?> GetOrganizationAbilityAsync(Guid orgId, CancellationToken cancellationToken = default)
2221
{
23-
var cacheKey = BuildCacheKeyForOrganizationAbility(orgId);
2422
return await cache.GetOrSetAsync<OrganizationAbility?>(
25-
cacheKey,
23+
orgId.ToString(),
2624
async (_, _) => await organizationRepository.GetAbilityAsync(orgId),
2725
token: cancellationToken);
2826
}
@@ -38,16 +36,11 @@ public async Task<IDictionary<Guid, OrganizationAbility>> GetOrganizationAbiliti
3836

3937
public async Task UpsertOrganizationAbilityAsync(Organization organization, CancellationToken cancellationToken = default)
4038
{
41-
var cacheKey = BuildCacheKeyForOrganizationAbility(organization.Id);
42-
await cache.SetAsync<OrganizationAbility?>(cacheKey, new OrganizationAbility(organization), token: cancellationToken);
39+
await cache.SetAsync<OrganizationAbility?>(organization.Id.ToString(), new OrganizationAbility(organization), token: cancellationToken);
4340
}
4441

4542
public async Task DeleteOrganizationAbilityAsync(Guid organizationId, CancellationToken cancellationToken = default)
4643
{
47-
var cacheKey = BuildCacheKeyForOrganizationAbility(organizationId);
48-
await cache.RemoveAsync(cacheKey, token: cancellationToken);
44+
await cache.RemoveAsync(organizationId.ToString(), token: cancellationToken);
4945
}
50-
51-
private static string BuildCacheKeyForOrganizationAbility(Guid organizationId)
52-
=> $"org-ability:{organizationId:N}";
5346
}

src/Core/AdminConsole/AbilitiesCache/OrganizationAbilityServiceCollectionsExtension.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ public static class OrganizationAbilityServiceCollectionsExtension
88
public static IServiceCollection AddOrganizationAbilityCache(this IServiceCollection serviceCollection,
99
GlobalSettings globalSettings) =>
1010
serviceCollection.AddExtendedCache(ExtendedOrganizationAbilityCacheConstants.CacheName, globalSettings)
11-
.AddScoped<IOrganizationAbilityCacheService, ExtendedOrganizationAbilityCacheService>();
11+
.AddSingleton<IOrganizationAbilityCacheService, ExtendedOrganizationAbilityCacheService>();
1212
}

src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/AcceptOrgUserCommand.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,15 @@ private async Task HandleAutomaticUserConfirmationPolicyAsync(OrganizationUser o
232232
var policyRequirement = await _policyRequirementQuery.GetAsync<AutomaticUserConfirmationPolicyRequirement>(
233233
user.Id);
234234

235+
// Ensure that the user is not already in the list of organization users
236+
if (!allOrgUsers.Any(x => x.OrganizationId == orgUser.OrganizationId && x.UserId == user.Id))
237+
{
238+
allOrgUsers.Add(orgUser);
239+
}
240+
235241
var error = (await _automaticUserConfirmationPolicyEnforcementValidator.IsCompliantAsync(
236242
new AutomaticUserConfirmationPolicyEnforcementRequest(orgUser.OrganizationId,
237-
allOrgUsers.Append(orgUser),
243+
allOrgUsers,
238244
user),
239245
policyRequirement))
240246
.Match(

src/Core/Services/Implementations/FeatureRoutedCacheService.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace Bit.Core.Services.Implementations;
88

99
public class FeatureRoutedCacheService(
1010
IVCurrentInMemoryApplicationCacheService inMemoryApplicationCacheService,
11-
IOrganizationAbilityCacheService extendedCacheService,
11+
IOrganizationAbilityCacheService extendedOrgAbilityCacheService,
1212
IFeatureService featureService)
1313
: IApplicationCacheService
1414
{
@@ -17,7 +17,7 @@ public Task<IDictionary<Guid, OrganizationAbility>> GetOrganizationAbilitiesAsyn
1717

1818
public Task<OrganizationAbility?> GetOrganizationAbilityAsync(Guid orgId) =>
1919
featureService.IsEnabled(FeatureFlagKeys.OrgAbilityExtendedCache)
20-
? extendedCacheService.GetOrganizationAbilityAsync(orgId)
20+
? extendedOrgAbilityCacheService.GetOrganizationAbilityAsync(orgId)
2121
: inMemoryApplicationCacheService.GetOrganizationAbilityAsync(orgId);
2222

2323
public Task<IDictionary<Guid, ProviderAbility>> GetProviderAbilitiesAsync() =>
@@ -42,7 +42,7 @@ public async Task<IDictionary<Guid, OrganizationAbility>> GetOrganizationAbiliti
4242
{
4343
if (featureService.IsEnabled(FeatureFlagKeys.OrgAbilityExtendedCache))
4444
{
45-
return await extendedCacheService.GetOrganizationAbilitiesAsync(orgIds);
45+
return await extendedOrgAbilityCacheService.GetOrganizationAbilitiesAsync(orgIds);
4646
}
4747

4848
var allOrganizationAbilities = await inMemoryApplicationCacheService.GetOrganizationAbilitiesAsync();
@@ -54,15 +54,15 @@ public async Task<IDictionary<Guid, OrganizationAbility>> GetOrganizationAbiliti
5454

5555
public Task UpsertOrganizationAbilityAsync(Organization organization) =>
5656
featureService.IsEnabled(FeatureFlagKeys.OrgAbilityExtendedCache)
57-
? extendedCacheService.UpsertOrganizationAbilityAsync(organization)
57+
? extendedOrgAbilityCacheService.UpsertOrganizationAbilityAsync(organization)
5858
: inMemoryApplicationCacheService.UpsertOrganizationAbilityAsync(organization);
5959

6060
public Task UpsertProviderAbilityAsync(Provider provider) =>
6161
inMemoryApplicationCacheService.UpsertProviderAbilityAsync(provider);
6262

6363
public Task DeleteOrganizationAbilityAsync(Guid organizationId) =>
6464
featureService.IsEnabled(FeatureFlagKeys.OrgAbilityExtendedCache)
65-
? extendedCacheService.DeleteOrganizationAbilityAsync(organizationId)
65+
? extendedOrgAbilityCacheService.DeleteOrganizationAbilityAsync(organizationId)
6666
: inMemoryApplicationCacheService.DeleteOrganizationAbilityAsync(organizationId);
6767

6868
public Task DeleteProviderAbilityAsync(Guid providerId) =>
@@ -72,7 +72,7 @@ public async Task BaseUpsertOrganizationAbilityAsync(Organization organization)
7272
{
7373
if (featureService.IsEnabled(FeatureFlagKeys.OrgAbilityExtendedCache))
7474
{
75-
await extendedCacheService.UpsertOrganizationAbilityAsync(organization);
75+
await extendedOrgAbilityCacheService.UpsertOrganizationAbilityAsync(organization);
7676
return;
7777
}
7878

@@ -90,7 +90,7 @@ public async Task BaseDeleteOrganizationAbilityAsync(Guid organizationId)
9090
{
9191
if (featureService.IsEnabled(FeatureFlagKeys.OrgAbilityExtendedCache))
9292
{
93-
await extendedCacheService.DeleteOrganizationAbilityAsync(organizationId);
93+
await extendedOrgAbilityCacheService.DeleteOrganizationAbilityAsync(organizationId);
9494
return;
9595
}
9696

test/Api.IntegrationTest/AdminConsole/Controllers/OrganizationAbilityCacheTests.cs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,36 +105,27 @@ public async Task Put_UpdatesOrganization_CacheReflectsUpdatedValues()
105105
[Fact]
106106
public async Task Delete_RemovesOrganization_CacheReturnsNull()
107107
{
108-
// Arrange - create a separate org for deletion so we don't affect other tests
109-
var deleteOwnerEmail = $"delete-test-{Guid.NewGuid()}@example.com";
110-
await _factory.LoginWithNewAccount(deleteOwnerEmail);
111-
112-
var signUpResult = await OrganizationTestHelpers.SignUpAsync(
113-
_factory,
114-
plan: PlanType.EnterpriseAnnually,
115-
ownerEmail: deleteOwnerEmail,
116-
passwordManagerSeats: 5,
117-
paymentMethod: PaymentMethodType.Card);
118-
var orgToDelete = signUpResult.Item1;
108+
// Arrange - setup in InitializeAsync()
109+
await _loginHelper.LoginAsync(_ownerEmail);
119110

120111
// Verify cache is populated before delete
121112
var cacheService = _factory.GetService<IApplicationCacheService>();
122-
var abilityBeforeDelete = await cacheService.GetOrganizationAbilityAsync(orgToDelete.Id);
113+
var abilityBeforeDelete = await cacheService.GetOrganizationAbilityAsync(_organization.Id);
123114
Assert.NotNull(abilityBeforeDelete);
124115

125116
// Act - delete the organization via the HTTP endpoint
126-
await _loginHelper.LoginAsync(deleteOwnerEmail);
117+
await _loginHelper.LoginAsync(_ownerEmail);
127118
var deleteRequest = new SecretVerificationRequestModel
128119
{
129120
MasterPasswordHash = "master_password_hash"
130121
};
131122
var response = await _client.PostAsJsonAsync(
132-
$"/organizations/{orgToDelete.Id}/delete", deleteRequest);
123+
$"/organizations/{_organization.Id}/delete", deleteRequest);
133124

134125
// Assert - endpoint succeeded and cache was cleared
135126
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
136127

137-
var abilityAfterDelete = await cacheService.GetOrganizationAbilityAsync(orgToDelete.Id);
128+
var abilityAfterDelete = await cacheService.GetOrganizationAbilityAsync(_organization.Id);
138129
Assert.Null(abilityAfterDelete);
139130
}
140131
}

0 commit comments

Comments
 (0)