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