001/*
002 *  Copyright 2019 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.List;
019import java.util.Map;
020import java.util.Optional;
021import java.util.stream.Collectors;
022
023import org.apache.commons.lang3.StringUtils;
024import org.apache.commons.lang3.tuple.Pair;
025
026import org.ametys.core.group.Group;
027import org.ametys.core.group.GroupIdentity;
028import org.ametys.core.observation.Event;
029import org.ametys.core.user.UserIdentity;
030import org.ametys.plugins.workspaces.ObservationConstants;
031import org.ametys.plugins.workspaces.members.JCRProjectMember.MemberType;
032import org.ametys.plugins.workspaces.project.objects.Project;
033import org.ametys.runtime.config.Config;
034import org.ametys.runtime.i18n.I18nizableText;
035
036/**
037 * Observer to send mail notifications on workspace member removal
038 */
039public class RemoveMemberMailNotifierObserver extends AbstractMemberMailNotifierObserver
040{
041    @Override
042    public boolean supports(Event event)
043    {
044        if (ObservationConstants.EVENT_MEMBER_DELETED.equals(event.getId()))
045        {
046            return Config.getInstance().getValue("workspaces.member.removed.send.notification", true, false);
047        }
048        return false;
049    }
050    
051    @Override
052    protected I18nizableText getI18nSubject(Event event, Project project)
053    {
054        return new I18nizableText("plugin." + _pluginName, "PROJECT_MAIL_NOTIFICATION_EVENT_SUBJECT_MEMBER_DELETED", List.of(project.getTitle()));
055    }
056    
057    @Override
058    protected String getMailBodyURI(Event event, Project project)
059    {
060        return "cocoon://_plugins/workspaces/notification-mail-member-event";
061    }
062
063    @Override
064    protected Map<String, List<String>> getUserToNotifyByLanguage(Event event, Project project)
065    {
066        // Retrieve removed member
067        Map<String, Object> args = event.getArguments();
068        String identity = (String) args.get(ObservationConstants.ARGS_MEMBER_IDENTITY);
069        MemberType identityType = (MemberType) args.get(ObservationConstants.ARGS_MEMBER_IDENTITY_TYPE);
070        
071        if (MemberType.USER == identityType)
072        {
073            return Optional.of(identity)
074                    .map(UserIdentity::stringToUserIdentity)
075                    .filter(userIdentity -> !_projectMemberManager.isProjectMember(project, userIdentity)) // user is not in a group that is still part of the project
076                    .map(_userManager::getUser)
077                    .map(user -> Pair.of(user, user.getEmail()))
078                    .filter(p -> StringUtils.isNotEmpty(p.getRight()))
079                    .map(p -> Map.of(StringUtils.defaultString(p.getLeft().getLanguage()), List.of(p.getRight())))
080                    .orElse(Map.of());
081        }
082        else if (MemberType.GROUP == identityType)
083        {
084            GroupIdentity groupIdentity = GroupIdentity.stringToGroupIdentity(identity);
085            if (groupIdentity != null)
086            {
087                Group group = _groupManager.getGroup(groupIdentity);
088                if (group != null)
089                {
090                    return group.getUsers().stream()
091                        .filter(u -> !_projectMemberManager.isProjectMember(project, u))
092                        .map(_userManager::getUser)
093                        .map(user -> Pair.of(user, user.getEmail()))
094                        .filter(p -> StringUtils.isNotEmpty(p.getRight()))
095                        .collect(Collectors.groupingBy(
096                                p -> {
097                                    return StringUtils.defaultString(p.getLeft().getLanguage());
098                                },
099                                Collectors.mapping(
100                                        Pair::getRight,
101                                        Collectors.toList()
102                                )
103                            )
104                        );
105                }
106            }
107        }
108        return Map.of();
109    }
110}