001/* 002 * Copyright 2014 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.socialnetworking; 017 018import java.io.IOException; 019import java.util.ArrayList; 020import java.util.HashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.regex.Pattern; 024 025import org.apache.avalon.framework.parameters.Parameters; 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.cocoon.acting.ServiceableAction; 029import org.apache.cocoon.environment.ObjectModelHelper; 030import org.apache.cocoon.environment.Redirector; 031import org.apache.cocoon.environment.Request; 032import org.apache.cocoon.environment.SourceResolver; 033import org.apache.commons.lang.StringUtils; 034 035import org.ametys.core.captcha.CaptchaHelper; 036import org.ametys.core.cocoon.ActionResultGenerator; 037import org.ametys.core.util.I18nUtils; 038import org.ametys.core.util.mail.SendMailHelper; 039import org.ametys.plugins.repository.AmetysObjectResolver; 040import org.ametys.runtime.i18n.I18nizableText; 041import org.ametys.web.repository.page.Page; 042 043import jakarta.mail.MessagingException; 044 045/** 046 * Check if the form is well formed 047 * Send the mail to all the receiver 048 */ 049public class SendMailAction extends ServiceableAction 050{ 051 /** The pattern to check emails */ 052 protected static final Pattern EMAIL_VALIDATOR = Pattern.compile("^([a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-zA-Z0-9]{2,})?$"); 053 054 /** The pattern to check a list of emails */ 055 protected static final Pattern EMAIL_LIST_VALIDATOR = Pattern.compile("^([a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,})?(\\s*,\\s*([a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-z]{2,})?)*$"); 056 057 /** The pattern to check text input */ 058 protected static final Pattern TEXT_VALIDATOR = Pattern.compile("^\\s*$"); 059 060 /** Repository content */ 061 protected AmetysObjectResolver _resolver; 062 063 /** The i18n utils of runtime */ 064 protected I18nUtils _i18nUtils; 065 066 @Override 067 public void service(ServiceManager smanager) throws ServiceException 068 { 069 super.service(smanager); 070 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 071 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 072 } 073 074 @SuppressWarnings("unchecked") 075 @Override 076 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 077 { 078 Map<String, Object> result = new HashMap<>(); 079 List<I18nizableText> errors = new ArrayList<>(); 080 Request request = ObjectModelHelper.getRequest(objectModel); 081 082 String captchaKey = request.getParameter("captcha-key"); 083 String captchaValue = request.getParameter("captcha-value"); 084 if (!CaptchaHelper.checkAndInvalidate(captchaKey, captchaValue)) 085 { 086 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_CAPTCHA")); 087 } 088 089 String pageId = _getPageId(request); 090 091 String emailBy = request.getParameter("email"); 092 if (emailBy == null || !EMAIL_VALIDATOR.matcher(StringUtils.trimToEmpty(emailBy)).matches() || TEXT_VALIDATOR.matcher(StringUtils.trimToEmpty(emailBy)).matches()) 093 { 094 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_MAILBY")); 095 } 096 else 097 { 098 result.put("emailBy", emailBy); 099 } 100 101 String emailTo = request.getParameter("emailTo"); 102 if (emailTo == null || !EMAIL_LIST_VALIDATOR.matcher(StringUtils.trimToEmpty(emailTo)).matches() || TEXT_VALIDATOR.matcher(StringUtils.trimToEmpty(emailTo)).matches()) 103 { 104 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_MAILTO")); 105 } 106 else 107 { 108 result.put("emailTo", emailTo); 109 } 110 111 String userName = request.getParameter("name"); 112 if (userName == null || TEXT_VALIDATOR.matcher(StringUtils.trimToEmpty(userName)).matches()) 113 { 114 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_NAME")); 115 } 116 else 117 { 118 result.put("name", userName); 119 } 120 121 String text = request.getParameter("text"); 122 if (text == null) 123 { 124 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_CONTENT")); 125 } 126 else 127 { 128 result.put("text", text); 129 } 130 131 if (errors.isEmpty()) 132 { 133 Page page = _resolver.resolveById(pageId); 134 String pagePath = request.getHeader("Referer"); 135 136 List<String> i18nparam = new ArrayList<>(); 137 i18nparam.add(page.getTitle()); 138 i18nparam.add(page.getSite().getTitle()); 139 140 I18nizableText i18nTextSubject = new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_SUBJECT", i18nparam); 141 String subject = _i18nUtils.translate(i18nTextSubject); 142 143 i18nparam = new ArrayList<>(); 144 i18nparam.add(userName); 145 i18nparam.add(pagePath); // Page path 146 i18nparam.add(text); 147 i18nparam.add(page.getSite().getUrl()); // Site url 148 149 I18nizableText i18nTextBody = new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_TEXT_BODY", i18nparam); 150 String textBody = _i18nUtils.translate(i18nTextBody); 151 152 i18nparam = new ArrayList<>(); 153 i18nparam.add(userName); 154 i18nparam.add(pagePath); // Page path 155 @SuppressWarnings("null") 156 String textB = text.replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", "<br/>"); 157 i18nparam.add(textB); 158 i18nparam.add(page.getSite().getUrl()); // Site url 159 160 I18nizableText i18nHtmlBody = new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_HTML_BODY", i18nparam); 161 String htmlBody = _i18nUtils.translate(i18nHtmlBody); 162 163 String[] tabMail = StringUtils.split(emailTo, ","); 164 for (int i = 0; i < tabMail.length; i++) 165 { 166 try 167 { 168 SendMailHelper.newMail() 169 .withSubject(subject) 170 .withHTMLBody(htmlBody) 171 .withTextBody(textBody) 172 .withSender(emailBy) 173 .withRecipient(StringUtils.trimToEmpty(tabMail[i])) 174 .sendMail(); 175 } 176 catch (MessagingException | IOException e) 177 { 178 if (!result.containsKey("mailError")) 179 { 180 result.put("mailError", new ArrayList<String>()); 181 } 182 183 ((List<String>) result.get("mailError")).add(tabMail[i]); 184 185 getLogger().error("Failed to send mail to '" + tabMail[i] + "'", e); 186 } 187 } 188 } 189 190 result.put("error", errors); 191 192 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result); 193 194 return EMPTY_MAP; 195 } 196 197 private String _getPageId(Request request) 198 { 199 String pageId = request.getParameter("page-id"); 200 if (pageId == null) 201 { 202 throw new IllegalStateException("Unable to send page by mail: cannot determine the current page"); 203 } 204 else 205 { 206 Page page = _resolver.resolveById(pageId); 207 if (page == null) 208 { 209 throw new IllegalStateException("Unable to send page by mail: the page of id " + pageId + " is unknown"); 210 } 211 } 212 return pageId; 213 } 214 215}