1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-01 23:31:41 +01:00

ses mail delivery service

This commit is contained in:
Kyle Spearrin 2019-03-13 14:07:08 -04:00
parent 6421e326b9
commit 8d54442173
3 changed files with 133 additions and 0 deletions

View File

@ -21,6 +21,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.3.7.38" />
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.7.0" />
<PackageReference Include="MailKit" Version="2.1.3" />

View File

@ -32,6 +32,7 @@ namespace Bit.Core
public virtual DuoSettings Duo { get; set; } = new DuoSettings();
public virtual BraintreeSettings Braintree { get; set; } = new BraintreeSettings();
public virtual BitPaySettings BitPay { get; set; } = new BitPaySettings();
public virtual AmazonSettings Amazon { get; set; } = new AmazonSettings();
public class BaseServiceUriSettings
{
@ -200,5 +201,12 @@ namespace Bit.Core
public string Key { get; set; }
public string IdentityUri { get; set; }
}
public class AmazonSettings
{
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public string Region { get; set; }
}
}
}

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.Core.Models.Mail;
using System.Linq;
using Amazon.SimpleEmail;
using Amazon;
using Amazon.SimpleEmail.Model;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
namespace Bit.Core.Services
{
public class AmazonSesMailDeliveryService : IMailDeliveryService, IDisposable
{
private readonly GlobalSettings _globalSettings;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly ILogger<AmazonSesMailDeliveryService> _logger;
private readonly AmazonSimpleEmailServiceClient _client;
private readonly string _source;
private readonly string _senderTag;
public AmazonSesMailDeliveryService(
GlobalSettings globalSettings,
IHostingEnvironment hostingEnvironment,
ILogger<AmazonSesMailDeliveryService> logger)
{
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeyId))
{
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeyId));
}
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.AccessKeySecret))
{
throw new ArgumentNullException(nameof(globalSettings.Amazon.AccessKeySecret));
}
if(string.IsNullOrWhiteSpace(globalSettings.Amazon?.Region))
{
throw new ArgumentNullException(nameof(globalSettings.Amazon.Region));
}
_globalSettings = globalSettings;
_hostingEnvironment = hostingEnvironment;
_logger = logger;
_client = new AmazonSimpleEmailServiceClient(globalSettings.Amazon.AccessKeyId,
globalSettings.Amazon.AccessKeySecret, RegionEndpoint.GetBySystemName(globalSettings.Amazon.Region));
_source = $"\"{globalSettings.SiteName}\" <{globalSettings.Mail.ReplyToEmail}>";
_senderTag = $"Server: {globalSettings.ProjectName}";
}
public void Dispose()
{
_client?.Dispose();
}
public async Task SendEmailAsync(MailMessage message)
{
var request = new SendEmailRequest
{
ConfigurationSetName = "Email",
Source = _source,
Destination = new Destination
{
ToAddresses = message.ToEmails.ToList()
},
Message = new Message
{
Subject = new Content(message.Subject),
Body = new Body
{
Html = new Content
{
Charset = "UTF-8",
Data = message.HtmlContent
},
Text = new Content
{
Charset = "UTF-8",
Data = message.TextContent
}
}
},
Tags = new List<MessageTag>
{
new MessageTag { Name = "Environment", Value = _hostingEnvironment.EnvironmentName },
new MessageTag { Name = "Sender", Value = _senderTag }
}
};
if(message.BccEmails?.Any() ?? false)
{
request.Destination.BccAddresses = message.BccEmails.ToList();
}
if(message.MetaData?.ContainsKey("SendGridCategories") ?? false)
{
var cats = (message.MetaData["SendGridCategories"] as List<string>)
.Select(c => new MessageTag { Name = "Category", Value = c });
request.Tags.AddRange(cats);
}
try
{
await SendAsync(request, false);
}
catch(Exception e)
{
_logger.LogWarning(e, "Failed to send email.");
await SendAsync(request, true);
throw e;
}
}
private async Task SendAsync(SendEmailRequest request, bool retry)
{
if(retry)
{
// wait and try again
await Task.Delay(2000);
}
await _client.SendEmailAsync(request);
}
}
}