Exemplo n.º 1
0
        public IActionResult EmailSendNowOnPost(RecordDetailsPageModel pageModel)
        {
            var emailId = (Guid)pageModel.DataModel.GetProperty("Record.id");

            var         internalSmtpSrv = new SmtpInternalService();
            Email       email           = internalSmtpSrv.GetEmail(emailId);
            SmtpService smtpService     = new EmailServiceManager().GetSmtpService(email.ServiceId);

            internalSmtpSrv.SendEmail(email, smtpService);

            if (email.Status == EmailStatus.Sent)
            {
                pageModel.TempData.Put("ScreenMessage", new ScreenMessage()
                {
                    Message = "Email was successfully sent", Type = ScreenMessageType.Success, Title = "Success"
                });
            }
            else
            {
                pageModel.TempData.Put("ScreenMessage", new ScreenMessage()
                {
                    Message = email.ServerError, Type = ScreenMessageType.Error, Title = "Error"
                });
            }

            var returnUrl = pageModel.HttpContext.Request.Query["returnUrl"];

            return(new RedirectResult($"/mail/emails/all/r/{emailId}/details?returnUrl={returnUrl}"));
        }
Exemplo n.º 2
0
        public int EmailLoginRequest(string SessionId, string Email, string SessionKey)
        {
            ObserverDbContext _db = new ObserverDbContext();
            var session           = _db.LoginSessions
                                    .Where(e => e.Id == SessionId)
                                    .FirstOrDefault();

            if (session.Status == 6)
            {
                // Session expired
                return(0);
            }

            if (session.Status != 1)
            {
                // Session type error
                return(1);
            }

            if (session.Key != SessionKey)
            {
                // Session expired
                return(0);
            }

            var users = _db.Users
                        .Where(e => e.Email == Email)
                        .ToList();

            if (users.Count > 0)
            {
                var user = users.FirstOrDefault();
                if (user.Status == 1)
                {
                    session.EmailKey = EncryptionAlgorithmServiceManager.GetRNGGuid().ToString();
                    session.Status   = 4;
                    session.Users    = user;
                    _db.SaveChanges();
                    EmailServiceManager.AccountEmailLogin(user.Name, Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + "/LoginEmail?Id=" + SessionId + "&Key=" + session.EmailKey, user.Email);
                    return(4);
                }
                else
                {
                    // Inactive user
                    return(3);
                }
            }
            else
            {
                // Cannot find user
                return(2);
            }
        }
Exemplo n.º 3
0
        public void ProcessSmtpQueue()
        {
            lock (lockObject)
            {
                if (queueProcessingInProgress)
                {
                    return;
                }

                queueProcessingInProgress = true;
            }

            try
            {
                List <Email> pendingEmails = new List <Email>();
                do
                {
                    EmailServiceManager serviceManager = new EmailServiceManager();

                    pendingEmails = new EqlCommand("SELECT * FROM email WHERE status = @status AND scheduled_on <> NULL" +
                                                   " AND scheduled_on < @scheduled_on  ORDER BY priority DESC, scheduled_on ASC PAGE 1 PAGESIZE 10",
                                                   new EqlParameter("status", ((int)EmailStatus.Pending).ToString()),
                                                   new EqlParameter("scheduled_on", DateTime.UtcNow)).Execute().MapTo <Email>();

                    foreach (var email in pendingEmails)
                    {
                        var service = serviceManager.GetSmtpService(email.ServiceId);
                        if (service == null)
                        {
                            email.Status      = EmailStatus.Aborted;
                            email.ServerError = "SMTP service not found.";
                            email.ScheduledOn = null;
                            SaveEmail(email);
                            continue;
                        }
                        else
                        {
                            SendEmail(email, service);
                        }
                    }
                }while (pendingEmails.Count > 0);
            }
            finally
            {
                lock (lockObject)
                {
                    queueProcessingInProgress = false;
                }
            }
        }
