Пример #1
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                DateTime dt = DateTime.UtcNow;
                using MailDemonDatabase db = dbProvider.GetDatabase();
                db.Subscriptions.RemoveRange(db.Subscriptions.Where(r => r.Expires <= dt && r.UnsubscribeToken == null));
                await db.SaveChangesAsync();

                await Task.Delay(loopTimeSpan, stoppingToken);
            }
        }
Пример #2
0
 public void Setup()
 {
     Cleanup();
     dbProvider = this as IMailDemonDatabaseProvider;
     using (var db = dbProvider.GetDatabase())
     {
         db.Initialize();
         MailList list = new MailList
         {
             Name             = listName,
             Company          = company,
             PhysicalAddress  = fullAddress,
             Title            = listName + " title",
             FromEmailAddress = fromAddress,
             FromEmailName    = fromName,
             Website          = website
         };
         MailTemplate template = new MailTemplate
         {
             Name         = templateName,
             LastModified = DateTime.UtcNow,
             Text         = templateText,
             Title        = "confirm"
         };
         MailTemplate template2 = new MailTemplate
         {
             Name         = templateName2,
             LastModified = DateTime.UtcNow,
             Text         = templateText2,
             Title        = "welcome"
         };
         db.Lists.Add(list);
         db.Templates.Add(template);
         db.Templates.Add(template2);
         db.SaveChanges();
     }
     mailCreator = new MailCreator(new RazorRenderer(null, Directory.GetCurrentDirectory(), Assembly.GetExecutingAssembly()))
     {
         IgnoreElements = authority
     };
     homeController = new HomeController(this, null, mailCreator, this, null, this)
     {
         RequireCaptcha = false,
         TempData       = new TempDataDictionary(httpContext, this)
     };
     homeController.ControllerContext.HttpContext = httpContext;
     httpContext.Request.Headers["User-Agent"]    = "Test";
     httpContext.Connection.RemoteIpAddress       = System.Net.IPAddress.Parse("127.0.0.1");
     httpContext.Request.Scheme = scheme;
     httpContext.Request.Host   = new HostString(domainName);
 }
Пример #3
0
        public async Task SendBulkMail(MailList list, IMailCreator mailCreator, IMailSender mailSender, ExpandoObject viewBag,
                                       bool all, string fullTemplateName, string unsubscribeUrl)
        {
            MailDemonLog.Warn("Started bulk send for {0}", fullTemplateName);

            DateTime    now          = DateTime.UtcNow;
            int         successCount = 0;
            int         failCount    = 0;
            List <Task> pendingTasks = new List <Task>();
            Stopwatch   timer        = Stopwatch.StartNew();

            using (var db = dbProvider.GetDatabase())
            {
                void callbackHandler(MailListSubscription _sub, string error)
                {
                    lock (db)
                    {
                        // although this is slow, it is required as we do not want to double email people in the event
                        // that server reboots, loses power, etc. for every message we have to mark that person
                        // with the correct status immediately
                        _sub.Result          = error;
                        _sub.ResultTimestamp = DateTime.UtcNow;
                        db.Update(_sub);
                        db.SaveChanges();
                        if (string.IsNullOrWhiteSpace(error))
                        {
                            successCount++;
                        }
                        else
                        {
                            failCount++;
                        }
                    }
                }

                // use a separate database instance to do the query, that way we can update records in our other database instance
                // preventing locking errors, especially with sqlite drivers
                MailDemonLog.Warn("Begin bulk send");
                using (var dbBulk = dbProvider.GetDatabase())
                {
                    IEnumerable <KeyValuePair <string, IEnumerable <MailListSubscription> > > pendingSubs = dbBulk.GetBulkEmailSubscriptions(list, unsubscribeUrl, all);
                    foreach (KeyValuePair <string, IEnumerable <MailListSubscription> > sub in pendingSubs)
                    {
                        now = DateTime.UtcNow;
                        try
                        {
                            IAsyncEnumerable <MailToSend> messagesToSend = GetMessages(sub.Value, mailCreator, list, viewBag, fullTemplateName, callbackHandler);
                            Task task = mailSender.SendMailAsync(sub.Key, messagesToSend);
                            pendingTasks.Add(task);
                        }
                        catch (Exception ex)
                        {
                            MailDemonLog.Error(ex);
                        }
                    }
                }

                await Task.WhenAll(pendingTasks);

                MailDemonLog.Warn("Finished bulk send for {0}, {1} messages succeeded, {2} messages failed in {3:0.00} seconds.", fullTemplateName, successCount, failCount, timer.Elapsed.TotalSeconds);
            }

            GC.Collect();
        }
