This commit is contained in:
		| @@ -1,12 +1,22 @@ | ||||
| package de.jottyfan.camporganizer.module.admin; | ||||
|  | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.validation.Valid; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.ui.Model; | ||||
| import org.springframework.validation.BindingResult; | ||||
| import org.springframework.validation.ObjectError; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.ModelAttribute; | ||||
| import org.springframework.web.bind.annotation.PostMapping; | ||||
|  | ||||
| import de.jottyfan.camporganizer.module.camplist.CommonController; | ||||
| import de.jottyfan.camporganizer.module.mail.MailBean; | ||||
|  | ||||
| /** | ||||
|  * | ||||
| @@ -16,6 +26,37 @@ import de.jottyfan.camporganizer.module.camplist.CommonController; | ||||
| @Controller | ||||
| public class AdminController extends CommonController { | ||||
|  | ||||
| 	private static final Logger LOGGER = LogManager.getLogger(AdminController.class); | ||||
|  | ||||
| 	@Autowired | ||||
| 	private AdminService service; | ||||
|  | ||||
| 	@Value("${spring.mail.username}") | ||||
| 	private String from; | ||||
|  | ||||
| 	@GetMapping("/admin/mail") | ||||
| 	public String getMail(Model model, HttpServletRequest request) { | ||||
| 		super.setupSession(model, request); | ||||
| 		MailBean mailBean = new MailBean(); | ||||
| 		mailBean.setFrom(from); | ||||
| 		mailBean.getTo().add(getCurrentEmail(request)); | ||||
| 		model.addAttribute("bean", mailBean); | ||||
| 		return "/admin/mail"; | ||||
| 	} | ||||
|  | ||||
| 	@PostMapping("/admin/mail/send") | ||||
| 	public String sendMail(@Valid @ModelAttribute("bean") MailBean bean, final BindingResult bindingResult, Model model, | ||||
| 			HttpServletRequest request) { | ||||
| 		super.setupSession(model, request); | ||||
| 		if (bindingResult.hasErrors()) { | ||||
| 			for (ObjectError error : bindingResult.getAllErrors()) | ||||
| 			LOGGER.error("error {}: {}", error.getCode(), error.getDefaultMessage()); | ||||
| 			return "/admin/mail"; | ||||
| 		} | ||||
| 		service.sendMail(bean); | ||||
| 		return "redirect:/admin"; | ||||
| 	} | ||||
|  | ||||
| 	@GetMapping("/admin") | ||||
| 	public String getMain(Model model, HttpServletRequest request) { | ||||
| 		super.setupSession(model, request); | ||||
|   | ||||
| @@ -0,0 +1,26 @@ | ||||
| package de.jottyfan.camporganizer.module.admin; | ||||
|  | ||||
| import javax.validation.Valid; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Service; | ||||
|  | ||||
| import de.jottyfan.camporganizer.module.mail.MailBean; | ||||
| import de.jottyfan.camporganizer.module.mail.MailRepository; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| @Service | ||||
| public class AdminService { | ||||
|  | ||||
| 	@Autowired | ||||
| 	private MailRepository mailRepository; | ||||
|  | ||||
| 	public void sendMail(@Valid MailBean bean) { | ||||
| 		mailRepository.sendMail(bean); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -24,6 +24,18 @@ public abstract class CommonController { | ||||
| 		return ksc == null ? null : ksc.getIdToken().getPreferredUsername(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * try to get th currnt keycloak email | ||||
| 	 * | ||||
| 	 * @param request the request | ||||
| 	 * @return the email or null | ||||
| 	 */ | ||||
| 	public String getCurrentEmail(HttpServletRequest request) { | ||||
| 		KeycloakSecurityContext ksc = (KeycloakSecurityContext) request | ||||
| 				.getAttribute(KeycloakSecurityContext.class.getName()); | ||||
| 		return ksc == null ? null : ksc.getIdToken().getEmail(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * setup the session for the template | ||||
| 	 * | ||||
|   | ||||
| @@ -12,9 +12,7 @@ import java.time.LocalDateTime; | ||||
| import java.time.format.DateTimeFormatter; | ||||
| import java.time.temporal.ChronoUnit; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| @@ -38,6 +36,7 @@ import de.jottyfan.camporganizer.db.jooq.tables.records.TCampRecord; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.TRssRecord; | ||||
| import de.jottyfan.camporganizer.module.camplist.LambdaResultWrapper; | ||||
| import de.jottyfan.camporganizer.module.mail.MailBean; | ||||
| import de.jottyfan.camporganizer.module.mail.MailRepository; | ||||
|  | ||||
| /** | ||||
| @@ -251,11 +250,13 @@ public class PersonGateway { | ||||
| 			} | ||||
| 		} | ||||
| 		if (sendMail) { | ||||
| 			Set<String> to = new HashSet<>(); | ||||
| 			to.add(email); | ||||
| 			to.add(bean.getEmail()); | ||||
| 			try { | ||||
| 				mailRepository.sendMail(to, subject, buf.toString()); // no matter if the sending works | ||||
| 				MailBean mailBean = new MailBean(); | ||||
| 				mailBean.getTo().add(email); | ||||
| 				mailBean.getTo().add(bean.getEmail()); | ||||
| 				mailBean.setSubject(subject); | ||||
| 				mailBean.setMessage(buf.toString()); | ||||
| 				mailRepository.sendMail(mailBean); // no matter if the sending works | ||||
| 			} catch (Exception e) { | ||||
| 				LOGGER.error(e.getMessage(), e); | ||||
| 			} | ||||
|   | ||||
| @@ -0,0 +1,94 @@ | ||||
| package de.jottyfan.camporganizer.module.mail; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.util.HashSet; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
|  | ||||
| import javax.validation.constraints.NotBlank; | ||||
| import javax.validation.constraints.NotEmpty; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| public class MailBean implements Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	@NotEmpty | ||||
| 	private final Set<String> to; | ||||
|  | ||||
| 	@NotBlank | ||||
| 	private String from; | ||||
| 	private String subject; | ||||
| 	private String message; | ||||
|  | ||||
| 	public MailBean() { | ||||
| 		this.to = new HashSet<>(); | ||||
| 	} | ||||
|  | ||||
| 	public String getTos() { | ||||
| 		StringBuilder buf = new StringBuilder(); | ||||
| 		boolean first = true; | ||||
| 		for (String s : to) { | ||||
| 			buf.append(first ? "" : ";").append(s); | ||||
| 			first = false; | ||||
| 		} | ||||
| 		return buf.toString(); | ||||
| 	} | ||||
|  | ||||
| 	public void setTos(String tos) { | ||||
| 		this.to.clear(); | ||||
| 		this.to.addAll(List.of(tos.split(";"))); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the from | ||||
| 	 */ | ||||
| 	public String getFrom() { | ||||
| 		return from; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param from the from to set | ||||
| 	 */ | ||||
| 	public void setFrom(String from) { | ||||
| 		this.from = from; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the subject | ||||
| 	 */ | ||||
| 	public String getSubject() { | ||||
| 		return subject; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param subject the subject to set | ||||
| 	 */ | ||||
| 	public void setSubject(String subject) { | ||||
| 		this.subject = subject; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the message | ||||
| 	 */ | ||||
| 	public String getMessage() { | ||||
| 		return message; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param message the message to set | ||||
| 	 */ | ||||
| 	public void setMessage(String message) { | ||||
| 		this.message = message; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the to | ||||
| 	 */ | ||||
| 	public Set<String> getTo() { | ||||
| 		return to; | ||||
| 	} | ||||
| } | ||||
| @@ -30,6 +30,16 @@ public class MailRepository { | ||||
| 	@Value("${spring.mail.username}") | ||||
| 	private String username; | ||||
|  | ||||
| 	/** | ||||
| 	 * Send an email with the message to the recipient. If email is blank, do | ||||
| 	 * nothing | ||||
| 	 * | ||||
| 	 * @param bean the mail | ||||
| 	 */ | ||||
| 	public void sendMail(MailBean bean) { | ||||
| 		sendMail(bean.getTo(), bean.getSubject(), bean.getMessage()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Send an email with the message to the recipient. If email is blank, do | ||||
| 	 * nothing | ||||
| @@ -38,7 +48,7 @@ public class MailRepository { | ||||
| 	 * @param subject the subject | ||||
| 	 * @param message the message | ||||
| 	 */ | ||||
| 	public void sendMail(Set<String> to, String subject, String message) { | ||||
| 	private void sendMail(Set<String> to, String subject, String message) { | ||||
| 		if (to != null && to.size() > 0) { | ||||
| 			if (username != null && !username.isBlank()) { | ||||
| 				try { | ||||
|   | ||||
							
								
								
									
										57
									
								
								src/main/resources/templates/admin/mail.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/main/resources/templates/admin/mail.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| <!DOCTYPE html> | ||||
| <html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> | ||||
| <head> | ||||
| <title>Camp Organizer Confirmation</title> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||||
| </head> | ||||
| <body> | ||||
| 	<th:block layout:fragment="header"> | ||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||
| 		</ul> | ||||
| 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||
| 			<li class="nav-item"><a th:href="@{/admin}" class="btn btn-seconary btn-icon-silent">Admin</a></li> | ||||
| 		</ul> | ||||
| 	</th:block> | ||||
| 	<th:block layout:fragment="content"> | ||||
| 		<div sec:authorize="hasRole('admin')"> | ||||
| 			<form th:action="@{/admin/mail/send}" th:object="${bean}" method="post"> | ||||
| 				<div class="card" style="max-width: 1024px; margin-left: auto; margin-right: auto"> | ||||
| 					<div class="card-header"> | ||||
| 						<span>eine Test-E-Mail verschicken</span> | ||||
| 					</div> | ||||
| 					<div class="card-body"> | ||||
| 						<div class="container"> | ||||
| 							<div class="row"> | ||||
| 								<div class="col-sm-12 col-md-3">Absender</div> | ||||
| 								<div class="col-sm-12 col-md-9"> | ||||
| 									<span th:text="${bean.from}"></span> <input type="hidden" th:field="*{from}" /> | ||||
| 								</div> | ||||
| 								<span class="error" th:each="error : ${#fields.errors('from')}">[[${error}]]<br /></span> | ||||
| 								<div class="col-sm-12 col-md-3">Empfänger</div> | ||||
| 								<div class="col-sm-12 col-md-9"> | ||||
| 									<span th:text="${bean.tos}"></span> <input type="hidden" th:field="*{tos}" /> | ||||
| 								</div> | ||||
| 								<span class="error" th:each="error : ${#fields.errors('tos')}">[[${error}]]<br /></span> | ||||
| 								<div class="col-sm-12 col-md-3">Betreff</div> | ||||
| 								<div class="col-sm-12 col-md-9"> | ||||
| 									<input type="text" th:field="*{subject}" th:class="${'form-control ' + (#fields.hasErrors('subject') ? 'inputerror' : '')}" /> | ||||
| 								</div> | ||||
| 								<span class="error" th:each="error : ${#fields.errors('subject')}">[[${error}]]<br /></span> | ||||
| 								<div class="col-sm-12 col-md-3">Nachricht</div> | ||||
| 								<div class="col-sm-12 col-md-9"> | ||||
| 									<textarea th:field="*{message}" th:class="${'form-control ' + (#fields.hasErrors('message') ? 'inputerror' : '')}" rows="5"></textarea> | ||||
| 								</div> | ||||
| 								<span class="error" th:each="error : ${#fields.errors('message')}">[[${error}]]<br /></span> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="card-footer"> | ||||
| 						<input type="submit" value="absenden" class="btn btn-outline-success from-control" /> | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</form> | ||||
| 		</div> | ||||
| 	</th:block> | ||||
| </body> | ||||
| </html> | ||||
| @@ -12,6 +12,9 @@ | ||||
| 		<ul class="navbar-nav mb-2 mb-lg-0"> | ||||
| 			<li class="nav-item"><a th:href="@{/}" class="btn btn-secondary btn-icon-silent">Hauptseite</a></li> | ||||
| 		</ul> | ||||
| 		<ul class="navbar-nav mb-2 mb-lg-0" sec:authorize="hasRole('admin')"> | ||||
| 			<li class="nav-item"><a th:href="@{/admin/mail}" class="btn btn-secondary btn-icon-silent">Testmail</a></li> | ||||
| 		</ul> | ||||
| 	</th:block> | ||||
| 	<th:block layout:fragment="content"> | ||||
| 		<div sec:authorize="hasRole('admin')"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user