Exemplo n.º 4
0
        public void OnPreDeleteRecord(string entityName, EntityRecord record, List <ErrorModel> errors)
        {
            var service = new EmailServiceManager().GetSmtpService((Guid)record["id"]);

            if (service != null && service.IsDefault)
            {
                errors.Add(new ErrorModel {
                    Key = "id", Message = "Default smtp service cannot be deleted."
                });
            }
            else
            {
                EmailServiceManager.ClearCache();
            }
        }
Exemplo n.º 5
0
        public IActionResult TestSmtpServiceOnPost(RecordDetailsPageModel pageModel)
        {
            SmtpService smtpService    = null;
            string      recipientEmail = string.Empty;
            string      subject        = string.Empty;
            string      content        = string.Empty;

            ValidationException valEx = new ValidationException();

            if (pageModel.HttpContext.Request.Form == null)
            {
                valEx.AddError("form", "Smtp service test page missing form tag");
                valEx.CheckAndThrow();
            }


            if (!pageModel.HttpContext.Request.Form.ContainsKey("recipient_email"))
            {
                valEx.AddError("recipient_email", "Recipient email is not specified.");
            }
            else
            {
                recipientEmail = pageModel.HttpContext.Request.Form["recipient_email"];
                if (string.IsNullOrWhiteSpace(recipientEmail))
                {
                    valEx.AddError("recipient_email", "Recipient email is not specified");
                }
                else if (!recipientEmail.IsEmail())
                {
                    valEx.AddError("recipient_email", "Recipient email is not a valid email address");
                }
            }

            if (!pageModel.HttpContext.Request.Form.ContainsKey("subject"))
            {
                valEx.AddError("subject", "Subject is not specified");
            }
            else
            {
                subject = pageModel.HttpContext.Request.Form["subject"];
                if (string.IsNullOrWhiteSpace(subject))
                {
                    valEx.AddError("subject", "Subject is required");
                }
            }

            if (!pageModel.HttpContext.Request.Form.ContainsKey("content"))
            {
                valEx.AddError("content", "Content is not specified");
            }
            else
            {
                content = pageModel.HttpContext.Request.Form["content"];
                if (string.IsNullOrWhiteSpace(content))
                {
                    valEx.AddError("content", "Content is required");
                }
            }

            var smtpServiceId = pageModel.DataModel.GetProperty("Record.id") as Guid?;

            if (smtpServiceId == null)
            {
                valEx.AddError("serviceId", "Invalid smtp service id");
            }
            else
            {
                smtpService = new EmailServiceManager().GetSmtpService(smtpServiceId.Value);
                if (smtpService == null)
                {
                    valEx.AddError("serviceId", "Smtp service with specified id does not exist");
                }
            }

            List <string> attachments = new List <string>();

            if (pageModel.HttpContext.Request.Form.ContainsKey("attachments"))
            {
                var ids = pageModel.HttpContext.Request.Form["attachments"].ToString().Split(",", StringSplitOptions.RemoveEmptyEntries).Select(x => new Guid(x));
                foreach (var id in ids)
                {
                    var fileRecord = new EqlCommand("SELECT name,path FROM user_file WHERE id = @id", new EqlParameter("id", id)).Execute().FirstOrDefault();
                    if (fileRecord != null)
                    {
                        attachments.Add((string)fileRecord["path"]);
                    }
                }
            }

            //we set current record to store properties which don't exist in current entity
            EntityRecord currentRecord = pageModel.DataModel.GetProperty("Record") as EntityRecord;

            currentRecord["recipient_email"] = recipientEmail;
            currentRecord["subject"]         = subject;
            currentRecord["content"]         = content;
            pageModel.DataModel.SetRecord(currentRecord);

            valEx.CheckAndThrow();

            try
            {
                EmailAddress recipient = new EmailAddress(recipientEmail);
                smtpService.SendEmail(recipient, subject, string.Empty, content, attachments: attachments);
                pageModel.TempData.Put("ScreenMessage", new ScreenMessage()
                {
                    Message = "Email was successfully sent", Type = ScreenMessageType.Success, Title = "Success"
                });
                var returnUrl = pageModel.HttpContext.Request.Query["returnUrl"];
                return(new RedirectResult($"/mail/services/smtp/r/{smtpService.Id}/details?returnUrl={returnUrl}"));
            }
            catch (Exception ex)
            {
                valEx.AddError("", ex.Message);
                valEx.CheckAndThrow();
                return(null);
            }
        }
