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.cache.PageHelper; 042import org.ametys.web.repository.page.Page; 043 044import jakarta.mail.MessagingException; 045 046/** 047 * Check if the form is well formed 048 * Send the mail to all the receiver 049 */ 050public class SendMailAction extends ServiceableAction 051{ 052 /** The pattern to check emails */ 053 protected static final Pattern EMAIL_VALIDATOR = Pattern.compile("^([a-z0-9._-]+@[a-z0-9.-]{2,}[.][a-zA-Z0-9]{2,})?$"); 054 055 /** The pattern to check a list of emails */ 056 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,})?)*$"); 057 058 /** The pattern to check text input */ 059 protected static final Pattern TEXT_VALIDATOR = Pattern.compile("^\\s*$"); 060 061 /** Repository content */ 062 protected AmetysObjectResolver _resolver; 063 064 /** The i18n utils of runtime */ 065 protected I18nUtils _i18nUtils; 066 067 /** The page helper */ 068 protected PageHelper _pageHelper; 069 070 @Override 071 public void service(ServiceManager smanager) throws ServiceException 072 { 073 super.service(smanager); 074 _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE); 075 _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE); 076 _pageHelper = (PageHelper) smanager.lookup(PageHelper.ROLE); 077 } 078 079 @SuppressWarnings("unchecked") 080 @Override 081 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 082 { 083 Map<String, Object> result = new HashMap<>(); 084 List<I18nizableText> errors = new ArrayList<>(); 085 Request request = ObjectModelHelper.getRequest(objectModel); 086 087 String pageId = _getPageId(request); 088 Page page = _resolver.resolveById(pageId); 089 090 if (_pageHelper.isCaptchaRequired(page)) 091 { 092 String captchaKey = request.getParameter("captcha-key"); 093 String captchaValue = request.getParameter("captcha-value"); 094 if (!CaptchaHelper.checkAndInvalidate(captchaKey, captchaValue)) 095 { 096 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_CAPTCHA")); 097 } 098 } 099 100 String emailBy = request.getParameter("email"); 101 if (emailBy == null || !EMAIL_VALIDATOR.matcher(StringUtils.trimToEmpty(emailBy)).matches() || TEXT_VALIDATOR.matcher(StringUtils.trimToEmpty(emailBy)).matches()) 102 { 103 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_MAILBY")); 104 } 105 else 106 { 107 result.put("emailBy", emailBy); 108 } 109 110 String emailTo = request.getParameter("emailTo"); 111 if (emailTo == null || !EMAIL_LIST_VALIDATOR.matcher(StringUtils.trimToEmpty(emailTo)).matches() || TEXT_VALIDATOR.matcher(StringUtils.trimToEmpty(emailTo)).matches()) 112 { 113 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_MAILTO")); 114 } 115 else 116 { 117 result.put("emailTo", emailTo); 118 } 119 120 String userName = request.getParameter("name"); 121 if (userName == null || TEXT_VALIDATOR.matcher(StringUtils.trimToEmpty(userName)).matches()) 122 { 123 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_NAME")); 124 } 125 else 126 { 127 result.put("name", userName); 128 } 129 130 String text = request.getParameter("text"); 131 if (text == null) 132 { 133 errors.add(new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_ERROR_CONTENT")); 134 } 135 else 136 { 137 result.put("text", text); 138 } 139 140 if (errors.isEmpty()) 141 { 142 String pagePath = request.getHeader("Referer"); 143 144 List<String> i18nparam = new ArrayList<>(); 145 i18nparam.add(page.getTitle()); 146 i18nparam.add(page.getSite().getTitle()); 147 148 I18nizableText i18nTextSubject = new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_SUBJECT", i18nparam); 149 String subject = _i18nUtils.translate(i18nTextSubject); 150 151 i18nparam = new ArrayList<>(); 152 i18nparam.add(userName); 153 i18nparam.add(pagePath); // Page path 154 i18nparam.add(text); 155 i18nparam.add(page.getSite().getUrl()); // Site url 156 157 I18nizableText i18nTextBody = new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_TEXT_BODY", i18nparam); 158 String textBody = _i18nUtils.translate(i18nTextBody); 159 160 i18nparam = new ArrayList<>(); 161 i18nparam.add(userName); 162 i18nparam.add(pagePath); // Page path 163 @SuppressWarnings("null") 164 String textB = text.replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", "<br/>"); 165 i18nparam.add(textB); 166 i18nparam.add(page.getSite().getUrl()); // Site url 167 168 I18nizableText i18nHtmlBody = new I18nizableText("plugin.socialnetworking", "PLUGINS_SOCIAL_NETWORKING_SEND_MAIL_HTML_BODY", i18nparam); 169 String htmlBody = _i18nUtils.translate(i18nHtmlBody); 170 171 String[] tabMail = StringUtils.split(emailTo, ","); 172 for (int i = 0; i < tabMail.length; i++) 173 { 174 try 175 { 176 SendMailHelper.newMail() 177 .withSubject(subject) 178 .withHTMLBody(htmlBody) 179 .withTextBody(textBody) 180 .withSender(emailBy) 181 .withRecipient(StringUtils.trimToEmpty(tabMail[i])) 182 .sendMail(); 183 } 184 catch (MessagingException | IOException e) 185 { 186 if (!result.containsKey("mailError")) 187 { 188 result.put("mailError", new ArrayList<String>()); 189 } 190 191 ((List<String>) result.get("mailError")).add(tabMail[i]); 192 193 getLogger().error("Failed to send mail to '" + tabMail[i] + "'", e); 194 } 195 } 196 } 197 198 result.put("error", errors); 199 200 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result); 201 202 return EMPTY_MAP; 203 } 204 205 private String _getPageId(Request request) 206 { 207 String pageId = request.getParameter("page-id"); 208 if (pageId == null) 209 { 210 throw new IllegalStateException("Unable to send page by mail: cannot determine the current page"); 211 } 212 else 213 { 214 Page page = _resolver.resolveById(pageId); 215 if (page == null) 216 { 217 throw new IllegalStateException("Unable to send page by mail: the page of id " + pageId + " is unknown"); 218 } 219 } 220 return pageId; 221 } 222 223}