001/* 002 * Copyright 2022 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.workspaces.project.notification; 017 018import java.io.ByteArrayOutputStream; 019import java.io.IOException; 020import java.io.InputStream; 021import java.util.Collection; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025import java.util.stream.Collectors; 026 027import org.apache.cocoon.environment.Request; 028import org.apache.commons.lang.StringUtils; 029import org.apache.excalibur.source.Source; 030import org.apache.excalibur.source.SourceUtil; 031 032import org.ametys.cms.contenttype.ContentTypesHelper; 033import org.ametys.cms.repository.Content; 034import org.ametys.cms.repository.WorkflowAwareContent; 035import org.ametys.core.user.User; 036import org.ametys.core.user.UserIdentity; 037import org.ametys.core.util.mail.SendMailHelper; 038import org.ametys.plugins.workspaces.WorkspacesConstants; 039import org.ametys.plugins.workspaces.project.ProjectManager; 040import org.ametys.plugins.workspaces.project.notification.preferences.NotificationPreferencesHelper; 041import org.ametys.plugins.workspaces.project.notification.preferences.NotificationPreferencesHelper.Frequency; 042import org.ametys.plugins.workspaces.project.objects.Project; 043import org.ametys.runtime.config.Config; 044import org.ametys.web.WebConstants; 045import org.ametys.web.renderingcontext.RenderingContext; 046import org.ametys.web.renderingcontext.RenderingContextHandler; 047import org.ametys.web.repository.content.WebContent; 048import org.ametys.web.repository.site.Site; 049import org.ametys.web.workflow.SendMailFunction; 050 051import com.google.common.collect.Iterables; 052import com.opensymphony.workflow.WorkflowException; 053 054import jakarta.mail.MessagingException; 055 056/** 057 * Function to notify news publication 058 * 059 */ 060public class SendNewsPublicationNotificationFunction extends SendMailFunction 061{ 062 private RenderingContextHandler _renderingContextHandler; 063 private ContentTypesHelper _contentTypeHelper; 064 private ProjectManager _projectManager; 065 private NotificationPreferencesHelper _notificationPrefHelper; 066 067 @Override 068 public void initialize() throws Exception 069 { 070 super.initialize(); 071 _renderingContextHandler = (RenderingContextHandler) _manager.lookup(RenderingContextHandler.ROLE); 072 _contentTypeHelper = (ContentTypesHelper) _manager.lookup(ContentTypesHelper.ROLE); 073 _projectManager = (ProjectManager) _manager.lookup(ProjectManager.ROLE); 074 _notificationPrefHelper = (NotificationPreferencesHelper) _manager.lookup(NotificationPreferencesHelper.ROLE); 075 } 076 077 @Override 078 protected List<String> getSubjectI18nParams(User user, WorkflowAwareContent content) 079 { 080 List<String> params = super.getSubjectI18nParams(user, content); 081 Project project = _getProject(content); 082 if (project != null) 083 { 084 params.add(project.getTitle()); // {3} 085 } 086 return params; 087 } 088 089 @Override 090 protected String getMailBody(String bodyI18nKey, User user, WorkflowAwareContent content, Map transientVars) 091 { 092 Request request = _getRequest(); 093 094 Source source = null; 095 RenderingContext currentContext = _renderingContextHandler.getRenderingContext(); 096 097 try 098 { 099 if (content instanceof WebContent && _contentTypeHelper.isInstanceOf(content, WorkspacesConstants.PROJECT_NEWS_CONTENT_TYPE_ID)) 100 { 101 // Force rendering context.FRONT to resolve URI 102 _renderingContextHandler.setRenderingContext(RenderingContext.FRONT); 103 request.setAttribute("forceAbsoluteUrl", true); 104 request.setAttribute("lang", content.getLanguage()); 105 106 Site site = ((WebContent) content).getSite(); 107 request.setAttribute(WebConstants.REQUEST_ATTR_SITE, site); 108 request.setAttribute(WebConstants.REQUEST_ATTR_SITE_NAME, site.getName()); 109 request.setAttribute(WebConstants.REQUEST_ATTR_SKIN_ID, site.getSkinId()); 110 request.setAttribute("forceBase64Encoding", true); 111 112 source = _sourceResolver.resolveURI("cocoon://_plugins/workspaces/notification-mail-news-publication", null, Map.of("content", content, "issuer", user, "project", _getProject(content))); 113 114 try (InputStream is = source.getInputStream()) 115 { 116 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 117 SourceUtil.copy(is, bos); 118 return bos.toString("UTF-8"); 119 } 120 } 121 } 122 catch (IOException e) 123 { 124 _logger.error("Fail to get mail body for news publication.", e); 125 } 126 finally 127 { 128 request.removeAttribute("forceBase64Encoding"); 129 130 _renderingContextHandler.setRenderingContext(currentContext); 131 if (source != null) 132 { 133 _sourceResolver.release(source); 134 } 135 } 136 137 return null; 138 } 139 140 private Project _getProject(Content content) 141 { 142 if (content instanceof WebContent) 143 { 144 Site site = ((WebContent) content).getSite(); 145 return Iterables.getFirst(_projectManager.getProjectsForSite(site), null); 146 } 147 return null; 148 } 149 150 @Override 151 protected void _sendMails(String subject, String body, Set<String> recipients, String from) 152 { 153 if (StringUtils.isNotEmpty(body)) 154 { 155 for (String recipient : recipients) 156 { 157 try 158 { 159 SendMailHelper.newMail() 160 .withSubject(subject) 161 .withHTMLBody(body) 162 .withSender(from) 163 .withRecipient(recipient) 164 .withAsync(true) 165 .withInlineCSS(false) 166 .sendMail(); 167 } 168 catch (MessagingException | IOException e) 169 { 170 _logger.warn("Could not send a workflow notification mail to " + recipient, e); 171 } 172 } 173 } 174 } 175 176 @Override 177 protected Set<UserIdentity> _getUsers(WorkflowAwareContent content, Set<String> rights) throws WorkflowException 178 { 179 boolean returnAll = Config.getInstance().getValue("runtime.mail.massive.sending"); 180 Collection<UserIdentity> allowedUsers = _rightManager.getReadAccessAllowedUsers(content).resolveAllowedUsers(returnAll); 181 182 return allowedUsers.stream() 183 .filter(userId -> _notificationPrefHelper.askedToBeNotified(userId, _getProject(content).getName(), Frequency.EACH)) 184 .collect(Collectors.toSet()); 185 } 186}