Finish mail settings management api

This commit is contained in:
2023-12-05 18:18:05 +08:00
parent 00964a15f3
commit 26c915eefe
14 changed files with 287 additions and 70 deletions

View File

@@ -2,11 +2,14 @@ package top.fatweb.api.controller.system
import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag import io.swagger.v3.oas.annotations.tags.Tag
import jakarta.validation.Valid
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
import top.fatweb.api.entity.common.ResponseResult import top.fatweb.api.entity.common.ResponseResult
import top.fatweb.api.param.system.MailSendParam
import top.fatweb.api.param.system.MailSettingsParam import top.fatweb.api.param.system.MailSettingsParam
import top.fatweb.api.service.system.ISettingsService import top.fatweb.api.service.system.ISettingsService
import top.fatweb.api.vo.system.SettingsVo import top.fatweb.api.vo.system.MailSettingsVo
/** /**
* System settings controller * System settings controller
@@ -22,17 +25,18 @@ class SettingsController(
private val settingsService: ISettingsService private val settingsService: ISettingsService
) { ) {
/** /**
* Get all settings * Get mail settings
* *
* @return Response object includes all settings * @return Response object includes mail settings
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
* @see ResponseResult * @see ResponseResult
* @see SettingsVo * @see MailSettingsVo
*/ */
@Operation(summary = "获取全部设置") @Operation(summary = "获取邮件设置")
@GetMapping @GetMapping("/mail")
fun get(): ResponseResult<SettingsVo> = ResponseResult.success(data = settingsService.get()) @PreAuthorize("hasAnyAuthority('system:settings:query:mail')")
fun getMail(): ResponseResult<MailSettingsVo> = ResponseResult.success(data = settingsService.getMail())
/** /**
* Update mail settings * Update mail settings
@@ -46,8 +50,23 @@ class SettingsController(
*/ */
@Operation(summary = "更新邮件设置") @Operation(summary = "更新邮件设置")
@PutMapping("/mail") @PutMapping("/mail")
@PreAuthorize("hasAnyAuthority('system:settings:modify:mail')")
fun updateMail(@RequestBody mailSettingsParam: MailSettingsParam): ResponseResult<Nothing> { fun updateMail(@RequestBody mailSettingsParam: MailSettingsParam): ResponseResult<Nothing> {
settingsService.updateMail(mailSettingsParam) settingsService.updateMail(mailSettingsParam)
return ResponseResult.success() return ResponseResult.success()
} }
/**
* Send mail test
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Operation(summary = "邮件发送测试")
@PostMapping("/mail")
@PreAuthorize("hasAnyAuthority('system:settings:modify:mail')")
fun sendMail(@RequestBody @Valid mailSendParam: MailSendParam): ResponseResult<Nothing> {
settingsService.sendMail(mailSendParam)
return ResponseResult.success()
}
} }

View File

@@ -2,6 +2,7 @@ package top.fatweb.api.converter.system
import top.fatweb.api.settings.MailSettings import top.fatweb.api.settings.MailSettings
import top.fatweb.api.settings.SystemSettings import top.fatweb.api.settings.SystemSettings
import top.fatweb.api.vo.system.MailSettingsVo
import top.fatweb.api.vo.system.SettingsVo import top.fatweb.api.vo.system.SettingsVo
/** /**
@@ -19,14 +20,16 @@ object SettingsConverter {
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
* @see MailSettings * @see MailSettings
* @see SettingsVo.MailSettingsVo * @see MailSettingsVo
*/ */
private fun mailSettingsToMailSettingsVo(mailSettings: MailSettings) = SettingsVo.MailSettingsVo( fun mailSettingsToMailSettingsVo(mailSettings: MailSettings) = MailSettingsVo(
host = mailSettings.host, host = mailSettings.host,
port = mailSettings.port, port = mailSettings.port,
securityType = mailSettings.securityType,
username = mailSettings.username, username = mailSettings.username,
password = mailSettings.password, password = mailSettings.password,
from = mailSettings.from from = mailSettings.from,
fromName = mailSettings.fromName
) )
/** /**

View File

@@ -0,0 +1,23 @@
package top.fatweb.api.param.system
import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
/**
* Mail send parameters
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Schema(description = "邮件发送请求参数")
data class MailSendParam(
/**
* Receiver
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Schema(description = "接收者")
@field:NotBlank
val to: String?
)

View File

@@ -1,6 +1,7 @@
package top.fatweb.api.param.system package top.fatweb.api.param.system
import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.media.Schema
import top.fatweb.api.settings.MailSecurityType
/** /**
* Mail settings parameters * Mail settings parameters
@@ -28,6 +29,15 @@ data class MailSettingsParam(
@Schema(description = "端口号") @Schema(description = "端口号")
val port: Int?, val port: Int?,
/**
* Security type
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Schema(description = "安全类型", allowableValues = ["None", "SSL/TLS", "StartTls"], defaultValue = "None")
val securityType: MailSecurityType? = MailSecurityType.NONE,
/** /**
* Username * Username
* *
@@ -53,5 +63,14 @@ data class MailSettingsParam(
* @since 1.0.0 * @since 1.0.0
*/ */
@Schema(description = "发送者") @Schema(description = "发送者")
val from: String? val from: String?,
/**
* Sender name
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
@Schema(description = "发送者名称")
val fromName: String?
) )

View File

@@ -15,6 +15,14 @@ import java.time.ZonedDateTime
@Component @Component
@ConfigurationProperties("app") @ConfigurationProperties("app")
object ServerProperties { object ServerProperties {
/**
* App name
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
lateinit var appName: String
/** /**
* Version * Version
* *

View File

@@ -1,7 +1,8 @@
package top.fatweb.api.service.system package top.fatweb.api.service.system
import top.fatweb.api.param.system.MailSendParam
import top.fatweb.api.param.system.MailSettingsParam import top.fatweb.api.param.system.MailSettingsParam
import top.fatweb.api.vo.system.SettingsVo import top.fatweb.api.vo.system.MailSettingsVo
/** /**
* Settings service interface * Settings service interface
@@ -11,21 +12,32 @@ import top.fatweb.api.vo.system.SettingsVo
*/ */
interface ISettingsService { interface ISettingsService {
/** /**
* Get all settings * Get mail settings
* *
* @return SettingVo object * @return MailSettingVo object
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
* @see SettingsVo * @see MailSettingsVo
*/ */
fun get(): SettingsVo fun getMail(): MailSettingsVo?
/** /**
* Update mail settings * Update mail settings
* *
* @param mailSettingsParam Mail settings parameters
* @author FatttSnake, fatttsnake@gmail.com * @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0 * @since 1.0.0
* @see MailSettingsParam * @see MailSettingsParam
*/ */
fun updateMail(mailSettingsParam: MailSettingsParam) fun updateMail(mailSettingsParam: MailSettingsParam)
/**
* Send mail
*
* @param mailSendParam Send mail parameters
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
* @see MailSettingsParam
*/
fun sendMail(mailSendParam: MailSendParam)
} }

