Ejemplo n.º 1
0
 public SpamModule() : base("api/spam")
 {
     this.Post["/", true] = (_, cancel) =>
     {
         return(Task.Run <dynamic>(() =>
         {
             var file = this.Request.Files.FirstOrDefault();
             string data;
             using (StreamReader sr = new StreamReader(file.Value))
             {
                 data = sr.ReadToEnd();
             }
             string username = this.Context.CurrentUser.UserName;
             bool isValid = IsValidSpamUser(username);
             var db = new CouchDBService();
             var tokens = new TokenService(db);
             string subject = this.Request.Form.subject;
             string body = this.Request.Form.body;
             foreach (var email in GetValidEmails(data, username, isValid))
             {
                 var modBody = InsertLink(body, email, tokens);
                 MailgunService.SendMail(email, subject, modBody);
             }
             return HttpStatusCode.OK;
         }));
     };
 }
Ejemplo n.º 2
0
 public void Service_Incorrect_Format_CompanyDomainName_Should_Throw_Exception(string companyDomainName)
 {
     Assert.Throws <FormatException>(() =>
     {
         var service = new MailgunService(companyDomainName, this.apikey);
     });
 }
Ejemplo n.º 3
0
 public void Service_Empty_ApiKey_Should_Throw_Exception(string apikey)
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         var service = new MailgunService(this.companyDomain, apikey);
     });
 }
Ejemplo n.º 4
0
 public void Service_Empty_CompanyDomainName_Should_Throw_Exception(string companyDomainName)
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         var service = new MailgunService(companyDomainName, this.apikey);
     });
 }
Ejemplo n.º 5
0
        protected override void OnBeforeSaving(Email entity, OPERATION_MODE mode = OPERATION_MODE.NONE)
        {
            if (mode == OPERATION_MODE.ADD)
            {
                #region Validations
                if (entity.ToList.Count() == 0 && entity.CcList.Count() == 0 && entity.BccList.Count == 0)
                {
                    throw new KnownError("Cannot send email without Recipients.");
                }
                #endregion

                entity.CreatedAt = DateTimeOffset.Now;
            }

            #region Send Email

            //Copy Attachments when resent:
            if (entity.IsResent)
            {
                string baseAttachmentsPath = AppSettings.Get <string>("EmailAttachments");
                entity.AttachmentsFolder = AttachmentsIO.CopyAttachments(entity.AttachmentsFolder, entity.Attachments, baseAttachmentsPath);
                entity.Attachments       = entity.Attachments.Where(e => !e.ToDelete).ToList();
            }

            var emailService = new MailgunService
            {
                From              = Auth.Email,
                Subject           = entity.Subject,
                Body              = entity.Body,
                AttachmentsFolder = entity.AttachmentsFolder
            };

            foreach (var item in entity.ToList)
            {
                emailService.To.Add(item.Email);
            }

            foreach (var item in entity.CcList)
            {
                emailService.Cc.Add(item.Email);
            }

            foreach (var item in entity.BccList)
            {
                emailService.Bcc.Add(item.Email);
            }

            emailService.Bcc.Add(Auth.Email); //Add sender as recipient as well.

            try
            {
                emailService.SendMail();
            }
            catch (Exception ex)
            {
                throw new KnownError("Could not send email:\n" + ex.Message);
            }
            #endregion
        }
Ejemplo n.º 6
0
        public void Setup()
        {
            logger     = A.Fake <ILogger <MailgunService> >();
            handler    = A.Fake <HttpMessageHandler>();
            httpClient = new HttpClient(handler);

            var config = new ConfigurationBuilder()
                         .AddJsonFile("appsettings.json")
                         .Build();

            sut   = new MailgunService(logger, config, httpClient);
            email = fixture.Create <Email>();
        }
Ejemplo n.º 7
0
        public async Task TestSendEmail()
        {
            MailgunService MSS = new MailgunService(logger);
            MailgunEmail   m   = new MailgunEmail()
            {
                To = new List <string>()
                {
                    "*****@*****.**"
                },
                From    = "ESk8BST <*****@*****.**>",
                Subject = "This is a Test Email",
                Body    = "Testing from Test",
                IsTest  = true
            };
            bool success = await MSS.Send(m);

            Assert.True(success);
        }
Ejemplo n.º 8
0
        public LoginModule()
            : base("/api/login")
        {
            var db           = new CouchDB.CouchDBService();
            var tokenService = new TokenService(db);

            Post["/"] = ctx =>
            {
                string username;
                var    dto = this.Bind <LoginRequestDto>();
                username = dto.Username;
                var validationResponse = ValidateUsername(username);
                if (validationResponse != null)
                {
                    return(validationResponse);
                }
                var token   = tokenService.Login(username);
                var combine = string.Format("{0}!{1}", username, token);
                MailgunService.SendMail(username, "The unicorn says hi!", string.Format(File.ReadAllText(Path.Combine(AssemblyDirectory, "Mailing\\LoginMailResponse.txt")), this.Request.Url.SiteBase, combine));
                return(HttpStatusCode.OK);
            };
        }
