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.ContentTypeAccessController;
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    public boolean supports(Object object)
084    {
085        Request request = ContextHelper.getRequest(_context);
086        if (request.getAttribute(ODF_REF_TABLE_SYNCHRONIZATION) != null)
087        {
088            return object instanceof Content && _contentHelper.isReferenceTable((Content) object)
089                    || ContentTypeAccessController.REFERENCE_TABLE_ROOT_CONTEXT.equals(object);
090        }
091        
092        return false;
093    }
094    
095    public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object)
096    {
097        if (__SUPPORTED_RIGHTS.contains(rightId))
098        {
099            RightResult rightResult = _rightManager.hasRight(user, ODF_REF_TABLE_SYNCHRONIZATION_RIGHT, AdminAccessController.ADMIN_RIGHT_CONTEXT);
100            return switch (rightResult)
101            {
102                case RIGHT_ALLOW -> AccessResult.USER_ALLOWED;
103                case RIGHT_DENY -> AccessResult.USER_DENIED;
104                default -> AccessResult.UNKNOWN;
105            };
106        }
107        
108        return AccessResult.UNKNOWN;
109    }
110    
111    public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object)
112    {
113        return AccessResult.UNKNOWN;
114    }
115    
116    public AccessResult getPermissionForAnonymous(String rightId, Object object)
117    {
118        return AccessResult.UNKNOWN;
119    }
120    
121    public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object)
122    {
123        return Collections.EMPTY_MAP;
124    }
125    
126    public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object)
127    {
128        return Collections.EMPTY_MAP;
129    }
130    
131    public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
132    {
133        return Collections.EMPTY_MAP;
134    }
135    
136    public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object)
137    {
138        return AccessResult.UNKNOWN;
139    }
140    
141    public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object)
142    {
143        return Collections.EMPTY_MAP;
144    }
145    
146    public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object)
147    {
148        return Collections.EMPTY_MAP;
149    }
150    
151    public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object)
152    {
153        return AccessResult.UNKNOWN;
154    }
155    
156    public AccessResult getReadAccessPermissionForAnonymous(Object object)
157    {
158        return AccessResult.UNKNOWN;
159    }
160    
161    public boolean hasUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups)
162    {
163        return false;
164    }
165    
166    public boolean hasAnyConnectedUserAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
167    {
168        return false;
169    }
170    
171    public boolean hasAnonymousAnyReadAccessPermissionOnWorkspace(Set<Object> workspacesContexts)
172    {
173        return false;
174    }
175    
176    public boolean hasUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, UserIdentity user, Set<GroupIdentity> userGroups, String rightId)
177    {
178        return false;
179    }
180    
181    public boolean hasAnyConnectedUserAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
182    {
183        return false;
184    }
185    
186    public boolean hasAnonymousAnyPermissionOnWorkspace(Set<Object> workspacesContexts, String rightId)
187    {
188        return false;
189    }
190    
191    @Override
192    public AccessExplanation explainPermission(UserIdentity user, Set<GroupIdentity> groups, String rightId, Object object)
193    {
194        AccessResult permission = getPermission(user, groups, rightId, object);
195        if (permission == AccessResult.USER_ALLOWED)
196        {
197            return new AccessExplanation(getId(), permission , new I18nizableText("plugin.odf", "PLUGINS_ODF_REF_TABLE_DATA_ACCESS_CONTROLLER_ALLOWED_PERMISSION"));
198            
199        }
200        else if (permission == AccessResult.USER_DENIED)
201        {
202            return new AccessExplanation(getId(), permission , new I18nizableText("plugin.odf", "PLUGINS_ODF_REF_TABLE_DATA_ACCESS_CONTROLLER_DENIED_PERMISSION"));
203        }
204        else // unknown
205        {
206            return AccessController.getDefaultAccessExplanation(getId(), permission);
207        }
208    }
209    
210    public Map<ExplanationObject, Map<Permission, AccessExplanation>> explainAllPermissions(UserIdentity identity, Set<GroupIdentity> groups)
211    {
212        // Only used in admin context
213        return Map.of();
214    }
215    
216    public Map<Permission, AccessExplanation> explainAllPermissionsForAnonymous(Object object)
217    {
218        // Only used in admin context
219        return Map.of();
220    }
221    
222    public Map<Permission, AccessExplanation> explainAllPermissionsForAnyConnected(Object object)
223    {
224        // Only used in admin context
225        return Map.of();
226    }
227    
228    public Map<UserIdentity, Map<Permission, AccessExplanation>> explainAllPermissionsByUser(Object object)
229    {
230        // Only used in admin context
231        return Map.of();
232    }
233
234    public Map<GroupIdentity, Map<Permission, AccessExplanation>> explainAllPermissionsByGroup(Object object)
235    {
236        // Only used in admin context
237        return Map.of();
238    }
239    
240    public String getId()
241    {
242        return _id;
243    }
244
245    public I18nizableText getObjectLabel(Object object)
246    {
247        // explainAllPermissions is not implemented
248        throw new UnsupportedOperationException();
249    }
250
251    public I18nizableText getObjectCategory(Object object)
252    {
253        // explainAllPermissions is not implemented
254        throw new UnsupportedOperationException();
255    }
256}