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 public boolean supports(Object object) 052 { 053 String collectionId = null; 054 if (object instanceof Content content && content.getInternalDataHolder().hasValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME)) 055 { 056 collectionId = content.getInternalDataHolder().<String[]>getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME)[0]; 057 } 058 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 059 { 060 collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 061 } 062 063 if (collectionId != null) 064 { 065 // Check that SCC still exists 066 return _collectionsDAO.getSynchronizableContentsCollection(collectionId) != null; 067 } 068 069 return false; 070 } 071 072 @Override 073 protected Set<Object> _getParents(Object object) 074 { 075 if (object instanceof Content) 076 { 077 String[] collectionIds = ((Content) object).getInternalDataHolder().getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME); 078 return Set.of(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX + collectionIds[0]); 079 } 080 081 return null; 082 } 083 084 @Override 085 protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts) 086 { 087 try 088 { 089 if (workspacesContexts.contains("/cms")) 090 { 091 Set<Object> rootContexts = new HashSet<>(); 092 093 for (SynchronizableContentsCollection synchronizableContentsCollection : _collectionsDAO.getSynchronizableContentsCollections()) 094 { 095 if (synchronizableContentsCollection.handleRightAssignmentContext()) 096 { 097 rootContexts.add(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX + synchronizableContentsCollection.getId()); 098 } 099 } 100 return rootContexts; 101 } 102 return null; 103 } 104 catch (UnknownAmetysObjectException e) 105 { 106 getLogger().debug("Root node for synchronized contents does not exist. Could not determine the contents root node to obtain all permissions"); 107 return null; 108 } 109 } 110 111 @Override 112 protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException 113 { 114 if (object instanceof Content) 115 { 116 Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object)); 117 return new I18nizableText("plugin.cms", "PLUGINS_CMS_CONTENT_ACCESS_CONTROLLER_CONTENT_CONTEXT_EXPLANATION_LABEL", params); 118 } 119 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 120 { 121 String collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 122 SynchronizableContentsCollection collection = _collectionsDAO.getSynchronizableContentsCollection(collectionId); 123 return new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_SCC_ACCESS_CONTROLLER_COLLECTION_CONTEXT_EXPLANATION_LABEL", Map.of("collection", collection.getLabel())); 124 } 125 throw new RightsException("Unsupported object " + object.toString()); 126 } 127 128 public I18nizableText getObjectLabel(Object object) throws RightsException 129 { 130 if (object instanceof Content content) 131 { 132 return new I18nizableText(content.getTitle()); 133 } 134 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 135 { 136 String collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 137 SynchronizableContentsCollection collection = _collectionsDAO.getSynchronizableContentsCollection(collectionId); 138 return new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_SCC_ACCESS_CONTROLLER_COLLECTION_CONTEXT_LABEL", Map.of("collection", collection.getLabel())); 139 } 140 throw new RightsException("Unsupported object " + object.toString()); 141 } 142 143 public I18nizableText getObjectCategory(Object object) 144 { 145 String collectionId = null; 146 if (object instanceof Content content) 147 { 148 collectionId = content.getInternalDataHolder().<String[]>getValue(SynchronizableContentsCollection.COLLECTION_ID_DATA_NAME)[0]; 149 } 150 else if (object instanceof String str && str.startsWith(SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX)) 151 { 152 collectionId = StringUtils.substringAfter(str, SynchronizeContentRightAssignmentContext.ROOT_CONTEXT_PREFIX); 153 } 154 155 SynchronizableContentsCollection collection = _collectionsDAO.getSynchronizableContentsCollection(collectionId); 156 Map<String, I18nizableTextParameter> params = Map.of("collection", collection != null ? collection.getLabel() : new I18nizableText(collectionId)); 157 return new I18nizableText("plugin.contentio", "PLUGINS_CONTENTIO_RIGHT_ASSIGNMENT_CONTEXT_SYNCHRONIZED_CONTENTS_LABEL", params); 158 } 159 160 public int getObjectPriority(Object object) 161 { 162 if (object instanceof String) 163 { 164 return 10; 165 } 166 return super.getObjectPriority(object); 167 } 168}