Ejemplo n.º 9
0
        public async Task TestMakeEmailsFromMatches()
        {
            MailgunService MSS = new MailgunService(logger);

            string bstthreadloc = await File.ReadAllTextAsync("resources/bstthread.json");

            JArray        BSTThreadJson = JArray.Parse(bstthreadloc);
            RedditService RSS           = new RedditService(logger);

            // Get BST thread
            string rawCompanies = await File.ReadAllTextAsync("resources/common_companies.json");

            string rawProducts = await File.ReadAllTextAsync("resources/common_boards.json");

            JArray         jarrCompany             = JArray.Parse(rawCompanies);
            JArray         jarrProduct             = JArray.Parse(rawProducts);
            List <Company> companies               = CompanyParser.ParseCompanies(jarrCompany);
            List <Product> products                = ProductParser.ParseProducts(jarrProduct);
            List <Company> combined                = CompanyParser.CombineCompanyLists(companies, products.Select(x => x.Company));
            Esk8Service    ESS                     = new Esk8Service(logger);
            List <RegexCategory <Company> > CompRs = ESS.GetCompanyRegexs(companies);
            List <RegexCategory <Product> > ProdRs = ESS.GetProductRegexs(products);

            List <BSTComment> comments = RSS.ParseComments(BSTThreadJson, CompRs, ProdRs);


            // Get mock subscribers
            string subloc = await File.ReadAllTextAsync("resources/Subscribers.json");

            JArray subArray = JArray.Parse(subloc);
            List <PostedSubscribeObject> psubs = SubscriberParser.ParseSubscribers(subArray);
            List <Subscriber>            subs  = psubs.Select(x => Subscriber.FromPostedSubscriber(x)).ToList();

            MatchService LSS = new MatchService(logger);
            Dictionary <Subscriber, List <LambdaMatch> > matches = LSS.MakeMatches(subs, comments);

            List <MailgunEmail> emails = matches.Select(x => MSS.MakeEmail(x.Key, x.Value)).ToList();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// The endpoint hit when a user submits their email to esk8bst
        /// This schedules a Mailgun Email that will include a Confirm Subscribe Link
        /// </summary>
        /// <param name="request"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task <APIGatewayProxyResponse> Subscribe(APIGatewayProxyRequest request, ILambdaContext context)
        {
            var logger = new Esk8LambdaLogger(context.Logger);

            logger.Log("Subscribe endpoint reached");


            if (request.HttpMethod != HttpMethod.Post.Method)
            {
                return(new APIGatewayProxyResponse()
                {
                    StatusCode = (int)HttpStatusCode.MethodNotAllowed
                });
            }
            ;

            string postbody           = request.Body;
            PostedSubscribeObject pso = null;
            string confirmkey         = "";

            try {
                JObject jobj = JObject.Parse(postbody);
                pso = PostedSubscribeObject.FromJson(jobj);

                if (pso.Email.Contains("@") && pso.Matches.Count > 0)   // we can proceed

                {
                    FirestoreService FSS = new FirestoreService(logger);
                    if (await FSS.CheckIsPreconfirmed(pso.Email))
                    {
                        // Immediately subscribe the user, they've already been here.
                        await FSS.UpsertSubscriber(pso);

                        return(new APIGatewayProxyResponse()
                        {
                            StatusCode = (int)HttpStatusCode.Created,
                            Headers = new Dictionary <string, string> {
                                { "Content-Type", "text/plain" }
                            },
                            Body = "Alright! You've been confirmed as interested in receiving updates from https://esk8bst.com",
                        });
                    }
                    else
                    {
                        // Not pre-confirmed, send an opt-in email.
                        string encryptionKey = Environment.GetEnvironmentVariable("ESK8BST_ENCRYPTION_KEY");
                        confirmkey = EncryptorService.CreateConfirmKey(pso.ToJson().ToString(), encryptionKey);
                    }
                }
            } catch (Exception e) {
                logger.Log($"Tried to parse a malformed subscriber json: {e.Message}");
                return(new APIGatewayProxyResponse()
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Headers = new Dictionary <string, string> {
                        { "Content-Type", "text/plain" }
                    },
                    Body = "Failed to parse json properly",
                });
            }

            if (String.IsNullOrWhiteSpace(confirmkey))
            {
                return(new APIGatewayProxyResponse()
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Body = "Failed to parse json properly - no email found",
                    Headers = new Dictionary <string, string> {
                        { "Content-Type", "text/plain" }
                    },
                });
            }

            MailgunService MSS = new MailgunService(logger);
            MailgunEmail   m   = new MailgunEmail()
            {
                To = new List <string> {
                    pso.Email
                },
                From    = MailgunService.POSTMASTER,
                Subject = "Esk8Bst Notification Opt In Request",
                Body    = "" +
                          "Someone has registered you as being interested in receiving notifications about new electric skateboard postings from https://esk8bst.com.\n\n" +
                          "If this was you, please click the link below to confirm your email. If this was not you, or you no longer wish to receive emails from us, then ignore this message.\n\n" +
                          $"https://1lol87xzbj.execute-api.us-east-2.amazonaws.com/Prod/confirm?confirmkey={confirmkey}",
            };

            bool success = await MSS.Send(m);

            if (!success)
            {
                return(new APIGatewayProxyResponse()
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Body = "Failed to send email to recipent",
                    Headers = new Dictionary <string, string> {
                        { "Content-Type", "text/plain" }
                    },
                });
            }

            //An email has been sent to the address specified confirming your subscription
            var response = new APIGatewayProxyResponse {
                StatusCode = (int)HttpStatusCode.OK,
                Body       = "An email has been sent to the address specified confirming your subscription",
                Headers    = new Dictionary <string, string> {
                    { "Content-Type", "text/plain" }
                },
            };

            return(response);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// The core function launched every hour.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Scan(APIGatewayProxyRequest request, ILambdaContext context)
        {
            var logger = new Esk8LambdaLogger(context.Logger);

            logger.Log("Scan initiated endpoint reached");
            HttpClient Client = new HttpClient();
            /* Set up our Services */
            FirestoreService FSS = new FirestoreService(logger);
            Esk8Service      ESS = new Esk8Service(logger, Client);
            RedditService    RSS = new RedditService(logger, ESS, Client);
            MailgunService   MSS = new MailgunService(logger, Client);
            MatchService     LSS = new MatchService(logger);

            /* Get our Firebase last-scanned time */
            ScanData sd = await FSS.GetScanData();

            if (sd == null)
            {
                return; /* Something happened, so we quit. */
            }

            /* Check Firebase Subscribers */
            List <Subscriber> subscribers = await FSS.GetSubscribers();

            if (subscribers == null || subscribers.Count == 0)
            {
                ScanData updatedScanData = new ScanData()
                {
                    LastScanDate = DateTimeOffset.Now, MostRecentlySeen = DateTimeOffset.Now
                };
                await FSS.UpdateScanTime(updatedScanData);

                return;
            }

            /* Get the BST Thread */
            if (!(await RSS.GetRedditItem() is JObject frontPage))
            {
                /* Some kind of error ocurred, do not update */
                return;
            }
            string BSTUrl = RSS.FindBSTThreadUrl(frontPage);

            if (String.IsNullOrWhiteSpace(BSTUrl))
            {
                /* Some kind of error ocurred, do not update */
                return;
            }
            if (!(await RSS.GetRedditItem(BSTUrl) is JArray BSTPage))
            {
                /* Some kind of error ocurred, do not update */
                return;
            }

            /* Check if there are new posts, to save on Network requests fetching Company / Board information */
            if (!RSS.AnyNewPosts(BSTPage, sd.MostRecentlySeen))
            {
                /* There have been no new posts since last time. */
                ScanData updatedScanData = new ScanData()
                {
                    LastScanDate = DateTimeOffset.Now, MostRecentlySeen = DateTimeOffset.Now
                };
                await FSS.UpdateScanTime(updatedScanData);

                return;
            }


            /* Fetch Company and Product information from Esk8 servers */
            List <Product> prods = await ESS.GetCommonBoards();

            List <Company> comps = await ESS.GetCommonCompanies();

            comps = CompanyParser.CombineCompanyLists(comps, prods.Select(x => x.Company));

            List <RegexCategory <Company> > CompRs = ESS.GetCompanyRegexs(comps);
            List <RegexCategory <Product> > ProdRs = ESS.GetProductRegexs(prods);

            /* Parse the full thread for new posts */
            List <BSTComment> comments = RSS.ParseComments(BSTPage, CompRs, ProdRs, sd.LastScanDate);


            /* Line up potential Match Objects */
            /* At this point we don't update until emails have been sent out. */
            Dictionary <Subscriber, List <LambdaMatch> > lambdadelta = LSS.MakeMatches(subscribers, comments);

            /* Assemble the emails to send */
            IEnumerable <MailgunEmail> emails = lambdadelta.Select(x => MSS.MakeEmail(x.Key, x.Value));

            /* Send emails */
            bool SentSuccessfully = await MSS.BatchSend(emails);

            if (SentSuccessfully)
            {
                ScanData updatedScanData = new ScanData()
                {
                    LastScanDate = DateTimeOffset.Now, MostRecentlySeen = DateTimeOffset.Now
                };
                await FSS.UpdateScanTime(updatedScanData);
            }
        }
Ejemplo n.º 12
0
 public SendEmailActivity(MailgunService mailgunService, ILoggingService loggingService)
 {
     _mailgunService = mailgunService;
     _loggingService = loggingService;
 }
Ejemplo n.º 13
0
 public MailgunTemplateManager(MailgunService mailgunService)
 {
     _mailgunService = mailgunService;
 }
 public NewsletterService(MailgunService mailgunService)
 {
     _mailgunService = mailgunService;
 }