001/*
002 *  Copyright 2013 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.web.repository.page.actions;
017
018import java.io.IOException;
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024import java.util.stream.Collectors;
025
026import org.apache.avalon.framework.parameters.Parameters;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.cocoon.acting.ServiceableAction;
030import org.apache.cocoon.environment.ObjectModelHelper;
031import org.apache.cocoon.environment.Redirector;
032import org.apache.cocoon.environment.SourceResolver;
033
034import org.ametys.core.group.Group;
035import org.ametys.core.group.GroupIdentity;
036import org.ametys.core.group.GroupManager;
037import org.ametys.core.ui.mail.StandardMailBodyHelper;
038import org.ametys.core.user.CurrentUserProvider;
039import org.ametys.core.user.User;
040import org.ametys.core.user.UserIdentity;
041import org.ametys.core.user.UserManager;
042import org.ametys.core.util.I18nUtils;
043import org.ametys.core.util.mail.SendMailHelper;
044import org.ametys.plugins.core.user.UserHelper;
045import org.ametys.plugins.repository.AmetysObjectResolver;
046import org.ametys.runtime.config.Config;
047import org.ametys.runtime.i18n.I18nizableText;
048import org.ametys.runtime.i18n.I18nizableTextParameter;
049import org.ametys.web.repository.page.Page;
050import org.ametys.web.repository.site.Site;
051
052import jakarta.mail.MessagingException;
053
054/**
055 * This actions send a email to notify the publication of a page.
056 *
057 */
058public class SendOnlineNotificationAction extends ServiceableAction
059{
060    private UserManager _userManager;
061    private GroupManager _groupManager;
062    private AmetysObjectResolver _resolver;
063    private I18nUtils _i18nUtils;
064    private CurrentUserProvider _userProvider;
065    private UserHelper _userHelper;
066    
067    @Override
068    public void service(ServiceManager smanager) throws ServiceException
069    {
070        super.service(smanager);
071        _userManager = (UserManager) smanager.lookup(UserManager.ROLE);
072        _userProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
073        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
074        _groupManager = (GroupManager) smanager.lookup(GroupManager.ROLE);
075        _i18nUtils = (I18nUtils) smanager.lookup(I18nUtils.ROLE);
076        _userHelper = (UserHelper) smanager.lookup(UserHelper.ROLE);
077    }
078    
079    @Override
080    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
081    {
082        @SuppressWarnings("unchecked")
083        Map<String, Object> jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT);
084        
085        String pageId = (String) jsParameters.get("id");
086        Page page = _resolver.resolveById(pageId);
087        
088        UserIdentity userIdentity = _userProvider.getUser();
089        User notifier = _userManager.getUser(userIdentity.getPopulationId(), userIdentity.getLogin());
090        
091        String from = _getSender(notifier, page);
092        String subject = _getSubject (notifier, page);
093        
094        @SuppressWarnings("unchecked")
095        List<Map<String, String>> jsUsers = (List<Map<String, String>>) jsParameters.get("users");
096        List<UserIdentity> userIdentities = jsUsers.stream()
097                .map(_userHelper::json2userIdentity)
098                .collect(Collectors.toList());
099        
100        @SuppressWarnings("unchecked")
101        List<Map<String, String>> jsGroups = (List<Map<String, String>>) jsParameters.get("groups");
102        List<GroupIdentity> groupIdentities = jsGroups.stream()
103                .map(jsGroup -> new GroupIdentity(jsGroup.get("id"), jsGroup.get("groupDirectory")))
104                .collect(Collectors.toList());
105        
106        Set<User> users = _getDistinctUsers(userIdentities, groupIdentities);
107        for (User user : users)
108        {
109            if (user.getEmail() != null)
110            {
111                try
112                {
113                    String body = _getBody(notifier, user, page);
114                    
115                    SendMailHelper.newMail()
116                                  .withSubject(subject)
117                                  .withHTMLBody(body)
118                                  .withSender(from)
119                                  .withRecipient(user.getEmail())
120                                  .sendMail();
121                }
122                catch (MessagingException | IOException e) 
123                {
124                    getLogger().error("Unable to send mail to user " + user.getEmail(), e);
125                }
126            }
127        }
128        
129        return EMPTY_MAP;
130    }
131    
132    /**
133     * Get the email sender
134     * @param sender The user responsible for the action
135     * @param page The published page
136     * @return The sender
137     */
138    protected String _getSender (User sender, Page page)
139    {
140        if (sender != null && sender.getEmail() != null)
141        {
142            return sender.getFullName() + " <" + sender.getEmail() + ">";
143        }
144
145        Site site = page.getSite();
146        String defaultFromValue = Config.getInstance().getValue("smtp.mail.from");
147        return site.getValue("site-mail-from", false, defaultFromValue);
148    }
149    
150    /**
151     * Get the email subject
152     * @param sender The user responsible for the notification
153     * @param page The published page
154     * @return The email subject
155     */
156    protected String _getSubject (User sender, Page page)
157    {
158        Site site = page.getSite();
159        
160        Map<String, I18nizableTextParameter> subjectI18nParameters = new HashMap<>();
161        subjectI18nParameters.put("user", new I18nizableText(sender.getFullName()));
162        subjectI18nParameters.put("siteTitle", new I18nizableText(site.getTitle()));
163        subjectI18nParameters.put("pageTitle", new I18nizableText(page.getTitle()));
164        
165        I18nizableText msg = new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_SUBJECT", subjectI18nParameters);
166        
167        return _i18nUtils.translate(msg, page.getSitemapName());
168    }
169    
170    /**
171     * Get the email body
172     * @param sender The user responsible for the notification
173     * @param user The recipient of the notification
174     * @param page The published page
175     * @return The email body
176     * @throws IOException if failed to build HTML body
177     */
178    protected String _getBody (User sender, User user, Page page) throws IOException
179    {
180        Site site = page.getSite();
181        String pageUrl = site.getUrl() + "/" + page.getSitemap().getName() + "/" + page.getPathInSitemap() + ".html";
182        
183        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
184        i18nParams.put("sender", new I18nizableText(sender.getFullName()));
185        i18nParams.put("user", new I18nizableText(user.getFullName()));
186        i18nParams.put("siteTitle", new I18nizableText(site.getTitle()));
187        i18nParams.put("siteUrl", new I18nizableText(site.getUrl()));
188        i18nParams.put("pageTitle", new I18nizableText(page.getTitle()));
189        i18nParams.put("pageUrl", new I18nizableText(pageUrl));
190        
191        return StandardMailBodyHelper.newHTMLBody()
192            .withTitle(new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY_TITLE"))
193            .addMessage(new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY", i18nParams))
194            .addMessage(new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY_LINK_TEXT", i18nParams))
195            .withLink(pageUrl, new I18nizableText("plugin.web", "PLUGINS_WEB_PAGE_NOTIFY_ONLINE_PUBLICATION_MAIL_BODY_LINK_BUTTON"))
196            .build();
197    }
198    
199    private Set<User> _getDistinctUsers (List<UserIdentity> userIdentities, List<GroupIdentity> groupIdentities)
200    {
201        Set<User> users = new HashSet<>();
202        
203        for (UserIdentity userIdentity : userIdentities)
204        {
205            User user = _userManager.getUser(userIdentity);
206            if (user != null)
207            {
208                users.add(user);
209            }
210        }
211        
212        for (GroupIdentity groupIdentity : groupIdentities)
213        {
214            Group group = _groupManager.getGroup(groupIdentity);
215            if (group != null)
216            {
217                Set<UserIdentity> userGroupIdentities = group.getUsers();
218                for (UserIdentity userGroupIdentity : userGroupIdentities)
219                {
220                    User user = _userManager.getUser(userGroupIdentity);
221                    if (user != null)
222                    {
223                        users.add(user);
224                    }
225                }
226            }
227        }
228        
229        return users;
230    }
231}