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