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