001/*
002 *  Copyright 2017 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.userdirectory.rights;
017
018import java.util.Collections;
019import java.util.HashSet;
020import java.util.Set;
021
022import org.apache.avalon.framework.context.Context;
023import org.apache.avalon.framework.context.ContextException;
024import org.apache.avalon.framework.context.Contextualizable;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.components.ContextHelper;
028import org.apache.cocoon.environment.Request;
029
030import org.ametys.cms.contenttype.ContentTypesHelper;
031import org.ametys.cms.repository.Content;
032import org.ametys.core.right.AccessController;
033import org.ametys.plugins.core.impl.right.AbstractHierarchicalAccessController;
034import org.ametys.plugins.repository.AmetysObject;
035import org.ametys.plugins.repository.AmetysObjectResolver;
036import org.ametys.plugins.repository.RepositoryConstants;
037import org.ametys.plugins.repository.UnknownAmetysObjectException;
038import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector;
039import org.ametys.plugins.userdirectory.OrganisationChartPageHandler;
040import org.ametys.plugins.userdirectory.UserDirectoryHelper;
041import org.ametys.plugins.userdirectory.UserDirectoryPageHandler;
042
043/**
044 * {@link AccessController} for a User directory {@link Content}
045 */
046public class UserDirectoryContentAccessController extends AbstractHierarchicalAccessController<AmetysObject> implements Contextualizable
047{
048    /** The avalon context */
049    protected Context _context;
050    
051    /** Ametys Object Resolver */
052    protected AmetysObjectResolver _resolver;
053    
054    /** The organisation chart page handler */
055    protected OrganisationChartPageHandler _organisationChartPageHandler;
056    
057    /** The content type helper */
058    protected ContentTypesHelper _contentTypeHelper;
059    
060    /** The user directory helper */
061    protected UserDirectoryHelper _userDirectoryHelper;
062    
063    public void contextualize(Context context) throws ContextException
064    {
065        _context = context;
066    }
067    
068    @Override
069    public void service(ServiceManager manager) throws ServiceException
070    {
071        super.service(manager);
072        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
073        _organisationChartPageHandler = (OrganisationChartPageHandler) manager.lookup(OrganisationChartPageHandler.ROLE);
074        _contentTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE);
075        _userDirectoryHelper = (UserDirectoryHelper) manager.lookup(UserDirectoryHelper.ROLE);
076    }
077    
078    @Override
079    public boolean isSupported(Object object)
080    {
081        if (object instanceof Content)
082        {
083            return _isContentUser(object) || _isContentOrgUnit(object);
084        }
085        
086        return false;
087    }
088    
089    @Override
090    protected Set<AmetysObject> _getParents(AmetysObject object)
091    {
092        if (object instanceof Content)
093        {
094            Set<AmetysObject> parents = new HashSet<>();
095            
096            Request request = ContextHelper.getRequest(_context);
097            String originalWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request);
098            try
099            {
100                RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE);
101                if (_isContentOrgUnit(object))
102                {
103                    Content parentContent = _organisationChartPageHandler.getParentContent((Content) object);
104                    if (parentContent != null)
105                    {
106                        parents.add(parentContent);
107                    }
108                    else
109                    {
110                        parents.add(_userDirectoryHelper.getUserDirectoryRootContent());
111                    }
112                }
113                else if (_isContentUser(object))
114                {
115                    parents.add(_userDirectoryHelper.getUserDirectoryRootContent());
116                }
117            }
118            finally
119            {
120                RequestAttributeWorkspaceSelector.setForcedWorkspace(request, originalWorkspace);
121            }
122            
123            return parents;
124        }
125        else
126        {
127            return null;
128        }
129    }
130    
131    @Override
132    protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts)
133    {
134        if (workspacesContexts.contains("/cms"))
135        {
136            try
137            {
138                return Collections.singleton(_userDirectoryHelper.getUserDirectoryRootContent());
139            }
140            catch (UnknownAmetysObjectException e)
141            {
142                // Root does not exist yet
143                return null;
144            }
145        }
146        return null;
147    }
148    
149    private boolean _isContentUser(Object object)
150    {
151        return _contentTypeHelper.isInstanceOf((Content) object, UserDirectoryPageHandler.ABSTRACT_USER_CONTENT_TYPE);
152    }
153    
154    private boolean _isContentOrgUnit(Object object)
155    {
156        return _contentTypeHelper.isInstanceOf((Content) object, OrganisationChartPageHandler.ORGUNIT_CONTENT_TYPE);
157    }
158}