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.ContentTypeAccessController; 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 public boolean supports(Object object) 078 { 079 Request request = ContextHelper.getRequest(_context); 080 String currentWorkspace = RequestAttributeWorkspaceSelector.getForcedWorkspace(request); 081 082 if (ArchiveConstants.ARCHIVE_WORKSPACE.equals(currentWorkspace)) 083 { 084 return false; 085 } 086 087 return object instanceof Content && _contentTypeHelper.isInstanceOf((Content) object, ThesaurusDAO.MICROTHESAURUS_ABSTRACT_CONTENT_TYPE); 088 } 089 090 @Override 091 protected Object _convertContext(Object initialContext) 092 { 093 String siteName = _getSiteName(); 094 return __APPLICATION_RIGHT_CONTEXT + (StringUtils.isNoneEmpty(siteName) ? "/" + siteName : ""); 095 } 096 097 /** 098 * Convert the asked right id to the real right to check 099 * @param rightId The asked right id 100 * @return the right to check 101 */ 102 protected String _convertRightId(String rightId) 103 { 104 return "Thesaurus_Rights_EditTerm"; 105 } 106 107 @Override 108 public AccessResult getPermission(UserIdentity user, Set<GroupIdentity> userGroups, String rightId, Object object) 109 { 110 return super.getPermission(user, userGroups, _convertRightId(rightId), object); 111 } 112 113 @Override 114 public AccessExplanation explainPermission(UserIdentity user, Set<GroupIdentity> groups, String rightId, Object object) 115 { 116 return super.explainPermission(user, groups, _convertRightId(rightId), object); 117 } 118 119 @Override 120 protected I18nizableText _getExplanationI18nText(PermissionDetails details) 121 { 122 return new I18nizableText("plugin.thesaurus", _getAccessExplanationI18nKey("PLUGINS_THESAURUS_ACCESS_CONTROLLER_", details), _getExplanationI18nParams(details)); 123 } 124 125 @Override 126 protected Map<String, I18nizableTextParameter> _getExplanationI18nParams(PermissionDetails details) 127 { 128 Map<String, I18nizableTextParameter> i18nParams = super._getExplanationI18nParams(details); 129 i18nParams.put("right", _rightEP.getExtension(_convertRightId(null)).getLabel()); 130 return i18nParams; 131 } 132 133 @Override 134 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 135 { 136 return new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_EXPLANATION_CONTEXT_LABEL"); 137 } 138 139 @Override 140 public AccessResult getReadAccessPermission(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 141 { 142 return AccessResult.ANY_CONNECTED_ALLOWED; 143 } 144 145 @Override 146 public AccessExplanation explainReadAccessPermission(UserIdentity user, Set<GroupIdentity> groups, Object object) 147 { 148 return new AccessExplanation( 149 getId(), 150 getReadAccessPermission(user, groups, object), 151 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_READ_ACCESS_EXPLANATION", Map.of("title", new I18nizableText(((Content) object).getTitle()))) 152 ); 153 } 154 155 @Override 156 public Map<String, AccessResult> getPermissionByRight(UserIdentity user, Set<GroupIdentity> userGroups, Object object) 157 { 158 return MapUtils.EMPTY_MAP; 159 } 160 161 @Override 162 public AccessResult getPermissionForAnonymous(String rightId, Object object) 163 { 164 return AccessResult.ANONYMOUS_DENIED; 165 } 166 167 @Override 168 public AccessExplanation explainPermissionForAnonymous(String rightId, Object object) 169 { 170 return new AccessExplanation( 171 getId(), 172 getPermissionForAnonymous(rightId, object), 173 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ANONYMOUS_PERMISSION_EXPLANATION", Map.of("title", new I18nizableText(((Content) object).getTitle()))) 174 ); 175 } 176 177 @Override 178 public AccessResult getReadAccessPermissionForAnonymous(Object object) 179 { 180 return AccessResult.ANONYMOUS_DENIED; 181 } 182 183 @Override 184 public AccessExplanation explainReadAccessPermissionForAnonymous(Object object) 185 { 186 return new AccessExplanation( 187 getId(), 188 getReadAccessPermissionForAnonymous(object), 189 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ANONYMOUS_PERMISSION_EXPLANATION", Map.of("title", new I18nizableText(((Content) object).getTitle()))) 190 ); 191 } 192 193 @Override 194 public AccessResult getPermissionForAnyConnectedUser(String rightId, Object object) 195 { 196 return AccessResult.ANY_CONNECTED_DENIED; 197 } 198 199 @Override 200 public AccessExplanation explainPermissionForAnyConnectedUser(String rightId, Object object) 201 { 202 return new AccessExplanation( 203 getId(), 204 getPermissionForAnyConnectedUser(rightId, object), 205 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ANY_CONNECTED_PERMISSION_EXPLANATION") 206 ); 207 } 208 209 @Override 210 public AccessResult getReadAccessPermissionForAnyConnectedUser(Object object) 211 { 212 return AccessResult.ANY_CONNECTED_ALLOWED; 213 } 214 215 @Override 216 public AccessExplanation explainReadAccessPermissionForAnyConnectedUser(Object object) 217 { 218 return new AccessExplanation( 219 getId(), 220 getReadAccessPermissionForAnyConnectedUser(object), 221 new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_READ_ACCESS_EXPLANATION") 222 ); 223 } 224 225 @Override 226 public Map<UserIdentity, AccessResult> getPermissionByUser(String rightId, Object object) 227 { 228 return MapUtils.EMPTY_MAP; 229 } 230 231 @Override 232 public Map<GroupIdentity, AccessResult> getReadAccessPermissionByGroup(Object object) 233 { 234 return MapUtils.EMPTY_MAP; 235 } 236 237 @Override 238 public Map<UserIdentity, AccessResult> getReadAccessPermissionByUser(Object object) 239 { 240 return MapUtils.EMPTY_MAP; 241 } 242 243 @Override 244 public Map<GroupIdentity, AccessResult> getPermissionByGroup(String rightId, Object object) 245 { 246 return MapUtils.EMPTY_MAP; 247 } 248 249 @Override 250 protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 251 { 252 return null; 253 } 254 255 // FIXME To remove https://issues.ametys.org/browse/THES-86 256 private String _getSiteName() 257 { 258 Request request = ContextHelper.getRequest(_context); 259 String siteName = request.getParameter("siteName"); 260 261 if (siteName == null) 262 { 263 siteName = (String) request.getAttribute("siteName"); 264 } 265 return siteName; 266 } 267 268 @Override 269 public Map<ExplanationObject, Map<Permission, AccessExplanation>> explainAllPermissions(UserIdentity identity, Set<GroupIdentity> groups) 270 { 271 AccessExplanation explanation = explainPermission(identity, groups, null, null); 272 if (explanation.accessResult() != AccessResult.UNKNOWN) 273 { 274 return Map.of( 275 getExplanationObject("thesaurus"), 276 Map.of(new Permission(PermissionType.ALL_RIGHTS, null), explanation) 277 ); 278 } 279 return Map.of(); 280 } 281 282 @Override 283 protected boolean _isSupportedStoredContext(Object storedObject) 284 { 285 String siteName = _getSiteName(); 286 String generalContext = __APPLICATION_RIGHT_CONTEXT + (StringUtils.isNoneEmpty(siteName) ? "/" + siteName : ""); 287 return storedObject instanceof String str && StringUtils.equals(str, generalContext); 288 } 289 290 public I18nizableText getObjectLabel(Object object) throws RightsException 291 { 292 return new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_ACCESS_CONTROLLER_ALL_CONTEXT"); 293 } 294 295 public I18nizableText getObjectCategory(Object object) 296 { 297 return ContentTypeAccessController.REFERENCE_TABLE_CONTEXT_CATEGORY; 298 } 299 300 public int getObjectPriority(Object object) 301 { 302 // after root but before the content type 303 return 5; 304 } 305 306}