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.thesaurus.right; 017 018import java.util.Map; 019import java.util.Set; 020 021import org.apache.avalon.framework.context.Context; 022import org.apache.avalon.framework.context.ContextException; 023import org.apache.avalon.framework.context.Contextualizable; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.components.ContextHelper; 027import org.apache.cocoon.environment.Request; 028import org.apache.commons.collections.MapUtils; 029import org.apache.commons.lang3.StringUtils; 030 031import org.ametys.cms.content.archive.ArchiveConstants; 032import org.ametys.cms.contenttype.ContentTypesHelper; 033import org.ametys.cms.repository.Content; 034import org.ametys.cms.rights.ReferenceTableAccessController; 035import org.ametys.core.group.GroupIdentity; 036import org.ametys.core.right.AccessController; 037import org.ametys.core.right.AccessController.Permission.PermissionType; 038import org.ametys.core.right.AccessExplanation; 039import org.ametys.core.right.RightsException; 040import org.ametys.core.right.RightsExtensionPoint; 041import org.ametys.core.user.UserIdentity; 042import org.ametys.plugins.core.impl.right.AbstractProfileStorageBasedAccessController; 043import org.ametys.plugins.repository.provider.RequestAttributeWorkspaceSelector; 044import org.ametys.plugins.thesaurus.ThesaurusDAO; 045import org.ametys.runtime.i18n.I18nizableText; 046import org.ametys.runtime.i18n.I18nizableTextParameter; 047 048/** 049 * {@link AccessController} for a thesaurus objects. The rights are checked on '/cms' context. 050 * Read access is allowed to any connected user. 051 */ 052public class ThesaurusAccessController extends AbstractProfileStorageBasedAccessController implements Contextualizable 053{ 054 /** The right context for thesaurus */ 055 private static final String __APPLICATION_RIGHT_CONTEXT = "/cms"; 056 057 /** The right extension point */ 058 protected RightsExtensionPoint _rightEP; 059 060 private ContentTypesHelper _contentTypeHelper; 061 062 private Context _context; 063 064 @Override 065 public void service(ServiceManager manager) throws ServiceException 066 { 067 super.service(manager); 068 _contentTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 069 _rightEP = (RightsExtensionPoint) manager.lookup(RightsExtensionPoint.ROLE); 070 } 071 072 public void contextualize(Context context) throws ContextException 073 { 074 _context = context; 075 } 076 077 @Override 078 public boolean isSupported(Object object) 079 { 080 Request request = ContextHelper.getRequest(_context); 081 String currentWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request); 082 083 if (ArchiveConstants.ARCHIVE_WORKSPACE.equals(currentWorkspace)) 084 { 085 return false; 086 } 087 088 return object instanceof Content && _contentTypeHelper.isInstanceOf((Content) object, ThesaurusDAO.MICROTHESAURUS_ABSTRACT_CONTENT_TYPE); 089 } 090 091 @Override 092 protected Object _convertContext(Object initialContext) 093 { 094 String siteName = _getSiteName(); 095 return __APPLICATION_RIGHT_CONTEXT + (StringUtils.isNoneEmpty(siteName) ? "/" + siteName : ""); 096 } 097 098 /** 099 * Convert the asked right id to the real right to check 100 * @param rightId The asked right id 101 * @return the right to check 102 */ 103 protected String _convertRightId(String rightId) 104 { 105 return "Thesaurus_Rights_EditTerm"; 106 } 107 108 @Override 109 public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object) 110 { 111 return super.getPermission(user, userGroups, _convertRightId(rightId), object); 112 } 113 114 @Override 115 public AccessExplanation explainPermission(UserIdentity user, Set<GroupIdentity> groups, String rightId, Object object) 116 { 117 return super.explainPermission(user, groups, _convertRightId(rightId), object); 118 } 119 120 @Override 121 protected I18nizableText _getExplanationI18nText(PermissionDetails details) 122 { 123 return new I18nizableText("plugin.thesaurus", _getAccessExplanationI18nKey("PLUGINS_THESAURUS_ACCESS_CONTROLLER_", details), _getExplanationI18nParams(details)); 124 } 125 126 @Override 127 protected Map<String, I18nizableTextParameter> _getExplanationI18nParams(PermissionDetails details) 128 { 129 Map<String, I18nizableTextParameter> i18nParams = super._getExplanationI18nParams(details); 130 i18nParams.put("right", _rightEP.getExtension(_convertRightId(null)).getLabel()); 131 return i18nParams; 132 } 133 134 @Override 135 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 136 { 137 return new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_EXPLANATION_CONTEXT_LABEL"); 138 } 139 140 @Override 141 public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 142 { 143 return AccessResult.ANY_CONNECTED_ALLOWED; 144 } 145 146 @Override 147 public AccessExplanation explainReadAccessPermission(UserIdentity user, Set<GroupIdentity> groups, Object object) 148 { 149 return new AccessExplanation( 150 getId(), 151 getReadAccessPermission(user, groups, object), 152 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_READ_ACCESS_EXPLANATION", Map.of("title", new I18nizableText(((Content) object).getTitle()))) 153 ); 154 } 155 156 @Override 157 public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 158 { 159 return MapUtils.EMPTY_MAP; 160 } 161 162 @Override 163 public AccessResult getPermissionForAnonymous(String rightId, Object object) 164 { 165 return AccessResult.ANONYMOUS_DENIED; 166 } 167 168 @Override 169 public AccessExplanation explainPermissionForAnonymous(String rightId, Object object) 170 { 171 return new AccessExplanation( 172 getId(), 173 AccessResult.ANONYMOUS_DENIED, 174 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ANONYMOUS_PERMISSION_EXPLANATION", Map.of("title", new I18nizableText(((Content) object).getTitle()))) 175 ); 176 } 177 178 @Override 179 public AccessResult getReadAccessPermissionForAnonymous(Object object) 180 { 181 return AccessResult.ANONYMOUS_DENIED; 182 } 183 184 @Override 185 public AccessExplanation explainReadAccessPermissionForAnonymous(Object object) 186 { 187 return new AccessExplanation( 188 getId(), 189 AccessResult.ANONYMOUS_DENIED, 190 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ANONYMOUS_PERMISSION_EXPLANATION", Map.of("title", new I18nizableText(((Content) object).getTitle()))) 191 ); 192 } 193 194 @Override 195 public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object) 196 { 197 return AccessResult.ANY_CONNECTED_DENIED; 198 } 199 200 @Override 201 public AccessExplanation explainPermissionForAnyConnectedUser(String rightId, Object object) 202 { 203 return new AccessExplanation( 204 getId(), 205 AccessResult.ANY_CONNECTED_DENIED, 206 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ANY_CONNECTED_PERMISSION_EXPLANATION") 207 ); 208 } 209 210 @Override 211 public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object) 212 { 213 return AccessResult.ANY_CONNECTED_ALLOWED; 214 } 215 216 @Override 217 public AccessExplanation explainReadAccessPermissionForAnyConnectedUser(Object object) 218 { 219 return new AccessExplanation( 220 getId(), 221 AccessResult.ANY_CONNECTED_ALLOWED, 222 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_READ_ACCESS_EXPLANATION") 223 ); 224 } 225 226 @Override 227 public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object) 228 { 229 return MapUtils.EMPTY_MAP; 230 } 231 232 @Override 233 public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object) 234 { 235 return MapUtils.EMPTY_MAP; 236 } 237 238 @Override 239 public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object) 240 { 241 return MapUtils.EMPTY_MAP; 242 } 243 244 @Override 245 public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object) 246 { 247 return MapUtils.EMPTY_MAP; 248 } 249 250 @Override 251 protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 252 { 253 return null; 254 } 255 256 // FIXME To remove https://issues.ametys.org/browse/THES-86 257 private String _getSiteName() 258 { 259 Request request = ContextHelper.getRequest(_context); 260 String siteName = request.getParameter("siteName"); 261 262 if (siteName == null) 263 { 264 siteName = (String) request.getAttribute("siteName"); 265 } 266 return siteName; 267 } 268 269 @Override 270 public Map<ExplanationObject, Map<Permission, AccessExplanation>> explainAllPermissions(UserIdentity identity, Set<GroupIdentity> groups) 271 { 272 AccessExplanation explanation = explainPermission(identity, groups, null, null); 273 if (explanation.accessResult() != AccessResult.UNKNOWN) 274 { 275 return Map.of( 276 getExplanationObject("thesaurus"), 277 Map.of(new Permission(PermissionType.ALL_RIGHTS, null), explanation) 278 ); 279 } 280 return Map.of(); 281 } 282 283 @Override 284 protected boolean _isSupportedStoredContext(Object storedObject) 285 { 286 String siteName = _getSiteName(); 287 String generalContext = __APPLICATION_RIGHT_CONTEXT + (StringUtils.isNoneEmpty(siteName) ? "/" + siteName : ""); 288 return storedObject instanceof String str && StringUtils.equals(str, generalContext); 289 } 290 291 public I18nizableText getObjectLabel(Object object) throws RightsException 292 { 293 return new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ALL_CONTEXT"); 294 } 295 296 public I18nizableText getObjectCategory(Object object) 297 { 298 return ReferenceTableAccessController.REFERENCE_TABLE_CONTEXT_CATEGORY; 299 } 300 301 public int getObjectPriority(Object object) 302 { 303 // after root but before the content type 304 return 5; 305 } 306 307}