001/*
002 *  Copyright 2016 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.runtime.plugins.admin.superuser;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025
026import org.ametys.core.right.Profile;
027import org.ametys.core.right.ProfileAssignmentStorageExtensionPoint;
028import org.ametys.core.right.RightAssignmentContext;
029import org.ametys.core.right.RightAssignmentContextExtensionPoint;
030import org.ametys.core.right.RightProfilesDAO;
031import org.ametys.core.right.RightsExtensionPoint;
032import org.ametys.core.ui.Callable;
033import org.ametys.core.ui.StaticClientSideElement;
034import org.ametys.core.user.UserIdentity;
035import org.ametys.runtime.workspace.WorkspaceMatcher;
036
037/**
038 * This implementation creates a control allowing to affect a super user to a given context
039 */
040public class SuperUserClientSideElement extends StaticClientSideElement
041{
042    /** The service manager */
043    protected ServiceManager _sManager;
044    /** The extension point for the rights */
045    protected RightsExtensionPoint _rightsEP;
046    /** The profiles DAO */
047    protected RightProfilesDAO _profilesDAO;
048    /** The profile assignments storage */
049    protected ProfileAssignmentStorageExtensionPoint _profileAssignmentStorageEP;
050    /** The extension point for right contexts */
051    protected RightAssignmentContextExtensionPoint _rightCtxEP;
052    
053    @Override
054    public void service(ServiceManager smanager) throws ServiceException
055    {
056        super.service(smanager);
057        _sManager = smanager;
058    }
059    
060    /**
061     * Affect a user to the given profile on the given context
062     * @param user The user
063     * @param profileId The profile id
064     * @param jsParameters The client-side parameters
065     */
066    @Callable
067    public void affectUserToProfile(Map<String, String> user, String profileId, Map<String, Object> jsParameters)
068    {
069        try
070        {
071            if (_profileAssignmentStorageEP == null)
072            {
073                _profileAssignmentStorageEP = (ProfileAssignmentStorageExtensionPoint) _sManager.lookup(ProfileAssignmentStorageExtensionPoint.ROLE);
074            }
075            if (_rightCtxEP == null)
076            {
077                _rightCtxEP = (RightAssignmentContextExtensionPoint) _sManager.lookup(RightAssignmentContextExtensionPoint.ROLE);
078            }
079        }
080        catch (ServiceException e)
081        {
082            throw new IllegalStateException(e);
083        }
084        
085        // Get all root contexts for the configured workspace
086        List<Object> rootContexts = new ArrayList<>();
087        for (String id : _rightCtxEP.getExtensionsIds())
088        {
089            RightAssignmentContext rightCtx = _rightCtxEP.getExtension(id);
090            rootContexts.addAll(rightCtx.getRootContexts(getContextualParameters(jsParameters)));
091        }
092        
093        // Affect user to this profile
094        UserIdentity userIdentity = new UserIdentity(user.get("login"), user.get("populationId"));
095        for (Object rootContext : rootContexts)
096        {
097            _profileAssignmentStorageEP.removeDeniedProfileFromUser(userIdentity, profileId, rootContext);
098            _profileAssignmentStorageEP.allowProfileToUser(userIdentity, profileId, rootContext);
099        }
100    }
101    
102    /**
103     * Affect a user to a new super profile on the given context. First, a new profile with the given name will be created and filled with all rights, and then the user will be affected.
104     * @param user The user
105     * @param newProfileName The name of the super profile to create
106     * @param jsParameters The client-side parameters
107     * @return The id of the created profile
108     */
109    @Callable
110    public String affectUserToNewProfile(Map<String, String> user, String newProfileName, Map<String, Object> jsParameters)
111    {
112        try
113        {
114            if (_rightsEP == null)
115            {
116                _rightsEP = (RightsExtensionPoint) _sManager.lookup(RightsExtensionPoint.ROLE);
117            }
118            if (_profilesDAO == null)
119            {
120                _profilesDAO = (RightProfilesDAO) _sManager.lookup(RightProfilesDAO.ROLE);
121            }
122        }
123        catch (ServiceException e)
124        {
125            throw new IllegalStateException(e);
126        }
127        
128        // Create a super profile
129        Profile newSuperProfile = _profilesDAO.addProfile(newProfileName, null);
130        _profilesDAO.addRights(newSuperProfile, new ArrayList<>(_rightsEP.getExtensionsIds()));
131
132        affectUserToProfile(user, newSuperProfile.getId(), jsParameters);
133        
134        return newSuperProfile.getId();
135    }
136    
137    /**
138     * Get the contextual parameters used to determines the root contexts
139     * @param jsParameters the client-side parameters
140     * @return the contextual parameters
141     */
142    protected Map<String, Object> getContextualParameters(Map<String, Object> jsParameters)
143    {
144        Map<String, Object> contextParameters = new HashMap<>(jsParameters);
145        
146        String workspaceName = (String) _script.getParameters().get(WorkspaceMatcher.WORKSPACE_NAME);
147        contextParameters.put(WorkspaceMatcher.WORKSPACE_NAME, workspaceName);
148        return contextParameters;
149    }
150}