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