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.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; 030 031import org.ametys.cms.contenttype.ContentTypesHelper; 032import org.ametys.cms.repository.Content; 033import org.ametys.core.right.AccessController; 034import org.ametys.core.right.RightsException; 035import org.ametys.plugins.core.impl.right.AbstractHierarchicalAccessController; 036import org.ametys.plugins.repository.AmetysObject; 037import org.ametys.plugins.repository.AmetysObjectResolver; 038import org.ametys.plugins.repository.RepositoryConstants; 039import org.ametys.plugins.repository.UnknownAmetysObjectException; 040import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector; 041import org.ametys.plugins.userdirectory.OrganisationChartPageHandler; 042import org.ametys.plugins.userdirectory.UserDirectoryHelper; 043import org.ametys.runtime.i18n.I18nizableText; 044import org.ametys.runtime.i18n.I18nizableTextParameter; 045 046/** 047 * {@link AccessController} for a User directory {@link Content} 048 */ 049public class UserDirectoryContentAccessController extends AbstractHierarchicalAccessController<AmetysObject> implements Contextualizable 050{ 051 /** the user directory context category */ 052 public static final I18nizableText USER_DIRECTORY_CONTEXT_CATEGORY = new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_RIGHT_ASSIGNMENT_CONTEXT_CONTENTS_LABEL"); 053 054 /** Ametys Object Resolver */ 055 protected AmetysObjectResolver _resolver; 056 057 /** The organisation chart page handler */ 058 protected OrganisationChartPageHandler _organisationChartPageHandler; 059 060 /** The content type helper */ 061 protected ContentTypesHelper _contentTypeHelper; 062 063 /** The user directory helper */ 064 protected UserDirectoryHelper _userDirectoryHelper; 065 066 private Context _context; 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 public void contextualize(Context context) throws ContextException 079 { 080 _context = context; 081 } 082 083 @Override 084 public boolean isSupported(Object object) 085 { 086 if (object instanceof Content) 087 { 088 return _isContentUser(object) || _isContentOrgUnit(object); 089 } 090 091 return false; 092 } 093 094 @Override 095 protected boolean _isSupportedStoredContext(Object storedObject) 096 { 097 return super._isSupportedStoredContext(storedObject) || _userDirectoryHelper.getUserDirectoryRootContent().equals(storedObject); 098 } 099 100 @Override 101 protected Set<AmetysObject> _getParents(AmetysObject object) 102 { 103 if (object instanceof Content) 104 { 105 Set<AmetysObject> parents = new HashSet<>(); 106 107 Request request = ContextHelper.getRequest(_context); 108 String originalWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request); 109 try 110 { 111 RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE); 112 if (_isContentOrgUnit(object)) 113 { 114 Content parentContent = _organisationChartPageHandler.getParentContent((Content) object); 115 if (parentContent != null) 116 { 117 parents.add(parentContent); 118 } 119 else 120 { 121 parents.add(_userDirectoryHelper.getUserDirectoryRootContent()); 122 } 123 } 124 else if (_isContentUser(object)) 125 { 126 parents.add(_userDirectoryHelper.getUserDirectoryRootContent()); 127 } 128 } 129 finally 130 { 131 RequestAttributeWorkspaceSelector.setForcedWorkspace(request, originalWorkspace); 132 } 133 134 return parents; 135 } 136 else 137 { 138 return null; 139 } 140 } 141 142 @Override 143 protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 144 { 145 if (workspacesContexts.contains("/cms")) 146 { 147 try 148 { 149 return Collections.singleton(_userDirectoryHelper.getUserDirectoryRootContent()); 150 } 151 catch (UnknownAmetysObjectException e) 152 { 153 // Root does not exist yet 154 return null; 155 } 156 } 157 return null; 158 } 159 160 private boolean _isContentUser(Object object) 161 { 162 return _contentTypeHelper.isInstanceOf((Content) object, UserDirectoryHelper.ABSTRACT_USER_CONTENT_TYPE); 163 } 164 165 private boolean _isContentOrgUnit(Object object) 166 { 167 return _contentTypeHelper.isInstanceOf((Content) object, UserDirectoryHelper.ORGUNIT_CONTENT_TYPE); 168 } 169 170 @Override 171 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 172 { 173 if (object instanceof Content content) 174 { 175 Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object)); 176 if (_isContentUser(content)) 177 { 178 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_USER_CONTEXT_EXPLANATION_LABEL", params); 179 } 180 else if (_isContentOrgUnit(content)) 181 { 182 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_ORGUNIT_CONTEXT_EXPLANATION_LABEL", params); 183 } 184 } 185 else if (_userDirectoryHelper.getUserDirectoryRootContent().equals(object)) 186 { 187 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_EXPLANATION_LABEL"); 188 } 189 throw new RightsException("Unsupported object " + object.toString()); 190 } 191 192 public I18nizableText getObjectLabel(Object object) throws RightsException 193 { 194 if (object instanceof Content content) 195 { 196 return new I18nizableText(content.getTitle()); 197 } 198 else if (_userDirectoryHelper.getUserDirectoryRootContent().equals(object)) 199 { 200 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_LABEL"); 201 } 202 throw new RightsException("Unsupported object " + object.toString()); 203 } 204 205 @Override 206 public I18nizableText getObjectCategory(Object object) 207 { 208 return USER_DIRECTORY_CONTEXT_CATEGORY; 209 } 210 211 @Override 212 public int getObjectPriority(Object object) 213 { 214 if (_userDirectoryHelper.getUserDirectoryRootContent().equals(object)) 215 { 216 return 10; 217 } 218 return super.getObjectPriority(object); 219 } 220}