Пример #4
0
        public IActionResult SubscribeInitial(string id)
        {
            string result = TempData["result"] as string;

            id = (id ?? string.Empty).Trim();
            if (id.Length == 0)
            {
                return(NotFound());
            }
            MailListSubscription model = (string.IsNullOrWhiteSpace(result) ? new MailListSubscription() : JsonConvert.DeserializeObject <MailListSubscription>(result));

            using (MailDemonDatabase db = dbProvider.GetDatabase())
            {
                model.MailList = db.Lists.FirstOrDefault(l => l.Name == id);
            }
            if (model.MailList == null)
            {
                return(NotFound());
            }
            model.ListName     = id;
            model.TemplateName = MailTemplate.GetFullTemplateName(id, MailTemplate.NameSubscribeInitial);
            return(View(model));
        }
Пример #5
0
        private string Subscribe()
        {
            using (var db = dbProvider.GetDatabase())
            {
                db.Lists.Add(new MailList {
                    Name    = listName, FromEmailAddress = fromAddress, FromEmailName = fromName,
                    Company = company, PhysicalAddress = fullAddress, Website = website
                });
                db.SaveChanges();
            }

            expectedSubject = "Hello Bob";
            expectedBody    = "<!-- Subject: Hello Bob --> Body: Last Name Smith, Subscribe: https://testdomain.com/SubscribeWelcome/TestList?token={subscribe-token}, Unsubscribe: ";
            homeController.SubscribeInitialPost(listName, new Dictionary <string, string>
            {
                { "ff_firstName", "Bob" },
                { "ff_lastName", "Smith" },
                { "ff_emailAddress", mailAddress },
                { "ff_company_optional", null }
            }).Sync();

            // check database for registration
            MailListSubscription reg = null;

            using (var db = dbProvider.GetDatabase())
            {
                reg = db.Subscriptions.FirstOrDefault();
                Assert.NotNull(reg);
                Assert.AreEqual("Bob", reg.Fields["firstName"]);
                Assert.AreEqual("Smith", reg.Fields["lastName"]);
                Assert.AreEqual(mailAddress, reg.EmailAddress);
                Assert.IsEmpty(reg.Fields["company"] as string);
                Assert.IsNotNull(reg.SubscribeToken);
                Assert.IsNull(reg.UnsubscribeToken);
                Assert.AreEqual(default(DateTime), reg.SubscribedDate);
                Assert.AreEqual(default(DateTime), reg.UnsubscribedDate);
                Assert.AreNotEqual(default(DateTime), reg.Expires);
            }

            // verify the subscribe confirm has no errors
            homeController.SubscribeConfirm(listName);
            Assert.AreEqual(1, sentMailCount);
            sentMailCount = 0;

            // perform the final subscribe action
            expectedSubject = "Hello2 Bob";
            expectedBody    = "<!-- Subject: Hello2 Bob --> Body2: Last Name Smith, Subscribe: , Unsubscribe: https://testdomain.com/Unsubscribe/TestList?token={unsubscribe-token}";
            homeController.SubscribeWelcome(listName, reg.SubscribeToken).Sync();
            Assert.AreEqual(1, sentMailCount);
            sentMailCount = 0;

            // validate there is an unsubscribe in the db
            using (var db = dbProvider.GetDatabase())
            {
                reg = db.Subscriptions.FirstOrDefault();
                Assert.AreEqual(listName, reg.ListName);
                Assert.AreEqual("127.0.0.1", reg.IPAddress);
                Assert.IsNotNull(reg.UnsubscribeToken);
                Assert.AreNotEqual(default(DateTime), reg.SubscribedDate);
                Assert.AreEqual(default(DateTime), reg.UnsubscribedDate);
                Assert.AreEqual(DateTime.MaxValue, reg.Expires);
            }

            return(reg.UnsubscribeToken);
        }