refactor: 邮件配置支持配置发件人

This commit is contained in:
CaptainB 2022-04-19 16:19:13 +08:00 committed by 刘瑞斌
parent b49a8bde80
commit 04086f6b9e
7 changed files with 125 additions and 176 deletions

View File

@ -1,45 +1,39 @@
package io.metersphere.notice.sender.impl; package io.metersphere.notice.sender.impl;
import io.metersphere.base.domain.SystemParameter;
import io.metersphere.base.domain.SystemParameterExample;
import io.metersphere.base.mapper.SystemParameterMapper;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.LogUtil;
import io.metersphere.notice.domain.MessageDetail; import io.metersphere.notice.domain.MessageDetail;
import io.metersphere.notice.domain.Receiver; import io.metersphere.notice.domain.Receiver;
import io.metersphere.notice.domain.UserDetail; import io.metersphere.notice.domain.UserDetail;
import io.metersphere.notice.sender.AbstractNoticeSender; import io.metersphere.notice.sender.AbstractNoticeSender;
import io.metersphere.notice.sender.NoticeModel; import io.metersphere.notice.sender.NoticeModel;
import io.metersphere.notice.service.MailService;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.mail.MessagingException; import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
public class MailNoticeSender extends AbstractNoticeSender { public class MailNoticeSender extends AbstractNoticeSender {
@Resource @Resource
private MailService mailService; private SystemParameterMapper systemParameterMapper;
public void sendMail(String context, NoticeModel noticeModel) throws Exception {
public void sendMail(String context, NoticeModel noticeModel) throws MessagingException {
LogUtil.debug("发送邮件开始 ");
JavaMailSenderImpl javaMailSender = mailService.getMailSender();
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//helper.setFrom(javaMailSender.getUsername());
if (javaMailSender.getUsername().contains("@")) {
helper.setFrom(javaMailSender.getUsername());
} else {
String mailHost = javaMailSender.getHost();
String domainName = mailHost.substring(mailHost.indexOf(".") + 1, mailHost.length());
helper.setFrom(javaMailSender.getUsername() + "@" + domainName);
}
LogUtil.debug("发件人地址" + javaMailSender.getUsername());
LogUtil.debug("helper" + helper);
helper.setSubject("MeterSphere " + noticeModel.getSubject());
List<String> userIds = noticeModel.getReceivers().stream() List<String> userIds = noticeModel.getReceivers().stream()
.map(Receiver::getUserId) .map(Receiver::getUserId)
.distinct() .distinct()
@ -53,27 +47,67 @@ public class MailNoticeSender extends AbstractNoticeSender {
.distinct() .distinct()
.toArray(String[]::new); .toArray(String[]::new);
LogUtil.info("收件人地址: {}", userIds); send(noticeModel.getSubject(), context, users, new String[0]);
}
private void send(String subject, String context, String[] users, String[] cc) throws Exception {
LogUtil.debug("发送邮件开始 ");
SystemParameterExample example = new SystemParameterExample();
example.createCriteria().andParamKeyLike(ParamConstants.Classify.MAIL.getValue() + "%");
List<SystemParameter> paramList = systemParameterMapper.selectByExample(example);
Map<String, String> paramMap = paramList.stream().collect(Collectors.toMap(SystemParameter::getParamKey, p -> {
if (StringUtils.equals(p.getParamKey(), ParamConstants.MAIL.PASSWORD.getValue())) {
return EncryptUtils.aesDecrypt(p.getParamValue()).toString();
}
if (StringUtils.isEmpty(p.getParamValue())) {
return "";
} else {
return p.getParamValue();
}
}));
JavaMailSenderImpl javaMailSender = getMailSender(paramMap);
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
String username = javaMailSender.getUsername();
String email;
if (username.contains("@")) {
email = username;
} else {
String mailHost = javaMailSender.getHost();
String domainName = mailHost.substring(mailHost.indexOf(".") + 1);
email = username + "@" + domainName;
}
InternetAddress from = new InternetAddress();
String smtpFrom = paramMap.get(ParamConstants.MAIL.FROM.getValue());
if (StringUtils.isBlank(smtpFrom)) {
from.setAddress(email);
from.setPersonal(username);
} else {
// 指定发件人后address 应该是邮件服务器验证过的发件人
if (smtpFrom.contains("@")) {
from.setAddress(smtpFrom);
} else {
from.setAddress(email);
}
from.setPersonal(smtpFrom);
}
helper.setFrom(from);
LogUtil.debug("发件人地址" + javaMailSender.getUsername());
LogUtil.debug("helper" + helper);
helper.setSubject("MeterSphere " + subject);
LogUtil.info("收件人地址: {}", users);
helper.setText(context, true); helper.setText(context, true);
helper.setTo(users); helper.setTo(users);
if (cc != null && cc.length > 0) {
helper.setCc(cc);
}
javaMailSender.send(mimeMessage); javaMailSender.send(mimeMessage);
} }
public void sendExternalMail(String context, NoticeModel noticeModel) throws MessagingException { public void sendExternalMail(String context, NoticeModel noticeModel) throws Exception {
LogUtil.debug("发送邮件开始 ");
JavaMailSenderImpl javaMailSender = mailService.getMailSender();
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
if (javaMailSender.getUsername().contains("@")) {
helper.setFrom(javaMailSender.getUsername());
} else {
String mailHost = javaMailSender.getHost();
String domainName = mailHost.substring(mailHost.indexOf(".") + 1, mailHost.length());
helper.setFrom(javaMailSender.getUsername() + "@" + domainName);
}
LogUtil.debug("发件人地址" + javaMailSender.getUsername());
LogUtil.debug("helper" + helper);
helper.setSubject(noticeModel.getSubject());
List<String> userIds = noticeModel.getReceivers().stream() List<String> userIds = noticeModel.getReceivers().stream()
.map(Receiver::getUserId) .map(Receiver::getUserId)
.distinct() .distinct()
@ -83,7 +117,7 @@ public class MailNoticeSender extends AbstractNoticeSender {
} }
List<String> recipients = new ArrayList<>(); List<String> recipients = new ArrayList<>();
if(CollectionUtils.isNotEmpty(noticeModel.getRecipients())){ if (CollectionUtils.isNotEmpty(noticeModel.getRecipients())) {
recipients = noticeModel.getRecipients().stream() recipients = noticeModel.getRecipients().stream()
.map(Receiver::getUserId) .map(Receiver::getUserId)
.distinct() .distinct()
@ -93,19 +127,14 @@ public class MailNoticeSender extends AbstractNoticeSender {
String[] users = userIds.stream() String[] users = userIds.stream()
.distinct() .distinct()
.toArray(String[]::new); .toArray(String[]::new);
String[] ccArr = new String[0];
LogUtil.info("收件人地址: {}", userIds); if (CollectionUtils.isNotEmpty(recipients)) {
helper.setText(context, true); ccArr = recipients.stream()
helper.setTo(users);
if(CollectionUtils.isNotEmpty(recipients)){
String[] ccArr = recipients.stream()
.distinct() .distinct()
.toArray(String[]::new); .toArray(String[]::new);
helper.setCc(ccArr);
} }
javaMailSender.send(mimeMessage); send(noticeModel.getSubject(), context, users, ccArr);
} }
@Override @Override
@ -118,4 +147,33 @@ public class MailNoticeSender extends AbstractNoticeSender {
LogUtil.error(e); LogUtil.error(e);
} }
} }
public JavaMailSenderImpl getMailSender(Map<String, String> paramMap) {
Properties props = new Properties();
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setDefaultEncoding("UTF-8");
javaMailSender.setProtocol("smtp");
javaMailSender.setHost(paramMap.get(ParamConstants.MAIL.SERVER.getValue()));
javaMailSender.setPort(Integer.parseInt(paramMap.get(ParamConstants.MAIL.PORT.getValue())));
javaMailSender.setUsername(paramMap.get(ParamConstants.MAIL.ACCOUNT.getValue()));
javaMailSender.setPassword(paramMap.get(ParamConstants.MAIL.PASSWORD.getValue()));
if (BooleanUtils.toBoolean(paramMap.get(ParamConstants.MAIL.SSL.getValue()))) {
javaMailSender.setProtocol("smtps");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
if (BooleanUtils.toBoolean(paramMap.get(ParamConstants.MAIL.TLS.getValue()))) {
String result = BooleanUtils.toString(BooleanUtils.toBoolean(paramMap.get(ParamConstants.MAIL.TLS.getValue())), "true", "false");
props.put("mail.smtp.starttls.enable", result);
props.put("mail.smtp.starttls.required", result);
}
props.put("mail.smtp.ssl.trust", javaMailSender.getHost());
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.timeout", "30000");
props.put("mail.smtp.connectiontimeout", "5000");
javaMailSender.setJavaMailProperties(props);
return javaMailSender;
}
} }

View File

@ -1,81 +0,0 @@
package io.metersphere.notice.service;
import io.metersphere.base.domain.SystemParameter;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.service.SystemParameterService;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;
@Service
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public class MailService {
@Resource
private SystemParameterService systemParameterService;
public JavaMailSenderImpl getMailSender() {
Properties props = new Properties();
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
List<SystemParameter> paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue());
javaMailSender.setDefaultEncoding("UTF-8");
javaMailSender.setProtocol("smtp");
props.put("mail.smtp.auth", "true");
String smtpHost = "";
for (SystemParameter p : paramList) {
switch (p.getParamKey()) {
case "smtp.host":
javaMailSender.setHost(p.getParamValue());
smtpHost = p.getParamValue();
break;
case "smtp.port":
javaMailSender.setPort(Integer.parseInt(p.getParamValue()));
break;
case "smtp.account":
javaMailSender.setUsername(p.getParamValue());
break;
case "smtp.password":
javaMailSender.setPassword(EncryptUtils.aesDecrypt(p.getParamValue()).toString());
break;
case "smtp.ssl":
if (BooleanUtils.toBoolean(p.getParamValue())) {
javaMailSender.setProtocol("smtps");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
break;
case "smtp.tls":
String result = BooleanUtils.toString(BooleanUtils.toBoolean(p.getParamValue()), "true", "false");
props.put("mail.smtp.starttls.enable", result);
props.put("mail.smtp.starttls.required", result);
props.put("mail.smtp.ssl.trust", smtpHost);
break;
/* case "smtp.anon":
boolean isAnon = BooleanUtils.toBoolean(p.getParamValue());
if (isAnon) {
props.put("mail.smtp.auth", "false");
javaMailSender.setUsername(null);
javaMailSender.setPassword(null);
}
break;*/
default:
break;
}
}
props.put("mail.smtp.timeout", "30000");
props.put("mail.smtp.connectiontimeout", "5000");
javaMailSender.setJavaMailProperties(props);
return javaMailSender;
}
}

View File

@ -22,21 +22,20 @@ import io.metersphere.log.vo.DetailColumn;
import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.OperatingLogDetails;
import io.metersphere.log.vo.system.SystemReference; import io.metersphere.log.vo.system.SystemReference;
import io.metersphere.notice.domain.MailInfo; import io.metersphere.notice.domain.MailInfo;
import io.metersphere.notice.domain.Receiver;
import io.metersphere.notice.sender.NoticeModel;
import io.metersphere.notice.sender.impl.MailNoticeSender;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress; import java.util.Arrays;
import javax.mail.internet.MimeMessage;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Properties;
import java.util.UUID; import java.util.UUID;
@ -53,6 +52,8 @@ public class SystemParameterService {
private SystemHeaderMapper systemHeaderMapper; private SystemHeaderMapper systemHeaderMapper;
@Resource @Resource
private ApiTestEnvironmentService apiTestEnvironmentService; private ApiTestEnvironmentService apiTestEnvironmentService;
@Resource
private MailNoticeSender mailNoticeSender;
public String searchEmail() { public String searchEmail() {
return extSystemParameterMapper.email(); return extSystemParameterMapper.email();
@ -102,62 +103,27 @@ public class SystemParameterService {
} }
public void testConnection(HashMap<String, String> hashMap) { public void testConnection(HashMap<String, String> hashMap) {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); JavaMailSenderImpl javaMailSender = mailNoticeSender.getMailSender(hashMap);
javaMailSender.setDefaultEncoding("UTF-8");
javaMailSender.setHost(hashMap.get(ParamConstants.MAIL.SERVER.getValue()));
javaMailSender.setPort(Integer.parseInt(hashMap.get(ParamConstants.MAIL.PORT.getValue())));
javaMailSender.setUsername(hashMap.get(ParamConstants.MAIL.ACCOUNT.getValue()));
javaMailSender.setPassword(hashMap.get(ParamConstants.MAIL.PASSWORD.getValue()));
Properties props = new Properties();
String recipients = hashMap.get(ParamConstants.MAIL.RECIPIENTS.getValue());
if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.SSL.getValue()))) {
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.TLS.getValue()))) {
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.trust", hashMap.get(ParamConstants.MAIL.SERVER.getValue()));
}
props.put("mail.smtp.timeout", "30000");
props.put("mail.smtp.connectiontimeout", "5000");
javaMailSender.setJavaMailProperties(props);
try { try {
javaMailSender.testConnection(); javaMailSender.testConnection();
} catch (MessagingException e) { } catch (MessagingException e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e.getMessage(), e);
MSException.throwException(Translator.get("connection_failed")); MSException.throwException(Translator.get("connection_failed"));
} }
String recipients = hashMap.get(ParamConstants.MAIL.RECIPIENTS.getValue());
if (!StringUtils.isBlank(recipients)) { if (!StringUtils.isBlank(recipients)) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage(); NoticeModel noticeModel = NoticeModel.builder()
MimeMessageHelper helper = null; .subject("MeterSphere测试邮件")
.receivers(Arrays.asList(new Receiver(recipients, recipients)))
.build();
try { try {
helper = new MimeMessageHelper(mimeMessage, true); mailNoticeSender.sendExternalMail("这是一封测试邮件,邮件发送成功", noticeModel);
String username = javaMailSender.getUsername();
String email;
if (username.contains("@")) {
email = username;
} else {
String mailHost = javaMailSender.getHost();
String domainName = mailHost.substring(mailHost.indexOf(".") + 1);
email = username + "@" + domainName;
}
InternetAddress from = new InternetAddress();
from.setAddress(email);
from.setPersonal(hashMap.getOrDefault(ParamConstants.MAIL.FROM.getValue(), username));
helper.setFrom(from);
helper.setSubject("MeterSphere测试邮件 ");
helper.setText("这是一封测试邮件,邮件发送成功", true);
helper.setTo(recipients);
javaMailSender.send(mimeMessage);
} catch (Exception e) { } catch (Exception e) {
LogUtil.error(e.getMessage(), e); LogUtil.error(e);
MSException.throwException(Translator.get("connection_failed")); MSException.throwException(Translator.get("connection_failed"));
} }
} }
} }
public String getVersion() { public String getVersion() {

View File

@ -38,7 +38,10 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col> <el-col>
<el-form-item :label="$t('system_parameter_setting.SMTP_from')" prop="from"> <el-form-item prop="from">
<template v-slot:label>
{{ $t('system_parameter_setting.SMTP_from') }} <i style="font-size: 10px;">{{$t('system_parameter_setting.from_tip')}}</i>
</template>
<el-input v-model="formInline.from" :placeholder="$t('system_parameter_setting.SMTP_from')" <el-input v-model="formInline.from" :placeholder="$t('system_parameter_setting.SMTP_from')"
type="text" v-on:input="change()"> type="text" v-on:input="change()">
</el-input> </el-input>

View File

@ -2467,6 +2467,7 @@ export default {
account: 'Account cannot be empty', account: 'Account cannot be empty',
test_recipients: 'Test recipients', test_recipients: 'Test recipients',
tip: 'Tip: use as test mail recipient only', tip: 'Tip: use as test mail recipient only',
from_tip: 'Note: It must be the mailbox verified by the mail server, otherwise it is sent by SMTP account by default'
}, },
i18n: { i18n: {
home: 'Home', home: 'Home',

View File

@ -2471,6 +2471,7 @@ export default {
account: '账户不能为空', account: '账户不能为空',
test_recipients: '测试收件人', test_recipients: '测试收件人',
tip: '提示:仅用来作为测试邮件收件人', tip: '提示:仅用来作为测试邮件收件人',
from_tip: '注必须是邮件服务器验证通过的邮箱否则默认为SMTP账户发送'
}, },
i18n: { i18n: {
home: '首页', home: '首页',

View File

@ -2470,6 +2470,7 @@ export default {
account: '賬戶不能為空', account: '賬戶不能為空',
test_recipients: '測試收件人', test_recipients: '測試收件人',
tip: '提示:僅用來作為測試郵件收件人', tip: '提示:僅用來作為測試郵件收件人',
from_tip: '注必須是郵件服務器驗證通過的郵箱否則默認為SMTP賬戶發送'
}, },
i18n: { i18n: {
home: '首頁', home: '首頁',