View File

@@ -2,11 +2,14 @@ package top.fatweb.api.service.system.impl
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import top.fatweb.api.converter.system.SettingsConverter import top.fatweb.api.converter.system.SettingsConverter
import top.fatweb.api.param.system.MailSendParam
import top.fatweb.api.param.system.MailSettingsParam import top.fatweb.api.param.system.MailSettingsParam
import top.fatweb.api.properties.ServerProperties
import top.fatweb.api.service.system.ISettingsService import top.fatweb.api.service.system.ISettingsService
import top.fatweb.api.settings.MailSettings import top.fatweb.api.settings.MailSettings
import top.fatweb.api.settings.SettingsOperator import top.fatweb.api.settings.SettingsOperator
import top.fatweb.api.vo.system.SettingsVo import top.fatweb.api.util.MailUtil
import top.fatweb.api.vo.system.MailSettingsVo
/** /**
* Settings service implement * Settings service implement
@@ -17,15 +20,33 @@ import top.fatweb.api.vo.system.SettingsVo
*/ */
@Service @Service
class SettingsServiceImpl : ISettingsService { class SettingsServiceImpl : ISettingsService {
override fun get(): SettingsVo = SettingsConverter.systemSettingsToSettingsVo(SettingsOperator.settings()) override fun getMail(): MailSettingsVo? = SettingsOperator.settings().mail?.let {
SettingsConverter.mailSettingsToMailSettingsVo(
it
)
}
override fun updateMail(mailSettingsParam: MailSettingsParam) { override fun updateMail(mailSettingsParam: MailSettingsParam) {
mailSettingsParam.apply { mailSettingsParam.apply {
SettingsOperator.setMailValue(MailSettings::host, host) SettingsOperator.setMailValue(MailSettings::host, host)
SettingsOperator.setMailValue(MailSettings::port, port) SettingsOperator.setMailValue(MailSettings::port, port)
SettingsOperator.setMailValue(MailSettings::securityType, securityType)
SettingsOperator.setMailValue(MailSettings::username, username) SettingsOperator.setMailValue(MailSettings::username, username)
SettingsOperator.setMailValue(MailSettings::password, password) SettingsOperator.setMailValue(MailSettings::password, password)
SettingsOperator.setMailValue(MailSettings::from, from) SettingsOperator.setMailValue(MailSettings::from, from)
SettingsOperator.setMailValue(MailSettings::fromName, fromName)
}
MailUtil.init()
}
override fun sendMail(mailSendParam: MailSendParam) {
mailSendParam.to?.let {
MailUtil.sendSimpleMail(
"${ServerProperties.appName} Test Message",
"This is a test email sent when testing the system email sending service.",
it
)
} }
} }
} }

View File

@@ -0,0 +1,25 @@
package top.fatweb.api.settings
import com.fasterxml.jackson.annotation.JsonCreator
import com.fasterxml.jackson.annotation.JsonValue
enum class MailSecurityType(val code: String) {
NONE("None"),
SSL_TLS("SSL/TLS"),
START_TLS("StartTls");
@JsonCreator
fun fromCode(code: String): MailSecurityType? {
values().forEach {
if (it.code == code) {
return it
}
}
return null
}
@JsonValue
override fun toString(): String {
return code
}
}

