1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-25 12:45:18 +01:00

[AC-2184] Fix push sync notification on opt-in to Flexible Collections (#3794)

* Fix push sync notification on opt-in to Flexible Collections

* Fix tests

* Fix tests more
This commit is contained in:
Thomas Rittson 2024-02-14 04:15:07 +10:00 committed by GitHub
parent ae5d6071ca
commit 0258f4949c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 47 additions and 9 deletions

View File

@ -899,8 +899,9 @@ public class OrganizationsController : Controller
var orgUsers = await _organizationUserRepository.GetManyByOrganizationAsync(id, null); var orgUsers = await _organizationUserRepository.GetManyByOrganizationAsync(id, null);
await Task.WhenAll(orgUsers await Task.WhenAll(orgUsers
.Where(ou => ou.UserId.HasValue && .Where(ou => ou.UserId.HasValue &&
ou.Status == OrganizationUserStatusType.Confirmed &&
ou.Type is OrganizationUserType.Admin or OrganizationUserType.Owner) ou.Type is OrganizationUserType.Admin or OrganizationUserType.Owner)
.Select(ou => _pushNotificationService.PushSyncVaultAsync(ou.UserId.Value))); .Select(ou => _pushNotificationService.PushSyncOrganizationsAsync(ou.UserId.Value)));
} }
private async Task TryGrantOwnerAccessToSecretsManagerAsync(Guid organizationId, Guid userId) private async Task TryGrantOwnerAccessToSecretsManagerAsync(Guid organizationId, Guid userId)

View File

@ -23,4 +23,6 @@ public enum PushType : byte
AuthRequest = 15, AuthRequest = 15,
AuthRequestResponse = 16, AuthRequestResponse = 16,
SyncOrganizations = 17,
} }

View File

@ -15,6 +15,7 @@ public interface IPushNotificationService
Task PushSyncFolderDeleteAsync(Folder folder); Task PushSyncFolderDeleteAsync(Folder folder);
Task PushSyncCiphersAsync(Guid userId); Task PushSyncCiphersAsync(Guid userId);
Task PushSyncVaultAsync(Guid userId); Task PushSyncVaultAsync(Guid userId);
Task PushSyncOrganizationsAsync(Guid userId);
Task PushSyncOrgKeysAsync(Guid userId); Task PushSyncOrgKeysAsync(Guid userId);
Task PushSyncSettingsAsync(Guid userId); Task PushSyncSettingsAsync(Guid userId);
Task PushLogOutAsync(Guid userId, bool excludeCurrentContextFromPush = false); Task PushLogOutAsync(Guid userId, bool excludeCurrentContextFromPush = false);

View File

