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.plugins.workspaces.project.rights;
017
018import java.util.Collections;
019import java.util.List;
020import java.util.Map;
021import java.util.Set;
022
023import org.apache.avalon.framework.context.Context;
024import org.apache.avalon.framework.context.ContextException;
025import org.apache.avalon.framework.context.Contextualizable;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.cocoon.components.ContextHelper;
029import org.apache.cocoon.environment.Request;
030import org.apache.commons.collections4.CollectionUtils;
031import org.apache.commons.lang3.ArrayUtils;
032
033import org.ametys.core.group.GroupIdentity;
034import org.ametys.core.right.AccessController;
035import org.ametys.core.user.UserIdentity;
036import org.ametys.plugins.core.impl.right.AbstractProfileStorageBasedAccessController;
037import org.ametys.plugins.workspaces.project.ProjectManager;
038import org.ametys.plugins.workspaces.project.objects.Project;
039import org.ametys.web.repository.site.SiteManager;
040
041/**
042 * {@link AccessController} for a {@link Project}
043 * The projects' managers have all rights on their projects
044 */
045public class ProjectAccessController extends AbstractProfileStorageBasedAccessController implements Contextualizable
046{
047    private static final String __RIGHT_PROJECT_FO_EDIT = "Plugins_Workspaces_Rights_Project_FO_Edit";
048    
049    /** The avalon context */
050    protected Context _context;
051    /** The web site manager */
052    protected SiteManager _siteManager;
053    /** The project manager */
054    protected ProjectManager _projectManager;
055
056    public void contextualize(Context context) throws ContextException
057    {
058        _context = context;
059    }
060    
061    @Override
062    public void service(ServiceManager manager) throws ServiceException
063    {
064        super.service(manager);
065        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
066        _projectManager = (ProjectManager) manager.lookup(ProjectManager.ROLE);
067    }
068    
069    @Override
070    public boolean isSupported(Object object)
071    {
072        return object instanceof Project;
073    }
074
075    @Override
076    protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts)
077    {
078        if (workspacesContexts.contains("/web"))
079        {
080            Request request = ContextHelper.getRequest(_context);
081            
082            String siteName = request.getParameter("siteName");
083            if (siteName == null)
084            {
085                siteName = (String) request.getAttribute("siteName");
086            }
087            if (siteName == null)
088            {
089                siteName = (String) request.getAttribute("site");
090            }
091            
092            if (siteName != null)
093            {
094                List<String> projects = _projectManager.getProjectsForSite(siteName);
095                if (!projects.isEmpty())
096                {
097                    return Collections.singleton(projects.get(0));
098                }
099            }
100            
101            getLogger().warn("Could not determine current project to obtain all permissions");
102        }
103        
104        return null;
105    }
106
107    @Override
108    public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object)
109    {
110        AccessResult permission = super.getPermission(user, userGroups, rightId, object);
111        
112        if (object instanceof Project && __RIGHT_PROJECT_FO_EDIT.equals(rightId))
113        {
114            Project project = (Project) object;
115            if (ArrayUtils.contains(project.getManagers(), user))
116            {
117                permission =  AccessResult.merge(permission, AccessResult.USER_ALLOWED);
118            }
119        }
120
121        return permission;
122    }
123
124    @Override
125    public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
126    {
127        Map<String, AccessResult> permissionByRight = super.getPermissionByRight(user, userGroups, object);
128        
129        if (object instanceof Project)
130        {
131            Project project = (Project) object;
132            if (ArrayUtils.contains(project.getManagers(), user))
133            {
134                if (permissionByRight.containsKey(__RIGHT_PROJECT_FO_EDIT))
135                {
136                    AccessResult oldPermission = permissionByRight.get(__RIGHT_PROJECT_FO_EDIT);
137                    permissionByRight.put(__RIGHT_PROJECT_FO_EDIT, AccessResult.merge(oldPermission, AccessResult.USER_ALLOWED));
138                }
139            }
140        }
141        
142        return permissionByRight;
143    }
144    
145    @Override
146    public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object)
147    {
148        Map<UserIdentity, AccessResult> permissionByUser = super.getPermissionByUser(rightId, object);
149        
150        if (object instanceof Project && __RIGHT_PROJECT_FO_EDIT.equals(rightId))
151        {
152            Project project = (Project) object;
153            
154            for (UserIdentity manager : project.getManagers())
155            {
156                AccessResult oldPermission = permissionByUser.containsKey(manager) ? permissionByUser.get(manager) : AccessResult.UNKNOWN;
157                permissionByUser.put(manager, AccessResult.merge(oldPermission, AccessResult.USER_ALLOWED));
158            }
159        }
160        
161        return permissionByUser;
162    }
163
164    @Override
165    public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId)
166    {
167        if (__RIGHT_PROJECT_FO_EDIT.equals(rightId))
168        {
169            Set<? extends Object> rootContexts = _convertWorkspaceToRootRightContexts(workspacesContexts);
170            if (!CollectionUtils.isEmpty(rootContexts))
171            {
172                for (Object projectName : rootContexts)
173                {
174                    if (projectName instanceof String && _projectManager.hasProject((String) projectName))
175                    {
176                        Project project = _projectManager.getProject((String) projectName);
177                        if (ArrayUtils.contains(project.getManagers(), user))
178                        {
179                            return true;
180                        }
181                    }
182                }
183            }
184        }
185        
186        return super.hasUserAnyPermissionOnWorkspace(workspacesContexts, user, userGroups, rightId);
187    }
188}