001/*
002 *  Copyright 2023 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.initialization;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021import java.util.Optional;
022import java.util.Set;
023
024import org.apache.avalon.framework.service.ServiceException;
025import org.apache.avalon.framework.service.ServiceManager;
026import org.apache.commons.lang3.StringUtils;
027
028import org.ametys.cms.repository.Content;
029import org.ametys.core.observation.Event;
030import org.ametys.core.user.directory.ModifiableUserDirectory;
031import org.ametys.core.user.directory.UserDirectory;
032import org.ametys.core.user.population.PopulationContextHelper;
033import org.ametys.core.user.population.UserPopulation;
034import org.ametys.core.user.population.UserPopulationDAO;
035import org.ametys.plugins.repository.AmetysObjectIterable;
036import org.ametys.plugins.repository.AmetysObjectResolver;
037import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder;
038import org.ametys.web.ObservationConstants;
039import org.ametys.web.repository.page.ModifiablePage;
040import org.ametys.web.repository.page.ModifiableSitemapElement;
041import org.ametys.web.repository.page.ModifiableZone;
042import org.ametys.web.repository.page.ModifiableZoneItem;
043import org.ametys.web.repository.page.Page;
044import org.ametys.web.repository.page.PageDAO;
045import org.ametys.web.repository.page.Zone;
046import org.ametys.web.repository.page.ZoneItem;
047import org.ametys.web.repository.page.ZoneItem.ZoneType;
048
049/**
050 * Initialize a page with user signup service.
051 */
052public class UserSignupPageInitializer extends DefaultStaticPageInitializer
053{
054    /** the population context helper */
055    protected PopulationContextHelper _populationContextHelper;
056    /** the user population DAO */
057    protected UserPopulationDAO _userPopulationDAO;
058    /** the page DAO */
059    protected PageDAO _pageDAO;
060    /** the Ametys object resolver */
061    protected AmetysObjectResolver _resolver;
062
063    @Override
064    public void service(ServiceManager manager) throws ServiceException
065    {
066        super.service(manager);
067        _pageDAO = (PageDAO) manager.lookup(PageDAO.ROLE);
068        _populationContextHelper = (PopulationContextHelper) manager.lookup(PopulationContextHelper.ROLE);
069        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
070        _userPopulationDAO = (UserPopulationDAO) manager.lookup(UserPopulationDAO.ROLE);
071    }
072    
073    @Override
074    public Optional< ? extends Page> createPage(ModifiableSitemapElement parent)
075    {
076        Optional< ? extends Page> result = super.createPage(parent);
077        if (result.isPresent() && result.get() instanceof ModifiablePage page)
078        {
079            try (AmetysObjectIterable<ModifiableZone> zones = page.getZones())
080            {
081                for (ModifiableZone zone : zones)
082                {
083                    try (AmetysObjectIterable<ModifiableZoneItem> zoneItems = zone.getZoneItems())
084                    {
085                        for (ModifiableZoneItem zoneItem : zoneItems)
086                        {
087                            if (StringUtils.equals(zoneItem.getServiceId(), "org.ametys.web.service.UserSignup"))
088                            {
089                                ModifiableModelAwareDataHolder serviceParams = zoneItem.getServiceParameters();
090                                
091                                Optional<Content> termsOfUseContent = _getTermsOfUseContent(parent);
092                                if (termsOfUseContent.isPresent())
093                                {
094                                    serviceParams.setValue("terms-of-service-content", termsOfUseContent.get().getId());
095                                }
096                                
097                                Set<String> frontPopulations = _populationContextHelper.getUserPopulationsOnContexts(List.of("/sites-fo/" + parent.getSiteName(), "/sites/" + parent.getSiteName()), false);
098                                Optional<UserDirectory> userDirectory = frontPopulations.stream()
099                                        .map(_userPopulationDAO::getUserPopulation)
100                                        .map(UserPopulation::getUserDirectories)
101                                        .flatMap(List::stream)
102                                        .filter(ModifiableUserDirectory.class::isInstance)
103                                        .findAny();
104                                if (userDirectory.isPresent())
105                                {
106                                    serviceParams.setValue("userdirectory", userDirectory.get().getPopulationId() + "#" + userDirectory.get().getId());
107                                }
108                                else
109                                {
110                                    getLogger().warn("No user directory found to set on the signup services. Consider configuring one or remove the sign up page.");
111                                }
112                                
113                                zoneItem.saveChanges();
114                                
115                                // FIXME we should use api that manage the event instead of doing it manually
116                                Map<String, Object> eventParams = new HashMap<>();
117                                eventParams.put(ObservationConstants.ARGS_ZONE_ITEM, zoneItem);
118                                eventParams.put(ObservationConstants.ARGS_ZONE_ITEM_ID, zoneItem.getId());
119                                eventParams.put(ObservationConstants.ARGS_ZONE_ITEM_SERVICE, zoneItem.getServiceId());
120                                _observationManager.notify(new Event(ObservationConstants.EVENT_SERVICE_MODIFIED, _currentUserProvider.getUser(), eventParams));
121                            }
122                        }
123                    }
124                }
125                
126            }
127            page.saveChanges();
128            
129        }
130        return result;
131    }
132
133    private Optional<Content> _getTermsOfUseContent(ModifiableSitemapElement parent)
134    {
135        for (String pageId : _pageDAO.findPagedIdsByTag(parent.getSiteName(), parent.getSitemapName(), "WORKSPACES_CGU"))
136        {
137            Page page = _resolver.resolveById(pageId);
138            try (AmetysObjectIterable< ? extends Zone> zones = page.getZones())
139            {
140                return zones.stream()
141                        .flatMap(zone -> zone.getZoneItems().stream())
142                        .filter(items -> items.getType().equals(ZoneType.CONTENT))
143                        .map(ZoneItem::<Content>getContent)
144                        .findAny();
145            }
146        }
147        
148        return Optional.empty();
149    }
150}