@ -106,6 +106,11 @@ public class AzureQueuePushNotificationService : IPushNotificationService
await PushUserAsync(userId, PushType.SyncVault); await PushUserAsync(userId, PushType.SyncVault);
} }
public async Task PushSyncOrganizationsAsync(Guid userId)
{
await PushUserAsync(userId, PushType.SyncOrganizations);
}
public async Task PushSyncOrgKeysAsync(Guid userId) public async Task PushSyncOrgKeysAsync(Guid userId)
{ {
await PushUserAsync(userId, PushType.SyncOrgKeys); await PushUserAsync(userId, PushType.SyncOrgKeys);

View File

@ -105,6 +105,12 @@ public class MultiServicePushNotificationService : IPushNotificationService
return Task.FromResult(0); return Task.FromResult(0);
} }
public Task PushSyncOrganizationsAsync(Guid userId)
{
PushToServices((s) => s.PushSyncOrganizationsAsync(userId));
return Task.FromResult(0);
}
public Task PushSyncOrgKeysAsync(Guid userId) public Task PushSyncOrgKeysAsync(Guid userId)
{ {
PushToServices((s) => s.PushSyncOrgKeysAsync(userId)); PushToServices((s) => s.PushSyncOrgKeysAsync(userId));

View File

@ -117,6 +117,11 @@ public class NotificationHubPushNotificationService : IPushNotificationService
await PushUserAsync(userId, PushType.SyncVault); await PushUserAsync(userId, PushType.SyncVault);
} }
public async Task PushSyncOrganizationsAsync(Guid userId)
{
await PushUserAsync(userId, PushType.SyncOrganizations);
}
public async Task PushSyncOrgKeysAsync(Guid userId) public async Task PushSyncOrgKeysAsync(Guid userId)
{ {
await PushUserAsync(userId, PushType.SyncOrgKeys); await PushUserAsync(userId, PushType.SyncOrgKeys);

View File

@ -113,6 +113,11 @@ public class NotificationsApiPushNotificationService : BaseIdentityClientService
await PushUserAsync(userId, PushType.SyncVault); await PushUserAsync(userId, PushType.SyncVault);
} }
public async Task PushSyncOrganizationsAsync(Guid userId)
{
await PushUserAsync(userId, PushType.SyncOrganizations);
}
public async Task PushSyncOrgKeysAsync(Guid userId) public async Task PushSyncOrgKeysAsync(Guid userId)
{ {
await PushUserAsync(userId, PushType.SyncOrgKeys); await PushUserAsync(userId, PushType.SyncOrgKeys);

View File

@ -114,6 +114,11 @@ public class RelayPushNotificationService : BaseIdentityClientService, IPushNoti
await PushUserAsync(userId, PushType.SyncVault); await PushUserAsync(userId, PushType.SyncVault);
} }
public async Task PushSyncOrganizationsAsync(Guid userId)
{
await PushUserAsync(userId, PushType.SyncOrganizations);
}
public async Task PushSyncOrgKeysAsync(Guid userId) public async Task PushSyncOrgKeysAsync(Guid userId)
{ {
await PushUserAsync(userId, PushType.SyncOrgKeys); await PushUserAsync(userId, PushType.SyncOrgKeys);

View File

@ -42,6 +42,11 @@ public class NoopPushNotificationService : IPushNotificationService
return Task.FromResult(0); return Task.FromResult(0);
} }
public Task PushSyncOrganizationsAsync(Guid userId)
{
return Task.FromResult(0);
}
public Task PushSyncOrgKeysAsync(Guid userId) public Task PushSyncOrgKeysAsync(Guid userId)
{ {
return Task.FromResult(0); return Task.FromResult(0);

View File

@ -50,6 +50,7 @@ public static class HubHelpers
break; break;
case PushType.SyncCiphers: case PushType.SyncCiphers:
case PushType.SyncVault: case PushType.SyncVault:
case PushType.SyncOrganizations:
case PushType.SyncOrgKeys: case PushType.SyncOrgKeys:
case PushType.SyncSettings: case PushType.SyncSettings:
case PushType.LogOut: case PushType.LogOut:

View File

@ -377,14 +377,15 @@ public class OrganizationsControllerTests : IDisposable
public async Task EnableCollectionEnhancements_Success(Organization organization) public async Task EnableCollectionEnhancements_Success(Organization organization)
{ {
organization.FlexibleCollections = false; organization.FlexibleCollections = false;
var admin = new OrganizationUser { UserId = Guid.NewGuid(), Type = OrganizationUserType.Admin }; var admin = new OrganizationUser { UserId = Guid.NewGuid(), Type = OrganizationUserType.Admin, Status = OrganizationUserStatusType.Confirmed };
var owner = new OrganizationUser { UserId = Guid.NewGuid(), Type = OrganizationUserType.Owner }; var owner = new OrganizationUser { UserId = Guid.NewGuid(), Type = OrganizationUserType.Owner, Status = OrganizationUserStatusType.Confirmed };
var user = new OrganizationUser { UserId = Guid.NewGuid(), Type = OrganizationUserType.User }; var user = new OrganizationUser { UserId = Guid.NewGuid(), Type = OrganizationUserType.User, Status = OrganizationUserStatusType.Confirmed };
var invited = new OrganizationUser var invited = new OrganizationUser
{ {
UserId = null, UserId = null,
Type = OrganizationUserType.Admin, Type = OrganizationUserType.Admin,
Email = "invited@example.com" Email = "invited@example.com",
Status = OrganizationUserStatusType.Invited
}; };
var orgUsers = new List<OrganizationUser> { admin, owner, user, invited }; var orgUsers = new List<OrganizationUser> { admin, owner, user, invited };
@ -395,9 +396,10 @@ public class OrganizationsControllerTests : IDisposable
await _sut.EnableCollectionEnhancements(organization.Id); await _sut.EnableCollectionEnhancements(organization.Id);
await _organizationEnableCollectionEnhancementsCommand.Received(1).EnableCollectionEnhancements(organization); await _organizationEnableCollectionEnhancementsCommand.Received(1).EnableCollectionEnhancements(organization);
await _pushNotificationService.Received(1).PushSyncVaultAsync(admin.UserId.Value); await _pushNotificationService.Received(1).PushSyncOrganizationsAsync(admin.UserId.Value);
await _pushNotificationService.Received(1).PushSyncVaultAsync(owner.UserId.Value); await _pushNotificationService.Received(1).PushSyncOrganizationsAsync(owner.UserId.Value);
await _pushNotificationService.DidNotReceive().PushSyncVaultAsync(user.UserId.Value); await _pushNotificationService.DidNotReceive().PushSyncOrganizationsAsync(user.UserId.Value);
// Invited orgUser does not have a UserId we can use to assert here, but sut will throw if that null isn't handled
} }
[Theory, AutoData] [Theory, AutoData]
@ -410,6 +412,6 @@ public class OrganizationsControllerTests : IDisposable
await Assert.ThrowsAsync<NotFoundException>(async () => await _sut.EnableCollectionEnhancements(organization.Id)); await Assert.ThrowsAsync<NotFoundException>(async () => await _sut.EnableCollectionEnhancements(organization.Id));
await _organizationEnableCollectionEnhancementsCommand.DidNotReceiveWithAnyArgs().EnableCollectionEnhancements(Arg.Any<Organization>()); await _organizationEnableCollectionEnhancementsCommand.DidNotReceiveWithAnyArgs().EnableCollectionEnhancements(Arg.Any<Organization>());
await _pushNotificationService.DidNotReceiveWithAnyArgs().PushSyncVaultAsync(Arg.Any<Guid>()); await _pushNotificationService.DidNotReceiveWithAnyArgs().PushSyncOrganizationsAsync(Arg.Any<Guid>());
} }
} }