Exemplo n.º 6
0
        public void SendEmailNotificationsTestRequeueForTransientErrors()
        {
            this.MsGraphSetting.Value.EnableBatching = false;
            EmailNotificationItem[] notificationItems = new EmailNotificationItem[]
            {
                new EmailNotificationItem()
                {
                    To = "*****@*****.**", Subject = "TestSubject", Body = "TestBody", NotificationId = "1"
                },
                new EmailNotificationItem()
                {
                    To = "*****@*****.**", Subject = "TestSubject", Body = "TestBody", NotificationId = "2"
                },
            };

            IList <EmailNotificationItemEntity> emailNotificationItemEntities = new List <EmailNotificationItemEntity>()
            {
                new EmailNotificationItemEntity()
                {
                    Application    = this.ApplicationName,
                    NotificationId = "1",
                    To             = "*****@*****.**",
                    Subject        = "TestEmailSubject",
                    Body           = "CfDJ8KvR5DP4DK5GqV1jviPzBnsv3onVDZ-ztz-AvRl_6nvVNg86jfmKjgySREDPW9xNrwpKALT5BIFNX6VK3wzKsxc51dbkQjPPG9l7436wQktrAMRadumTpGKNKG1lLlP0FA",
                    Id             = "1",
                },
                new EmailNotificationItemEntity()
                {
                    Application    = this.ApplicationName,
                    NotificationId = "2",
                    To             = "*****@*****.**",
                    Subject        = "TestEmailSubject",
                    Body           = "CfDJ8KvR5DP4DK5GqV1jviPzBnsv3onVDZ-ztz-AvRl_6nvVNg86jfmKjgySREDPW9xNrwpKALT5BIFNX6VK3wzKsxc51dbkQjPPG9l7436wQktrAMRadumTpGKNKG1lLlP0FA",
                    Id             = "2",
                },
            };

            var retrySetting = new RetrySetting
            {
                MaxRetries          = 10,
                TransientRetryCount = 3,
            };

            _ = this.EmailNotificationRepository
                .Setup(repository => repository.GetRepository(StorageType.StorageAccount).GetEmailNotificationItemEntities(It.IsAny <IList <string> >(), It.IsAny <string>()))
                .Returns(Task.FromResult(emailNotificationItemEntities));

            // Test the transient error: Too many Requests/ Request Timeout
            var graphProvider = new Mock <IMSGraphProvider>();

            _ = graphProvider
                .Setup(gp => gp.SendEmailNotification(It.IsAny <AuthenticationHeaderValue>(), It.IsAny <EmailMessagePayload>(), It.IsAny <string>()))
                .Returns(Task.FromResult(false));

            _ = this.TokenHelper
                .Setup(th => th.GetAuthenticationHeaderValueForSelectedAccount(It.IsAny <AccountCredential>()))
                .ReturnsAsync(new AuthenticationHeaderValue(ApplicationConstants.BearerAuthenticationScheme, "Test"));

            this.MSGraphNotificationProvider = new MSGraphNotificationProvider(this.Configuration, this.EmailAccountManager.Object, this.Logger, this.MsGraphSetting, this.TokenHelper.Object, graphProvider.Object, this.EmailManager);

            _ = this.NotificationProviderFactory
                .Setup(provider => provider.GetNotificationProvider(NotificationProviderType.Graph))
                .Returns(this.MSGraphNotificationProvider);

            var emailServiceManager = new EmailServiceManager(this.Configuration, this.EmailNotificationRepository.Object, this.CloudStorageClient.Object, this.Logger, this.NotificationProviderFactory.Object, this.EmailManager);

            Task <IList <NotificationResponse> > result = emailServiceManager.SendEmailNotifications(this.ApplicationName, notificationItems);

            Assert.AreEqual(result.Status.ToString(), "RanToCompletion");
            Assert.AreEqual(result.Result.Count(x => x.Status == NotificationItemStatus.Retrying), notificationItems.Count());
            this.EmailNotificationRepository.Verify(repo => repo.GetRepository(StorageType.StorageAccount).UpdateEmailNotificationItemEntities(It.IsAny <IList <EmailNotificationItemEntity> >()), Times.Once);
            this.CloudStorageClient.Verify(csa => csa.QueueCloudMessages(It.IsAny <CloudQueue>(), It.IsAny <IEnumerable <string> >(), null), Times.Once);

            // When Graph calls succeed
            _ = graphProvider
                .Setup(gp => gp.SendEmailNotification(It.IsAny <AuthenticationHeaderValue>(), It.IsAny <EmailMessagePayload>(), It.IsAny <string>()))
                .Returns(Task.FromResult(true));

            emailServiceManager = new EmailServiceManager(this.Configuration, this.EmailNotificationRepository.Object, this.CloudStorageClient.Object, this.Logger, this.NotificationProviderFactory.Object, this.EmailManager);

            result = emailServiceManager.SendEmailNotifications(this.ApplicationName, notificationItems);
            Assert.AreEqual(result.Status.ToString(), "RanToCompletion");
            Assert.AreEqual(result.Result.Count(x => x.Status == NotificationItemStatus.Sent), notificationItems.Count());

            this.EmailNotificationRepository.Verify(repo => repo.GetRepository(StorageType.StorageAccount).UpdateEmailNotificationItemEntities(It.IsAny <IList <EmailNotificationItemEntity> >()), Times.Exactly(2));

            // This is called when retrying the transient failed items previously, count not changed
            this.CloudStorageClient.Verify(csa => csa.QueueCloudMessages(It.IsAny <CloudQueue>(), It.IsAny <IEnumerable <string> >(), null), Times.Once);

            // When graph call throws exception
            _ = graphProvider
                .Setup(gp => gp.SendEmailNotification(It.IsAny <AuthenticationHeaderValue>(), It.IsAny <EmailMessagePayload>(), It.IsAny <string>()))
                .ThrowsAsync(new AggregateException());

            emailServiceManager = new EmailServiceManager(this.Configuration, this.EmailNotificationRepository.Object, this.CloudStorageClient.Object, this.Logger, this.NotificationProviderFactory.Object, this.EmailManager);

            result = emailServiceManager.SendEmailNotifications(this.ApplicationName, notificationItems);
            Assert.AreEqual(result.Status.ToString(), "RanToCompletion");
            Assert.AreEqual(result.Result.Count(x => x.Status == NotificationItemStatus.Failed), notificationItems.Count());

            this.EmailNotificationRepository.Verify(repo => repo.GetRepository(StorageType.StorageAccount).UpdateEmailNotificationItemEntities(It.IsAny <IList <EmailNotificationItemEntity> >()), Times.Exactly(3));

            // This is called when retrying the transient failed items previously, count not changed
            this.CloudStorageClient.Verify(csa => csa.QueueCloudMessages(It.IsAny <CloudQueue>(), It.IsAny <IEnumerable <string> >(), null), Times.Once);

            Assert.Pass();
        }
