[REFACTOR] Improved Structure For Email Module (#17755)

* [fix] code structure

* fix test
This commit is contained in:
Siddhant 2024-09-11 18:23:39 +05:30 committed by GitHub
parent 504b84138b
commit 25175089fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 232 additions and 200 deletions

View File

@ -31,8 +31,8 @@ import org.openmetadata.service.exception.CatalogExceptionMessage;
import org.openmetadata.service.formatter.decorators.EmailMessageDecorator; import org.openmetadata.service.formatter.decorators.EmailMessageDecorator;
import org.openmetadata.service.formatter.decorators.MessageDecorator; import org.openmetadata.service.formatter.decorators.MessageDecorator;
import org.openmetadata.service.jdbi3.CollectionDAO; import org.openmetadata.service.jdbi3.CollectionDAO;
import org.openmetadata.service.util.EmailUtil;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.email.EmailUtil;
@Slf4j @Slf4j
public class EmailPublisher implements Destination<ChangeEvent> { public class EmailPublisher implements Destination<ChangeEvent> {

View File

@ -6,6 +6,7 @@ import static org.openmetadata.service.Entity.TEAM;
import static org.openmetadata.service.apps.scheduler.AppScheduler.APP_NAME; import static org.openmetadata.service.apps.scheduler.AppScheduler.APP_NAME;
import static org.openmetadata.service.util.SubscriptionUtil.getAdminsData; import static org.openmetadata.service.util.SubscriptionUtil.getAdminsData;
import static org.openmetadata.service.util.Utilities.getMonthAndDateFromEpoch; import static org.openmetadata.service.util.Utilities.getMonthAndDateFromEpoch;
import static org.openmetadata.service.util.email.TemplateConstants.DATA_INSIGHT_REPORT_TEMPLATE;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@ -41,10 +42,10 @@ import org.openmetadata.service.jdbi3.KpiRepository;
import org.openmetadata.service.jdbi3.ListFilter; import org.openmetadata.service.jdbi3.ListFilter;
import org.openmetadata.service.search.SearchClient; import org.openmetadata.service.search.SearchClient;
import org.openmetadata.service.search.SearchRepository; import org.openmetadata.service.search.SearchRepository;
import org.openmetadata.service.util.EmailUtil;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.ResultList; import org.openmetadata.service.util.ResultList;
import org.openmetadata.service.util.Utilities; import org.openmetadata.service.util.Utilities;
import org.openmetadata.service.util.email.EmailUtil;
import org.openmetadata.service.workflows.searchIndex.PaginatedEntitiesSource; import org.openmetadata.service.workflows.searchIndex.PaginatedEntitiesSource;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
@ -142,7 +143,7 @@ public class DataInsightsReportApp extends AbstractNativeApplication {
ownershipTemplate, ownershipTemplate,
tierTemplate, tierTemplate,
EmailUtil.getDataInsightReportSubject(), EmailUtil.getDataInsightReportSubject(),
EmailUtil.DATA_INSIGHT_REPORT_TEMPLATE); DATA_INSIGHT_REPORT_TEMPLATE);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error( LOG.error(
"[DataInsightReport] Failed for Team: {}, Reason : {}", "[DataInsightReport] Failed for Team: {}, Reason : {}",
@ -177,7 +178,7 @@ public class DataInsightsReportApp extends AbstractNativeApplication {
ownershipTemplate, ownershipTemplate,
tierTemplate, tierTemplate,
EmailUtil.getDataInsightReportSubject(), EmailUtil.getDataInsightReportSubject(),
EmailUtil.DATA_INSIGHT_REPORT_TEMPLATE); DATA_INSIGHT_REPORT_TEMPLATE);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("[DataInsightReport] Failed for Admin, Reason : {}", ex.getMessage(), ex); LOG.error("[DataInsightReport] Failed for Admin, Reason : {}", ex.getMessage(), ex);
} }

View File

@ -14,7 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;

View File

@ -14,7 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -14,7 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -14,7 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -30,10 +30,10 @@ import org.openmetadata.service.Entity;
import org.openmetadata.service.exception.EntityNotFoundException; import org.openmetadata.service.exception.EntityNotFoundException;
import org.openmetadata.service.resources.docstore.DocStoreResource; import org.openmetadata.service.resources.docstore.DocStoreResource;
import org.openmetadata.service.resources.settings.SettingsCache; import org.openmetadata.service.resources.settings.SettingsCache;
import org.openmetadata.service.util.DefaultTemplateProvider;
import org.openmetadata.service.util.EntityUtil.Fields; import org.openmetadata.service.util.EntityUtil.Fields;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.TemplateProvider; import org.openmetadata.service.util.email.DefaultTemplateProvider;
import org.openmetadata.service.util.email.TemplateProvider;
@Slf4j @Slf4j
public class DocumentRepository extends EntityRepository<Document> { public class DocumentRepository extends EntityRepository<Document> {

View File

@ -99,13 +99,8 @@ public class SystemRepository {
if (fetchedSettings == null) { if (fetchedSettings == null) {
return null; return null;
} }
if (fetchedSettings.getConfigType() == SettingsType.EMAIL_CONFIGURATION) {
SmtpSettings emailConfig = (SmtpSettings) fetchedSettings.getConfigValue();
emailConfig.setPassword("***********");
fetchedSettings.setConfigValue(emailConfig);
}
return fetchedSettings;
return fetchedSettings;
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("Error while trying fetch Settings ", ex); LOG.error("Error while trying fetch Settings ", ex);
} }

View File

@ -64,9 +64,9 @@ import org.openmetadata.service.limits.Limits;
import org.openmetadata.service.resources.Collection; import org.openmetadata.service.resources.Collection;
import org.openmetadata.service.resources.EntityResource; import org.openmetadata.service.resources.EntityResource;
import org.openmetadata.service.security.Authorizer; import org.openmetadata.service.security.Authorizer;
import org.openmetadata.service.util.DefaultTemplateProvider;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.ResultList; import org.openmetadata.service.util.ResultList;
import org.openmetadata.service.util.email.DefaultTemplateProvider;
@Slf4j @Slf4j
@Path("/v1/docStore") @Path("/v1/docStore")

View File

@ -46,8 +46,8 @@ import org.openmetadata.service.jdbi3.SystemRepository;
import org.openmetadata.service.resources.Collection; import org.openmetadata.service.resources.Collection;
import org.openmetadata.service.security.Authorizer; import org.openmetadata.service.security.Authorizer;
import org.openmetadata.service.security.JwtFilter; import org.openmetadata.service.security.JwtFilter;
import org.openmetadata.service.util.EmailUtil;
import org.openmetadata.service.util.ResultList; import org.openmetadata.service.util.ResultList;
import org.openmetadata.service.util.email.EmailUtil;
@Path("/v1/system") @Path("/v1/system")
@Tag(name = "System", description = "APIs related to System configuration and settings.") @Tag(name = "System", description = "APIs related to System configuration and settings.")

View File

@ -27,12 +27,12 @@ import static org.openmetadata.service.exception.CatalogExceptionMessage.EMAIL_S
import static org.openmetadata.service.jdbi3.UserRepository.AUTH_MECHANISM_FIELD; import static org.openmetadata.service.jdbi3.UserRepository.AUTH_MECHANISM_FIELD;
import static org.openmetadata.service.secrets.ExternalSecretsManager.NULL_SECRET_STRING; import static org.openmetadata.service.secrets.ExternalSecretsManager.NULL_SECRET_STRING;
import static org.openmetadata.service.security.jwt.JWTTokenGenerator.getExpiryDate; import static org.openmetadata.service.security.jwt.JWTTokenGenerator.getExpiryDate;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings;
import static org.openmetadata.service.util.UserUtil.getRoleListFromUser; import static org.openmetadata.service.util.UserUtil.getRoleListFromUser;
import static org.openmetadata.service.util.UserUtil.getRolesFromAuthorizationToken; import static org.openmetadata.service.util.UserUtil.getRolesFromAuthorizationToken;
import static org.openmetadata.service.util.UserUtil.getUser; import static org.openmetadata.service.util.UserUtil.getUser;
import static org.openmetadata.service.util.UserUtil.reSyncUserRolesFromToken; import static org.openmetadata.service.util.UserUtil.reSyncUserRolesFromToken;
import static org.openmetadata.service.util.UserUtil.validateAndGetRolesRef; import static org.openmetadata.service.util.UserUtil.validateAndGetRolesRef;
import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import at.favre.lib.crypto.bcrypt.BCrypt; import at.favre.lib.crypto.bcrypt.BCrypt;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
@ -146,7 +146,6 @@ import org.openmetadata.service.security.mask.PIIMasker;
import org.openmetadata.service.security.policyevaluator.OperationContext; import org.openmetadata.service.security.policyevaluator.OperationContext;
import org.openmetadata.service.security.policyevaluator.ResourceContext; import org.openmetadata.service.security.policyevaluator.ResourceContext;
import org.openmetadata.service.security.saml.JwtTokenCacheManager; import org.openmetadata.service.security.saml.JwtTokenCacheManager;
import org.openmetadata.service.util.EmailUtil;
import org.openmetadata.service.util.EntityUtil; import org.openmetadata.service.util.EntityUtil;
import org.openmetadata.service.util.EntityUtil.Fields; import org.openmetadata.service.util.EntityUtil.Fields;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
@ -154,6 +153,8 @@ import org.openmetadata.service.util.PasswordUtil;
import org.openmetadata.service.util.RestUtil.PutResponse; import org.openmetadata.service.util.RestUtil.PutResponse;
import org.openmetadata.service.util.ResultList; import org.openmetadata.service.util.ResultList;
import org.openmetadata.service.util.TokenUtil; import org.openmetadata.service.util.TokenUtil;
import org.openmetadata.service.util.email.EmailUtil;
import org.openmetadata.service.util.email.TemplateConstants;
@Slf4j @Slf4j
@Path("/v1/users") @Path("/v1/users")
@ -644,7 +645,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
authHandler.sendInviteMailToUser( authHandler.sendInviteMailToUser(
uriInfo, uriInfo,
user, user,
String.format("Welcome to %s", EmailUtil.getEmailingEntity()), String.format("Welcome to %s", EmailUtil.getSmtpSettings().getEmailingEntity()),
create.getCreatePasswordType(), create.getCreatePasswordType(),
create.getPassword()); create.getPassword());
} catch (Exception ex) { } catch (Exception ex) {
@ -1074,7 +1075,7 @@ public class UserResource extends EntityResource<User, UserRepository> {
uriInfo, uriInfo,
registeredUser, registeredUser,
EmailUtil.getPasswordResetSubject(), EmailUtil.getPasswordResetSubject(),
EmailUtil.PASSWORD_RESET_TEMPLATE_FILE); TemplateConstants.RESET_LINK_TEMPLATE);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("Error in sending mail for reset password" + ex.getMessage()); LOG.error("Error in sending mail for reset password" + ex.getMessage());
return Response.status(424).entity(new ErrorMessage(424, EMAIL_SENDING_ISSUE)).build(); return Response.status(424).entity(new ErrorMessage(424, EMAIL_SENDING_ISSUE)).build();

View File

@ -37,9 +37,17 @@ import static org.openmetadata.service.exception.CatalogExceptionMessage.SELF_SI
import static org.openmetadata.service.exception.CatalogExceptionMessage.TOKEN_EXPIRED; import static org.openmetadata.service.exception.CatalogExceptionMessage.TOKEN_EXPIRED;
import static org.openmetadata.service.exception.CatalogExceptionMessage.TOKEN_EXPIRY_ERROR; import static org.openmetadata.service.exception.CatalogExceptionMessage.TOKEN_EXPIRY_ERROR;
import static org.openmetadata.service.resources.teams.UserResource.USER_PROTECTED_FIELDS; import static org.openmetadata.service.resources.teams.UserResource.USER_PROTECTED_FIELDS;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings;
import static org.openmetadata.service.util.UserUtil.getRoleListFromUser; import static org.openmetadata.service.util.UserUtil.getRoleListFromUser;
import static org.openmetadata.service.util.UserUtil.getUser; import static org.openmetadata.service.util.UserUtil.getUser;
import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import static org.openmetadata.service.util.email.EmailUtil.sendAccountStatus;
import static org.openmetadata.service.util.email.TemplateConstants.APPLICATION_LOGIN_LINK;
import static org.openmetadata.service.util.email.TemplateConstants.ENTITY;
import static org.openmetadata.service.util.email.TemplateConstants.INVITE_CREATE_PASSWORD_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.INVITE_RANDOM_PASSWORD_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.PASSWORD;
import static org.openmetadata.service.util.email.TemplateConstants.SUPPORT_URL;
import static org.openmetadata.service.util.email.TemplateConstants.USERNAME;
import at.favre.lib.crypto.bcrypt.BCrypt; import at.favre.lib.crypto.bcrypt.BCrypt;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
@ -81,12 +89,12 @@ import org.openmetadata.service.jdbi3.UserRepository;
import org.openmetadata.service.security.AuthenticationException; import org.openmetadata.service.security.AuthenticationException;
import org.openmetadata.service.security.SecurityUtil; import org.openmetadata.service.security.SecurityUtil;
import org.openmetadata.service.security.jwt.JWTTokenGenerator; import org.openmetadata.service.security.jwt.JWTTokenGenerator;
import org.openmetadata.service.util.EmailUtil;
import org.openmetadata.service.util.EntityUtil; import org.openmetadata.service.util.EntityUtil;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.PasswordUtil; import org.openmetadata.service.util.PasswordUtil;
import org.openmetadata.service.util.RestUtil.PutResponse; import org.openmetadata.service.util.RestUtil.PutResponse;
import org.openmetadata.service.util.TokenUtil; import org.openmetadata.service.util.TokenUtil;
import org.openmetadata.service.util.email.EmailUtil;
@Slf4j @Slf4j
public class BasicAuthenticator implements AuthenticatorHandler { public class BasicAuthenticator implements AuthenticatorHandler {
@ -253,7 +261,7 @@ public class BasicAuthenticator implements AuthenticatorHandler {
// Update user about Password Change // Update user about Password Change
try { try {
EmailUtil.sendAccountStatus(storedUser, "Update Password", "Change Successful"); sendAccountStatus(storedUser, "Update Password", "Change Successful");
} catch (TemplateException ex) { } catch (TemplateException ex) {
LOG.error("Error in sending Password Change Mail to User. Reason : " + ex.getMessage(), ex); LOG.error("Error in sending Password Change Mail to User. Reason : " + ex.getMessage(), ex);
throw new CustomExceptionMessage(424, FAILED_SEND_EMAIL, EMAIL_SENDING_ISSUE); throw new CustomExceptionMessage(424, FAILED_SEND_EMAIL, EMAIL_SENDING_ISSUE);
@ -311,7 +319,7 @@ public class BasicAuthenticator implements AuthenticatorHandler {
sendInviteMailToUser( sendInviteMailToUser(
uriInfo, uriInfo,
response.getEntity(), response.getEntity(),
String.format("%s: Password Update", EmailUtil.getEmailingEntity()), String.format("%s: Password Update", getSmtpSettings().getEmailingEntity()),
ADMIN_CREATE, ADMIN_CREATE,
request.getNewPassword()); request.getNewPassword());
} }
@ -328,14 +336,14 @@ public class BasicAuthenticator implements AuthenticatorHandler {
switch (requestType) { switch (requestType) {
case ADMIN_CREATE -> { case ADMIN_CREATE -> {
Map<String, Object> templatePopulator = new HashMap<>(); Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put(EmailUtil.ENTITY, EmailUtil.getEmailingEntity()); templatePopulator.put(ENTITY, getSmtpSettings().getEmailingEntity());
templatePopulator.put(EmailUtil.SUPPORT_URL, EmailUtil.getSupportUrl()); templatePopulator.put(SUPPORT_URL, getSmtpSettings().getSupportUrl());
templatePopulator.put(EmailUtil.USERNAME, user.getName()); templatePopulator.put(USERNAME, user.getName());
templatePopulator.put(EmailUtil.PASSWORD, pwd); templatePopulator.put(PASSWORD, pwd);
templatePopulator.put(EmailUtil.APPLICATION_LOGIN_LINK, EmailUtil.getOMUrl()); templatePopulator.put(APPLICATION_LOGIN_LINK, getSmtpSettings().getOpenMetadataUrl());
try { try {
EmailUtil.sendMail( EmailUtil.sendMail(
subject, templatePopulator, user.getEmail(), EmailUtil.INVITE_RANDOM_PWD, true); subject, templatePopulator, user.getEmail(), INVITE_RANDOM_PASSWORD_TEMPLATE, true);
} catch (TemplateException ex) { } catch (TemplateException ex) {
LOG.error( LOG.error(
"Failed in sending Mail to user [{}]. Reason : {}", "Failed in sending Mail to user [{}]. Reason : {}",
@ -345,7 +353,7 @@ public class BasicAuthenticator implements AuthenticatorHandler {
} }
} }
case USER_CREATE -> sendPasswordResetLink( case USER_CREATE -> sendPasswordResetLink(
uriInfo, user, subject, EmailUtil.INVITE_CREATE_PWD); uriInfo, user, subject, INVITE_CREATE_PASSWORD_TEMPLATE);
default -> LOG.error("Invalid Password Create Type"); default -> LOG.error("Invalid Password Create Type");
} }
} }
@ -478,7 +486,7 @@ public class BasicAuthenticator implements AuthenticatorHandler {
loginAttemptCache.recordFailedLogin(providedIdentity); loginAttemptCache.recordFailedLogin(providedIdentity);
int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(providedIdentity); int failedLoginAttempt = loginAttemptCache.getUserFailedLoginCount(providedIdentity);
if (failedLoginAttempt == SecurityUtil.getLoginConfiguration().getMaxLoginFailAttempts()) { if (failedLoginAttempt == SecurityUtil.getLoginConfiguration().getMaxLoginFailAttempts()) {
EmailUtil.sendAccountStatus( sendAccountStatus(
storedUser, storedUser,
"Multiple Failed Login Attempts.", "Multiple Failed Login Attempts.",
String.format( String.format(

View File

@ -68,11 +68,11 @@ import org.openmetadata.service.jdbi3.UserRepository;
import org.openmetadata.service.security.AuthenticationException; import org.openmetadata.service.security.AuthenticationException;
import org.openmetadata.service.security.SecurityUtil; import org.openmetadata.service.security.SecurityUtil;
import org.openmetadata.service.security.jwt.JWTTokenGenerator; import org.openmetadata.service.security.jwt.JWTTokenGenerator;
import org.openmetadata.service.util.EmailUtil;
import org.openmetadata.service.util.JsonUtils; import org.openmetadata.service.util.JsonUtils;
import org.openmetadata.service.util.LdapUtil; import org.openmetadata.service.util.LdapUtil;
import org.openmetadata.service.util.TokenUtil; import org.openmetadata.service.util.TokenUtil;
import org.openmetadata.service.util.UserUtil; import org.openmetadata.service.util.UserUtil;
import org.openmetadata.service.util.email.EmailUtil;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;

View File

@ -51,6 +51,7 @@ import org.openmetadata.service.security.auth.CatalogSecurityContext;
import org.openmetadata.service.security.jwt.JWTTokenGenerator; import org.openmetadata.service.security.jwt.JWTTokenGenerator;
import org.openmetadata.service.util.EntityUtil.Fields; import org.openmetadata.service.util.EntityUtil.Fields;
import org.openmetadata.service.util.RestUtil.PutResponse; import org.openmetadata.service.util.RestUtil.PutResponse;
import org.openmetadata.service.util.email.EmailUtil;
@Slf4j @Slf4j
public final class UserUtil { public final class UserUtil {

View File

@ -1,12 +1,12 @@
package org.openmetadata.service.util; package org.openmetadata.service.util.email;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -15,7 +15,6 @@ import lombok.extern.slf4j.Slf4j;
import org.openmetadata.schema.email.EmailTemplate; import org.openmetadata.schema.email.EmailTemplate;
import org.openmetadata.schema.email.EmailTemplatePlaceholder; import org.openmetadata.schema.email.EmailTemplatePlaceholder;
import org.openmetadata.schema.email.TemplateValidationResponse; import org.openmetadata.schema.email.TemplateValidationResponse;
import org.openmetadata.schema.entities.docStore.Document;
import org.openmetadata.service.Entity; import org.openmetadata.service.Entity;
import org.openmetadata.service.jdbi3.DocumentRepository; import org.openmetadata.service.jdbi3.DocumentRepository;
@ -32,7 +31,7 @@ public class DefaultTemplateProvider implements TemplateProvider {
public Template getTemplate(String templateName) throws IOException { public Template getTemplate(String templateName) throws IOException {
EmailTemplate emailTemplate = documentRepository.fetchEmailTemplateByName(templateName); EmailTemplate emailTemplate = documentRepository.fetchEmailTemplateByName(templateName);
String template = emailTemplate.getTemplate(); String template = emailTemplate.getTemplate();
if (template == null || template.isEmpty()) { if (nullOrEmpty(template)) {
throw new IOException("Template content not found for template: " + templateName); throw new IOException("Template content not found for template: " + templateName);
} }
@ -40,33 +39,6 @@ public class DefaultTemplateProvider implements TemplateProvider {
templateName, new StringReader(template), new Configuration(Configuration.VERSION_2_3_31)); templateName, new StringReader(template), new Configuration(Configuration.VERSION_2_3_31));
} }
public Map<String, Set<EmailTemplatePlaceholder>> getDocumentPlaceHolders() {
List<Document> documents = documentRepository.fetchAllEmailTemplates();
return documents.stream()
.collect(
Collectors.toMap(
Document::getName,
document -> {
EmailTemplate emailTemplate =
JsonUtils.convertValue(document.getData(), EmailTemplate.class);
return emailTemplate.getPlaceHolders();
}));
}
public Map<String, Set<String>> getPlaceholdersFromTemplate() {
List<Document> listOfDocuments = documentRepository.fetchAllEmailTemplates();
return listOfDocuments.stream()
.collect(
Collectors.toMap(
Document::getName,
document ->
extractPlaceholders(
JsonUtils.convertValue(document.getData(), EmailTemplate.class)
.getTemplate())));
}
@Override @Override
public TemplateValidationResponse validateEmailTemplate(String docName, String actualContent) { public TemplateValidationResponse validateEmailTemplate(String docName, String actualContent) {
Set<String> expectedPlaceholders = Set<String> expectedPlaceholders =

View File

@ -11,8 +11,32 @@
* limitations under the License. * limitations under the License.
*/ */
package org.openmetadata.service.util; package org.openmetadata.service.util.email;
import static org.openmetadata.service.util.email.TemplateConstants.ACCOUNT_ACTIVITY_CHANGE_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.ACCOUNT_STATUS_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.ACTION_KEY;
import static org.openmetadata.service.util.email.TemplateConstants.ACTION_STATUS_KEY;
import static org.openmetadata.service.util.email.TemplateConstants.APPLICATION_LOGIN_LINK;
import static org.openmetadata.service.util.email.TemplateConstants.CHANGE_EVENT_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.CHANGE_EVENT_UPDATE;
import static org.openmetadata.service.util.email.TemplateConstants.DEFAULT_EXPIRATION_TIME;
import static org.openmetadata.service.util.email.TemplateConstants.EMAIL_IGNORE_MSG;
import static org.openmetadata.service.util.email.TemplateConstants.EMAIL_VERIFICATION_LINKKEY;
import static org.openmetadata.service.util.email.TemplateConstants.EMAIL_VERIFICATION_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.EMAIL_VERIFICATION_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.ENTITY;
import static org.openmetadata.service.util.email.TemplateConstants.EXPIRATION_TIME_KEY;
import static org.openmetadata.service.util.email.TemplateConstants.INVITE_RANDOM_PASSWORD_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.INVITE_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.PASSWORD;
import static org.openmetadata.service.util.email.TemplateConstants.PASSWORD_RESET_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.REPORT_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.SUPPORT_URL;
import static org.openmetadata.service.util.email.TemplateConstants.TASK_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.TEST_EMAIL_SUBJECT;
import static org.openmetadata.service.util.email.TemplateConstants.TEST_MAIL_TEMPLATE;
import static org.openmetadata.service.util.email.TemplateConstants.USERNAME;
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP; import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP;
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTPS; import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTPS;
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP_TLS; import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP_TLS;
@ -22,6 +46,7 @@ import freemarker.template.TemplateException;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -46,46 +71,8 @@ import org.simplejavamail.mailer.MailerBuilder;
@Slf4j @Slf4j
public class EmailUtil { public class EmailUtil {
public static final String USERNAME = "userName";
public static final String ENTITY = "entity";
public static final String SUPPORT_URL = "supportUrl";
// Email Verification
private static final String EMAIL_VERIFICATION_SUBJECT =
"%s: Verify your Email Address (Action Required)";
public static final String EMAIL_VERIFICATION_LINKKEY = "userEmailTokenVerificationLink";
public static final String EMAIL_VERIFICATION_TEMPLATE = "email-verification";
// Password Reset Link
private static final String PASSWORD_RESET_SUBJECT = "%s: Reset your Password";
public static final String PASSWORD_RESET_LINKKEY = "userResetPasswordLink";
public static final String EXPIRATION_TIME_KEY = "expirationTime";
public static final String DEFAULT_EXPIRATION_TIME = "60";
public static final String PASSWORD = "password";
public static final String APPLICATION_LOGIN_LINK = "applicationLoginLink";
public static final String PASSWORD_RESET_TEMPLATE_FILE = "reset-link";
// Account Change Status
private static final String ACCOUNT_STATUS_SUBJECT = "%s: Change in Account Status";
public static final String ACTION_KEY = "action";
public static final String ACTION_STATUS_KEY = "actionStatus";
public static final String ACCOUNT_STATUS_TEMPLATE_FILE = "account-activity-change";
private static final String INVITE_SUBJECT = "Welcome to %s";
private static final String CHANGE_EVENT_UPDATE = "[%s] - Change Event Update from %s";
private static final String TASK_SUBJECT = "%s : Task Assignment Notification";
public static final String INVITE_RANDOM_PWD = "invite-randompwd";
public static final String CHANGE_EVENT_TEMPLATE = "changeEvent";
public static final String INVITE_CREATE_PWD = "invite-createPassword";
public static final String TASK_NOTIFICATION_TEMPLATE = "taskAssignment";
private static final String REPORT_SUBJECT = "%s: Data Insights Weekly - %s";
public static final String DATA_INSIGHT_REPORT_TEMPLATE = "dataInsightReport";
public static final String TEST_EMAIL_TEMPLATE = "testMail";
public static final String TEST_EMAIL_SUBJECT = "%s : Test Email";
private static SmtpSettings storedSmtpSettings;
private static Mailer mailer; private static Mailer mailer;
private static SmtpSettings storedSmtpSettings;
private static final String EMAIL_IGNORE_MSG =
"Email was not sent to {} as SMTP setting is not enabled";
private static TemplateProvider templateProvider; private static TemplateProvider templateProvider;
static { static {
@ -93,7 +80,6 @@ public class EmailUtil {
initializeTemplateProvider(); initializeTemplateProvider();
} }
// initialize template provider
private static void initializeTemplateProvider() { private static void initializeTemplateProvider() {
templateProvider = new DefaultTemplateProvider(); templateProvider = new DefaultTemplateProvider();
} }
@ -102,7 +88,7 @@ public class EmailUtil {
try { try {
getSmtpSettings(); getSmtpSettings();
initializeTemplateProvider(); initializeTemplateProvider();
LOG.info("Email Util cache is initialized"); LOG.info("Email Util Cache is initialized");
} catch (Exception ex) { } catch (Exception ex) {
LOG.warn("[MAILER] Smtp Configurations are missing : Reason {} ", ex.getMessage(), ex); LOG.warn("[MAILER] Smtp Configurations are missing : Reason {} ", ex.getMessage(), ex);
} }
@ -137,18 +123,22 @@ public class EmailUtil {
public static void sendAccountStatus(User user, String action, String status) public static void sendAccountStatus(User user, String action, String status)
throws IOException, TemplateException { throws IOException, TemplateException {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>(); Map<String, Object> templatePopulator =
templatePopulator.put(ENTITY, getEmailingEntity()); new TemplatePopulatorBuilder()
templatePopulator.put(SUPPORT_URL, getSupportUrl()); .add(ENTITY, getSmtpSettings().getEmailingEntity())
templatePopulator.put(USERNAME, user.getName()); .add(SUPPORT_URL, getSmtpSettings().getSupportUrl())
templatePopulator.put(ACTION_KEY, action); .add(USERNAME, user.getName())
templatePopulator.put(ACTION_STATUS_KEY, status); .add(ACTION_KEY, action)
.add(ACTION_STATUS_KEY, status)
.build();
sendMail( sendMail(
getAccountStatusChangeSubject(), getAccountStatusChangeSubject(),
templatePopulator, templatePopulator,
user.getEmail(), user.getEmail(),
ACCOUNT_STATUS_TEMPLATE_FILE, ACCOUNT_ACTIVITY_CHANGE_TEMPLATE,
true); true);
} else { } else {
LOG.warn(EMAIL_IGNORE_MSG, user.getEmail()); LOG.warn(EMAIL_IGNORE_MSG, user.getEmail());
@ -158,12 +148,16 @@ public class EmailUtil {
public static void sendEmailVerification(String emailVerificationLink, User user) public static void sendEmailVerification(String emailVerificationLink, User user)
throws IOException, TemplateException { throws IOException, TemplateException {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put(ENTITY, getEmailingEntity()); Map<String, Object> templatePopulator =
templatePopulator.put(SUPPORT_URL, getSupportUrl()); new TemplatePopulatorBuilder()
templatePopulator.put(USERNAME, user.getName()); .add(ENTITY, getSmtpSettings().getEmailingEntity())
templatePopulator.put(EMAIL_VERIFICATION_LINKKEY, emailVerificationLink); .add(SUPPORT_URL, getSmtpSettings().getSupportUrl())
templatePopulator.put(EXPIRATION_TIME_KEY, "24"); .add(USERNAME, user.getName())
.add(EMAIL_VERIFICATION_LINKKEY, emailVerificationLink)
.add(EXPIRATION_TIME_KEY, "24")
.build();
sendMail( sendMail(
getEmailVerificationSubject(), getEmailVerificationSubject(),
templatePopulator, templatePopulator,
@ -179,12 +173,15 @@ public class EmailUtil {
String passwordResetLink, User user, String subject, String templateFilePath) String passwordResetLink, User user, String subject, String templateFilePath)
throws IOException, TemplateException { throws IOException, TemplateException {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put(ENTITY, getEmailingEntity()); Map<String, Object> templatePopulator =
templatePopulator.put(SUPPORT_URL, getSupportUrl()); new TemplatePopulatorBuilder()
templatePopulator.put(USERNAME, user.getName()); .add(ENTITY, getSmtpSettings().getEmailingEntity())
templatePopulator.put(PASSWORD_RESET_LINKKEY, passwordResetLink); .add(SUPPORT_URL, getSmtpSettings().getSupportUrl())
templatePopulator.put(EXPIRATION_TIME_KEY, DEFAULT_EXPIRATION_TIME); .add(USERNAME, user.getName())
.add(EMAIL_VERIFICATION_LINKKEY, passwordResetLink)
.add(EXPIRATION_TIME_KEY, DEFAULT_EXPIRATION_TIME)
.build();
sendMail(subject, templatePopulator, user.getEmail(), templateFilePath, true); sendMail(subject, templatePopulator, user.getEmail(), templateFilePath, true);
} else { } else {
@ -201,15 +198,18 @@ public class EmailUtil {
String templateFilePath) String templateFilePath)
throws IOException, TemplateException { throws IOException, TemplateException {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put("assignee", assigneeName); Map<String, Object> templatePopulator =
templatePopulator.put("createdBy", thread.getCreatedBy()); new TemplatePopulatorBuilder()
templatePopulator.put("taskName", thread.getMessage()); .add("assignee", assigneeName)
templatePopulator.put("taskStatus", thread.getTask().getStatus().toString()); .add("createdBy", thread.getCreatedBy())
templatePopulator.put("taskType", thread.getTask().getType().toString()); .add("taskName", thread.getMessage())
templatePopulator.put("fieldOldValue", thread.getTask().getOldValue()); .add("taskStatus", thread.getTask().getStatus().toString())
templatePopulator.put("fieldNewValue", thread.getTask().getSuggestion()); .add("taskType", thread.getTask().getType().toString())
templatePopulator.put("taskLink", taskLink); .add("fieldOldValue", thread.getTask().getOldValue())
.add("fieldNewValue", thread.getTask().getSuggestion())
.add("taskLink", taskLink)
.build();
sendMail(subject, templatePopulator, email, templateFilePath, true); sendMail(subject, templatePopulator, email, templateFilePath, true);
} else { } else {
@ -267,20 +267,24 @@ public class EmailUtil {
} }
} }
public static void sendInviteMailToAdmin(User user, String pwd) { public static void sendInviteMailToAdmin(User user, String password) {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put(EmailUtil.ENTITY, EmailUtil.getEmailingEntity()); Map<String, Object> templatePopulator =
templatePopulator.put(EmailUtil.SUPPORT_URL, EmailUtil.getSupportUrl()); new TemplatePopulatorBuilder()
templatePopulator.put(EmailUtil.USERNAME, user.getName()); .add(ENTITY, getSmtpSettings().getEmailingEntity())
templatePopulator.put(EmailUtil.PASSWORD, pwd); .add(SUPPORT_URL, getSmtpSettings().getSupportUrl())
templatePopulator.put(EmailUtil.APPLICATION_LOGIN_LINK, EmailUtil.getOMUrl()); .add(USERNAME, user.getName())
.add(PASSWORD, password)
.add(APPLICATION_LOGIN_LINK, getSmtpSettings().getOpenMetadataUrl())
.build();
try { try {
EmailUtil.sendMail( EmailUtil.sendMail(
EmailUtil.getEmailInviteSubject(), EmailUtil.getEmailInviteSubject(),
templatePopulator, templatePopulator,
user.getEmail(), user.getEmail(),
EmailUtil.INVITE_RANDOM_PWD, INVITE_RANDOM_PASSWORD_TEMPLATE,
true); true);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error( LOG.error(
@ -294,22 +298,27 @@ public class EmailUtil {
public static void sendChangeEventMail( public static void sendChangeEventMail(
String publisherName, String receiverMail, EmailMessage emailMessaged) { String publisherName, String receiverMail, EmailMessage emailMessaged) {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put(EmailUtil.USERNAME, receiverMail.split("@")[0]);
templatePopulator.put("updatedBy", emailMessaged.getUpdatedBy());
templatePopulator.put("entityUrl", emailMessaged.getEntityUrl());
StringBuilder buff = new StringBuilder(); StringBuilder buff = new StringBuilder();
for (String cmessage : emailMessaged.getChangeMessage()) { for (String cmessage : emailMessaged.getChangeMessage()) {
buff.append(cmessage); buff.append(cmessage);
buff.append("\n"); buff.append("\n");
} }
templatePopulator.put("changeMessage", buff.toString());
Map<String, Object> templatePopulator =
new TemplatePopulatorBuilder()
.add(USERNAME, receiverMail.split("@")[0])
.add("updatedBy", emailMessaged.getUpdatedBy())
.add("entityUrl", emailMessaged.getEntityUrl())
.add("changeMessage", buff.toString())
.build();
try { try {
EmailUtil.sendMail( EmailUtil.sendMail(
EmailUtil.getChangeEventTemplate(publisherName), EmailUtil.getChangeEventTemplate(publisherName),
templatePopulator, templatePopulator,
receiverMail, receiverMail,
EmailUtil.CHANGE_EVENT_TEMPLATE, CHANGE_EVENT_TEMPLATE,
true); true);
} catch (Exception ex) { } catch (Exception ex) {
LOG.error( LOG.error(
@ -332,16 +341,21 @@ public class EmailUtil {
String templateFilePath) String templateFilePath)
throws IOException, TemplateException { throws IOException, TemplateException {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put("startDate", startDate); Map<String, Object> templatePopulator =
templatePopulator.put("endDate", endDate); new TemplatePopulatorBuilder()
templatePopulator.put("totalAssetObj", totalAssetObj); .add("startDate", startDate)
templatePopulator.put("descriptionObj", descriptionObj); .add("endDate", endDate)
templatePopulator.put("ownershipObj", ownerShipObj); .add("totalAssetObj", totalAssetObj)
templatePopulator.put("tierObj", tierObj); .add("descriptionObj", descriptionObj)
templatePopulator.put( .add("ownershipObj", ownerShipObj)
"viewReportUrl", .add("tierObj", tierObj)
String.format("%s/data-insights/data-assets", getSmtpSettings().getOpenMetadataUrl())); .add(
"viewReportUrl",
String.format(
"%s/data-insights/data-assets", getSmtpSettings().getOpenMetadataUrl()))
.build();
sendMailToMultiple(subject, templatePopulator, emails, templateFilePath); sendMailToMultiple(subject, templatePopulator, emails, templateFilePath);
} else { } else {
LOG.warn(EMAIL_IGNORE_MSG, emails.toString()); LOG.warn(EMAIL_IGNORE_MSG, emails.toString());
@ -351,11 +365,15 @@ public class EmailUtil {
public static void sendTestEmail(String email, boolean async) public static void sendTestEmail(String email, boolean async)
throws IOException, TemplateException { throws IOException, TemplateException {
if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) { if (Boolean.TRUE.equals(getSmtpSettings().getEnableSmtpServer())) {
Map<String, Object> templatePopulator = new HashMap<>();
templatePopulator.put("userName", email.split("@")[0]); Map<String, Object> templatePopulator =
templatePopulator.put("entity", getSmtpSettings().getEmailingEntity()); new TemplatePopulatorBuilder()
templatePopulator.put("supportUrl", getSmtpSettings().getSupportUrl()); .add("userName", email.split("@")[0])
sendMail(getTestEmailSubject(), templatePopulator, email, TEST_EMAIL_TEMPLATE, async); .add("entity", getSmtpSettings().getEmailingEntity())
.add("supportUrl", getSmtpSettings().getSupportUrl())
.build();
sendMail(getTestEmailSubject(), templatePopulator, email, TEST_MAIL_TEMPLATE, async);
} else { } else {
LOG.warn(EMAIL_IGNORE_MSG, email); LOG.warn(EMAIL_IGNORE_MSG, email);
} }
@ -404,18 +422,6 @@ public class EmailUtil {
new SimpleDateFormat("dd-MM-yy").format(new Date())); new SimpleDateFormat("dd-MM-yy").format(new Date()));
} }
public static String getEmailingEntity() {
return getSmtpSettings().getEmailingEntity();
}
public static String getSupportUrl() {
return getSmtpSettings().getSupportUrl();
}
public static String getOMUrl() {
return getSmtpSettings().getOpenMetadataUrl();
}
public static SmtpSettings getSmtpSettings() { public static SmtpSettings getSmtpSettings() {
SmtpSettings emailConfig = SmtpSettings emailConfig =
SettingsCache.getSetting(SettingsType.EMAIL_CONFIGURATION, SmtpSettings.class); SettingsCache.getSetting(SettingsType.EMAIL_CONFIGURATION, SmtpSettings.class);
@ -426,16 +432,27 @@ public class EmailUtil {
return emailConfig; return emailConfig;
} }
/**
* Check if given email address is valid
*
* @param email email address
* @return true if valid, false otherwise
*/
public static Boolean isValidEmail(String email) { public static Boolean isValidEmail(String email) {
if (StringUtils.isBlank(email)) { if (StringUtils.isBlank(email)) {
return false; return false;
} }
return email.matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$"); return email.matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$");
} }
static class TemplatePopulatorBuilder {
private final Map<String, Object> templatePopulator;
public TemplatePopulatorBuilder() {
this.templatePopulator = new HashMap<>();
}
public TemplatePopulatorBuilder add(String key, Object value) {
templatePopulator.put(key, value);
return this;
}
public Map<String, Object> build() {
return Collections.unmodifiableMap(templatePopulator);
}
}
} }

View File

@ -0,0 +1,46 @@
package org.openmetadata.service.util.email;
public class TemplateConstants {
public static final String USERNAME = "userName";
public static final String ENTITY = "entity";
public static final String SUPPORT_URL = "supportUrl";
// templates
public static final String ACCOUNT_ACTIVITY_CHANGE_TEMPLATE = "account-activity-change";
public static final String CHANGE_EVENT_TEMPLATE = "changeEvent";
public static final String DATA_INSIGHT_REPORT_TEMPLATE = "dataInsightReport";
public static final String EMAIL_VERIFICATION_TEMPLATE = "email-verification";
public static final String INVITE_CREATE_PASSWORD_TEMPLATE = "invite-createPassword";
public static final String INVITE_RANDOM_PASSWORD_TEMPLATE = "invite-randompwd";
public static final String RESET_LINK_TEMPLATE = "reset-link";
public static final String TASK_ASSIGNMENT_TEMPLATE = "taskAssignment";
public static final String TEST_MAIL_TEMPLATE = "testMail";
public static final String TEST_RESULT_STATUS_TEMPLATE = "testResultStatusTemplate";
// Email Verification
public static final String EMAIL_VERIFICATION_SUBJECT =
"%s: Verify your Email Address (Action Required)";
public static final String EMAIL_VERIFICATION_LINKKEY = "userEmailTokenVerificationLink";
// Password Reset Link
public static final String PASSWORD_RESET_SUBJECT = "%s: Reset your Password";
public static final String PASSWORD_RESET_LINKKEY = "userResetPasswordLink";
public static final String EXPIRATION_TIME_KEY = "expirationTime";
public static final String DEFAULT_EXPIRATION_TIME = "60";
public static final String PASSWORD = "password";
public static final String APPLICATION_LOGIN_LINK = "applicationLoginLink";
// Account Change Status
public static final String ACCOUNT_STATUS_SUBJECT = "%s: Change in Account Status";
public static final String ACTION_KEY = "action";
public static final String ACTION_STATUS_KEY = "actionStatus";
public static final String INVITE_SUBJECT = "Welcome to %s";
public static final String CHANGE_EVENT_UPDATE = "[%s] - Change Event Update from %s";
public static final String TASK_SUBJECT = "%s : Task Assignment Notification";
public static final String REPORT_SUBJECT = "%s: Data Insights Weekly - %s";
public static final String TEST_EMAIL_SUBJECT = "%s : Test Email";
public static final String EMAIL_IGNORE_MSG =
"Email was not sent to {} as SMTP setting is not enabled";
}

View File

@ -1,10 +1,7 @@
package org.openmetadata.service.util; package org.openmetadata.service.util.email;
import freemarker.template.Template; import freemarker.template.Template;
import java.io.IOException; import java.io.IOException;
import java.util.Map;
import java.util.Set;
import org.openmetadata.schema.email.EmailTemplatePlaceholder;
import org.openmetadata.schema.email.TemplateValidationResponse; import org.openmetadata.schema.email.TemplateValidationResponse;
public interface TemplateProvider { public interface TemplateProvider {
@ -18,10 +15,4 @@ public interface TemplateProvider {
* - "missingParameters" (List<String>): If validation fails, lists the placeholders that are missing. * - "missingParameters" (List<String>): If validation fails, lists the placeholders that are missing.
*/ */
TemplateValidationResponse validateEmailTemplate(String docName, String actualContent); TemplateValidationResponse validateEmailTemplate(String docName, String actualContent);
/**
* Maps each template's name to a list of
* {@link EmailTemplatePlaceholder}s extracted from the template data.
*/
Map<String, Set<EmailTemplatePlaceholder>> getDocumentPlaceHolders();
} }

View File

@ -8,7 +8,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.openmetadata.service.Entity.DOCUMENT; import static org.openmetadata.service.Entity.DOCUMENT;
import static org.openmetadata.service.Entity.PERSONA; import static org.openmetadata.service.Entity.PERSONA;
import static org.openmetadata.service.exception.CatalogExceptionMessage.permissionNotAllowed; import static org.openmetadata.service.exception.CatalogExceptionMessage.permissionNotAllowed;
import static org.openmetadata.service.util.EmailUtil.EMAIL_VERIFICATION_TEMPLATE;
import static org.openmetadata.service.util.EntityUtil.fieldUpdated; import static org.openmetadata.service.util.EntityUtil.fieldUpdated;
import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS; import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.service.util.TestUtils.TEST_AUTH_HEADERS; import static org.openmetadata.service.util.TestUtils.TEST_AUTH_HEADERS;
@ -17,6 +16,7 @@ import static org.openmetadata.service.util.TestUtils.UpdateType.MINOR_UPDATE;
import static org.openmetadata.service.util.TestUtils.assertListNotNull; import static org.openmetadata.service.util.TestUtils.assertListNotNull;
import static org.openmetadata.service.util.TestUtils.assertResponse; import static org.openmetadata.service.util.TestUtils.assertResponse;
import static org.openmetadata.service.util.TestUtils.put; import static org.openmetadata.service.util.TestUtils.put;
import static org.openmetadata.service.util.email.TemplateConstants.EMAIL_VERIFICATION_TEMPLATE;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -1,6 +1,6 @@
package org.openmetadata.service.resources.events; package org.openmetadata.service.resources.events;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.Path; import javax.ws.rs.Path;

View File

@ -1,7 +1,7 @@
package org.openmetadata.service.resources.events; package org.openmetadata.service.resources.events;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.Path; import javax.ws.rs.Path;

View File

@ -183,10 +183,10 @@ public class SystemResourceTest extends OpenMetadataApplicationTest {
// Test Email Config // Test Email Config
Settings emailSettings = getSystemConfig(SettingsType.EMAIL_CONFIGURATION); Settings emailSettings = getSystemConfig(SettingsType.EMAIL_CONFIGURATION);
SmtpSettings smtp = JsonUtils.convertValue(emailSettings.getConfigValue(), SmtpSettings.class); SmtpSettings smtp = JsonUtils.convertValue(emailSettings.getConfigValue(), SmtpSettings.class);
// Password for Email is always sent in hidden // Password for Email is encrypted using fernet
SmtpSettings expected = config.getSmtpSettings(); SmtpSettings expected = config.getSmtpSettings();
expected.setPassword("***********"); expected.setPassword(smtp.getPassword());
assertEquals(expected, smtp); assertEquals(config.getSmtpSettings(), smtp);
// Test Custom Ui Theme Preference Config // Test Custom Ui Theme Preference Config
Settings uiThemeConfigWrapped = getSystemConfig(SettingsType.CUSTOM_UI_THEME_PREFERENCE); Settings uiThemeConfigWrapped = getSystemConfig(SettingsType.CUSTOM_UI_THEME_PREFERENCE);