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

[Provider] Send email on removal (#1463)

This commit is contained in:
Oscar Hinton 2021-07-15 16:37:16 +02:00 committed by GitHub
parent eb0b8da911
commit 8ac2dc50af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 3 deletions

View File

@ -259,7 +259,7 @@ namespace Bit.CommCore.Services
await _providerUserRepository.ReplaceAsync(providerUser); await _providerUserRepository.ReplaceAsync(providerUser);
events.Add((providerUser, EventType.ProviderUser_Confirmed, null)); events.Add((providerUser, EventType.ProviderUser_Confirmed, null));
await _mailService.SendOrganizationConfirmedEmailAsync(provider.Name, user.Email); await _mailService.SendProviderConfirmedEmailAsync(provider.Name, user.Email);
result.Add(Tuple.Create(providerUser, "")); result.Add(Tuple.Create(providerUser, ""));
} }
catch (BadRequestException e) catch (BadRequestException e)
@ -293,7 +293,17 @@ namespace Bit.CommCore.Services
public async Task<List<Tuple<ProviderUser, string>>> DeleteUsersAsync(Guid providerId, public async Task<List<Tuple<ProviderUser, string>>> DeleteUsersAsync(Guid providerId,
IEnumerable<Guid> providerUserIds, Guid deletingUserId) IEnumerable<Guid> providerUserIds, Guid deletingUserId)
{ {
var provider = await _providerRepository.GetByIdAsync(providerId);
if (provider == null)
{
throw new NotFoundException();
}
var providerUsers = await _providerUserRepository.GetManyAsync(providerUserIds); var providerUsers = await _providerUserRepository.GetManyAsync(providerUserIds);
var users = await _userRepository.GetManyAsync(providerUsers.Where(pu => pu.UserId.HasValue)
.Select(pu => pu.UserId.Value));
var keyedUsers = users.ToDictionary(u => u.Id);
if (!await HasConfirmedProviderAdminExceptAsync(providerId, providerUserIds)) if (!await HasConfirmedProviderAdminExceptAsync(providerId, providerUserIds))
{ {
@ -319,6 +329,13 @@ namespace Bit.CommCore.Services
events.Add((providerUser, EventType.ProviderUser_Removed, null)); events.Add((providerUser, EventType.ProviderUser_Removed, null));
var user = keyedUsers.GetValueOrDefault(providerUser.UserId.GetValueOrDefault());
var email = user == null ? providerUser.Email : user.Email;
if (!string.IsNullOrWhiteSpace(email))
{
await _mailService.SendProviderUserRemoved(provider.Name, email);
}
result.Add(Tuple.Create(providerUser, "")); result.Add(Tuple.Create(providerUser, ""));
deletedUserIds.Add(providerUser.Id); deletedUserIds.Add(providerUser.Id);
} }

View File

@ -361,6 +361,7 @@ namespace Bit.CommCore.Test.Services
} }
providerUsers.Last().ProviderId = default; providerUsers.Last().ProviderId = default;
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>(); var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
providerUserRepository.GetManyAsync(default).ReturnsForAnyArgs(providerUsers); providerUserRepository.GetManyAsync(default).ReturnsForAnyArgs(providerUsers);
providerUserRepository.GetManyByProviderAsync(default, default).ReturnsForAnyArgs(new ProviderUser[] {}); providerUserRepository.GetManyByProviderAsync(default, default).ReturnsForAnyArgs(new ProviderUser[] {});
@ -384,6 +385,7 @@ namespace Bit.CommCore.Test.Services
} }
providerUsers.Last().ProviderId = default; providerUsers.Last().ProviderId = default;
sutProvider.GetDependency<IProviderRepository>().GetByIdAsync(provider.Id).Returns(provider);
var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>(); var providerUserRepository = sutProvider.GetDependency<IProviderUserRepository>();
providerUserRepository.GetManyAsync(default).ReturnsForAnyArgs(providerUsers); providerUserRepository.GetManyAsync(default).ReturnsForAnyArgs(providerUsers);
providerUserRepository.GetManyByProviderAsync(default, default).ReturnsForAnyArgs(new[] {remainingOwner}); providerUserRepository.GetManyByProviderAsync(default, default).ReturnsForAnyArgs(new[] {remainingOwner});

View File

@ -0,0 +1,9 @@
{{#>FullHtmlLayout}}
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top" align="left">
You have been removed from <b style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">{{ProviderName}}</b>. You will no longer have access to the Provider Portal. If you have an existing Bitwarden account, your account is unaffected.
</td>
</tr>
</table>
{{/FullHtmlLayout}}

View File

@ -0,0 +1,4 @@
{{#>BasicTextLayout}}
You have been removed from {{ProviderName}}. You will no longer have access to the Provider Portal.
If you have an existing Bitwarden account, your account is unaffected.
{{/BasicTextLayout}}

View File

@ -0,0 +1,7 @@
namespace Bit.Core.Models.Mail.Provider
{
public class ProviderUserRemovedViewModel : BaseMailModel
{
public string ProviderName { get; set; }
}
}

View File

@ -45,5 +45,6 @@ namespace Bit.Core.Services
Task SendProviderSetupInviteEmailAsync(Provider provider, string token, string email); Task SendProviderSetupInviteEmailAsync(Provider provider, string token, string email);
Task SendProviderInviteEmailAsync(string providerName, ProviderUser providerUser, string token, string email); Task SendProviderInviteEmailAsync(string providerName, ProviderUser providerUser, string token, string email);
Task SendProviderConfirmedEmailAsync(string providerName, string email); Task SendProviderConfirmedEmailAsync(string providerName, string email);
Task SendProviderUserRemoved(string providerName, string email);
} }
} }

View File

@ -697,5 +697,19 @@ namespace Bit.Core.Services
message.Category = "ProviderUserConfirmed"; message.Category = "ProviderUserConfirmed";
await _mailDeliveryService.SendEmailAsync(message); await _mailDeliveryService.SendEmailAsync(message);
} }
public async Task SendProviderUserRemoved(string providerName, string email)
{
var message = CreateDefaultMessage($"You Have Been Removed from {providerName}", email);
var model = new ProviderUserRemovedViewModel
{
ProviderName = CoreHelpers.SanitizeForEmail(providerName),
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
SiteName = _globalSettings.SiteName
};
await AddMessageContentAsync(message, "Provider.ProviderUserRemoved", model);
message.Category = "ProviderUserRemoved";
await _mailDeliveryService.SendEmailAsync(message);
}
} }
} }

View File

@ -179,5 +179,10 @@ namespace Bit.Core.Services
{ {
return Task.FromResult(0); return Task.FromResult(0);
} }
public Task SendProviderUserRemoved(string providerName, string email)
{
return Task.FromResult(0);
}
} }
} }