mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 3f31e4b1a2 | ||
|  | 787a331869 | ||
|  | 5ce3a3ddd6 | ||
|  | 9ed96ec593 | ||
|  | 03b1fa8b09 | ||
|  | d69f9b52c3 | ||
|  | 72b910bb48 | ||
|  | cfaf3b280b | ||
|  | 00d814ec55 | ||
|  | becabb3a41 | ||
|  | 033157800b | ||
|  | b9c8ff91e4 | ||
|  | c54d46ab67 | ||
|  | dec514c5c2 | ||
|  | 7c5a8a1963 | 
| @@ -7,7 +7,7 @@ | |||||||
|    <parent> |    <parent> | ||||||
|       <groupId>org.alfresco</groupId> |       <groupId>org.alfresco</groupId> | ||||||
|       <artifactId>alfresco-community-repo-amps</artifactId> |       <artifactId>alfresco-community-repo-amps</artifactId> | ||||||
|       <version>11.141-SNAPSHOT</version> |       <version>12.4</version> | ||||||
|    </parent> |    </parent> | ||||||
|  |  | ||||||
|    <modules> |    <modules> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|    <parent> |    <parent> | ||||||
|       <groupId>org.alfresco</groupId> |       <groupId>org.alfresco</groupId> | ||||||
|       <artifactId>alfresco-governance-services-community-parent</artifactId> |       <artifactId>alfresco-governance-services-community-parent</artifactId> | ||||||
|       <version>11.141-SNAPSHOT</version> |       <version>12.4</version> | ||||||
|    </parent> |    </parent> | ||||||
|  |  | ||||||
|    <modules> |    <modules> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|    <parent> |    <parent> | ||||||
|       <groupId>org.alfresco</groupId> |       <groupId>org.alfresco</groupId> | ||||||
|       <artifactId>alfresco-governance-services-automation-community-repo</artifactId> |       <artifactId>alfresco-governance-services-automation-community-repo</artifactId> | ||||||
|       <version>11.141-SNAPSHOT</version> |       <version>12.4</version> | ||||||
|    </parent> |    </parent> | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -619,11 +619,27 @@ public class BaseRMRestTest extends RestTest | |||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     public List<String> searchForContentAsUser(UserModel user, String term) |     public List<String> searchForContentAsUser(UserModel user, String term) | ||||||
|  |     { | ||||||
|  |         String query = "cm:name:*" + term + "*"; | ||||||
|  |         return searchForContentAsUser(user,query,"afts"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns search results for the given search term | ||||||
|  |      * | ||||||
|  |      * @param user | ||||||
|  |      * @param term | ||||||
|  |      * @param query language | ||||||
|  |      * @return | ||||||
|  |      * @throws Exception | ||||||
|  |      */ | ||||||
|  |     public List<String> searchForContentAsUser(UserModel user, String q, String queryLanguage) | ||||||
|     { |     { | ||||||
|         getRestAPIFactory().getRmRestWrapper().authenticateUser(user); |         getRestAPIFactory().getRmRestWrapper().authenticateUser(user); | ||||||
|         RestRequestQueryModel queryReq = new RestRequestQueryModel(); |         RestRequestQueryModel queryReq = new RestRequestQueryModel(); | ||||||
|         SearchRequest query = new SearchRequest(queryReq); |         SearchRequest query = new SearchRequest(queryReq); | ||||||
|         queryReq.setQuery("cm:name:*" + term + "*"); |         queryReq.setQuery(q); | ||||||
|  |         queryReq.setLanguage(queryLanguage); | ||||||
|  |  | ||||||
|         List<String> names = new ArrayList<>(); |         List<String> names = new ArrayList<>(); | ||||||
|         // wait for solr indexing |         // wait for solr indexing | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|    <parent> |    <parent> | ||||||
|       <groupId>org.alfresco</groupId> |       <groupId>org.alfresco</groupId> | ||||||
|       <artifactId>alfresco-governance-services-community-parent</artifactId> |       <artifactId>alfresco-governance-services-community-parent</artifactId> | ||||||
|       <version>11.141-SNAPSHOT</version> |       <version>12.4</version> | ||||||
|    </parent> |    </parent> | ||||||
|  |  | ||||||
|    <modules> |    <modules> | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|    <parent> |    <parent> | ||||||
|       <groupId>org.alfresco</groupId> |       <groupId>org.alfresco</groupId> | ||||||
|       <artifactId>alfresco-governance-services-community-repo-parent</artifactId> |       <artifactId>alfresco-governance-services-community-repo-parent</artifactId> | ||||||
|       <version>11.141-SNAPSHOT</version> |       <version>12.4</version> | ||||||
|    </parent> |    </parent> | ||||||
|  |  | ||||||
|    <properties> |    <properties> | ||||||
|   | |||||||
| @@ -306,7 +306,7 @@ public class RMAfterInvocationProvider extends RMSecurityCommon | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private boolean isUnfiltered(NodeRef nodeRef) |     protected boolean isUnfiltered(NodeRef nodeRef) | ||||||
|     { |     { | ||||||
|         return !nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT); |         return !nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-governance-services-community-repo-parent</artifactId> |         <artifactId>alfresco-governance-services-community-repo-parent</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <build> |     <build> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo</artifactId> |         <artifactId>alfresco-community-repo</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <modules> |     <modules> | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-amps</artifactId> |         <artifactId>alfresco-community-repo-amps</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <properties> |     <properties> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|    <parent> |    <parent> | ||||||
|       <groupId>org.alfresco</groupId> |       <groupId>org.alfresco</groupId> | ||||||
|       <artifactId>alfresco-community-repo</artifactId> |       <artifactId>alfresco-community-repo</artifactId> | ||||||
|       <version>11.141-SNAPSHOT</version> |       <version>12.4</version> | ||||||
|    </parent> |    </parent> | ||||||
|  |  | ||||||
|    <dependencies> |    <dependencies> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo</artifactId> |         <artifactId>alfresco-community-repo</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <properties> |     <properties> | ||||||
|   | |||||||
| @@ -9,6 +9,6 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> |         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
| </project> | </project> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> |         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <properties> |     <properties> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo</artifactId> |         <artifactId>alfresco-community-repo</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <modules> |     <modules> | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> |         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <modules> |     <modules> | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-tests</artifactId> |         <artifactId>alfresco-community-repo-tests</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <developers> |     <developers> | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-tests</artifactId> |         <artifactId>alfresco-community-repo-tests</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <developers> |     <developers> | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-tests</artifactId> |         <artifactId>alfresco-community-repo-tests</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <developers> |     <developers> | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-tests</artifactId> |         <artifactId>alfresco-community-repo-tests</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <developers> |     <developers> | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-tests</artifactId> |         <artifactId>alfresco-community-repo-tests</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <developers> |     <developers> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo-packaging</artifactId> |         <artifactId>alfresco-community-repo-packaging</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <properties> |     <properties> | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -2,7 +2,7 @@ | |||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|     <modelVersion>4.0.0</modelVersion> |     <modelVersion>4.0.0</modelVersion> | ||||||
|     <artifactId>alfresco-community-repo</artifactId> |     <artifactId>alfresco-community-repo</artifactId> | ||||||
|     <version>11.141-SNAPSHOT</version> |     <version>12.4</version> | ||||||
|     <packaging>pom</packaging> |     <packaging>pom</packaging> | ||||||
|     <name>Alfresco Community Repo Parent</name> |     <name>Alfresco Community Repo Parent</name> | ||||||
|  |  | ||||||
| @@ -24,7 +24,7 @@ | |||||||
|     <properties> |     <properties> | ||||||
|         <acs.version.major>7</acs.version.major> |         <acs.version.major>7</acs.version.major> | ||||||
|         <acs.version.minor>1</acs.version.minor> |         <acs.version.minor>1</acs.version.minor> | ||||||
|         <acs.version.revision>0</acs.version.revision> |         <acs.version.revision>1</acs.version.revision> | ||||||
|         <acs.version.label /> |         <acs.version.label /> | ||||||
|         <amp.min.version>${acs.version.major}.0.0</amp.min.version> |         <amp.min.version>${acs.version.major}.0.0</amp.min.version> | ||||||
|  |  | ||||||
| @@ -142,7 +142,7 @@ | |||||||
|         <connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection> |         <connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection> | ||||||
|         <developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection> |         <developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection> | ||||||
|         <url>https://github.com/Alfresco/alfresco-community-repo</url> |         <url>https://github.com/Alfresco/alfresco-community-repo</url> | ||||||
|         <tag>HEAD</tag> |         <tag>12.4</tag> | ||||||
|     </scm> |     </scm> | ||||||
|  |  | ||||||
|     <distributionManagement> |     <distributionManagement> | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo</artifactId> |         <artifactId>alfresco-community-repo</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <dependencies> |     <dependencies> | ||||||
|   | |||||||
| @@ -30,8 +30,19 @@ import java.net.InetAddress; | |||||||
| import java.net.UnknownHostException; | import java.net.UnknownHostException; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Objects; | ||||||
|  | import java.util.OptionalInt; | ||||||
|  | import java.util.function.Function; | ||||||
|  | import java.util.function.Supplier; | ||||||
|  |  | ||||||
|  | import com.google.common.primitives.Ints; | ||||||
|  |  | ||||||
| import org.alfresco.repo.bulkimport.BulkFilesystemImporter; | import org.alfresco.repo.bulkimport.BulkFilesystemImporter; | ||||||
|  | import org.alfresco.repo.bulkimport.BulkImportParameters; | ||||||
|  | import org.alfresco.repo.bulkimport.NodeImporter; | ||||||
|  | import org.alfresco.repo.bulkimport.impl.MultiThreadedBulkFilesystemImporter; | ||||||
| import org.alfresco.repo.model.Repository; | import org.alfresco.repo.model.Repository; | ||||||
| import org.alfresco.service.cmr.model.FileFolderService; | import org.alfresco.service.cmr.model.FileFolderService; | ||||||
| import org.alfresco.service.cmr.model.FileInfo; | import org.alfresco.service.cmr.model.FileInfo; | ||||||
| @@ -39,8 +50,12 @@ import org.alfresco.service.cmr.model.FileNotFoundException; | |||||||
| import org.alfresco.service.cmr.repository.NodeRef; | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
| import org.apache.commons.logging.Log; | import org.apache.commons.logging.Log; | ||||||
| import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | ||||||
|  | import org.springframework.extensions.surf.util.I18NUtil; | ||||||
|  | import org.springframework.extensions.webscripts.Cache; | ||||||
| import org.springframework.extensions.webscripts.DeclarativeWebScript; | import org.springframework.extensions.webscripts.DeclarativeWebScript; | ||||||
|  | import org.springframework.extensions.webscripts.Status; | ||||||
| import org.springframework.extensions.webscripts.WebScriptException; | import org.springframework.extensions.webscripts.WebScriptException; | ||||||
|  | import org.springframework.extensions.webscripts.WebScriptRequest; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * contains common fields and methods for the import web scripts. |  * contains common fields and methods for the import web scripts. | ||||||
| @@ -60,10 +75,10 @@ public class AbstractBulkFileSystemImportWebScript extends DeclarativeWebScript | |||||||
|     // Web scripts parameters (common) |     // Web scripts parameters (common) | ||||||
| 	protected static final String PARAMETER_REPLACE_EXISTING        = "replaceExisting"; | 	protected static final String PARAMETER_REPLACE_EXISTING        = "replaceExisting"; | ||||||
| 	protected static final String PARAMETER_EXISTING_FILE_MODE      = "existingFileMode"; | 	protected static final String PARAMETER_EXISTING_FILE_MODE      = "existingFileMode"; | ||||||
| 	protected static final String PARAMETER_VALUE_REPLACE_EXISTING 	= "replaceExisting"; | 	protected static final String PARAMETER_VALUE_REPLACE_EXISTING 	= "true"; | ||||||
| 	protected static final String PARAMETER_SOURCE_DIRECTORY       	= "sourceDirectory"; | 	protected static final String PARAMETER_SOURCE_DIRECTORY       	= "sourceDirectory"; | ||||||
| 	protected static final String PARAMETER_DISABLE_RULES		    = "disableRules"; | 	protected static final String PARAMETER_DISABLE_RULES		    = "disableRules"; | ||||||
| 	protected static final String PARAMETER_VALUE_DISABLE_RULES		= "disableRules"; | 	protected static final String PARAMETER_VALUE_DISABLE_RULES		= "true"; | ||||||
|  |  | ||||||
| 	protected static final String IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY = "importInProgress"; | 	protected static final String IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY = "importInProgress"; | ||||||
| 	protected static final String IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY ="bfsit.error.importAlreadyInProgress"; | 	protected static final String IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY ="bfsit.error.importAlreadyInProgress"; | ||||||
| @@ -219,4 +234,198 @@ public class AbstractBulkFileSystemImportWebScript extends DeclarativeWebScript | |||||||
| 		this.repository = repository; | 		this.repository = repository; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	protected class MultithreadedImportWebScriptLogic | ||||||
|  | 	{ | ||||||
|  | 		private final MultiThreadedBulkFilesystemImporter bulkImporter; | ||||||
|  | 		private final Supplier<NodeImporter> nodeImporterFactory; | ||||||
|  | 		private final WebScriptRequest request; | ||||||
|  | 		private final Status status; | ||||||
|  | 		private final Cache cache; | ||||||
|  |  | ||||||
|  | 		public MultithreadedImportWebScriptLogic(MultiThreadedBulkFilesystemImporter bulkImporter, Supplier<NodeImporter> nodeImporterFactory, WebScriptRequest request, Status status, Cache cache) | ||||||
|  | 		{ | ||||||
|  | 			this.bulkImporter = Objects.requireNonNull(bulkImporter); | ||||||
|  | 			this.nodeImporterFactory = Objects.requireNonNull(nodeImporterFactory); | ||||||
|  | 			this.request = Objects.requireNonNull(request); | ||||||
|  | 			this.status = Objects.requireNonNull(status); | ||||||
|  | 			this.cache = Objects.requireNonNull(cache); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public Map<String, Object> executeImport() | ||||||
|  | 		{ | ||||||
|  | 			Map<String, Object> model  = new HashMap<>(); | ||||||
|  | 			cache.setNeverCache(true); | ||||||
|  | 			String targetPath = null; | ||||||
|  |  | ||||||
|  | 			try | ||||||
|  | 			{ | ||||||
|  | 				targetPath = request.getParameter(PARAMETER_TARGET_PATH); | ||||||
|  | 				if (isRunning()) | ||||||
|  | 				{ | ||||||
|  | 					model.put(IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY, I18NUtil.getMessage(IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY)); | ||||||
|  | 					return model; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				final BulkImportParameters bulkImportParameters = getBulkImportParameters(); | ||||||
|  | 				final NodeImporter nodeImporter = nodeImporterFactory.get(); | ||||||
|  |  | ||||||
|  | 				bulkImporter.asyncBulkImport(bulkImportParameters, nodeImporter); | ||||||
|  |  | ||||||
|  | 				waitForImportToBegin(); | ||||||
|  |  | ||||||
|  | 				// redirect to the status Web Script | ||||||
|  | 				status.setCode(Status.STATUS_MOVED_TEMPORARILY); | ||||||
|  | 				status.setRedirect(true); | ||||||
|  | 				status.setLocation(request.getServiceContextPath() + WEB_SCRIPT_URI_BULK_FILESYSTEM_IMPORT_STATUS); | ||||||
|  | 			} | ||||||
|  | 			catch (WebScriptException | IllegalArgumentException e) | ||||||
|  | 			{ | ||||||
|  | 				status.setCode(Status.STATUS_BAD_REQUEST, e.getMessage()); | ||||||
|  | 				status.setRedirect(true); | ||||||
|  | 			} | ||||||
|  | 			catch (FileNotFoundException fnfe) | ||||||
|  | 			{ | ||||||
|  | 				status.setCode(Status.STATUS_BAD_REQUEST,"The repository path '" + targetPath + "' does not exist !"); | ||||||
|  | 				status.setRedirect(true); | ||||||
|  | 			} | ||||||
|  | 			catch (Throwable t) | ||||||
|  | 			{ | ||||||
|  | 				throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, buildTextMessage(t), t); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return model; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private void waitForImportToBegin() throws InterruptedException | ||||||
|  | 		{ | ||||||
|  | 			// ACE-3047 fix, since bulk import is started asynchronously there is a chance that client | ||||||
|  | 			// will get into the status page before import is actually started. | ||||||
|  | 			// In this case wrong information (for previous import) will be displayed. | ||||||
|  | 			// So lets ensure that import started before redirecting client to status page. | ||||||
|  | 			int i = 0; | ||||||
|  | 			while (!bulkImporter.getStatus().inProgress() && i < 10) | ||||||
|  | 			{ | ||||||
|  | 				Thread.sleep(100); | ||||||
|  | 				i++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private BulkImportParameters getBulkImportParameters() throws FileNotFoundException | ||||||
|  | 		{ | ||||||
|  | 			final BulkImportParametersExtractor extractor = new BulkImportParametersExtractor(request::getParameter, | ||||||
|  | 					AbstractBulkFileSystemImportWebScript.this::getTargetNodeRef, | ||||||
|  | 					bulkImporter.getDefaultBatchSize(), | ||||||
|  | 					bulkImporter.getDefaultNumThreads()); | ||||||
|  | 			return extractor.extract(); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private boolean isRunning() | ||||||
|  | 		{ | ||||||
|  | 			return bulkImporter.getStatus().inProgress(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	protected static class BulkImportParametersExtractor | ||||||
|  | 	{ | ||||||
|  | 		private final Function<String, String> paramsProvider; | ||||||
|  | 		private final NodeRefCreator nodeRefCreator; | ||||||
|  | 		private final int defaultBatchSize; | ||||||
|  | 		private final int defaultNumThreads; | ||||||
|  |  | ||||||
|  | 		public BulkImportParametersExtractor(final Function<String, String> paramsProvider, final NodeRefCreator nodeRefCreator, | ||||||
|  | 											 final int defaultBatchSize, final int defaultNumThreads) | ||||||
|  | 		{ | ||||||
|  | 			this.paramsProvider = Objects.requireNonNull(paramsProvider); | ||||||
|  | 			this.nodeRefCreator = Objects.requireNonNull(nodeRefCreator); | ||||||
|  | 			this.defaultBatchSize = defaultBatchSize; | ||||||
|  | 			this.defaultNumThreads = defaultNumThreads; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		public BulkImportParameters extract() throws FileNotFoundException | ||||||
|  | 		{ | ||||||
|  | 			BulkImportParameters result = new BulkImportParameters(); | ||||||
|  |  | ||||||
|  | 			result.setTarget(getTargetNodeRef()); | ||||||
|  | 			setExistingFileMode(result); | ||||||
|  | 			result.setNumThreads(getOptionalPositiveInteger(PARAMETER_NUM_THREADS).orElse(defaultNumThreads)); | ||||||
|  | 			result.setBatchSize(getOptionalPositiveInteger(PARAMETER_BATCH_SIZE).orElse(defaultBatchSize)); | ||||||
|  | 			setDisableRules(result); | ||||||
|  |  | ||||||
|  | 			return result; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private void setExistingFileMode(BulkImportParameters params) | ||||||
|  | 		{ | ||||||
|  | 			String replaceExistingStr = getParamStringValue(PARAMETER_REPLACE_EXISTING); | ||||||
|  | 			String existingFileModeStr = getParamStringValue(PARAMETER_EXISTING_FILE_MODE); | ||||||
|  |  | ||||||
|  | 			if (!isNullOrEmpty(replaceExistingStr) && !isNullOrEmpty(existingFileModeStr)) | ||||||
|  | 			{ | ||||||
|  | 				// Check that we haven't had both the deprecated and new (existingFileMode) | ||||||
|  | 				// parameters supplied. | ||||||
|  | 				throw new IllegalStateException( | ||||||
|  | 						String.format("Only one of these parameters may be used, not both: %s, %s", | ||||||
|  | 								PARAMETER_REPLACE_EXISTING, | ||||||
|  | 								PARAMETER_EXISTING_FILE_MODE)); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (!isNullOrEmpty(existingFileModeStr)) | ||||||
|  | 			{ | ||||||
|  | 				params.setExistingFileMode(BulkImportParameters.ExistingFileMode.valueOf(existingFileModeStr)); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				params.setReplaceExisting(PARAMETER_VALUE_REPLACE_EXISTING.equals(replaceExistingStr)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private void setDisableRules(final BulkImportParameters params) | ||||||
|  | 		{ | ||||||
|  | 			final String disableRulesStr = getParamStringValue(PARAMETER_DISABLE_RULES); | ||||||
|  | 			params.setDisableRulesService(!isNullOrEmpty(disableRulesStr) && PARAMETER_VALUE_DISABLE_RULES.equals(disableRulesStr)); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private NodeRef getTargetNodeRef() throws FileNotFoundException | ||||||
|  | 		{ | ||||||
|  | 			String targetNodeRefStr = getParamStringValue(PARAMETER_TARGET_NODEREF); | ||||||
|  | 			String targetPath = getParamStringValue(PARAMETER_TARGET_PATH); | ||||||
|  | 			return nodeRefCreator.fromNodeRefAndPath(targetNodeRefStr, targetPath); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private OptionalInt getOptionalPositiveInteger(final String paramName) | ||||||
|  | 		{ | ||||||
|  | 			final String strValue = getParamStringValue(paramName); | ||||||
|  | 			if (isNullOrEmpty(strValue)) | ||||||
|  | 			{ | ||||||
|  | 				return OptionalInt.empty(); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			final Integer asInt = Ints.tryParse(strValue); | ||||||
|  | 			if (asInt == null || asInt < 1) | ||||||
|  | 			{ | ||||||
|  | 				throw new WebScriptException("Error: parameter '" + paramName + "' must be an integer > 0."); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return OptionalInt.of(asInt); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private String getParamStringValue(String paramName) | ||||||
|  | 		{ | ||||||
|  | 			Objects.requireNonNull(paramName); | ||||||
|  |  | ||||||
|  | 			return paramsProvider.apply(paramName); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		private boolean isNullOrEmpty(String str) | ||||||
|  | 		{ | ||||||
|  | 			return str == null || str.trim().length() == 0; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		@FunctionalInterface | ||||||
|  | 		protected interface NodeRefCreator | ||||||
|  | 		{ | ||||||
|  | 			NodeRef fromNodeRefAndPath(String nodeRef, String path) throws FileNotFoundException; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -27,17 +27,12 @@ | |||||||
| package org.alfresco.repo.web.scripts.bulkimport.copy; | package org.alfresco.repo.web.scripts.bulkimport.copy; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  |  | ||||||
| import org.alfresco.repo.bulkimport.BulkImportParameters; |  | ||||||
| import org.alfresco.repo.bulkimport.NodeImporter; | import org.alfresco.repo.bulkimport.NodeImporter; | ||||||
| import org.alfresco.repo.bulkimport.impl.MultiThreadedBulkFilesystemImporter; | import org.alfresco.repo.bulkimport.impl.MultiThreadedBulkFilesystemImporter; | ||||||
| import org.alfresco.repo.bulkimport.impl.StreamingNodeImporterFactory; | import org.alfresco.repo.bulkimport.impl.StreamingNodeImporterFactory; | ||||||
| import org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript; | import org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript; | ||||||
| import org.alfresco.service.cmr.model.FileNotFoundException; |  | ||||||
| import org.alfresco.service.cmr.repository.NodeRef; |  | ||||||
| import org.springframework.extensions.surf.util.I18NUtil; |  | ||||||
| import org.springframework.extensions.webscripts.Cache; | import org.springframework.extensions.webscripts.Cache; | ||||||
| import org.springframework.extensions.webscripts.Status; | import org.springframework.extensions.webscripts.Status; | ||||||
| import org.springframework.extensions.webscripts.WebScriptException; | import org.springframework.extensions.webscripts.WebScriptException; | ||||||
| @@ -69,170 +64,22 @@ public class BulkFilesystemImportWebScript extends AbstractBulkFileSystemImportW | |||||||
|     @Override |     @Override | ||||||
|     protected Map<String, Object> executeImpl(final WebScriptRequest request, final Status status, final Cache cache) |     protected Map<String, Object> executeImpl(final WebScriptRequest request, final Status status, final Cache cache) | ||||||
|     { |     { | ||||||
|         Map<String, Object> model  = new HashMap<String, Object>(); |         final MultithreadedImportWebScriptLogic importLogic = new MultithreadedImportWebScriptLogic(bulkImporter, | ||||||
|         String targetNodeRefStr = null; |                 () -> createNodeImporter(request), request, status, cache); | ||||||
|         String targetPath = null; |         return importLogic.executeImport(); | ||||||
|         String sourceDirectoryStr = null; |     } | ||||||
|         @Deprecated String replaceExistingStr = null; |  | ||||||
|         String existingFileModeStr = null; |  | ||||||
|         String batchSizeStr = null; |  | ||||||
|         String numThreadsStr = null; |  | ||||||
|         String disableRulesStr = null; |  | ||||||
|  |  | ||||||
|         cache.setNeverCache(true); |     private NodeImporter createNodeImporter(WebScriptRequest request) | ||||||
|          |  | ||||||
|         try |  | ||||||
|     { |     { | ||||||
|             if(!bulkImporter.getStatus().inProgress()) |         final String sourceDirectoryStr = request.getParameter(PARAMETER_SOURCE_DIRECTORY); | ||||||
|             { |  | ||||||
|                 NodeRef targetNodeRef = null; |  | ||||||
|                 File sourceDirectory = null; |  | ||||||
|                 boolean replaceExisting = false; |  | ||||||
|                 BulkImportParameters.ExistingFileMode existingFileMode = null; |  | ||||||
|                 int batchSize = bulkImporter.getDefaultBatchSize(); |  | ||||||
|                 int numThreads = bulkImporter.getDefaultNumThreads(); |  | ||||||
|                 boolean disableRules = false; |  | ||||||
|                  |  | ||||||
|                 // Retrieve, validate and convert parameters |  | ||||||
|                 targetNodeRefStr = request.getParameter(PARAMETER_TARGET_NODEREF); |  | ||||||
|                 targetPath = request.getParameter(PARAMETER_TARGET_PATH); |  | ||||||
|                 sourceDirectoryStr = request.getParameter(PARAMETER_SOURCE_DIRECTORY); |  | ||||||
|                 replaceExistingStr = request.getParameter(PARAMETER_REPLACE_EXISTING); |  | ||||||
|                 existingFileModeStr = request.getParameter(PARAMETER_EXISTING_FILE_MODE); |  | ||||||
|  |  | ||||||
|                 batchSizeStr = request.getParameter(PARAMETER_BATCH_SIZE); |  | ||||||
|                 numThreadsStr = request.getParameter(PARAMETER_NUM_THREADS); |  | ||||||
|                 disableRulesStr = request.getParameter(PARAMETER_DISABLE_RULES); |  | ||||||
|  |  | ||||||
|                 targetNodeRef = getTargetNodeRef(targetNodeRefStr, targetPath); |  | ||||||
|                  |  | ||||||
|         if (sourceDirectoryStr == null || sourceDirectoryStr.trim().length() == 0) |         if (sourceDirectoryStr == null || sourceDirectoryStr.trim().length() == 0) | ||||||
|         { |         { | ||||||
|                     throw new RuntimeException("Error: mandatory parameter '" + PARAMETER_SOURCE_DIRECTORY + "' was not provided."); |             throw new WebScriptException("Error: mandatory parameter '" + PARAMETER_SOURCE_DIRECTORY + "' was not provided."); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|                 sourceDirectory = new File(sourceDirectoryStr.trim()); |         final File sourceDirectory = new File(sourceDirectoryStr.trim()); | ||||||
|  |  | ||||||
|                 if (replaceExistingStr != null && existingFileModeStr != null) |         return nodeImporterFactory.getNodeImporter(sourceDirectory); | ||||||
|                 { |  | ||||||
|                     // Check that we haven't had both the deprecated and new (existingFileMode) |  | ||||||
|                     // parameters supplied. |  | ||||||
|                     throw new IllegalStateException( |  | ||||||
|                             String.format("Only one of these parameters may be used, not both: %s, %s", |  | ||||||
|                                     PARAMETER_REPLACE_EXISTING, |  | ||||||
|                                     PARAMETER_EXISTING_FILE_MODE)); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (replaceExistingStr != null && replaceExistingStr.trim().length() > 0) |  | ||||||
|                 { |  | ||||||
|                     replaceExisting = PARAMETER_VALUE_REPLACE_EXISTING.equals(replaceExistingStr); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (existingFileModeStr != null && existingFileModeStr.trim().length() > 0) |  | ||||||
|                 { |  | ||||||
|                     existingFileMode = BulkImportParameters.ExistingFileMode.valueOf(existingFileModeStr); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (disableRulesStr != null && disableRulesStr.trim().length() > 0) |  | ||||||
|                 { |  | ||||||
|                     disableRules = PARAMETER_VALUE_DISABLE_RULES.equals(disableRulesStr); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 // Initiate the import |  | ||||||
|                 NodeImporter nodeImporter = nodeImporterFactory.getNodeImporter(sourceDirectory); |  | ||||||
|                 BulkImportParameters bulkImportParameters = new BulkImportParameters(); |  | ||||||
|                  |  | ||||||
|                 if (numThreadsStr != null && numThreadsStr.trim().length() > 0) |  | ||||||
|                 { |  | ||||||
|                 	try |  | ||||||
|                 	{ |  | ||||||
|                 		numThreads = Integer.parseInt(numThreadsStr); |  | ||||||
|                 		if(numThreads < 1) |  | ||||||
|                 		{ |  | ||||||
|                             throw new RuntimeException("Error: parameter '" + PARAMETER_NUM_THREADS + "' must be an integer > 0."); |  | ||||||
|                 		} |  | ||||||
|                         bulkImportParameters.setNumThreads(numThreads); |  | ||||||
|                 	} |  | ||||||
|                 	catch(NumberFormatException e) |  | ||||||
|                 	{ |  | ||||||
|                         throw new RuntimeException("Error: parameter '" + PARAMETER_NUM_THREADS + "' must be an integer > 0."); |  | ||||||
|                 	} |  | ||||||
|                 } |  | ||||||
|                  |  | ||||||
|                 if (batchSizeStr != null && batchSizeStr.trim().length() > 0) |  | ||||||
|                 { |  | ||||||
|                 	try |  | ||||||
|                 	{ |  | ||||||
|                 		batchSize = Integer.parseInt(batchSizeStr); |  | ||||||
|                 		if(batchSize < 1) |  | ||||||
|                 		{ |  | ||||||
|                             throw new RuntimeException("Error: parameter '" + PARAMETER_BATCH_SIZE + "' must be an integer > 0."); |  | ||||||
|                 		} |  | ||||||
|                         bulkImportParameters.setBatchSize(batchSize); |  | ||||||
|                 	} |  | ||||||
|                 	catch(NumberFormatException e) |  | ||||||
|                 	{ |  | ||||||
|                         throw new RuntimeException("Error: parameter '" + PARAMETER_BATCH_SIZE + "' must be an integer > 0."); |  | ||||||
|                 	} |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if (existingFileMode != null) |  | ||||||
|                 { |  | ||||||
|                     bulkImportParameters.setExistingFileMode(existingFileMode); |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     // Fall back to the old/deprecated way. |  | ||||||
|                     bulkImportParameters.setReplaceExisting(replaceExisting); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 bulkImportParameters.setTarget(targetNodeRef); |  | ||||||
|                 bulkImportParameters.setDisableRulesService(disableRules); |  | ||||||
|  |  | ||||||
|                 bulkImporter.asyncBulkImport(bulkImportParameters, nodeImporter); |  | ||||||
|  |  | ||||||
|                 // ACE-3047 fix, since bulk import is started asynchronously there is a chance that client  |  | ||||||
|                 // will get into the status page before import is actually started. |  | ||||||
|                 // In this case wrong information (for previous import) will be displayed. |  | ||||||
|                 // So lets ensure that import started before redirecting client to status page. |  | ||||||
|                 int i = 0; |  | ||||||
|                 while (!bulkImporter.getStatus().inProgress() && i < 10) |  | ||||||
|                 { |  | ||||||
|                 	Thread.sleep(100); |  | ||||||
|                 	i++; |  | ||||||
|                 } |  | ||||||
|                  |  | ||||||
|                 // redirect to the status Web Script |  | ||||||
|                 status.setCode(Status.STATUS_MOVED_TEMPORARILY); |  | ||||||
|                 status.setRedirect(true); |  | ||||||
|                 status.setLocation(request.getServiceContextPath() + WEB_SCRIPT_URI_BULK_FILESYSTEM_IMPORT_STATUS); |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|             	model.put(IMPORT_ALREADY_IN_PROGRESS_MODEL_KEY, I18NUtil.getMessage(IMPORT_ALREADY_IN_PROGRESS_ERROR_KEY)); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         catch (WebScriptException wse) |  | ||||||
|         { |  | ||||||
|         	status.setCode(Status.STATUS_BAD_REQUEST, wse.getMessage()); |  | ||||||
|         	status.setRedirect(true); |  | ||||||
|         } |  | ||||||
|         catch (FileNotFoundException fnfe) |  | ||||||
|         { |  | ||||||
|         	status.setCode(Status.STATUS_BAD_REQUEST,"The repository path '" + targetPath + "' does not exist !"); |  | ||||||
|         	status.setRedirect(true); |  | ||||||
|         } |  | ||||||
|         catch(IllegalArgumentException iae) |  | ||||||
|         { |  | ||||||
|         	status.setCode(Status.STATUS_BAD_REQUEST,iae.getMessage()); |  | ||||||
|         	status.setRedirect(true); |  | ||||||
|         } |  | ||||||
|         catch (Throwable t) |  | ||||||
|         { |  | ||||||
|             throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, buildTextMessage(t), t); |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         return model; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1070,7 +1070,7 @@ | |||||||
|         <property name="enabled" value="${system.api.discovery.enabled}" /> |         <property name="enabled" value="${system.api.discovery.enabled}" /> | ||||||
|         <property name="thumbnailService" ref="ThumbnailService" /> |         <property name="thumbnailService" ref="ThumbnailService" /> | ||||||
|         <property name="restApiDirectUrlConfig" ref="restApiDirectUrlConfig" /> |         <property name="restApiDirectUrlConfig" ref="restApiDirectUrlConfig" /> | ||||||
|         <property name="contentService" ref="ContentService" /> |         <property name="contentService" ref="contentService" /> | ||||||
|     </bean> |     </bean> | ||||||
|  |  | ||||||
|     <bean id="org.alfresco.rest.api.probes.ProbeEntityResource.get" class="org.alfresco.rest.api.probes.ProbeEntityResource"> |     <bean id="org.alfresco.rest.api.probes.ProbeEntityResource.get" class="org.alfresco.rest.api.probes.ProbeEntityResource"> | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ import org.junit.runners.Suite; | |||||||
|     org.alfresco.rest.api.tests.TestPublicApiAtomPub10TCK.class, |     org.alfresco.rest.api.tests.TestPublicApiAtomPub10TCK.class, | ||||||
|     org.alfresco.rest.api.tests.TestPublicApiAtomPub11TCK.class, |     org.alfresco.rest.api.tests.TestPublicApiAtomPub11TCK.class, | ||||||
|     org.alfresco.rest.api.tests.TestPublicApiBrowser11TCK.class, |     org.alfresco.rest.api.tests.TestPublicApiBrowser11TCK.class, | ||||||
|  |     org.alfresco.repo.web.scripts.bulkimport.BulkImportParametersExtractorTest.class | ||||||
| }) | }) | ||||||
| public class AppContext01TestSuite | public class AppContext01TestSuite | ||||||
| { | { | ||||||
|   | |||||||
| @@ -0,0 +1,252 @@ | |||||||
|  | /* | ||||||
|  |  * #%L | ||||||
|  |  * Alfresco Remote API | ||||||
|  |  * %% | ||||||
|  |  * Copyright (C) 2005 - 2021 Alfresco Software Limited | ||||||
|  |  * %% | ||||||
|  |  * This file is part of the Alfresco software. | ||||||
|  |  * If the software was purchased under a paid Alfresco license, the terms of | ||||||
|  |  * the paid license agreement will prevail.  Otherwise, the software is | ||||||
|  |  * provided under the following open source license terms: | ||||||
|  |  * | ||||||
|  |  * Alfresco is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU Lesser General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * Alfresco is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU Lesser General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Lesser General Public License | ||||||
|  |  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * #L% | ||||||
|  |  */ | ||||||
|  | package org.alfresco.repo.web.scripts.bulkimport; | ||||||
|  |  | ||||||
|  | import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_BATCH_SIZE; | ||||||
|  | import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_DISABLE_RULES; | ||||||
|  | import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_NUM_THREADS; | ||||||
|  | import static org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.PARAMETER_TARGET_NODEREF; | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | import static org.junit.Assert.assertFalse; | ||||||
|  | import static org.junit.Assert.assertNotNull; | ||||||
|  | import static org.junit.Assert.assertNull; | ||||||
|  | import static org.junit.Assert.assertThrows; | ||||||
|  | import static org.junit.Assert.assertTrue; | ||||||
|  | import static org.junit.Assert.fail; | ||||||
|  |  | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
|  | import org.alfresco.repo.bulkimport.BulkImportParameters; | ||||||
|  | import org.alfresco.repo.bulkimport.BulkImportParameters.ExistingFileMode; | ||||||
|  | import org.alfresco.repo.web.scripts.bulkimport.AbstractBulkFileSystemImportWebScript.BulkImportParametersExtractor; | ||||||
|  | import org.alfresco.service.cmr.model.FileNotFoundException; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.springframework.extensions.webscripts.WebScriptException; | ||||||
|  |  | ||||||
|  | public class BulkImportParametersExtractorTest | ||||||
|  | { | ||||||
|  |     private static final String TEST_NODE_REF = "workspace://SpacesStore/this-is-just-a-test-ref"; | ||||||
|  |     private static final String TEST_MISSING_NODE_REF = "workspace://SpacesStore/this-is-just-a-not-existing-test-ref"; | ||||||
|  |     private static final Integer DEFAULT_BATCH_SIZE = 1234; | ||||||
|  |     private static final Integer DEFAULT_NUMBER_OF_THREADS = 4321; | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldExtractTargetRef() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF)); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertNotNull(params); | ||||||
|  |         assertNotNull(params.getTarget()); | ||||||
|  |         assertEquals(TEST_NODE_REF, params.getTarget().toString()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldFallbackToDefaultValues() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF)); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertEquals(DEFAULT_BATCH_SIZE, params.getBatchSize()); | ||||||
|  |         assertEquals(DEFAULT_NUMBER_OF_THREADS, params.getNumThreads()); | ||||||
|  |         assertFalse(params.isDisableRulesService()); | ||||||
|  |         assertEquals(ExistingFileMode.SKIP, params.getExistingFileMode()); | ||||||
|  |         assertNull(params.getLoggingInterval()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldExtractDisableFolderRulesFlagWhenSetToTrue() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_DISABLE_RULES, "true" | ||||||
|  |                                                                              )); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertTrue(params.isDisableRulesService()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldExtractDisableFolderRulesFlagWhenSetToFalse() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_DISABLE_RULES, "false" | ||||||
|  |                                                                              )); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertFalse(params.isDisableRulesService()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldExtractDisableFolderRulesFlagWhenSetToNotBooleanValue() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_DISABLE_RULES, "unknown" | ||||||
|  |                                                                              )); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertFalse(params.isDisableRulesService()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldPropagateFileNotFoundExceptionWhenTargetIsNotFound() | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_MISSING_NODE_REF)); | ||||||
|  |  | ||||||
|  |         assertThrows(FileNotFoundException.class, extractor::extract); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldExtractValidBatchSize() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_BATCH_SIZE, "1")); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertEquals(Integer.valueOf(1), params.getBatchSize()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldFailWithWebScriptExceptionWhenInvalidBatchSizeIsRequested() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_BATCH_SIZE, "not-a-number")); | ||||||
|  |  | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             extractor.extract(); | ||||||
|  |         } catch (WebScriptException e) | ||||||
|  |         { | ||||||
|  |             assertNotNull(e.getMessage()); | ||||||
|  |             assertTrue(e.getMessage().contains(PARAMETER_BATCH_SIZE)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fail("Expected exception to be thrown."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldFailWithWebScriptExceptionWhenNegativeBatchSizeIsRequested() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_BATCH_SIZE, "-1")); | ||||||
|  |  | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             extractor.extract(); | ||||||
|  |         } catch (WebScriptException e) | ||||||
|  |         { | ||||||
|  |             assertNotNull(e.getMessage()); | ||||||
|  |             assertTrue(e.getMessage().contains(PARAMETER_BATCH_SIZE)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fail("Expected exception to be thrown."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldExtractValidNumberOfThreads() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_NUM_THREADS, "1")); | ||||||
|  |  | ||||||
|  |         final BulkImportParameters params = extractor.extract(); | ||||||
|  |  | ||||||
|  |         assertEquals(Integer.valueOf(1), params.getNumThreads()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldFailWithWebScriptExceptionWhenInvalidNumberOfThreadsIsRequested() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_NUM_THREADS, "not-a-number")); | ||||||
|  |  | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             extractor.extract(); | ||||||
|  |         } catch (WebScriptException e) | ||||||
|  |         { | ||||||
|  |             assertNotNull(e.getMessage()); | ||||||
|  |             assertTrue(e.getMessage().contains(PARAMETER_NUM_THREADS)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fail("Expected exception to be thrown."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void shouldFailWithWebScriptExceptionWhenNegativeNumberOfThreadsIsRequested() throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         final BulkImportParametersExtractor extractor = givenExtractor(Map.of( | ||||||
|  |                 PARAMETER_TARGET_NODEREF, TEST_NODE_REF, | ||||||
|  |                 PARAMETER_NUM_THREADS, "-1")); | ||||||
|  |  | ||||||
|  |         try | ||||||
|  |         { | ||||||
|  |             extractor.extract(); | ||||||
|  |         } catch (WebScriptException e) | ||||||
|  |         { | ||||||
|  |             assertNotNull(e.getMessage()); | ||||||
|  |             assertTrue(e.getMessage().contains(PARAMETER_NUM_THREADS)); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fail("Expected exception to be thrown."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private BulkImportParametersExtractor givenExtractor(Map<String, String> params) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         return new BulkImportParametersExtractor(params::get, this::testRefCreator, DEFAULT_BATCH_SIZE, DEFAULT_NUMBER_OF_THREADS); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private NodeRef testRefCreator(String nodeRef, String path) throws FileNotFoundException | ||||||
|  |     { | ||||||
|  |         if (TEST_MISSING_NODE_REF.equals(nodeRef)) | ||||||
|  |         { | ||||||
|  |             throw new FileNotFoundException(new NodeRef(nodeRef)); | ||||||
|  |         } | ||||||
|  |         return new NodeRef(nodeRef); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <parent> |     <parent> | ||||||
|         <groupId>org.alfresco</groupId> |         <groupId>org.alfresco</groupId> | ||||||
|         <artifactId>alfresco-community-repo</artifactId> |         <artifactId>alfresco-community-repo</artifactId> | ||||||
|         <version>11.141-SNAPSHOT</version> |         <version>12.4</version> | ||||||
|     </parent> |     </parent> | ||||||
|  |  | ||||||
|     <dependencies> |     <dependencies> | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  * #%L |  * #%L | ||||||
|  * Alfresco Repository |  * Alfresco Repository | ||||||
|  * %% |  * %% | ||||||
|  * Copyright (C) 2005 - 2016 Alfresco Software Limited |  * Copyright (C) 2005 - 2021 Alfresco Software Limited | ||||||
|  * %% |  * %% | ||||||
|  * This file is part of the Alfresco software.  |  * This file is part of the Alfresco software.  | ||||||
|  * If the software was purchased under a paid Alfresco license, the terms of  |  * If the software was purchased under a paid Alfresco license, the terms of  | ||||||
| @@ -25,6 +25,9 @@ | |||||||
|  */ |  */ | ||||||
| package org.alfresco.repo.security.permissions.impl.acegi; | package org.alfresco.repo.security.permissions.impl.acegi; | ||||||
|  |  | ||||||
|  | import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.getNodeRef; | ||||||
|  | import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.shouldAbstainOrDeny; | ||||||
|  |  | ||||||
| import java.io.Serializable; | import java.io.Serializable; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| @@ -46,8 +49,6 @@ import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; | |||||||
| import org.alfresco.service.cmr.repository.ChildAssociationRef; | import org.alfresco.service.cmr.repository.ChildAssociationRef; | ||||||
| import org.alfresco.service.cmr.repository.NodeRef; | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
| import org.alfresco.service.cmr.repository.NodeService; | import org.alfresco.service.cmr.repository.NodeService; | ||||||
| import org.alfresco.service.cmr.repository.StoreRef; |  | ||||||
| import org.alfresco.service.cmr.security.AccessStatus; |  | ||||||
| import org.alfresco.service.cmr.security.AuthenticationService; | import org.alfresco.service.cmr.security.AuthenticationService; | ||||||
| import org.alfresco.service.cmr.security.AuthorityService; | import org.alfresco.service.cmr.security.AuthorityService; | ||||||
| import org.alfresco.service.cmr.security.OwnableService; | import org.alfresco.service.cmr.security.OwnableService; | ||||||
| @@ -59,6 +60,7 @@ import org.apache.commons.logging.Log; | |||||||
| import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | ||||||
| import org.springframework.beans.factory.InitializingBean; | import org.springframework.beans.factory.InitializingBean; | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * @author andyh |  * @author andyh | ||||||
|  */ |  */ | ||||||
| @@ -395,61 +397,53 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean | |||||||
|                 { |                 { | ||||||
|                     throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef"); |                     throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef"); | ||||||
|                 } |                 } | ||||||
|                 else if (StoreRef.class.isAssignableFrom(params[cad.parameter[0]])) |  | ||||||
|  |                 if (List.class.isAssignableFrom(params[cad.parameter[0]])) | ||||||
|                 { |                 { | ||||||
|                     StoreRef storeRef = getArgument(invocation, cad.parameter[0]); |                     List<?> listArgument = getArgument(invocation, cad.parameter[0]); | ||||||
|                     if (storeRef != null) |                     if (listArgument != null) | ||||||
|                     { |                     { | ||||||
|                         if (log.isDebugEnabled()) |                         NodeRef listNodeRef; | ||||||
|  |                         Integer accessAbstainOrDeny = null; | ||||||
|  |                         for (Object listElement : listArgument) | ||||||
|                         { |                         { | ||||||
|                             log.debug("\tPermission test against the store - using permissions on the root node"); |                             listNodeRef = getNodeRef(listElement, nodeService); | ||||||
|                         } |                             Integer currentValue = shouldAbstainOrDeny(cad.required, listNodeRef, abstainForClassQNames, nodeService, permissionService); | ||||||
|                         if (nodeService.exists(storeRef)) |  | ||||||
|  |                             if (currentValue != null) | ||||||
|                             { |                             { | ||||||
|                             testNodeRef = nodeService.getRootNode(storeRef); |                                 if (currentValue == AccessDecisionVoter.ACCESS_DENIED) | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 else if (NodeRef.class.isAssignableFrom(params[cad.parameter[0]])) |  | ||||||
|                                 { |                                 { | ||||||
|                     testNodeRef = getArgument(invocation, cad.parameter[0]); |                                     return AccessDecisionVoter.ACCESS_DENIED; | ||||||
|                     if (log.isDebugEnabled()) |  | ||||||
|                     { |  | ||||||
|                         if (testNodeRef != null) |  | ||||||
|                         { |  | ||||||
|                             if (nodeService.exists(testNodeRef)) |  | ||||||
|                             { |  | ||||||
|                                 log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); |  | ||||||
|                                 } |                                 } | ||||||
|                                 else |                                 else | ||||||
|                                 { |                                 { | ||||||
|                                 log.debug("\tPermission test on non-existing node " +testNodeRef); |                                     accessAbstainOrDeny = currentValue; | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|  |  | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|  |                         if (accessAbstainOrDeny != null) | ||||||
|  |                         { | ||||||
|  |                             return accessAbstainOrDeny; | ||||||
|                         } |                         } | ||||||
|                 else if (ChildAssociationRef.class.isAssignableFrom(params[cad.parameter[0]])) |                         if((hasMethodEntry == null) || (hasMethodEntry.booleanValue())) | ||||||
|                         { |                         { | ||||||
|                     ChildAssociationRef testChildRef = getArgument(invocation, cad.parameter[0]); |                             return AccessDecisionVoter.ACCESS_GRANTED; | ||||||
|                     if (testChildRef != null) |  | ||||||
|                     { |  | ||||||
|                         testNodeRef = testChildRef.getChildRef(); |  | ||||||
|                         if (log.isDebugEnabled()) |  | ||||||
|                         { |  | ||||||
|                             if (nodeService.exists(testNodeRef)) |  | ||||||
|                             { |  | ||||||
|                                 log.debug("\tPermission test on node " + nodeService.getPath(testNodeRef)); |  | ||||||
|                         } |                         } | ||||||
|                         else |                         else | ||||||
|                         { |                         { | ||||||
|                                 log.debug("\tPermission test on non-existing node " + testNodeRef); |                             return AccessDecisionVoter.ACCESS_DENIED; | ||||||
|                             } |  | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef"); |                     Object testObject = getArgument(invocation, cad.parameter[0]); | ||||||
|  |                     //If the execution reaches here, then testNodeRef is always null | ||||||
|  |                     testNodeRef = getNodeRef(testObject, nodeService); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             else if (cad.typeString.equals(ACL_ITEM)) |             else if (cad.typeString.equals(ACL_ITEM)) | ||||||
| @@ -584,44 +578,10 @@ public class ACLEntryVoter implements AccessDecisionVoter, InitializingBean | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (testNodeRef != null) |             Integer accessAbstainOrDeny = shouldAbstainOrDeny(cad.required, testNodeRef, abstainForClassQNames, nodeService, permissionService); | ||||||
|  |             if (accessAbstainOrDeny != null) | ||||||
|             { |             { | ||||||
|                 // now we know the node - we can abstain for certain types and aspects (eg. RM) |                 return accessAbstainOrDeny; | ||||||
|                 if(abstainForClassQNames.size() > 0) |  | ||||||
|                 { |  | ||||||
|                     // check node exists |  | ||||||
|                     if (nodeService.exists(testNodeRef)) |  | ||||||
|                     { |  | ||||||
|                         QName typeQName = nodeService.getType(testNodeRef); |  | ||||||
|                         if(abstainForClassQNames.contains(typeQName)) |  | ||||||
|                         { |  | ||||||
|                             return AccessDecisionVoter.ACCESS_ABSTAIN; |  | ||||||
|                         } |  | ||||||
|                         |  | ||||||
|                         Set<QName> aspectQNames = nodeService.getAspects(testNodeRef); |  | ||||||
|                         for(QName abstain : abstainForClassQNames) |  | ||||||
|                         { |  | ||||||
|                             if(aspectQNames.contains(abstain)) |  | ||||||
|                             { |  | ||||||
|                                 return AccessDecisionVoter.ACCESS_ABSTAIN; |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                  |  | ||||||
|                 if (log.isDebugEnabled()) |  | ||||||
|                 { |  | ||||||
|                     log.debug("\t\tNode ref is not null"); |  | ||||||
|                 } |  | ||||||
|                 if (permissionService.hasPermission(testNodeRef, cad.required.toString()) == AccessStatus.DENIED) |  | ||||||
|                 { |  | ||||||
|                     if (log.isDebugEnabled()) |  | ||||||
|                     { |  | ||||||
|                         log.debug("\t\tPermission is denied"); |  | ||||||
|                         Thread.dumpStack(); |  | ||||||
|                     } |  | ||||||
|                     return AccessDecisionVoter.ACCESS_DENIED; |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,175 @@ | |||||||
|  | /* | ||||||
|  |  * #%L | ||||||
|  |  * Alfresco Repository | ||||||
|  |  * %% | ||||||
|  |  * Copyright (C) 2005 - 2021 Alfresco Software Limited | ||||||
|  |  * %% | ||||||
|  |  * This file is part of the Alfresco software. | ||||||
|  |  * If the software was purchased under a paid Alfresco license, the terms of | ||||||
|  |  * the paid license agreement will prevail.  Otherwise, the software is | ||||||
|  |  * provided under the following open source license terms: | ||||||
|  |  * | ||||||
|  |  * Alfresco is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU Lesser General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * Alfresco is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU Lesser General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Lesser General Public License | ||||||
|  |  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * #L% | ||||||
|  |  */ | ||||||
|  | package org.alfresco.repo.security.permissions.impl.acegi; | ||||||
|  |  | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | import net.sf.acegisecurity.vote.AccessDecisionVoter; | ||||||
|  | import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; | ||||||
|  | import org.alfresco.service.cmr.repository.ChildAssociationRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeService; | ||||||
|  | import org.alfresco.service.cmr.repository.StoreRef; | ||||||
|  | import org.alfresco.service.cmr.security.AccessStatus; | ||||||
|  | import org.alfresco.service.cmr.security.PermissionService; | ||||||
|  | import org.alfresco.service.namespace.QName; | ||||||
|  | import org.slf4j.Logger; | ||||||
|  | import org.slf4j.LoggerFactory; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Utility methods extracted from AclEntryVoter | ||||||
|  |  * | ||||||
|  |  * @author Lev Belava | ||||||
|  |  */ | ||||||
|  | final class ACLEntryVoterUtils | ||||||
|  | { | ||||||
|  |     private static final Logger LOG = LoggerFactory.getLogger(ACLEntryVoterUtils.class); | ||||||
|  |  | ||||||
|  |     private ACLEntryVoterUtils() | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets NodeRef for testObject based on inferred type | ||||||
|  |      * | ||||||
|  |      * @param testObject                Tested object to work on | ||||||
|  |      * @param nodeService               Node service to perform checks on refs | ||||||
|  |      * @return                          NodeRef for testObject or null if (testObject is null or StoreRef from testObject does not exist in the provided NodeService) | ||||||
|  |      * @throws ACLEntryVoterException   if testObject is not null and not one of a NodeRef or ChildAssociationRef types | ||||||
|  |      */ | ||||||
|  |     static NodeRef getNodeRef(Object testObject, NodeService nodeService) | ||||||
|  |     { | ||||||
|  |         if (testObject == null) | ||||||
|  |         { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (StoreRef.class.isAssignableFrom(testObject.getClass())) | ||||||
|  |         { | ||||||
|  |             LOG.debug("Permission test against the store - using permissions on the root node"); | ||||||
|  |             StoreRef storeRef = (StoreRef) testObject; | ||||||
|  |             if (nodeService.exists(storeRef)) | ||||||
|  |             { | ||||||
|  |                 return nodeService.getRootNode(storeRef); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 LOG.debug("StoreRef does not exist"); | ||||||
|  |                 return null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (NodeRef.class.isAssignableFrom(testObject.getClass())) | ||||||
|  |         { | ||||||
|  |             NodeRef result = (NodeRef) testObject; | ||||||
|  |             if (LOG.isDebugEnabled()) | ||||||
|  |             { | ||||||
|  |                 if (nodeService.exists(result)) | ||||||
|  |                 { | ||||||
|  |                     LOG.debug("Permission test on node {}", nodeService.getPath(result)); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     LOG.debug("Permission test on non-existing node {}", result); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (ChildAssociationRef.class.isAssignableFrom(testObject.getClass())) | ||||||
|  |         { | ||||||
|  |             ChildAssociationRef testChildRef = (ChildAssociationRef) testObject; | ||||||
|  |             NodeRef result = testChildRef.getChildRef(); | ||||||
|  |             if (LOG.isDebugEnabled()) | ||||||
|  |             { | ||||||
|  |                 if (nodeService.exists(result)) | ||||||
|  |                 { | ||||||
|  |                     LOG.debug("Permission test on node {}", nodeService.getPath(result)); | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     LOG.debug("Permission test on non-existing node {}", result); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         throw new ACLEntryVoterException("The specified parameter is not a NodeRef or ChildAssociationRef"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Checks if tested NodeRef instance is abstained or denied based on set of QNames to abstain and | ||||||
|  |      * | ||||||
|  |      * @param requiredPermissionReference           Required permissions | ||||||
|  |      * @param testNodeRef                           NodeRef to be verified | ||||||
|  |      * @param abstainForClassQNames                 Set of QNames to abstain | ||||||
|  |      * @param nodeService                           Node service to perform checks on tested NodeRef | ||||||
|  |      * @param permissionService                     Permission service to check for required permissions | ||||||
|  |      * @return                                      null if testNodeRef is not abstained or denied, otherwise returns appropriate status. | ||||||
|  |      */ | ||||||
|  |     static Integer shouldAbstainOrDeny(SimplePermissionReference requiredPermissionReference, NodeRef testNodeRef, Set<QName> abstainForClassQNames, | ||||||
|  |                                         NodeService nodeService, PermissionService permissionService) | ||||||
|  |     { | ||||||
|  |         if (testNodeRef == null) | ||||||
|  |         { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         LOG.debug("Node ref is not null"); | ||||||
|  |  | ||||||
|  |         if (abstainForClassQNames.size() > 0 && nodeService.exists(testNodeRef)) | ||||||
|  |         { | ||||||
|  |             if (abstainForClassQNames.contains(nodeService.getType(testNodeRef))) | ||||||
|  |             { | ||||||
|  |                 return AccessDecisionVoter.ACCESS_ABSTAIN; | ||||||
|  |             } | ||||||
|  |             Set<QName> testNodeRefAspects = nodeService.getAspects(testNodeRef); | ||||||
|  |             for (QName abstain : abstainForClassQNames) | ||||||
|  |             { | ||||||
|  |                 if (testNodeRefAspects.contains(abstain)) | ||||||
|  |                 { | ||||||
|  |                     return AccessDecisionVoter.ACCESS_ABSTAIN; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (AccessStatus.DENIED == permissionService.hasPermission(testNodeRef, requiredPermissionReference.toString())) | ||||||
|  |         { | ||||||
|  |             if (LOG.isDebugEnabled()) | ||||||
|  |             { | ||||||
|  |                 LOG.debug("Permission is denied"); | ||||||
|  |                 Thread.dumpStack(); | ||||||
|  |             } | ||||||
|  |             return AccessDecisionVoter.ACCESS_DENIED; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -3,7 +3,7 @@ | |||||||
| repository.name=Main Repository | repository.name=Main Repository | ||||||
|  |  | ||||||
| # Schema number | # Schema number | ||||||
| version.schema=15002 | version.schema=15100 | ||||||
|  |  | ||||||
| # Directory configuration | # Directory configuration | ||||||
|  |  | ||||||
|   | |||||||
| @@ -209,6 +209,7 @@ import org.junit.runners.Suite; | |||||||
|     org.alfresco.repo.security.authentication.AuthorizationTest.class, |     org.alfresco.repo.security.authentication.AuthorizationTest.class, | ||||||
|     org.alfresco.repo.security.permissions.PermissionCheckedCollectionTest.class, |     org.alfresco.repo.security.permissions.PermissionCheckedCollectionTest.class, | ||||||
|     org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSetTest.class, |     org.alfresco.repo.security.permissions.impl.acegi.FilteringResultSetTest.class, | ||||||
|  |     org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtilsTest.class, | ||||||
|     org.alfresco.repo.security.authentication.ChainingAuthenticationServiceTest.class, |     org.alfresco.repo.security.authentication.ChainingAuthenticationServiceTest.class, | ||||||
|     org.alfresco.repo.security.authentication.NameBasedUserNameGeneratorTest.class, |     org.alfresco.repo.security.authentication.NameBasedUserNameGeneratorTest.class, | ||||||
|     org.alfresco.repo.version.common.VersionImplTest.class, |     org.alfresco.repo.version.common.VersionImplTest.class, | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ | |||||||
|  * #%L |  * #%L | ||||||
|  * Alfresco Repository |  * Alfresco Repository | ||||||
|  * %% |  * %% | ||||||
|  * Copyright (C) 2005 - 2016 Alfresco Software Limited |  * Copyright (C) 2005 - 2021 Alfresco Software Limited | ||||||
|  * %% |  * %% | ||||||
|  * This file is part of the Alfresco software.  |  * This file is part of the Alfresco software.  | ||||||
|  * If the software was purchased under a paid Alfresco license, the terms of  |  * If the software was purchased under a paid Alfresco license, the terms of  | ||||||
| @@ -96,6 +96,8 @@ public abstract class AbstractPermissionTest extends TestCase | |||||||
|  |  | ||||||
|     protected NodeRef systemNodeRef; |     protected NodeRef systemNodeRef; | ||||||
|  |  | ||||||
|  |     protected NodeRef abstainedNode; | ||||||
|  |  | ||||||
|     protected AuthenticationComponent authenticationComponent; |     protected AuthenticationComponent authenticationComponent; | ||||||
|  |  | ||||||
|     protected ModelDAO permissionModelDAO; |     protected ModelDAO permissionModelDAO; | ||||||
| @@ -186,6 +188,8 @@ public abstract class AbstractPermissionTest extends TestCase | |||||||
|         props = createPersonProperties(USER2_LEMUR); |         props = createPersonProperties(USER2_LEMUR); | ||||||
|         nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef(); |         nodeService.createNode(typesNodeRef, children, ContentModel.TYPE_PERSON, container, props).getChildRef(); | ||||||
|  |  | ||||||
|  |         abstainedNode= nodeService.createNode(rootNodeRef, ContentModel.ASSOC_FAILED_THUMBNAIL, system, ContentModel.TYPE_FAILED_THUMBNAIL).getChildRef(); | ||||||
|  |  | ||||||
|         // create an authentication object e.g. the user |         // create an authentication object e.g. the user | ||||||
|         if(authenticationDAO.userExists(USER1_ANDY)) |         if(authenticationDAO.userExists(USER1_ANDY)) | ||||||
|         { |         { | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,181 @@ | |||||||
|  | /* | ||||||
|  |  * #%L | ||||||
|  |  * Alfresco Repository | ||||||
|  |  * %% | ||||||
|  |  * Copyright (C) 2005 - 2021 Alfresco Software Limited | ||||||
|  |  * %% | ||||||
|  |  * This file is part of the Alfresco software. | ||||||
|  |  * If the software was purchased under a paid Alfresco license, the terms of | ||||||
|  |  * the paid license agreement will prevail.  Otherwise, the software is | ||||||
|  |  * provided under the following open source license terms: | ||||||
|  |  * | ||||||
|  |  * Alfresco is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU Lesser General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * Alfresco is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU Lesser General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU Lesser General Public License | ||||||
|  |  * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  * #L% | ||||||
|  |  */ | ||||||
|  | package org.alfresco.repo.security.permissions.impl.acegi; | ||||||
|  |  | ||||||
|  | import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.getNodeRef; | ||||||
|  | import static org.alfresco.repo.security.permissions.impl.acegi.ACLEntryVoterUtils.shouldAbstainOrDeny; | ||||||
|  | import static org.hamcrest.CoreMatchers.is; | ||||||
|  | import static org.hamcrest.CoreMatchers.nullValue; | ||||||
|  | import static org.hamcrest.MatcherAssert.assertThat; | ||||||
|  | import static org.mockito.ArgumentMatchers.eq; | ||||||
|  | import static org.mockito.ArgumentMatchers.nullable; | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  |  | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
|  | import net.sf.acegisecurity.vote.AccessDecisionVoter; | ||||||
|  | import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; | ||||||
|  | import org.alfresco.service.cmr.repository.ChildAssociationRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeService; | ||||||
|  | import org.alfresco.service.cmr.repository.StoreRef; | ||||||
|  | import org.alfresco.service.cmr.security.AccessStatus; | ||||||
|  | import org.alfresco.service.cmr.security.PermissionService; | ||||||
|  | import org.alfresco.service.namespace.QName; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.mockito.Mock; | ||||||
|  | import org.mockito.junit.MockitoJUnitRunner; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @RunWith(MockitoJUnitRunner.class) | ||||||
|  | public class ACLEntryVoterUtilsTest | ||||||
|  | { | ||||||
|  |     private final NodeRef testNodeRef = new NodeRef("workspace://testNodeRef/testNodeRef"); | ||||||
|  |     private final NodeRef rootNodeRef = new NodeRef("workspace://rootNodeRef/rootNodeRef"); | ||||||
|  |     private final NodeRef refNodeForTestObject = new NodeRef("workspace://refNodeForTestObject/refNodeForTestObject"); | ||||||
|  |     private final NodeRef childRefNode = new NodeRef("workspace://childRefNode/childRefNode"); | ||||||
|  |     private final StoreRef testStoreNodeRef = new StoreRef("system://testStoreRefMock/testStoreRefMock"); | ||||||
|  |     private final SimplePermissionReference simplePermissionReference = SimplePermissionReference.getPermissionReference(QName.createQName("uri", "local"), "Write"); | ||||||
|  |     private final QName qNameToAbstain1 = QName.createQName("{test}testnode1"); | ||||||
|  |     private final QName qNameToAbstain2 = QName.createQName("{test}testnode2"); | ||||||
|  |     private final QName qNameToAbstain3 = QName.createQName("{test}testnode3"); | ||||||
|  |     private final QName qNameNotFromTheAbstainSet = QName.createQName("{test}testnodeAbstain"); | ||||||
|  |     private final Set<QName> qNamesToAbstain = Set.of(qNameToAbstain1, qNameToAbstain2, qNameToAbstain3); | ||||||
|  |     @Mock | ||||||
|  |     private PermissionService permissionServiceMock; | ||||||
|  |     @Mock | ||||||
|  |     private NodeService nodeServiceMock; | ||||||
|  |     @Mock | ||||||
|  |     private ChildAssociationRef childAssocRefMock; | ||||||
|  |  | ||||||
|  |     @Before | ||||||
|  |     public void setUp() | ||||||
|  |     { | ||||||
|  |         when(nodeServiceMock.exists(testStoreNodeRef)).thenReturn(Boolean.TRUE); | ||||||
|  |         when(nodeServiceMock.exists(testNodeRef)).thenReturn(Boolean.TRUE); | ||||||
|  |         when(nodeServiceMock.getRootNode(testStoreNodeRef)).thenReturn(rootNodeRef); | ||||||
|  |         when(nodeServiceMock.getType(testNodeRef)).thenReturn(qNameNotFromTheAbstainSet); | ||||||
|  |         when(nodeServiceMock.getAspects(testNodeRef)).thenReturn(Set.of(qNameNotFromTheAbstainSet)); | ||||||
|  |         when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.DENIED); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsAccessDeniedFromPermissionService() | ||||||
|  |     { | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(AccessDecisionVoter.ACCESS_DENIED)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsNullOnNullTestObject() | ||||||
|  |     { | ||||||
|  |         assertThat(getNodeRef(null, nodeServiceMock), is(nullValue())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test(expected = ACLEntryVoterException.class) | ||||||
|  |     public void throwsExceptionWhenParameterIsNotNodeRefOrChildAssociationRef() | ||||||
|  |     { | ||||||
|  |         getNodeRef("TEST", nodeServiceMock); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsGivenTestNodeRefWhenStoreRefDoesNotExist() | ||||||
|  |     { | ||||||
|  |         when(nodeServiceMock.exists(testStoreNodeRef)).thenReturn(Boolean.FALSE); | ||||||
|  |         assertThat(getNodeRef(testStoreNodeRef, nodeServiceMock), is(nullValue())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsRootNode() | ||||||
|  |     { | ||||||
|  |         assertThat(getNodeRef(testStoreNodeRef, nodeServiceMock), is(rootNodeRef)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsNodeRefFromTestObject() | ||||||
|  |     { | ||||||
|  |         assertThat(getNodeRef(refNodeForTestObject, nodeServiceMock), is(refNodeForTestObject)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsChildRefFromChildAssocRef() | ||||||
|  |     { | ||||||
|  |         when(childAssocRefMock.getChildRef()).thenReturn(childRefNode); | ||||||
|  |         assertThat(getNodeRef(childAssocRefMock, nodeServiceMock), is(childRefNode)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsNullOnNullTestNodeRef() | ||||||
|  |     { | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, null, qNamesToAbstain, nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(nullValue())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsNullOnAbstainClassQnamesIsEmptyAndThereAreNoDeniedPermissions() | ||||||
|  |     { | ||||||
|  |         when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.ALLOWED); | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, Collections.emptySet(), nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(nullValue())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsNullOnTestNodeRefDoesNotExistAndThereAreNoDeniedPermissions() | ||||||
|  |     { | ||||||
|  |         when(nodeServiceMock.exists(testNodeRef)).thenReturn(Boolean.FALSE); | ||||||
|  |         when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.ALLOWED); | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(nullValue())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsNullOnNodeTypeAndNodeAspectsAreNotInSetToAbstainAndThereAreNoDeniedPermissions() | ||||||
|  |     { | ||||||
|  |         when(permissionServiceMock.hasPermission(eq(testNodeRef), nullable(String.class))).thenReturn(AccessStatus.ALLOWED); | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(nullValue())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsAbstainWhenNodeRefTypeIsInSetToAbstain() | ||||||
|  |     { | ||||||
|  |         when(nodeServiceMock.getType(testNodeRef)).thenReturn(qNameToAbstain2); | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(AccessDecisionVoter.ACCESS_ABSTAIN)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     public void returnsAbstainWhenAtLeastOneAspectIsInSetToAbstain() | ||||||
|  |     { | ||||||
|  |         when(nodeServiceMock.getAspects(testNodeRef)).thenReturn(Set.of(qNameNotFromTheAbstainSet, qNameToAbstain3)); | ||||||
|  |         assertThat(shouldAbstainOrDeny(simplePermissionReference, testNodeRef, qNamesToAbstain, nodeServiceMock, permissionServiceMock), | ||||||
|  |                    is(AccessDecisionVoter.ACCESS_ABSTAIN)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user