001/*
002 *  Copyright 2020 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.extraction.rights;
017
018import java.io.File;
019import java.util.HashMap;
020import java.util.LinkedList;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import org.apache.avalon.framework.parameters.Parameters;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.cocoon.acting.ServiceableAction;
029import org.apache.cocoon.environment.ObjectModelHelper;
030import org.apache.cocoon.environment.Redirector;
031import org.apache.cocoon.environment.Request;
032import org.apache.cocoon.environment.SourceResolver;
033import org.apache.excalibur.source.Source;
034import org.apache.excalibur.source.impl.FileSource;
035
036import org.ametys.core.cocoon.JSonReader;
037import org.ametys.core.group.Group;
038import org.ametys.core.group.GroupIdentity;
039import org.ametys.core.group.GroupManager;
040import org.ametys.core.user.CurrentUserProvider;
041import org.ametys.core.user.User;
042import org.ametys.core.user.UserIdentity;
043import org.ametys.core.user.UserManager;
044import org.ametys.core.user.population.UserPopulationDAO;
045import org.ametys.plugins.extraction.ExtractionConstants;
046import org.ametys.plugins.extraction.execution.Extraction;
047import org.ametys.plugins.extraction.execution.Extraction.ExtractionProfile;
048import org.ametys.plugins.extraction.execution.Extraction.Visibility;
049import org.ametys.plugins.extraction.execution.ExtractionDefinitionReader;
050
051/**
052 * Action populating a map containing information about the visibility of an {@link Extraction}
053 */
054public class GetExtractionProfileTreeAction extends ServiceableAction
055{
056    /** Source resolver */
057    protected org.apache.excalibur.source.SourceResolver _sourceResolver;
058    /** Extraction definition reader */
059    protected ExtractionDefinitionReader _reader;
060    /** Group manager */
061    protected GroupManager _groupManager;
062    /** User manager */
063    protected UserManager _userManager;
064    /** The current user provider */
065    protected CurrentUserProvider _userProvider;
066    /** The user population DAO */
067    protected UserPopulationDAO _userPopulationDAO;
068    
069    @Override
070    public void service(ServiceManager smanager) throws ServiceException
071    {
072        super.service(smanager);
073        _sourceResolver = (org.apache.excalibur.source.SourceResolver) smanager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
074        _reader = (ExtractionDefinitionReader) smanager.lookup(ExtractionDefinitionReader.ROLE);
075        _userManager = (UserManager) smanager.lookup(UserManager.ROLE);
076        _groupManager = (GroupManager) smanager.lookup(GroupManager.ROLE);
077        _userProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
078        _userPopulationDAO = (UserPopulationDAO) smanager.lookup(UserPopulationDAO.ROLE);
079    }
080    
081    @Override
082    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
083    {
084        Request request = ObjectModelHelper.getRequest(objectModel);
085        
086        String definitionFilePath = request.getParameter("definitionFilePath");
087        Extraction extraction = _readExtractionDefinitionFile(definitionFilePath);
088        
089        Map<String, Object> results = new HashMap<>();
090        
091        List<Object> profiles = new LinkedList<>();
092        results.put("children", profiles);
093        
094        // Read only profile
095        profiles.add(_getProfileInfo(extraction, ExtractionProfile.READ_ACCESS));
096        
097        // Read write profile
098        profiles.add(_getProfileInfo(extraction, ExtractionProfile.WRITE_ACCESS));
099        
100        request.setAttribute(JSonReader.OBJECT_TO_READ, results);
101        
102        return EMPTY_MAP;
103    }
104    
105    private Extraction _readExtractionDefinitionFile(String relativeDefinitionFilePath) throws Exception
106    {
107        String definitionFilePath = ExtractionConstants.DEFINITIONS_DIR + relativeDefinitionFilePath;
108        Source src = _sourceResolver.resolveURI(definitionFilePath);
109        File file = ((FileSource) src).getFile();
110        
111        if (!file.exists())
112        {
113            throw new IllegalArgumentException("The file " + definitionFilePath + " does not exist.");
114        }
115        
116        return _reader.readExtractionDefinitionFile(file);
117    }
118
119    private Map<String, Object> _getProfileInfo(Extraction extraction, ExtractionProfile profile)
120    {
121        Map<String, Object> profileMap = new HashMap<>();
122        
123        profileMap.put("type", "profile");
124        profileMap.put("id", profile.toString());
125        profileMap.put("text", profile.getTitle());
126        profileMap.put("description", profile.getDescription());
127        
128        List<Map<String, Object>> entries = new LinkedList<>();
129         
130        if (extraction != null)
131        {
132            // Check shared visibility + author is current user
133            boolean addInfo = Visibility.SHARED.equals(extraction.getVisibility()) && extraction.getAuthor().equals(_userProvider.getUser());
134            
135            if (addInfo)
136            {
137                Set<UserIdentity> users = extraction.getGrantedUsers(profile);
138                for (UserIdentity user : users)
139                {
140                    _addUserInfo(entries, user);
141                }
142                
143                Set<GroupIdentity> groups = extraction.getGrantedGroups(profile);
144                for (GroupIdentity group : groups)
145                {
146                    _addGroupInfo(entries, group);
147                }
148            }
149        }
150        
151        if (entries.isEmpty())
152        {
153            profileMap.put("leaf", true);
154        }
155        else
156        {
157            profileMap.put("children", entries);
158        }
159        
160        return profileMap;
161    }
162    
163    private void _addUserInfo(List<Map<String, Object>> entries, UserIdentity userIdentity)
164    {
165        String populationId = userIdentity.getPopulationId();
166        User user = _userManager.getUser(populationId, userIdentity.getLogin());
167        
168        Map<String, Object> entry = new HashMap<>();
169        entry.put("type", "user");
170        entry.put("id", UserIdentity.userIdentityToString(userIdentity));
171        entry.put("login", userIdentity.getLogin());
172        entry.put("populationId", populationId);
173        entry.put("populationLabel", _userPopulationDAO.getUserPopulation(populationId).getLabel());
174        entry.put("leaf", true);
175        
176        if (user != null)
177        {
178            entry.put("name", user.getName());
179            entry.put("fullName", user.getFullName());
180        }
181        else
182        {
183            entry.put("not-found", true);
184        }
185        
186        entries.add(entry);
187    }
188
189    private void _addGroupInfo(List<Map<String, Object>> entries, GroupIdentity groupIdentity)
190    {
191        Group group = _groupManager.getGroup(groupIdentity.getDirectoryId(), groupIdentity.getId());
192        
193        Map<String, Object> entry = new HashMap<>();
194        entry.put("type", "group");
195        entry.put("id", GroupIdentity.groupIdentityToString(groupIdentity));
196        entry.put("groupId", groupIdentity.getId());
197        entry.put("groupDirectory", groupIdentity.getDirectoryId());
198        entry.put("leaf", true);
199        
200        if (group != null)
201        {
202            entry.put("label", group.getLabel());
203        }
204        else
205        {
206            entry.put("not-found", true);
207        }
208        
209        entries.add(entry);
210    }
211}