View File

@@ -26,6 +26,14 @@ data class MailSettings(
*/ */
var port: Int? = null, var port: Int? = null,
/**
* Security type
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
var securityType: MailSecurityType? = MailSecurityType.NONE,
/** /**
* Username * Username
* *
@@ -49,4 +57,12 @@ data class MailSettings(
* @since 1.0.0 * @since 1.0.0
*/ */
var from: String? = null, var from: String? = null,
/**
* Sender name
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
var fromName: String? = null
) )

View File

@@ -0,0 +1,47 @@
package top.fatweb.api.util
import org.springframework.mail.MailSender
import org.springframework.mail.SimpleMailMessage
import org.springframework.mail.javamail.JavaMailSenderImpl
import top.fatweb.api.settings.MailSecurityType
import top.fatweb.api.settings.MailSettings
import top.fatweb.api.settings.SettingsOperator
import java.util.*
object MailUtil {
private val mailSender: JavaMailSenderImpl = JavaMailSenderImpl()
init {
init()
}
fun init() {
mailSender.defaultEncoding = Charsets.UTF_8.name()
mailSender.protocol = "smtp"
mailSender.host = SettingsOperator.getMailValue(MailSettings::host)
SettingsOperator.getMailValue(MailSettings::port)?.let { mailSender.port = it }
mailSender.username = SettingsOperator.getMailValue(MailSettings::username)
mailSender.password = SettingsOperator.getMailValue(MailSettings::password)
val properties = Properties()
when (SettingsOperator.getMailValue(MailSettings::securityType)) {
MailSecurityType.SSL_TLS -> properties.setProperty("mail.smtp.ssl.enable", "true")
MailSecurityType.START_TLS -> properties.setProperty("mail.smtp.starttls.enable", "true")
else -> {}
}
properties["mail.smtp.timeout"] = "10000"
mailSender.javaMailProperties = properties
}
fun getSender(): MailSender = mailSender
fun sendSimpleMail(subject: String, text: String, vararg to: String) {
mailSender.send(SimpleMailMessage().apply {
setSubject(subject)
from = "${SettingsOperator.getMailValue(MailSettings::fromName)}<${SettingsOperator.getMailValue(MailSettings::from)}>"
sentDate = Date()
setTo(*to)
setText(text)
})
}
}

View File

@@ -0,0 +1,67 @@
package top.fatweb.api.vo.system
import top.fatweb.api.settings.MailSecurityType
/**
* Mail settings value object
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
data class MailSettingsVo(
/**
* Host
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val host: String?,
/**
* Port
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val port: Int?,
/**
* Security type
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val securityType: MailSecurityType?,
/**
* Username
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val username: String?,
/**
* Password
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val password: String?,
/**
* Sender
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val from: String?,
/**
* Sender name
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val fromName: String?
)

View File

@@ -15,52 +15,4 @@ data class SettingsVo(
* @see MailSettingsVo * @see MailSettingsVo
*/ */
val mail: MailSettingsVo? val mail: MailSettingsVo?
) { )
/**
* Mail settings value object
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
data class MailSettingsVo(
/**
* Host
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val host: String?,
/**
* Port
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val port: Int?,
/**
* Username
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val username: String?,
/**
* Password
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val password: String?,
/**
* Sender
*
* @author FatttSnake, fatttsnake@gmail.com
* @since 1.0.0
*/
val from: String?
)
}

View File

@@ -1,4 +1,5 @@
app: app:
app-name: FatWeb
version: @project.version@ version: @project.version@
build-time: @build.timestamp@ build-time: @build.timestamp@

View File

@@ -54,7 +54,9 @@ insert into t_power (id, type_id)
(1030402, 4), (1030402, 4),
(1040103, 4), (1040103, 4),
(1050101, 4), (1050101, 4),
(1050301, 4) (1050102, 4),
(1050301, 4),
(1050302, 4)
as new_value as new_value
on duplicate key update type_id = new_value.type_id; on duplicate key update type_id = new_value.type_id;
@@ -122,8 +124,10 @@ insert into t_operation(id, name, code, func_id)
(1030402, '多个', 'system:group:delete:multiple', 1030400), (1030402, '多个', 'system:group:delete:multiple', 1030400),
(1040103, '列表', 'system:power:query:list', 1040100), (1040103, '列表', 'system:power:query:list', 1040100),
(1510101, '列表', 'system:log:query:all', 1510100), (1510101, '列表', 'system:log:query:all', 1510100),
(1520101, '全部', 'system:settings:query:all', 1520100), (1520101, '基础', 'system:settings:query:base', 1520100),
(1520301, '全部', 'system:settings:modify:all', 1520300) as new_value (1520102, '邮件', 'system:settings:query:mail', 1520100),
(1520301, '基础', 'system:settings:modify:base', 1520300),
(1520302, '邮件', 'system:settings:modify:mail', 1520300) as new_value
on duplicate key update name=new_value.name, on duplicate key update name=new_value.name,
code=new_value.code, code=new_value.code,
func_id=new_value.func_id; func_id=new_value.func_id;