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 AddMemberMailNotifierObserver 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        String newMemberId = (String) event.getArguments().get(ObservationConstants.ARGS_MEMBER_ID);
052        JCRProjectMember newMember = _resolver.resolveById(newMemberId);
053        
054        // get user to notify
055        List<User> newUsersInProject = new ArrayList<>();
056        if (MemberType.USER == newMember.getType())
057        {
058            newUsersInProject.add(_userManager.getUser(newMember.getUser()));
059        }
060        else if (MemberType.GROUP == newMember.getType())
061        {
062            GroupIdentity groupIdentity = newMember.getGroup();
063            Group group = _groupManager.getGroup(groupIdentity);
064            if (group != null && project != null)
065            {
066                newUsersInProject = _projectMemberManager.getGroupUsersFromProject(group, project, (currentProject, identity) -> _isMemberNewToTheProject(currentProject, identity, groupIdentity));
067            }
068        }
069        return getUsersEmail(newUsersInProject);
070    }
071    
072    @Override
073    protected I18nizableText getI18nSubject(Event event, Project project)
074    {
075        return new I18nizableText("plugin." + _pluginName, "PROJECT_MAIL_NOTIFICATION_SUBJECT_MEMBER_ADDED", List.of(project.getTitle()));
076    }
077
078    private boolean _isMemberNewToTheProject(Project project, UserIdentity userIdentity, GroupIdentity newGroupToIgnore)
079    {
080        Set<ProjectMember> projectMembers = _projectMemberManager.getProjectMembers(project, false);
081        boolean isUserOfProject = projectMembers.stream()
082                .filter(member -> MemberType.USER == member.getType())
083                .map(ProjectMember::getUser)
084                .map(User::getIdentity)
085                .filter(userIdentity::equals)
086                .findAny()
087                .isPresent();
088        
089        if (isUserOfProject)
090        {
091            // User from group was already part of the project, as a member of type "user"
092            return false;
093        }
094        
095        return projectMembers.stream()
096                .filter(member -> MemberType.GROUP == member.getType())
097                .map(ProjectMember::getGroup)
098                .filter(group -> !newGroupToIgnore.equals(group.getIdentity()))
099                .filter(Objects::nonNull)
100                .map(Group::getUsers)
101                .flatMap(Set::stream)
102                .filter(userIdentity::equals)
103                .findAny()
104                .isEmpty(); // User was not found in any group of the project, apart from the ignored group
105    }
106}