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 public boolean supports(Object object) 084 { 085 if (object instanceof Content) 086 { 087 return _isContentUser(object) || _isContentOrgUnit(object); 088 } 089 090 return false; 091 } 092 093 @Override 094 protected Set<AmetysObject> _getParents(AmetysObject object) 095 { 096 if (object instanceof Content) 097 { 098 Set<AmetysObject> parents = new HashSet<>(); 099 100 Request request = ContextHelper.getRequest(_context); 101 String originalWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request); 102 try 103 { 104 RequestAttributeWorkspaceSelector.setForcedWorkspace(request, RepositoryConstants.DEFAULT_WORKSPACE); 105 if (_isContentOrgUnit(object)) 106 { 107 Content parentContent = _organisationChartPageHandler.getParentContent((Content) object); 108 if (parentContent != null) 109 { 110 parents.add(parentContent); 111 } 112 else 113 { 114 parents.add(_userDirectoryHelper.getUserDirectoryRootContent()); 115 } 116 } 117 else if (_isContentUser(object)) 118 { 119 parents.add(_userDirectoryHelper.getUserDirectoryRootContent()); 120 } 121 } 122 finally 123 { 124 RequestAttributeWorkspaceSelector.setForcedWorkspace(request, originalWorkspace); 125 } 126 127 return parents; 128 } 129 else 130 { 131 return null; 132 } 133 } 134 135 @Override 136 protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 137 { 138 if (workspacesContexts.contains("/cms")) 139 { 140 try 141 { 142 return Collections.singleton(_userDirectoryHelper.getUserDirectoryRootContent()); 143 } 144 catch (UnknownAmetysObjectException e) 145 { 146 // Root does not exist yet 147 return null; 148 } 149 } 150 return null; 151 } 152 153 private boolean _isContentUser(Object object) 154 { 155 return _contentTypeHelper.isInstanceOf((Content) object, UserDirectoryHelper.ABSTRACT_USER_CONTENT_TYPE); 156 } 157 158 private boolean _isContentOrgUnit(Object object) 159 { 160 return _contentTypeHelper.isInstanceOf((Content) object, UserDirectoryHelper.ORGUNIT_CONTENT_TYPE); 161 } 162 163 @Override 164 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 165 { 166 if (object instanceof Content content) 167 { 168 Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object)); 169 if (_isContentUser(content)) 170 { 171 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_USER_CONTEXT_EXPLANATION_LABEL", params); 172 } 173 else if (_isContentOrgUnit(content)) 174 { 175 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_ORGUNIT_CONTEXT_EXPLANATION_LABEL", params); 176 } 177 } 178 else if (_userDirectoryHelper.getUserDirectoryRootContent().equals(object)) 179 { 180 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_EXPLANATION_LABEL"); 181 } 182 throw new RightsException("Unsupported object " + object.toString()); 183 } 184 185 public I18nizableText getObjectLabel(Object object) throws RightsException 186 { 187 if (object instanceof Content content) 188 { 189 return new I18nizableText(content.getTitle()); 190 } 191 else if (_userDirectoryHelper.getUserDirectoryRootContent().equals(object)) 192 { 193 return new I18nizableText("plugin.user-directory", "PLUGINS_USER_DIRECTORY_CONTENT_ACCESS_CONTROLLER_ROOT_CONTEXT_LABEL"); 194 } 195 throw new RightsException("Unsupported object " + object.toString()); 196 } 197 198 @Override 199 public I18nizableText getObjectCategory(Object object) 200 { 201 return USER_DIRECTORY_CONTEXT_CATEGORY; 202 } 203 204 @Override 205 public int getObjectPriority(Object object) 206 { 207 if (_userDirectoryHelper.getUserDirectoryRootContent().equals(object)) 208 { 209 return 10; 210 } 211 return super.getObjectPriority(object); 212 } 213}