summaryrefslogtreecommitdiffstats
path: root/SendGrid/SendGridMail/Transport/SMTP.cs
blob: 606afcd3e481e5115900d2c671e24e98290d00bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Net;
using System.Net.Mail;

namespace SendGridMail.Transport
{
    /// <summary>
    /// Transport class for delivering messages via SMTP
    /// </summary>
    public class SMTP : ITransport
    {
        /// <summary>
        /// SendGrid's host name
        /// </summary>
        public const String SmtpServer = "smtp.sendgrid.net";

        /// <summary>
        /// Port for Simple Mail Transfer Protocol
        /// </summary>
        public const Int32 Port = 25;

        /// <summary>
        /// Port for Secure SMTP
        /// </summary>
        public const Int32 SslPort = 465;

        /// <summary>
        /// Port for TLS (currently not supported)
        /// </summary>
        public const Int32 TlsPort = 571;

        /// <summary>
        /// Client used to deliver SMTP message
        /// </summary>
        private readonly ISmtpClient _client;

        /// <summary>
        /// Transport created to deliver messages to SendGrid using SMTP
        /// </summary>
        /// <param name="client">SMTP client we are wrapping</param>
        /// <param name="credentials">Sendgrid user credentials</param>
        /// <param name="host">MTA recieving this message.  By default, sent through SendGrid.</param>
        /// <param name="port">SMTP port 25 is the default.  Port 465 can be used for Secure SMTP.</param>
        private SMTP(ISmtpClient client, NetworkCredential credentials, string host = SmtpServer, int port = Port)
        {
            _client = client;
            switch (port)
            {
                case Port:
                    break;
                case SslPort:
                    _client.EnableSsl = true;
                    break;
                case TlsPort:
                    throw new NotSupportedException("TLS not supported");
            }
        }

        /// <summary>
        /// Deliver an email using SMTP protocol
        /// </summary>
        /// <param name="message"></param>
        public void Deliver(ISendGrid message)
        {
            var mime = message.CreateMimeMessage();
            _client.Send(mime);
        }

        /// <summary>
        /// Transport created to deliver messages to SendGrid using SMTP
        /// </summary>
        /// <param name="credentials">Sendgrid user credentials</param>
        /// <param name="host">MTA recieving this message.  By default, sent through SendGrid.</param>
        /// <param name="port">SMTP port 25 is the default.  Port 465 can be used for Secure SMTP.</param>
        public static SMTP GenerateInstance(NetworkCredential credentials, String host = SmtpServer, Int32 port = Port)
        {
            var client = new SmtpWrapper(host, port, credentials, SmtpDeliveryMethod.Network);
            return new SMTP(client, credentials, host, port);
        }

        /// <summary>
        /// For Unit Testing Only!
        /// </summary>
        /// <param name="client"></param>
        /// <param name="credentials"></param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        internal static SMTP GenerateInstance(ISmtpClient client, NetworkCredential credentials, String host = SmtpServer, Int32 port = Port)
        {
            return new SMTP(client, credentials, host, port);
        }

        /// <summary>
        /// Interface to allow testing
        /// </summary>
        internal interface ISmtpClient
        {
            bool EnableSsl { get; set; }
            void Send(MailMessage mime);
        }

        /// <summary>
        /// Implementation of SmtpClient wrapper, separated to allow dependency injection
        /// </summary>
        internal class SmtpWrapper : ISmtpClient
        {
            private readonly SmtpClient _client;
            public bool EnableSsl
            {
                get
                {
                    return _client.EnableSsl;
                }
                set
                {
                    _client.EnableSsl = value;
                }
            }

            public SmtpWrapper(String host, Int32 port, NetworkCredential credentials, SmtpDeliveryMethod deliveryMethod)
            {
                _client = new SmtpClient(host, port) { Credentials = credentials, DeliveryMethod = deliveryMethod };
            }

            public void Send(MailMessage mime)
            {
                _client.Send(mime);
            }
        }
    }
}