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("<", "&lt;").replaceAll(">", "&gt;").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}