1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 08:32:50 -05:00

Record when a provider user accesses a clients vault (#1496)

* Record when a provider user accesses a clients vault

* Do not allow removal from provider unless owner exists

* PR Review

* Null safe event processing
* append `Async` to async methods
This commit is contained in:
Matt Gibson
2021-08-05 08:50:41 -04:00
committed by GitHub
parent 744e8f1a13
commit cfc7fa071b
9 changed files with 56 additions and 15 deletions

View File

@ -30,6 +30,7 @@ namespace Bit.Api.Controllers
private readonly ICipherService _cipherService;
private readonly IUserService _userService;
private readonly IAttachmentStorageService _attachmentStorageService;
private readonly IProviderService _providerService;
private readonly ICurrentContext _currentContext;
private readonly ILogger<CiphersController> _logger;
private readonly GlobalSettings _globalSettings;
@ -40,6 +41,7 @@ namespace Bit.Api.Controllers
ICipherService cipherService,
IUserService userService,
IAttachmentStorageService attachmentStorageService,
IProviderService providerService,
ICurrentContext currentContext,
ILogger<CiphersController> logger,
GlobalSettings globalSettings)
@ -49,6 +51,7 @@ namespace Bit.Api.Controllers
_cipherService = cipherService;
_userService = userService;
_attachmentStorageService = attachmentStorageService;
_providerService = providerService;
_currentContext = currentContext;
_logger = logger;
_globalSettings = globalSettings;
@ -224,6 +227,12 @@ namespace Bit.Api.Controllers
var responses = ciphers.Select(c => new CipherMiniDetailsResponseModel(c, _globalSettings,
collectionCiphersGroupDict));
var providerId = await _currentContext.ProviderIdForOrg(orgIdGuid);
if (providerId.HasValue)
{
await _providerService.LogProviderAccessToOrganizationAsync(orgIdGuid);
}
return new ListResponseModel<CipherMiniDetailsResponseModel>(responses);
}

View File

@ -91,7 +91,7 @@ namespace Bit.Api.Controllers
}
var userId = _userService.GetProperUserId(User);
await _providerService.RemoveOrganization(providerId, id, userId.Value);
await _providerService.RemoveOrganizationAsync(providerId, id, userId.Value);
}
}
}

View File

@ -52,6 +52,7 @@
Organization_Updated = 1600,
Organization_PurgedVault = 1601,
// Organization_ClientExportedVault = 1602,
Organization_VaultAccessed = 1603,
Policy_Updated = 1700,
@ -63,5 +64,6 @@
ProviderOrganization_Created = 1900,
ProviderOrganization_Added = 1901,
ProviderOrganization_Removed = 1902,
ProviderOrganization_VaultAccessed = 1903,
}
}

View File

@ -59,6 +59,6 @@ namespace Bit.Core.Services
Task RotateApiKeyAsync(Organization organization);
Task DeleteSsoUserAsync(Guid userId, Guid? organizationId);
Task<Organization> UpdateOrganizationKeysAsync(Guid orgId, string publicKey, string privateKey);
Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId);
Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId, bool includeProvider = true);
}
}

View File

@ -27,6 +27,7 @@ namespace Bit.Core.Services
Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key);
Task<ProviderOrganization> CreateOrganizationAsync(Guid providerId, OrganizationSignup organizationSignup,
string clientOwnerEmail, User user);
Task RemoveOrganization(Guid providerId, Guid providerOrganizationId, Guid removingUserId);
Task RemoveOrganizationAsync(Guid providerId, Guid providerOrganizationId, Guid removingUserId);
Task LogProviderAccessToOrganizationAsync(Guid organizationId);
}
}

View File

@ -1689,11 +1689,16 @@ namespace Bit.Core.Services
return result;
}
public async Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId)
public async Task<bool> HasConfirmedOwnersExceptAsync(Guid organizationId, IEnumerable<Guid> organizationUsersId, bool includeProvider = true)
{
var confirmedOwners = await GetConfirmedOwnersAsync(organizationId);
var confirmedOwnersIds = confirmedOwners.Select(u => u.Id);
return confirmedOwnersIds.Except(organizationUsersId).Any();
bool hasOtherOwner = confirmedOwnersIds.Except(organizationUsersId).Any();
if (!hasOtherOwner && includeProvider)
{
return (await _currentContext.ProviderIdForOrg(organizationId)).HasValue;
}
return hasOtherOwner;
}
public async Task UpdateUserGroupsAsync(OrganizationUser organizationUser, IEnumerable<Guid> groupIds, Guid? loggedInUserId)

View File

@ -31,6 +31,7 @@ namespace Bit.Core.Services
public Task AddOrganization(Guid providerId, Guid organizationId, Guid addingUserId, string key) => throw new NotImplementedException();
public Task<ProviderOrganization> CreateOrganizationAsync(Guid providerId, OrganizationSignup organizationSignup, string clientOwnerEmail, User user) => throw new NotImplementedException();
public Task RemoveOrganization(Guid providerId, Guid providerOrganizationId, Guid removingUserId) => throw new NotImplementedException();
public Task RemoveOrganizationAsync(Guid providerId, Guid providerOrganizationId, Guid removingUserId) => throw new NotImplementedException();
public Task LogProviderAccessToOrganizationAsync(Guid organizationId) => throw new NotImplementedException();
}
}