001/*
002 *  Copyright 2015 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.core.right.profile;
017
018import java.util.HashMap;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.component.Component;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.commons.lang3.StringUtils;
027
028import org.ametys.core.group.InvalidModificationException;
029import org.ametys.core.right.Profile;
030import org.ametys.core.right.RightManager;
031import org.ametys.core.right.RightProfilesDAO;
032import org.ametys.core.right.RightsException;
033import org.ametys.core.ui.Callable;
034import org.ametys.core.user.CurrentUserProvider;
035import org.ametys.core.user.UserIdentity;
036import org.ametys.runtime.plugin.component.AbstractLogEnabled;
037
038/**
039 * DAO for manipulating {@link Profile}
040 *
041 */
042public class ProfileDAO extends AbstractLogEnabled implements Serviceable, Component
043{
044    /** The service manager */
045    protected ServiceManager _smanager;
046    /** The current user provider. */
047    protected CurrentUserProvider _currentUserProvider;
048    /** The right manager */
049    protected RightManager _rightManager;
050    /** The SQL DAO */
051    protected RightProfilesDAO _profilesDAO;
052
053    public void service(ServiceManager smanager) throws ServiceException
054    {
055        _smanager = smanager;
056        _rightManager = (RightManager) smanager.lookup(RightManager.ROLE);
057        _profilesDAO = (RightProfilesDAO) smanager.lookup(RightProfilesDAO.ROLE);
058    }
059    
060    /**
061     * Get profile's properties
062     * @param id The profile's id
063     * @return The profile's information
064     * @throws InvalidModificationException If modification are not possible
065     * @throws ServiceException If there is an issue with the service manager
066     */
067    @Callable
068    public Map<String, Object> getProfile(String id) throws ServiceException, InvalidModificationException
069    {
070        return getProfile(id, false);
071    }
072    
073    /**
074     * Get profile's properties
075     * @param id The profile's id
076     * @param withRights True to also get the rights of the profile
077     * @return The profile's information
078     * @throws InvalidModificationException If modification are not possible
079     * @throws ServiceException If there is an issue with the service manager
080     */
081    @Callable
082    public Map<String, Object> getProfile(String id, boolean withRights) throws ServiceException, InvalidModificationException
083    {
084        Profile profile = _profilesDAO.getProfile(id);
085        if (profile == null)
086        {
087            return null;
088        }
089        
090        Map<String, Object> jsonProfile = profile.toJSON();
091        if (withRights)
092        {
093            jsonProfile.put("rights", _profilesDAO.getRights(profile));
094        }
095        
096        return jsonProfile;
097        
098    }
099
100    /**
101     * Creates a new profile
102     * @param name The profile's name
103     * @param context The profile's context
104     * @return The profile's information
105     * @throws InvalidModificationException If modification are not possible
106     * @throws ServiceException If there is an issue with the service manager
107     */
108    @Callable(right = "Runtime_Rights_Rights_Profile_Handle")
109    public Map<String, Object> addProfile (String name, String context) throws ServiceException, InvalidModificationException
110    {
111        getLogger().debug("Starting profile creation");
112    
113        if (StringUtils.isBlank(name))
114        {
115            throw new IllegalArgumentException("The profile name cannot be empty");
116        }
117        
118        getLogger().info("User {} is adding a new profile '{}'", _getCurrentUser(), name);
119        
120        Profile profile = _profilesDAO.addProfile(name, context);
121        
122        getLogger().debug("Ending profile creation");
123        
124        return profile.toJSON();
125    }
126    
127    /**
128     * Renames a profile
129     * @param id The profile's id
130     * @param name The profile's new name
131     * @return The profile's information
132     * @throws InvalidModificationException If modification are not possible
133     * @throws ServiceException If there is an issue with the service manager
134     */
135    @Callable(right = "Runtime_Rights_Rights_Profile_Handle")
136    public Map<String, Object> renameProfile (String id, String name) throws ServiceException, InvalidModificationException
137    {
138        getLogger().debug("Starting profile modification");
139        
140        if (StringUtils.isBlank(name))
141        {
142            throw new IllegalArgumentException("The profile new name cannot be empty");
143        }
144        
145        getLogger().info("User {} is renaming the profile '{}' to '{}'", _getCurrentUser(), id, name);
146        
147        Profile profile = _profilesDAO.getProfile(id);
148        if (profile == null)
149        {
150            Map<String, Object> result = new HashMap<>();
151            result.put("error", "unknown-profile");
152            return result;
153        }
154        else
155        {
156            _profilesDAO.renameProfile(profile, name);
157        }
158        
159        getLogger().debug("Ending profile modification");
160        
161        return profile.toJSON();
162    }
163    
164    /**
165     * Edit profile's rights
166     * @param id The profile's id
167     * @param rights The profile's rights
168     * @return The profile's information
169     * @throws InvalidModificationException If modification are not possible
170     * @throws ServiceException If there is an issue with the service manager
171     */
172    @Callable(right = "Runtime_Rights_Rights_Profile_Handle")
173    public Map<String, Object> editProfileRights (String id, List<String> rights) throws ServiceException, InvalidModificationException
174    {
175        getLogger().debug("Starting profile modification");
176        
177        getLogger().info("User {} is edit rights of profile '{}'", _getCurrentUser(), id);
178        
179        Profile profile = _profilesDAO.getProfile(id);
180        if (profile == null)
181        {
182            Map<String, Object> result = new HashMap<>();
183            result.put("error", "unknown-profile");
184            return result;
185        }
186        else
187        {
188            _profilesDAO.updateRights(profile, rights);
189        }
190        
191        getLogger().debug("Ending profile modification");
192        
193        return profile.toJSON();
194    }
195    
196    
197    /**
198     * Deletes profiles
199     * @param ids The ids of profiles to delete
200     * @throws InvalidModificationException If modification are not possible
201     * @throws ServiceException If there is an issue with the service manager
202     */
203    @Callable(right = "Runtime_Rights_Rights_Profile_Handle")
204    public void deleteProfiles (List<String> ids) throws InvalidModificationException, ServiceException
205    {
206        getLogger().debug("Starting profile removal");
207        
208        for (String id : ids)
209        {
210            if (RightManager.READER_PROFILE_ID.equals(id))
211            {
212                throw new RightsException("You cannot remove the system profile 'READER'");
213            }
214            
215            getLogger().info("User {} is is removing profile '{}'", _getCurrentUser(), id);
216            
217            Profile profile = _profilesDAO.getProfile(id);
218            if (profile != null)
219            {
220                _profilesDAO.deleteProfile(profile);
221            }
222            else
223            {
224                getLogger().info("User {} is trying to remove an unexisting profile '{}'", _getCurrentUser(), id);
225            }
226        }
227
228        getLogger().debug("Ending profile removal");
229    }
230    
231    /**
232     * Provides the login of the current user.
233     * @return the login which cannot be <code>null</code>.
234     */
235    protected UserIdentity _getCurrentUser()
236    {
237        if (_currentUserProvider == null)
238        {
239            try
240            {
241                _currentUserProvider = (CurrentUserProvider) _smanager.lookup(CurrentUserProvider.ROLE);
242            }
243            catch (ServiceException e)
244            {
245                throw new IllegalStateException(e);
246            }
247        }
248        
249        return _currentUserProvider.getUser();
250    }
251}