private static IEnumerable <EmailMessageEntity> CreateEmailMessage(EmailTemplateEntity template, ModifiableEntity?modifiableEntity, ref IEmailModel?model, CultureInfo?cultureInfo = null) { Entity?entity = null; if (template.Model != null) { if (model == null) { model = EmailModelLogic.CreateModel(template.Model, modifiableEntity); } else if (template.Model.ToType() != model.GetType()) { throw new ArgumentException("model should be a {0} instead of {1}".FormatWith(template.Model.FullClassName, model.GetType().FullName)); } } else { entity = modifiableEntity as Entity ?? throw new InvalidOperationException("Model should be an Entity"); } using (template.DisableAuthorization ? ExecutionMode.Global() : null) { var emailBuilder = new EmailMessageBuilder(template, entity, model, cultureInfo); return(emailBuilder.CreateEmailMessageInternal().ToList()); } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { sb.Include <ResetPasswordRequestEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.RequestDate, e.Code, e.User, e.User.Email }); EmailLogic.AssertStarted(sb); EmailModelLogic.RegisterEmailModel <ResetPasswordRequestEmail>(() => new EmailTemplateEntity { Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YouRecentlyRequestedANewPassword.NiceToString()) + "<p>{0} @[User.UserName]</p>".FormatWith(AuthEmailMessage.YourUsernameIs.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.ResetPasswordRequestSubject.NiceToString() }).ToMList() }); } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { sb.Include <ResetPasswordRequestEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.RequestDate, e.Code, e.User, e.User.Email }); EmailLogic.AssertStarted(sb); EmailModelLogic.RegisterEmailModel <ResetPasswordRequestEmail>(() => new EmailTemplateEntity { DisableAuthorization = true, Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YouRecentlyRequestedANewPassword.NiceToString()) + "<p>{0} @[User.UserName]</p>".FormatWith(AuthEmailMessage.YourUsernameIs.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.ResetPasswordRequestSubject.NiceToString() }).ToMList() }); new Graph <ResetPasswordRequestEntity> .Execute(ResetPasswordRequestOperation.Execute) { CanBeNew = false, CanBeModified = false, CanExecute = (e) => e.Lapsed == false ? null : AuthEmailMessage.YourResetPasswordRequestHasExpired.NiceToString(), Execute = (e, args) => { string password = args.GetArg <string>(); e.Lapsed = true; var user = e.User; var error = UserEntity.OnValidatePassword(password); if (error != null) { throw new ApplicationException(error); } user.PasswordHash = Security.EncodePassword(password); using (AuthLogic.Disable()) user.Execute(UserOperation.Save); } } .Register(); } }
static SqlPreCommand?Schema_Synchronizing_DefaultTemplates(Replacements replacements) { if (AvoidSynchronizeDefaultTemplates) { return(null); } var table = Schema.Current.Table(typeof(EmailTemplateEntity)); var emailModels = Database.Query <EmailModelEntity>().Where(se => !se.EmailTemplates().Any()).ToList(); string cis = Database.Query <CultureInfoEntity>().Select(a => a.Name).ToString(", ").Etc(60); if (!emailModels.Any()) { return(null); } if (!replacements.Interactive || !SafeConsole.Ask("{0}\r\n have no EmailTemplates. Create in {1}?".FormatWith(emailModels.ToString("\r\n"), cis.DefaultText("No CultureInfos registered!")))) { return(null); } using (replacements.WithReplacedDatabaseName()) { var cmd = emailModels.Select(se => { try { return(table.InsertSqlSync(EmailModelLogic.CreateDefaultTemplateInternal(se), includeCollections: true)); } catch (Exception e) { return(new SqlPreCommandSimple("Exception on SystemEmail {0}: {1}".FormatWith(se, e.Message))); } }).Combine(Spacing.Double); if (cmd != null) { return(SqlPreCommand.Combine(Spacing.Double, new SqlPreCommandSimple("DECLARE @parentId INT"), cmd)); } return(cmd); } }
public static bool IsVisible(EmailTemplateEntity et, EmailTemplateVisibleOn visibleOn) { if (et.Model == null) { return(visibleOn == EmailTemplateVisibleOn.Single); } if (EmailModelLogic.HasDefaultTemplateConstructor(et.Model)) { return(false); } var entityType = EmailModelLogic.GetEntityType(et.Model.ToType()); if (entityType.IsEntity()) { return(visibleOn == EmailTemplateVisibleOn.Single); } var should = VisibleOnDictionary.TryGet(entityType, EmailTemplateVisibleOn.Single); return((should & visibleOn) != 0); }
public static void GenerateDefaultTemplates() { var systemEmails = Database.Query <EmailModelEntity>().Where(se => !se.EmailTemplates().Any()).ToList(); List <string> exceptions = new List <string>(); foreach (var se in systemEmails) { try { EmailModelLogic.CreateDefaultTemplateInternal(se).Save(); } catch (Exception ex) { exceptions.Add("{0} in {1}:\r\n{2}".FormatWith(ex.GetType().Name, se.FullClassName, ex.Message.Indent(4))); } } if (exceptions.Any()) { throw new Exception(exceptions.ToString("\r\n\r\n")); } }
public EmailModelEntity GetEmailModel(string fullClassName) { return(EmailModelLogic.GetEmailModelEntity(fullClassName)); }
public static void Start(SchemaBuilder sb, string?systemUserName, string?anonymousUserName) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { SystemUserName = systemUserName; AnonymousUserName = anonymousUserName; CultureInfoLogic.AssertStarted(sb); sb.Include <UserEntity>() .WithExpressionFrom((RoleEntity r) => r.Users()) .WithQuery(() => e => new { Entity = e, e.Id, e.UserName, e.Email, e.Role, e.State, e.CultureInfo, }); sb.Include <RoleEntity>() .WithSave(RoleOperation.Save) .WithDelete(RoleOperation.Delete) .WithQuery(() => r => new { Entity = r, r.Id, r.Name, }); roles = sb.GlobalLazy(CacheRoles, new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); rolesInverse = sb.GlobalLazy(() => roles.Value.Inverse(), new InvalidateWith(typeof(RoleEntity))); rolesByName = sb.GlobalLazy(() => roles.Value.ToDictionaryEx(a => a.ToString() !), new InvalidateWith(typeof(RoleEntity))); mergeStrategies = sb.GlobalLazy(() => { var strategies = Database.Query <RoleEntity>().Select(r => KeyValuePair.Create(r.ToLite(), r.MergeStrategy)).ToDictionary(); var graph = roles.Value; Dictionary <Lite <RoleEntity>, RoleData> result = new Dictionary <Lite <RoleEntity>, RoleData>(); foreach (var r in graph.CompilationOrder()) { var strat = strategies.GetOrThrow(r); var baseValues = graph.RelatedTo(r).Select(r2 => result[r2].DefaultAllowed); result.Add(r, new RoleData { MergeStrategy = strat, DefaultAllowed = strat == MergeStrategy.Union ? baseValues.Any(a => a) : baseValues.All(a => a) }); } return(result); }, new InvalidateWith(typeof(RoleEntity)), AuthLogic.NotifyRulesChanged); sb.Schema.EntityEvents <RoleEntity>().Saving += Schema_Saving; UserGraph.Register(); EmailModelLogic.RegisterEmailModel <UserLockedMail>(() => new EmailTemplateEntity { Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YourAccountHasBeenLockedDueToSeveralFailedLogins.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.YourAccountHasBeenLocked.NiceToString() }).ToMList() }); } }
public static void RegisterAlertNotificationMail(SchemaBuilder sb) { EmailModelLogic.RegisterEmailModel <AlertNotificationMail>(() => new EmailTemplateEntity { Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = @" <p>Hi @[m:Entity],</p> <p>You have some pending alerts:</p> <ul> @foreach[m:Alerts] as $a <li> <strong>@[$a.AlertType]:</strong><br/> @[m:TextFormatted]<br/> <small>@[$a.AlertDate] @[$a.CreatedBy]</small> </li> @endforeach </ul> <p>Please visit <a href=""@[g:UrlLeft]"">@[g:UrlLeft]</a></p>", Subject = AlertMessage.NewUnreadNotifications.NiceToString(), }).ToMList() }); sb.Include <SendNotificationEmailTaskEntity>() .WithSave(SendNotificationEmailTaskOperation.Save) .WithQuery(() => e => new { Entity = e, e.Id, e.SendNotificationsOlderThan, e.SendBehavior, }); SchedulerLogic.ExecuteTask.Register((SendNotificationEmailTaskEntity task, ScheduledTaskContext ctx) => { var limit = DateTime.Now.AddMinutes(-task.SendNotificationsOlderThan); var query = Database.Query <AlertEntity>() .Where(a => a.State == AlertState.Saved && a.EmailNotificationsSent == 0 && a.Recipient != null && a.CreationDate < limit) .Where(a => task.SendBehavior == SendAlertTypeBehavior.All || task.SendBehavior == SendAlertTypeBehavior.Include && task.AlertTypes.Contains(a.AlertType !) || task.SendBehavior == SendAlertTypeBehavior.Exclude && !task.AlertTypes.Contains(a.AlertType !)); if (!query.Any()) { return(null); } var alerts = query .Select(a => new { Alert = a, Recipient = a.Recipient !.Entity }) .ToList(); EmailPackageEntity emailPackage = new EmailPackageEntity().Save(); var emails = alerts.GroupBy(a => a.Recipient, a => a.Alert).SelectMany(gr => new AlertNotificationMail((UserEntity)gr.Key, gr.ToList()).CreateEmailMessage()).ToList(); emails.ForEach(a => { a.State = EmailMessageState.ReadyToSend; a.Package = emailPackage.ToLite(); }); emails.BulkInsertQueryIds(a => a.Target !); query.UnsafeUpdate().Set(a => a.EmailNotificationsSent, a => 1).Execute(); return(emailPackage.ToLite()); });
public string GetConstructorType([Required, FromBody] EmailModelEntity model) { var type = EmailModelLogic.GetEntityType(model.ToType()); return(ReflectionServer.GetTypeName(type)); }
public static void Start(SchemaBuilder sb, Func <EmailTemplateEntity, Lite <Entity>?, EmailMessageEntity?, EmailSenderConfigurationEntity?>?getSmtpConfiguration) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { CultureInfoLogic.AssertStarted(sb); TemplatingLogic.Start(sb); GetSmtpConfiguration = getSmtpConfiguration; sb.Include <EmailTemplateEntity>() .WithQuery(() => t => new { Entity = t, t.Id, t.Name, t.IsBodyHtml }); EmailTemplatesLazy = sb.GlobalLazy(() => Database.Query <EmailTemplateEntity>().ToDictionary(et => et.ToLite()) , new InvalidateWith(typeof(EmailTemplateEntity))); TemplatesByQueryName = sb.GlobalLazy(() => { return(EmailTemplatesLazy.Value.Values.SelectCatch(et => KeyValuePair.Create(et.Query.ToQueryName(), et)).GroupToDictionary()); }, new InvalidateWith(typeof(EmailTemplateEntity))); EmailModelLogic.Start(sb); EmailMasterTemplateLogic.Start(sb); sb.Schema.EntityEvents <EmailTemplateEntity>().PreSaving += new PreSavingEventHandler <EmailTemplateEntity>(EmailTemplate_PreSaving); sb.Schema.EntityEvents <EmailTemplateEntity>().Retrieved += EmailTemplateLogic_Retrieved; sb.Schema.Table <EmailModelEntity>().PreDeleteSqlSync += e => Administrator.UnsafeDeletePreCommand(Database.Query <EmailTemplateEntity>() .Where(a => a.Model.Is(e))); Validator.OverridePropertyValidator((EmailTemplateMessageEmbedded m) => m.Text).StaticPropertyValidation += EmailTemplateMessageText_StaticPropertyValidation; Validator.OverridePropertyValidator((EmailTemplateMessageEmbedded m) => m.Subject).StaticPropertyValidation += EmailTemplateMessageSubject_StaticPropertyValidation; EmailTemplateGraph.Register(); GlobalValueProvider.RegisterGlobalVariable("UrlLeft", _ => EmailLogic.Configuration.UrlLeft); GlobalValueProvider.RegisterGlobalVariable("Now", _ => Clock.Now); GlobalValueProvider.RegisterGlobalVariable("Today", _ => Clock.Now.Date, "d"); sb.Schema.Synchronizing += Schema_Synchronizing_Tokens; sb.Schema.Synchronizing += Schema_Synchronizing_DefaultTemplates; sb.Schema.Table <EmailModelEntity>().PreDeleteSqlSync += EmailTemplateLogic_PreDeleteSqlSync; Validator.PropertyValidator <EmailTemplateEntity>(et => et.Messages).StaticPropertyValidation += (et, pi) => { var dc = EmailLogic.Configuration.DefaultCulture; if (!et.Messages.Any(m => m.CultureInfo != null && dc.Name.StartsWith(m.CultureInfo.Name))) { return(EmailTemplateMessage.ThereMustBeAMessageFor0.NiceToString().FormatWith(CultureInfoLogic.EntityToCultureInfo.Value.Keys.Where(c => dc.Name.StartsWith(c.Name)).CommaOr(a => a.EnglishName))); } return(null); }; } }
public static void Register() { GetState = m => m.State; new Construct(EmailMessageOperation.CreateMail) { ToStates = { EmailMessageState.Created }, Construct = _ => new EmailMessageEntity { State = EmailMessageState.Created, } }.Register(); new ConstructFrom <EmailTemplateEntity>(EmailMessageOperation.CreateEmailFromTemplate) { ToStates = { EmailMessageState.Created }, CanConstruct = et => { if (et.Model != null && EmailModelLogic.RequiresExtraParameters(et.Model)) { return(EmailMessageMessage._01requiresExtraParameters.NiceToString(typeof(EmailModelEntity).NiceName(), et.Model)); } return(null); }, Construct = (et, args) => { var entity = args.TryGetArgC <ModifiableEntity>() ?? args.GetArg <Lite <Entity> >().RetrieveAndRemember(); var emailMessageEntity = et.ToLite().CreateEmailMessage(entity).FirstOrDefault(); if (emailMessageEntity == null) { throw new InvalidOperationException("No suitable recipients were found"); } return(emailMessageEntity); } }.Register(); new Execute(EmailMessageOperation.Save) { CanBeNew = true, CanBeModified = true, FromStates = { EmailMessageState.Created, EmailMessageState.Outdated }, ToStates = { EmailMessageState.Draft }, Execute = (m, _) => { m.State = EmailMessageState.Draft; } }.Register(); new Execute(EmailMessageOperation.ReadyToSend) { CanBeNew = true, CanBeModified = true, FromStates = { EmailMessageState.Created, EmailMessageState.Draft, EmailMessageState.SentException, EmailMessageState.RecruitedForSending, EmailMessageState.Outdated }, ToStates = { EmailMessageState.ReadyToSend }, Execute = (m, _) => { m.SendRetries = 0; m.Exception = null; m.State = EmailMessageState.ReadyToSend; } }.Register(); new Execute(EmailMessageOperation.Send) { CanExecute = m => m.State == EmailMessageState.Created || m.State == EmailMessageState.Draft || m.State == EmailMessageState.ReadyToSend || m.State == EmailMessageState.RecruitedForSending || m.State == EmailMessageState.Outdated ? null : EmailMessageMessage.TheEmailMessageCannotBeSentFromState0.NiceToString().FormatWith(m.State.NiceToString()), CanBeNew = true, CanBeModified = true, FromStates = { EmailMessageState.Created, EmailMessageState.Draft, EmailMessageState.ReadyToSend, EmailMessageState.Outdated }, ToStates = { EmailMessageState.Sent }, Execute = (m, _) => EmailLogic.SenderManager.Send(m) }.Register(); new ConstructFrom <EmailMessageEntity>(EmailMessageOperation.ReSend) { ToStates = { EmailMessageState.Created }, Construct = (m, _) => { return(new EmailMessageEntity { From = m.From.Clone(), Recipients = m.Recipients.Select(r => r.Clone()).ToMList(), Target = m.Target, Subject = m.Subject, Body = new BigStringEmbedded(m.Body.Text), IsBodyHtml = m.IsBodyHtml, Template = m.Template, EditableMessage = m.EditableMessage, State = EmailMessageState.Created, Attachments = m.Attachments.Select(a => a.Clone()).ToMList() }); } }.Register(); new Graph <EmailMessageEntity> .Delete(EmailMessageOperation.Delete) { Delete = (m, _) => m.Delete() } .Register(); }