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

SendGrid Mail Delivery Provider (#1892)

* add sendgrid mail delivery service

* <

* remove duplicate code

* fix test by using ISendGridClient interface
This commit is contained in:
Kyle Spearrin
2022-03-01 19:09:51 -05:00
committed by GitHub
parent 5dd6a05615
commit 4cbe05da3c
32 changed files with 741 additions and 279 deletions

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bit.Core.Models.Mail;
using Bit.Core.Services;
using Bit.Core.Settings;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
using NSubstitute;
using SendGrid;
using SendGrid.Helpers.Mail;
using Xunit;
namespace Bit.Core.Test.Services
{
public class SendGridMailDeliveryServiceTests : IDisposable
{
private readonly SendGridMailDeliveryService _sut;
private readonly GlobalSettings _globalSettings;
private readonly IWebHostEnvironment _hostingEnvironment;
private readonly ILogger<SendGridMailDeliveryService> _logger;
private readonly ISendGridClient _sendGridClient;
public SendGridMailDeliveryServiceTests()
{
_globalSettings = new GlobalSettings
{
Mail =
{
SendGridApiKey = "SendGridApiKey"
}
};
_hostingEnvironment = Substitute.For<IWebHostEnvironment>();
_logger = Substitute.For<ILogger<SendGridMailDeliveryService>>();
_sendGridClient = Substitute.For<ISendGridClient>();
_sut = new SendGridMailDeliveryService(
_sendGridClient,
_globalSettings,
_hostingEnvironment,
_logger
);
}
public void Dispose()
{
_sut?.Dispose();
}
[Fact]
public async Task SendEmailAsync_CallsSendEmailAsync_WhenMessageIsValid()
{
var mailMessage = new MailMessage
{
ToEmails = new List<string> { "ToEmails" },
BccEmails = new List<string> { "BccEmails" },
Subject = "Subject",
HtmlContent = "HtmlContent",
TextContent = "TextContent",
Category = "Category"
};
_sendGridClient.SendEmailAsync(Arg.Any<SendGridMessage>()).Returns(
new Response(System.Net.HttpStatusCode.OK, null, null));
await _sut.SendEmailAsync(mailMessage);
await _sendGridClient.Received(1).SendEmailAsync(
Arg.Do<SendGridMessage>(msg =>
{
msg.Received(1).AddTos(new List<EmailAddress> { new EmailAddress(mailMessage.ToEmails.First()) });
msg.Received(1).AddBccs(new List<EmailAddress> { new EmailAddress(mailMessage.ToEmails.First()) });
Assert.Equal(mailMessage.Subject, msg.Subject);
Assert.Equal(mailMessage.HtmlContent, msg.HtmlContent);
Assert.Equal(mailMessage.TextContent, msg.PlainTextContent);
Assert.Contains("type:Cateogry", msg.Categories);
Assert.Contains(msg.Categories, x => x.StartsWith("env:"));
Assert.Contains(msg.Categories, x => x.StartsWith("sender:"));
msg.Received(1).SetClickTracking(false, false);
msg.Received(1).SetOpenTracking(false);
}));
}
}
}

View File

@ -1748,6 +1748,15 @@
"resolved": "4.4.0",
"contentHash": "YhEdSQUsTx+C8m8Bw7ar5/VesXvCFMItyZF7G1AUY+OM0VPZUOeAVpJ4Wl6fydBGUYZxojTDR3I6Bj/+BPkJNA=="
},
"SendGrid": {
"type": "Transitive",
"resolved": "9.25.3",
"contentHash": "Dldhsc4+jV28rfa53W+09A549lDfKqGEFFtdOU4uOxHvS/pFhBN8lRkAEzvbMbycwZJJCzfrDdKc/qT1MxWynQ==",
"dependencies": {
"Newtonsoft.Json": "9.0.1",
"starkbank-ecdsa": "[1.3.3, 2.0.0)"
}
},
"Sentry": {
"type": "Transitive",
"resolved": "2.1.5",
@ -1963,6 +1972,11 @@
"System.Threading.Timer": "4.3.0"
}
},
"starkbank-ecdsa": {
"type": "Transitive",
"resolved": "1.3.3",
"contentHash": "OblOaKb1enXn+dSp7tsx9yjwV+/BEKM9jFhshIkZTwCk7LuTFTp+wSon6rFzuPiIiTGtvVWQNUw2slHjGktJog=="
},
"Stripe.net": {
"type": "Transitive",
"resolved": "37.26.0",
@ -3522,27 +3536,27 @@
"type": "Project",
"dependencies": {
"Azure.Messaging.EventGrid": "4.7.0",
"CommCore": "1.46.0",
"Core": "1.46.0",
"CommCore": "1.46.2",
"Core": "1.46.2",
"Microsoft.AspNetCore.Mvc.NewtonsoftJson": "5.0.9",
"NewRelic.Agent": "8.41.0",
"SharedWeb": "1.46.0",
"SharedWeb": "1.46.2",
"Swashbuckle.AspNetCore": "6.2.3"
}
},
"commcore": {
"type": "Project",
"dependencies": {
"Core": "1.46.0"
"Core": "1.46.2"
}
},
"common": {
"type": "Project",
"dependencies": {
"Api": "1.46.0",
"Api": "1.46.2",
"AutoFixture.AutoNSubstitute": "4.14.0",
"AutoFixture.Xunit2": "4.14.0",
"Core": "1.46.0",
"Core": "1.46.2",
"Microsoft.NET.Test.Sdk": "16.6.1",
"NSubstitute": "4.2.2",
"xunit": "2.4.1"
@ -3575,6 +3589,7 @@
"Newtonsoft.Json": "12.0.3",
"Otp.NET": "1.2.2",
"Quartz": "3.1.0",
"SendGrid": "9.25.3",
"Sentry.Serilog": "2.1.5",
"Serilog.AspNetCore": "3.4.0",
"Serilog.Extensions.Logging": "3.0.1",
@ -3589,7 +3604,7 @@
"infrastructure.dapper": {
"type": "Project",
"dependencies": {
"Core": "1.46.0",
"Core": "1.46.2",
"Dapper": "2.0.123",
"System.Data.SqlClient": "4.8.3"
}
@ -3598,7 +3613,7 @@
"type": "Project",
"dependencies": {
"AutoMapper.Extensions.Microsoft.DependencyInjection": "8.0.1",
"Core": "1.46.0",
"Core": "1.46.2",
"Microsoft.EntityFrameworkCore.Relational": "5.0.12",
"Npgsql.EntityFrameworkCore.PostgreSQL": "5.0.2",
"Pomelo.EntityFrameworkCore.MySql": "5.0.3",
@ -3608,9 +3623,9 @@
"sharedweb": {
"type": "Project",
"dependencies": {
"Core": "1.46.0",
"Infrastructure.Dapper": "1.46.0",
"Infrastructure.EntityFramework": "1.46.0"
"Core": "1.46.2",
"Infrastructure.Dapper": "1.46.2",
"Infrastructure.EntityFramework": "1.46.2"
}
}
}