Exemplo n.º 7
0
        public void SendEmailNotificationsInBatchTestRequeueForTransientErrors()
        {
            this.MsGraphSetting.Value.EnableBatching = true;
            EmailNotificationItem[] notificationItems = new EmailNotificationItem[]
            {
                new EmailNotificationItem()
                {
                    To = "*****@*****.**", Subject = "TestSubject", Body = "TestBody", NotificationId = "1"
                },
                new EmailNotificationItem()
                {
                    To = "*****@*****.**", Subject = "TestSubject", Body = "TestBody", NotificationId = "2"
                },
                new EmailNotificationItem()
                {
                    To = "*****@*****.**", Subject = "TestSubject", Body = "TestBody", NotificationId = "3"
                },
            };

            IList <EmailNotificationItemEntity> emailNotificationItemEntities = new List <EmailNotificationItemEntity>()
            {
                new EmailNotificationItemEntity()
                {
                    Application    = this.ApplicationName,
                    NotificationId = "1",
                    To             = "*****@*****.**",
                    Subject        = "TestEmailSubject",
                    Body           = "CfDJ8KvR5DP4DK5GqV1jviPzBnsv3onVDZ-ztz-AvRl_6nvVNg86jfmKjgySREDPW9xNrwpKALT5BIFNX6VK3wzKsxc51dbkQjPPG9l7436wQktrAMRadumTpGKNKG1lLlP0FA",
                    Id             = "1",
                },
                new EmailNotificationItemEntity()
                {
                    Application    = this.ApplicationName,
                    NotificationId = "2",
                    To             = "*****@*****.**",
                    Subject        = "TestEmailSubject",
                    Body           = "CfDJ8KvR5DP4DK5GqV1jviPzBnsv3onVDZ-ztz-AvRl_6nvVNg86jfmKjgySREDPW9xNrwpKALT5BIFNX6VK3wzKsxc51dbkQjPPG9l7436wQktrAMRadumTpGKNKG1lLlP0FA",
                    Id             = "2",
                },
                new EmailNotificationItemEntity()
                {
                    Application    = this.ApplicationName,
                    NotificationId = "3",
                    To             = "*****@*****.**",
                    Subject        = "TestEmailSubject",
                    Body           = "CfDJ8KvR5DP4DK5GqV1jviPzBnsv3onVDZ-ztz-AvRl_6nvVNg86jfmKjgySREDPW9xNrwpKALT5BIFNX6VK3wzKsxc51dbkQjPPG9l7436wQktrAMRadumTpGKNKG1lLlP0FA",
                    Id             = "3",
                },
            };
            var retrySetting = new RetrySetting
            {
                MaxRetries          = 10,
                TransientRetryCount = 3,
            };

            // Test the transient error: Too many Requests/ Request Timeout
            IList <NotificationBatchItemResponse> responses = new List <NotificationBatchItemResponse>();

            responses.Add(new NotificationBatchItemResponse()
            {
                NotificationId = "1", Status = System.Net.HttpStatusCode.TooManyRequests
            });
            responses.Add(new NotificationBatchItemResponse()
            {
                NotificationId = "2", Status = System.Net.HttpStatusCode.RequestTimeout
            });
            responses.Add(new NotificationBatchItemResponse()
            {
                NotificationId = "3", Status = System.Net.HttpStatusCode.Accepted
            });

            Mock <IMSGraphProvider> graphProvider = new Mock <IMSGraphProvider>();

            _ = graphProvider
                .Setup(gp => gp.ProcessEmailRequestBatch(It.IsAny <AuthenticationHeaderValue>(), It.IsAny <GraphBatchRequest>()))
                .Returns(Task.FromResult(responses));

            _ = this.EmailNotificationRepository
                .Setup(repository => repository.GetRepository(StorageType.StorageAccount).GetEmailNotificationItemEntities(It.IsAny <IList <string> >(), It.IsAny <string>()))
                .Returns(Task.FromResult(emailNotificationItemEntities));

            _ = this.TokenHelper
                .Setup(th => th.GetAuthenticationHeaderValueForSelectedAccount(It.IsAny <AccountCredential>()))
                .ReturnsAsync(new AuthenticationHeaderValue(ApplicationConstants.BearerAuthenticationScheme, "Test"));

            this.MSGraphNotificationProvider = new MSGraphNotificationProvider(this.Configuration, this.EmailAccountManager.Object, this.Logger, this.MsGraphSetting, this.TokenHelper.Object, graphProvider.Object, this.EmailManager);

            _ = this.NotificationProviderFactory
                .Setup(provider => provider.GetNotificationProvider(NotificationProviderType.Graph))
                .Returns(this.MSGraphNotificationProvider);

            var emailServiceManager = new EmailServiceManager(this.Configuration, this.EmailNotificationRepository.Object, this.CloudStorageClient.Object, this.Logger, this.NotificationProviderFactory.Object, this.EmailManager);

            Task <IList <NotificationResponse> > result = emailServiceManager.SendEmailNotifications(this.ApplicationName, notificationItems);

            Assert.AreEqual(result.Status.ToString(), "RanToCompletion");
            Assert.AreEqual(result.Result.Count(x => x.Status == NotificationItemStatus.Retrying), 2);
            this.EmailNotificationRepository.Verify(repo => repo.GetRepository(StorageType.StorageAccount).UpdateEmailNotificationItemEntities(It.IsAny <IList <EmailNotificationItemEntity> >()), Times.Once);
            this.CloudStorageClient.Verify(csa => csa.QueueCloudMessages(It.IsAny <CloudQueue>(), It.IsAny <IEnumerable <string> >(), null), Times.Once);
            Assert.Pass();
        }
