001/*
002 *  Copyright 2022 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.odf.init;
017
018import java.util.Collections;
019import java.util.Map;
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.avalon.framework.service.Serviceable;
028import org.apache.cocoon.components.ContextHelper;
029import org.apache.cocoon.environment.Request;
030
031import org.ametys.cms.content.ContentHelper;
032import org.ametys.cms.repository.Content;
033import org.ametys.cms.rights.ReferenceTableAccessController;
034import org.ametys.core.group.GroupIdentity;
035import org.ametys.core.right.AccessController;
036import org.ametys.core.right.AccessExplanation;
037import org.ametys.core.right.RightManager;
038import org.ametys.core.right.RightManager.RightResult;
039import org.ametys.core.user.UserIdentity;
040import org.ametys.runtime.i18n.I18nizableText;
041import org.ametys.runtime.plugin.component.PluginAware;
042import org.ametys.runtime.plugins.admin.rights.AdminAccessController;
043
044/**
045 * Access controller to allow users with ODF_Rights_RefTableData_Sync right on context /admin to modify reference tables during initialization only.
046 */
047public class OdfRefTableDataSynchronizationAccessController implements AccessController, Contextualizable, Serviceable, PluginAware
048{
049    /** Attribute to add to activate the current access controller */
050    public static final String ODF_REF_TABLE_SYNCHRONIZATION = OdfRefTableDataSynchronizationAccessController.class.getName() + "$isSynchronization";
051    
052    /** Right to initialize ODF reference table data */
053    public static final String ODF_REF_TABLE_SYNCHRONIZATION_RIGHT = "ODF_Rights_RefTableData_Sync";
054    
055    private static final Set<String> __SUPPORTED_RIGHTS = Set.of("Workflow_Rights_Edition_Online");
056    
057    /** The helper for contents */
058    protected ContentHelper _contentHelper;
059    
060    /** The right manager */
061    protected RightManager _rightManager;
062
063    private Context _context;
064    private String _id;
065    
066    @Override
067    public void contextualize(Context context) throws ContextException
068    {
069        _context = context;
070    }
071
072    public void service(ServiceManager manager) throws ServiceException
073    {
074        _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE);
075        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
076    }
077    
078    public void setPluginInfo(String pluginName, String featureName, String id)
079    {
080        _id = id;
081    }
082    
083    @Override
084    public boolean isSupported(Object object)
085    {
086        Request request = ContextHelper.getRequest(_context);
087        if (request.getAttribute(ODF_REF_TABLE_SYNCHRONIZATION) != null)
088        {
089            return object instanceof Content && _contentHelper.isReferenceTable((Content) object)
090                    || ReferenceTableAccessController.ROOT_CONTEXT.equals(object);
091        }
092        
093        return false;
094    }
095    
096    public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object)
097    {
098        if (__SUPPORTED_RIGHTS.contains(rightId))
099        {
100            RightResult rightResult = _rightManager.hasRight(user, ODF_REF_TABLE_SYNCHRONIZATION_RIGHT, AdminAccessController.ADMIN_RIGHT_CONTEXT);
101            return switch (rightResult)
102            {
103                case RIGHT_ALLOW -> AccessResult.USER_ALLOWED;
104                case RIGHT_DENY -> AccessResult.USER_DENIED;
105                default -> AccessResult.UNKNOWN;
106            };
107        }
108        
109        return AccessResult.UNKNOWN;
110    }
111    
112    public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object)
113    {
114        return AccessResult.UNKNOWN;
115    }
116    
117    public AccessResult getPermissionForAnonymous(String rightId, Object object)
118    {
119        return AccessResult.UNKNOWN;
120    }
121    
122    public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object)
123    {
124        return Collections.EMPTY_MAP;
125    }
126    
127    public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object)
128    {
129        return Collections.EMPTY_MAP;
130    }
131    
132    public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
133    {
134        return Collections.EMPTY_MAP;
135    }
136    
137    public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
138    {
139        return AccessResult.UNKNOWN;
140    }
141    
142    public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object)
143    {
144        return Collections.EMPTY_MAP;
145    }
146    
147    public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object)
148    {
149        return Collections.EMPTY_MAP;
150    }
151    
152    public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object)
153    {
154        return AccessResult.UNKNOWN;
155    }
156    
157    public AccessResult getReadAccessPermissionForAnonymous(Object object)
158    {
159        return AccessResult.UNKNOWN;
160    }
161    
162    public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups)
163    {
164        return false;
165    }
166    
167    public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
168    {
169        return false;
170    }
171    
172    public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
173    {
174        return false;
175    }
176    
177    public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId)
178    {
179        return false;
180    }
181    
182    public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
183    {
184        return false;
185    }
186    
187    public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
188    {
189        return false;
190    }
191    
192    @Override
193    public AccessExplanation explainPermission(UserIdentity user, Set<GroupIdentity> groups, String rightId, Object object)
194    {
195        AccessResult permission = getPermission(user, groups, rightId, object);
196        if (permission == AccessResult.USER_ALLOWED)
197        {
198            return new AccessExplanation(getId(), permission , new I18nizableText("plugin.odf", "PLUGINS_ODF_REF_TABLE_DATA_ACCESS_CONTROLLER_ALLOWED_PERMISSION"));
199            
200        }
201        else if (permission == AccessResult.USER_DENIED)
202        {
203            return new AccessExplanation(getId(), permission , new I18nizableText("plugin.odf", "PLUGINS_ODF_REF_TABLE_DATA_ACCESS_CONTROLLER_DENIED_PERMISSION"));
204        }
205        else // unknown
206        {
207            return AccessController.getDefaultAccessExplanation(getId(), permission);
208        }
209    }
210    
211    public Map<ExplanationObject, Map<Permission, AccessExplanation>> explainAllPermissions(UserIdentity identity, Set<GroupIdentity> groups)
212    {
213        // Only used in admin context
214        return Map.of();
215    }
216
217    public String getId()
218    {
219        return _id;
220    }
221
222    public I18nizableText getObjectLabel(Object object)
223    {
224        // explainAllPermissions is not implemented
225        throw new UnsupportedOperationException();
226    }
227
228    public I18nizableText getObjectCategory(Object object)
229    {
230        // explainAllPermissions is not implemented
231        throw new UnsupportedOperationException();
232    }
233}