001/* 002 * Copyright 2017 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.util.ArrayList; 019import java.util.Collection; 020import java.util.List; 021import java.util.Map; 022import java.util.Objects; 023import java.util.Set; 024 025import javax.mail.MessagingException; 026 027import org.ametys.core.group.Group; 028import org.ametys.core.group.GroupIdentity; 029import org.ametys.core.observation.Event; 030import org.ametys.core.user.User; 031import org.ametys.core.user.UserIdentity; 032import org.ametys.core.util.mail.SendMailHelper; 033import org.ametys.plugins.workspaces.ObservationConstants; 034import org.ametys.plugins.workspaces.members.JCRProjectMember; 035import org.ametys.plugins.workspaces.members.JCRProjectMember.MemberType; 036import org.ametys.plugins.workspaces.members.ProjectMemberManager.ProjectMember; 037import org.ametys.plugins.workspaces.project.objects.Project; 038import org.ametys.runtime.config.Config; 039import org.ametys.runtime.i18n.I18nizableText; 040 041/** 042 * Notifier to send mail to a newly added member of a workspace. 043 */ 044public class AddMemberMailNotifierObserver extends AbstractMemberMailNotifierObserver 045{ 046 @Override 047 public boolean supports(Event event) 048 { 049 return event.getId().equals(ObservationConstants.EVENT_MEMBER_ADDED); 050 } 051 052 @Override 053 public void observe(Event event, Map<String, Object> transientVars) throws Exception 054 { 055 // Check feature enabled 056 boolean notification = Config.getInstance().getValue("workspaces.member.added.send.notification"); 057 if (!notification) 058 { 059 return; 060 } 061 062 Map<String, Object> args = event.getArguments(); 063 064 // Retrieve newly added member 065 String newMemberId = (String) args.get(ObservationConstants.ARGS_MEMBER_ID); 066 JCRProjectMember newMember = _resolver.resolveById(newMemberId); 067 068 // Retrieve project 069 String projectId = (String) args.get(ObservationConstants.ARGS_PROJECT_ID); 070 Project project = _resolver.resolveById(projectId); 071 072 // Compute subject and body 073 String subject = _i18nUtils.translate(getSubjectI18nizableText(project, newMember)); 074 String textBody = _i18nUtils.translate(getBodyI18nizableText(project, newMember)); 075 076 List<User> newUsersInProject = new ArrayList<>(); 077 if (MemberType.USER == newMember.getType()) 078 { 079 newUsersInProject.add(_userManager.getUser(newMember.getUser())); 080 } 081 else if (MemberType.GROUP == newMember.getType()) 082 { 083 GroupIdentity groupIdentity = newMember.getGroup(); 084 Group group = _groupManager.getGroup(groupIdentity); 085 if (group != null && project != null) 086 { 087 newUsersInProject = _projectMemberManager.getGroupUsersFromProject(group, project, (currentProject, identity) -> _isMemberNewToTheProject(currentProject, identity, groupIdentity)); 088 } 089 } 090 091 // Retrieve mail sender 092 String sender = Config.getInstance().getValue("smtp.mail.from"); 093 094 for (String memberMail : getUsersEmail(newUsersInProject)) 095 { 096 try 097 { 098 SendMailHelper.sendMail(subject, null, textBody, memberMail, sender); 099 } 100 catch (MessagingException e) 101 { 102 getLogger().warn("Could not send a notification e-mail to " + memberMail, e); 103 } 104 } 105 } 106 107 private boolean _isMemberNewToTheProject(Project project, UserIdentity userIdentity, GroupIdentity newGroupToIgnore) 108 { 109 Collection<ProjectMember> projectMembers = _projectMemberManager.getProjectMembers(project, false, false); 110 boolean isUserOfProject = projectMembers.stream() 111 .filter(member -> MemberType.USER == member.getType()) 112 .map(ProjectMember::getUser) 113 .map(User::getIdentity) 114 .filter(userIdentity::equals) 115 .findAny() 116 .isPresent(); 117 118 if (isUserOfProject) 119 { 120 // User from group was already part of the project, as a member of type "user" 121 return false; 122 } 123 124 return projectMembers.stream() 125 .filter(member -> MemberType.GROUP == member.getType()) 126 .map(ProjectMember::getGroup) 127 .filter(group -> !newGroupToIgnore.equals(group.getIdentity())) 128 .filter(Objects::nonNull) 129 .map(Group::getUsers) 130 .flatMap(Set::stream) 131 .filter(userIdentity::equals) 132 .findAny() 133 .isEmpty(); // User was not found in any group of the project, apart from the ignored group 134 } 135 136 /** 137 * Gets the {@link I18nizableText} for subject of the mail 138 * @param project the project 139 * @param member the member 140 * @return the subject 141 */ 142 protected I18nizableText getSubjectI18nizableText(Project project, JCRProjectMember member) 143 { 144 return new I18nizableText("plugin." + _pluginName, getSubjectI18nKey(), getSubjectParams(project, member)); 145 } 146 147 /** 148 * Gets the i18n subject key 149 * @return the i18n subject key 150 */ 151 protected String getSubjectI18nKey() 152 { 153 return "PROJECT_MAIL_NOTIFICATION_SUBJECT_MEMBER_ADDED"; 154 } 155 156 /** 157 * Gets the i18n parameters for subject key 158 * @param project the project 159 * @param member the member 160 * @return the i18n parameters 161 */ 162 protected List<String> getSubjectParams(Project project, JCRProjectMember member) 163 { 164 return getI18nParams(project.getTitle()); // {0} 165 } 166 167 /** 168 * Gets the {@link I18nizableText} for body of the mail 169 * @param project the project 170 * @param member the member 171 * @return the body 172 */ 173 protected I18nizableText getBodyI18nizableText(Project project, JCRProjectMember member) 174 { 175 return new I18nizableText("plugin." + _pluginName, getBodyI18nKey(), getBodyParams(project, member)); 176 } 177 178 /** 179 * Gets the i18n body key 180 * @return the i18n body key 181 */ 182 protected String getBodyI18nKey() 183 { 184 return "PROJECT_MAIL_NOTIFICATION_BODY_MEMBER_ADDED"; 185 } 186 187 /** 188 * Gets the i18n parameters for body key 189 * @param project the project 190 * @param jcrMember the member 191 * @return the i18n parameters 192 */ 193 protected List<String> getBodyParams(Project project, JCRProjectMember jcrMember) 194 { 195 return getI18nParams( 196 project.getTitle(), // {0} 197 getProjectUrl(project)); // {1} 198 } 199 200}