Exemplo n.º 8
0
 public void OnPostUpdateRecord(string entityName, EntityRecord record)
 {
     EmailServiceManager.ClearCache();
 }
        public ActionResult Register(RegisterInputModel Input)
        {
            ObserverDbContext _db = new ObserverDbContext();

            if (User.Identity.IsAuthenticated)
            {
                return(RedirectToAction("Index", "Home"));
            }

            var pendingUsers = _db.PendingUsers
                               .Where(e => e.Email == Input.Email)
                               .OrderByDescending(e => e.DateCreated)
                               .ToList();

            var user = _db.Users
                       .Where(e => e.Email == Input.Email)
                       .ToList();

            if (user.Count > 0)
            {
                ViewBag.ErrorMessage = "Error: The email has been used.";
                return(View());
            }
            else if (pendingUsers.Count >= 1)
            {
                var pendingUser = pendingUsers.FirstOrDefault();
                if (pendingUser.Status == 1)
                {
                    ViewBag.ErrorMessage = "Error: The email has been used.";
                    return(View());
                }
                else if (pendingUser.Status == 0 || pendingUser.Status == 2)
                {
                    if (pendingUser.DateCreated.AddHours(1) < DateTime.UtcNow)
                    {
                        pendingUser.Status = 2;

                        string            id      = Guid.NewGuid().ToString();
                        string            key     = EncryptionAlgorithmServiceManager.GetRNGGuid().ToString();
                        PendingUsersModel newUser = new PendingUsersModel()
                        {
                            Id          = id,
                            DisplayName = Input.Name,
                            Email       = Input.Email,
                            Key         = key,
                            Status      = 0,
                            DateCreated = DateTime.UtcNow
                        };

                        _db.PendingUsers.Add(newUser);
                        _db.SaveChanges();
                        EmailServiceManager.AccountPendingVerification(Input.Name, Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + "/VerifyEmail?Id=" + id + "&Key=" + key, Input.Email);
                        return(RedirectToAction("Index", "Home", new { Status = 7, email = Input.Email }));
                    }
                    else
                    {
                        int minute = DateTime.UtcNow.Subtract(pendingUser.DateCreated).Minutes;
                        return(RedirectToAction("Index", "Home", new { Status = 6, min = minute }));
                    }
                }
                return(View());
            }
            else
            {
                string            key     = Guid.NewGuid().ToString();
                string            id      = Guid.NewGuid().ToString();
                PendingUsersModel newUser = new PendingUsersModel()
                {
                    Id          = id,
                    DisplayName = Input.Name,
                    Email       = Input.Email,
                    Key         = key,
                    Status      = 0,
                    DateCreated = DateTime.UtcNow
                };

                _db.PendingUsers.Add(newUser);
                _db.SaveChanges();
                EmailServiceManager.AccountPendingVerification(Input.Name, Request.Url.Scheme + "://" + Request.Url.Host + ":" + Request.Url.Port + "/VerifyEmail?Id=" + id + "&Key=" + key, Input.Email);
                return(RedirectToAction("Index", "Home", new { Status = 7, email = Input.Email }));
            }
        }
        public IActionResult TestSmtpServiceOnPost(RecordDetailsPageModel pageModel)
        {
            SmtpService smtpService    = null;
            string      recipientEmail = string.Empty;
            string      subject        = string.Empty;
            string      content        = string.Empty;

            ValidationException valEx = new ValidationException();

            if (pageModel.HttpContext.Request.Form == null)
            {
                valEx.AddError("form", "Smtp service test page missing form tag");
                valEx.CheckAndThrow();
            }


            if (!pageModel.HttpContext.Request.Form.ContainsKey("recipient_email"))
            {
                valEx.AddError("recipient_email", "Recipient email is not specified.");
            }
            else
            {
                recipientEmail = pageModel.HttpContext.Request.Form["recipient_email"];
                if (string.IsNullOrWhiteSpace(recipientEmail))
                {
                    valEx.AddError("recipient_email", "Recipient email is not specified");
                }
                else if (!recipientEmail.IsEmail())
                {
                    valEx.AddError("recipient_email", "Recipient email is not a valid email address");
                }
            }

            if (!pageModel.HttpContext.Request.Form.ContainsKey("subject"))
            {
                valEx.AddError("subject", "Subject is not specified");
            }
            else
            {
                subject = pageModel.HttpContext.Request.Form["subject"];
                if (string.IsNullOrWhiteSpace(subject))
                {
                    valEx.AddError("subject", "Subject is required");
                }
            }

            if (!pageModel.HttpContext.Request.Form.ContainsKey("content"))
            {
                valEx.AddError("content", "Content is not specified");
            }
            else
            {
                content = pageModel.HttpContext.Request.Form["content"];
                if (string.IsNullOrWhiteSpace(content))
                {
                    valEx.AddError("content", "Content is required");
                }
            }

            var smtpServiceId = pageModel.DataModel.GetProperty("Record.id") as Guid?;

            if (smtpServiceId == null)
            {
                valEx.AddError("serviceId", "Invalid smtp service id");
            }
            else
            {
                smtpService = new EmailServiceManager().GetSmtpService(smtpServiceId.Value);
                if (smtpService == null)
                {
                    valEx.AddError("serviceId", "Smtp service with specified id does not exist");
                }
            }

            //we set current record to store properties which don't exist in current entity
            EntityRecord currentRecord = pageModel.DataModel.GetProperty("Record") as EntityRecord;

            currentRecord["recipient_email"] = recipientEmail;
            currentRecord["subject"]         = subject;
            currentRecord["content"]         = content;
            pageModel.DataModel.SetRecord(currentRecord);

            valEx.CheckAndThrow();

            try
            {
                EmailAddress recipient = new EmailAddress(recipientEmail);
                smtpService.SendEmail(recipient, subject, string.Empty, content);
                pageModel.TempData.Put("ScreenMessage", new ScreenMessage()
                {
                    Message = "Email was successfully sent", Type = ScreenMessageType.Success, Title = "Success"
                });
                var returnUrl = pageModel.HttpContext.Request.Query["returnUrl"];
                return(new RedirectResult($"/mail/services/smtp/r/{smtpService.Id}/details?returnUrl={returnUrl}"));
            }
            catch (Exception ex)
            {
                valEx.AddError("", ex.Message);
                valEx.CheckAndThrow();
                return(null);
            }
        }