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.Objects; 021import java.util.Set; 022 023import org.ametys.core.group.Group; 024import org.ametys.core.group.GroupIdentity; 025import org.ametys.core.observation.Event; 026import org.ametys.core.user.User; 027import org.ametys.core.user.UserIdentity; 028import org.ametys.plugins.workspaces.ObservationConstants; 029import org.ametys.plugins.workspaces.members.JCRProjectMember; 030import org.ametys.plugins.workspaces.members.JCRProjectMember.MemberType; 031import org.ametys.plugins.workspaces.members.ProjectMemberManager.ProjectMember; 032import org.ametys.plugins.workspaces.project.objects.Project; 033import org.ametys.runtime.config.Config; 034import org.ametys.runtime.i18n.I18nizableText; 035 036/** 037 * Notifier to send mail to a newly added member of a workspace. 038 */ 039public class WelcomeMemberMailNotifierObserver extends AbstractMemberMailNotifierObserver 040{ 041 @Override 042 public boolean supports(Event event) 043 { 044 return event.getId().equals(ObservationConstants.EVENT_MEMBER_ADDED) 045 && Config.getInstance().getValue("workspaces.member.added.send.notification", true, false); // Check feature enabled 046 } 047 048 @Override 049 protected List<String> getUserToNotify(Event event, Project project) 050 { 051 // async observer, we need to resolve the member 052 String memberId = (String) event.getArguments().get(ObservationConstants.ARGS_MEMBER_ID); 053 JCRProjectMember newMember = _resolver.resolveById(memberId); 054 055 // get user to notify 056 List<User> newUsersInProject = new ArrayList<>(); 057 if (MemberType.USER == newMember.getType()) 058 { 059 User user = _userManager.getUser(newMember.getUser()); 060 if (_isUserMemberNewToProject(user.getIdentity(), project)) 061 { 062 newUsersInProject.add(user); 063 } 064 } 065 else if (MemberType.GROUP == newMember.getType()) 066 { 067 GroupIdentity groupIdentity = newMember.getGroup(); 068 Group group = _groupManager.getGroup(groupIdentity); 069 if (group != null && project != null) 070 { 071 newUsersInProject = _projectMemberManager.getGroupUsersFromProject(group, project, (currentProject, identity) -> _isGroupMemberNewToTheProject(currentProject, identity, groupIdentity)); 072 } 073 } 074 return getUsersEmail(newUsersInProject); 075 } 076 077 @Override 078 protected I18nizableText getI18nSubject(Event event, Project project) 079 { 080 return new I18nizableText("plugin." + _pluginName, "PROJECT_MAIL_NOTIFICATION_EVENT_SUBJECT_MEMBER_ADDED", List.of(project.getTitle())); 081 } 082 083 @Override 084 protected String getMailBodyURI(Event event, Project project) 085 { 086 return "cocoon://_plugins/workspaces/notification-mail-member-event"; 087 } 088 089 private boolean _isGroupMemberNewToTheProject(Project project, UserIdentity userIdentity, GroupIdentity newGroupToIgnore) 090 { 091 Set<ProjectMember> projectMembers = _projectMemberManager.getProjectMembers(project, false); 092 boolean isUserOfProject = projectMembers.stream() 093 .filter(member -> MemberType.USER == member.getType()) 094 .map(ProjectMember::getUser) 095 .map(User::getIdentity) 096 .filter(userIdentity::equals) 097 .findAny() 098 .isPresent(); 099 100 if (isUserOfProject) 101 { 102 // User from group was already part of the project, as a member of type "user" 103 return false; 104 } 105 106 return _isUserMemberInAGroupMember(userIdentity, newGroupToIgnore, projectMembers); 107 } 108 109 private boolean _isUserMemberNewToProject(UserIdentity userIdentity, Project project) 110 { 111 Set<ProjectMember> projectMembers = _projectMemberManager.getProjectMembers(project, false); 112 return _isUserMemberInAGroupMember(userIdentity, null, projectMembers); 113 } 114 115 private boolean _isUserMemberInAGroupMember(UserIdentity userIdentity, GroupIdentity newGroupToIgnore, Set<ProjectMember> projectMembers) 116 { 117 return projectMembers.stream() 118 .filter(member -> MemberType.GROUP == member.getType()) 119 .map(ProjectMember::getGroup) 120 .filter(group -> newGroupToIgnore == null || !newGroupToIgnore.equals(group.getIdentity())) 121 .filter(Objects::nonNull) 122 .map(Group::getUsers) 123 .flatMap(Set::stream) 124 .filter(userIdentity::equals) 125 .findAny() 126 .isEmpty(); // User was not found in any group of the project, apart from the ignored group 127 } 128}