001/* 002 * Copyright 2016 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.contentio.synchronize.rights; 017 018import java.util.HashSet; 019import java.util.Map; 020import java.util.Set; 021 022import org.apache.avalon.framework.service.ServiceException; 023import org.apache.avalon.framework.service.ServiceManager; 024import org.apache.commons.lang3.StringUtils; 025 026import org.ametys.cms.repository.Content; 027import org.ametys.core.right.AccessController; 028import org.ametys.core.right.RightsException; 029import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection; 030import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollectionDAO; 031import org.ametys.plugins.core.impl.right.AbstractHierarchicalAccessController; 032import org.ametys.plugins.repository.UnknownAmetysObjectException; 033import org.ametys.runtime.i18n.I18nizableText; 034import org.ametys.runtime.i18n.I18nizableTextParameter; 035 036/** 037 * {@link AccessController} for a {@link Content} 038 */ 039public class SynchronizedContentAccessController extends AbstractHierarchicalAccessController<Object> 040{ 041 /** The synchronize collection DAO */ 042 private SynchronizableContentsCollectionDAO _collectionsDAO; 043 044 @Override 045 public void service(ServiceManager manager) throws ServiceException 046 { 047 super.service(manager); 048 _collectionsDAO = (SynchronizableContentsCollectionDAO) manager.lookup(SynchronizableContentsCollectionDAO.ROLE); 049 } 050 051 @Override 052 public boolean isSupported(Object object) 053 { 054 String collectionId = null; 055 if (object instanceof Content content && content.getInternalDataHolder().hasValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME)) 056 { 057 collectionId = content.getInternalDataHolder().<String[]>getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME)[0]; 058 } 059 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 060 { 061 collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 062 } 063 064 if (collectionId != null) 065 { 066 // Check that SCC still exists 067 return _collectionsDAO.getSynchronizableContentsCollection(collectionId) != null; 068 } 069 070 return false; 071 } 072 073 @Override 074 protected Set<Object> _getParents(Object object) 075 { 076 if (object instanceof Content) 077 { 078 String[] collectionIds = ((Content) object).getInternalDataHolder().getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME); 079 return Set.of(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX + collectionIds[0]); 080 } 081 082 return null; 083 } 084 085 @Override 086 protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 087 { 088 try 089 { 090 if (workspacesContexts.contains("/cms")) 091 { 092 Set<Object> rootContexts = new HashSet<>(); 093 094 for (SynchronizableContentsCollection synchronizableContentsCollection : _collectionsDAO.getSynchronizableContentsCollections()) 095 { 096 if (synchronizableContentsCollection.handleRightAssignmentContext()) 097 { 098 rootContexts.add(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX + synchronizableContentsCollection.getId()); 099 } 100 } 101 return rootContexts; 102 } 103 return null; 104 } 105 catch (UnknownAmetysObjectException e) 106 { 107 getLogger().debug("Root node for synchronized contents does not exist. Could not determine the contents root node to obtain all permissions"); 108 return null; 109 } 110 } 111 112 @Override 113 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 114 { 115 if (object instanceof Content) 116 { 117 Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object)); 118 return new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_ACCESS_CONTROLLER_CONTENT_CONTEXT_EXPLANATION_LABEL", params); 119 } 120 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 121 { 122 String collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 123 SynchronizableContentsCollection collection = _collectionsDAO.getSynchronizableContentsCollection(collectionId); 124 return new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_SCC_ACCESS_CONTROLLER_COLLECTION_CONTEXT_EXPLANATION_LABEL", Map.of("collection", collection.getLabel())); 125 } 126 throw new RightsException("Unsupported object " + object.toString()); 127 } 128 129 public I18nizableText getObjectLabel(Object object) throws RightsException 130 { 131 if (object instanceof Content content) 132 { 133 return new I18nizableText(content.getTitle()); 134 } 135 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 136 { 137 String collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 138 SynchronizableContentsCollection collection = _collectionsDAO.getSynchronizableContentsCollection(collectionId); 139 return new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_SCC_ACCESS_CONTROLLER_COLLECTION_CONTEXT_LABEL", Map.of("collection", collection.getLabel())); 140 } 141 throw new RightsException("Unsupported object " + object.toString()); 142 } 143 144 public I18nizableText getObjectCategory(Object object) 145 { 146 String collectionId = null; 147 if (object instanceof Content content) 148 { 149 collectionId = content.getInternalDataHolder().<String[]>getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME)[0]; 150 } 151 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 152 { 153 collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 154 } 155 156 SynchronizableContentsCollection collection = _collectionsDAO.getSynchronizableContentsCollection(collectionId); 157 Map<String, I18nizableTextParameter> params = Map.of("collection", collection != null ? collection.getLabel() : new I18nizableText(collectionId)); 158 return new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_RIGHT_ASSIGNMENT_CONTEXT_SYNCHRONIZED_CONTENTS_LABEL", params); 159 } 160 161 public int getObjectPriority(Object object) 162 { 163 if (object instanceof String) 164 { 165 return 10; 166 } 167 return super.getObjectPriority(object); 168 } 169}