/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright (c) 2002-2017 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.platform.plugin.services.importer;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.junit.Test;
import org.pentaho.platform.api.mimetype.IMimeType;
import org.pentaho.platform.api.repository2.unified.Converter;
import org.pentaho.platform.api.repository2.unified.IRepositoryDefaultAclHandler;
import org.pentaho.platform.api.repository2.unified.IUnifiedRepository;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.repository2.unified.RepositoryFileAce;
import org.pentaho.platform.api.repository2.unified.RepositoryFileAcl;
import org.pentaho.platform.api.repository2.unified.RepositoryFilePermission;
import org.pentaho.platform.api.repository2.unified.RepositoryFileSid;
import org.pentaho.platform.core.mimetype.MimeType;
import org.pentaho.platform.plugin.services.importexport.ImportSession;
import org.pentaho.platform.plugin.services.importexport.Log4JRepositoryImportLogger;
import org.pentaho.platform.plugin.services.importexport.exportManifest.ExportManifest;
import org.pentaho.platform.security.userroledao.DefaultTenantedPrincipleNameResolver;
import org.pentaho.test.platform.repository2.unified.MockUnifiedRepository;
import org.pentaho.test.platform.repository2.unified.MockUnifiedRepository.ICurrentUserProvider;
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.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
*
* @author tkafalas
*
*/
public class RepositoryFileImportFileHandlerTest {
private static final String USER_NAME = "__root__"; // The mock unified repository gives this user full access
private static final String USER_NAME2 = "mickeyMouse"; // Used with acls
private static final String PATH = "/public/path1/path2";
//we use it as file name when we import file and we use it as folder name when we import the folder
private static final String TARGET_RESOURCE_NAME = "resourceName.dum";
private static final String TARGET_RESOURCE_NAME_NOEXT = "resourceName";
private static final String TARGET_RESOURCE_NAME_ERREXT = "resourceName.err";
private static final String MIMENAME = "mimeName";
private static final String MIME_EXTENSION = "dum";
DefaultTenantedPrincipleNameResolver principleNameResolver = new DefaultTenantedPrincipleNameResolver();
RepositoryFileImportFileHandler fileHandler;
ImportSession importSession;
IUnifiedRepository mockRepository;
RepositoryFileImportBundle mockBundle;
UserProvider userProvider;
@Test
public void testGetImportSession() {
setup( MIMENAME, MIME_EXTENSION, "", "", false );
assertNotNull( importSession );
}
@Test
public void testGetLogger() {
setup( MIMENAME, MIME_EXTENSION, "", "", false );
Log logger = fileHandler.getLogger();
assertNotNull( logger );
}
@Test
public void testGetMimeTypeMap() {
setup( MIMENAME, MIME_EXTENSION, "", "", false );
Map<String, IMimeType> map = fileHandler.getMimeTypeMap();
assertNotNull( map );
assertNotNull( map.get( MIMENAME ) );
}
@Test
public void testImportNewFileWithNoManifest() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasDefaultOwner( acl );
}
@Test
public void testImportNewFileWithNoManifestNoEXT() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.targetName( TARGET_RESOURCE_NAME_NOEXT ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME_NOEXT );
assertNull( repositoryFile );
}
@Test
public void testImportNewFileWithNoManifestNoMime() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.mimename( null ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNull( repositoryFile );
}
@Test
public void testImportNewFileWithNoManifestMimeNotRegistred() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.targetName( TARGET_RESOURCE_NAME_ERREXT ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNull( repositoryFile );
}
@Test
public void testImportNewFileWithManifestApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.hasManifest( true ).applyAclSettings( true )
.overwriteAclSettings( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasManifestOwner( acl );
}
@Test
public void testImportNewFileWithManifestPermissionsApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.hasManifest( true ).applyAclSettings( true ).overwriteAclSettings( true )
.retainOwnership( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasDefaultOwner( acl );
}
@Test
public void testImportNewFileWithManifestOwnerApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.hasManifest( true ).applyAclSettings( false ).overwriteAclSettings( true ).retainOwnership(
false ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasManifestOwner( acl );
}
@Test
public void testImportExistingFileWithManifestApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.fileExists( true ).hasManifest( true )
.overwriteFileIfExists( true ).applyAclSettings( true )
.overwriteAclSettings( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasManifestOwner( acl );
}
/*
* This case tests attempt to overwrite a file when flag does not allow overwriting the file
*/
@Test
public void testNonImportExistingFileWithManifestApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
try {
importTesterBuilder.fileExists( true ).hasManifest( true ).overwriteFileIfExists( false ).applyAclSettings( true )
.overwriteAclSettings( true ).build().initialSetup().execute();
} catch ( PlatformImportException e ) {
// This test should throw this exception. Check that the original file exists
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasDefaultOwner( acl );
return;
}
fail( "This test should have thrown a PlatformImportException" );
}
@Test
public void testImportExistingFileWithManifestNotApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.fileExists( true ).hasManifest( true ).retainOwnership( true ).overwriteFileIfExists( true )
.build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasDefaultOwner( acl );
}
@Test
public void testImportExistingFileWithManifestButOverwriteAclDisabled() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.fileExists( true ).hasManifest( true ).retainOwnership( false ).applyAclSettings( true )
.overwriteAclSettings( false ).overwriteFileIfExists( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasManifestOwner( acl ); // ******* I don't think this is right *******
}
@Test
public void testImportExistingFileWithManifestPermissions() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.fileExists( true ).hasManifest( true ).overwriteFileIfExists( true ).retainOwnership( true )
.applyAclSettings( true ).overwriteAclSettings( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasDefaultOwner( acl );
}
@Test
public void testImportExistingFileWithManifestOwner() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.fileExists( true ).hasManifest( true ).overwriteFileIfExists( true ).retainOwnership( false )
.applyAclSettings( true ).overwriteAclSettings( false ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( PATH + "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasManifestOwner( acl );
}
@Test
public void testImportNewFolderWithNoManifest() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.folder( true ).path( "/" ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
assertTrue( repositoryFile.isFolder() );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasDefaultOwner( acl );
}
@Test
public void testImportNewFolderWithManifestApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.folder( true ).path( "/" ).hasManifest( true ).
applyAclSettings( true ).overwriteAclSettings( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
assertTrue( repositoryFile.isFolder() );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasManifestOwner( acl );
}
@Test
public void testImportNewFolderWithManifestPermissionsApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.folder( true ).path( "/" ).hasManifest( true )
.applyAclSettings( true ).overwriteAclSettings( true )
.retainOwnership( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
assertTrue( repositoryFile.isFolder() );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasDefaultOwner( acl );
}
@Test
public void testImportNewFolderWithManifestOwnerApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.folder( true ).path( "/" ).hasManifest( true )
.applyAclSettings( false ).overwriteAclSettings( true )
.retainOwnership( false ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( "/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
assertTrue( repositoryFile.isFolder() );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasDefaultPermissions( acl );
assertHasManifestOwner( acl );
}
@Test
public void testImportExistingFolderWithManifestApplied() throws Exception {
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.folder( true ).path( "/public" ).targetName( TARGET_RESOURCE_NAME )
.fileExists( true ).hasManifest( true )
.overwriteFileIfExists( true ).applyAclSettings( true )
.overwriteAclSettings( true ).build().initialSetup().execute();
RepositoryFile repositoryFile = mockRepository.getFile( "/public/" + TARGET_RESOURCE_NAME );
assertNotNull( repositoryFile );
assertTrue( repositoryFile.isFolder() );
RepositoryFileAcl acl = mockRepository.getAcl( repositoryFile.getId() );
assertHasManifestPermissions( acl );
assertHasManifestOwner( acl );
}
@Test
public void testExtensionNotTruncated() {
String name = "file.csv";
setup( MIMENAME, MIME_EXTENSION, "", "", false );
String title = fileHandler.getTitle( name );
assertEquals( name, title );
}
@Test
public void testExtensionTruncated() {
String name = "file.prpt";
setup( MIMENAME, MIME_EXTENSION, "", "", false );
String title = fileHandler.getTitle( name );
assertEquals( "file", title );
}
@Test
public void testFileWithoutExtension() {
String name = "file";
setup( MIMENAME, MIME_EXTENSION, "", "", false );
String title = fileHandler.getTitle( name );
assertEquals( name, title );
}
private void assertHasDefaultPermissions( RepositoryFileAcl acl ) {
assertNotNull( acl );
assertTrue( acl.isEntriesInheriting() );
assertNotNull( acl.getAces() );
assertEquals( 0, acl.getAces().size() );
}
private void assertHasManifestPermissions( RepositoryFileAcl acl ) {
assertNotNull( acl );
assertFalse( acl.isEntriesInheriting() );
assertNotNull( acl.getAces() );
assertEquals( 2, acl.getAces().size() );
EnumSet<RepositoryFilePermission> permissions = acl.getAces().get( 0 ).getPermissions();
assertNotNull( permissions );
assertEquals( 3, permissions.size() );
}
private void assertHasDefaultOwner( RepositoryFileAcl acl ) {
assertNotNull( acl );
assertNotNull( acl.getOwner() );
assertEquals( USER_NAME, principleNameResolver.getPrincipleName( acl.getOwner().getName() ) );
}
private void assertHasManifestOwner( RepositoryFileAcl acl ) {
assertNotNull( acl );
assertNotNull( acl.getOwner() );
assertEquals( USER_NAME2, principleNameResolver.getPrincipleName( acl.getOwner().getName() ) );
}
private ExportManifest createExportManifest( RepositoryFile repoFile, RepositoryFileAcl acl ) throws Exception {
String path = repoFile.getPath();
String parentFolder = path.substring( 0, path.lastIndexOf( "/" ) );
ExportManifest manifest = new ExportManifest();
manifest.getManifestInformation().setManifestVersion( "2" );
manifest.getManifestInformation().setRootFolder( parentFolder );
manifest.add( repoFile, acl );
return manifest;
}
private RepositoryFileAcl createRepositoryFileAcl2() {
final RepositoryFileSid sid = new RepositoryFileSid( USER_NAME2 );
final boolean inheriting = false;
final RepositoryFileAce ace1 =
new RepositoryFileAce( sid, RepositoryFilePermission.READ, RepositoryFilePermission.WRITE,
RepositoryFilePermission.DELETE );
final RepositoryFileAce ace2 =
new RepositoryFileAce( new RepositoryFileSid( USER_NAME ), RepositoryFilePermission.READ,
RepositoryFilePermission.WRITE, RepositoryFilePermission.DELETE );
final List<RepositoryFileAce> aces = Arrays.asList( ace1, ace2 );
return new RepositoryFileAcl( "", sid, inheriting, aces );
}
private void setup( String mimeTypeName, String extension, String path, String fileName, boolean folder ) {
List<String> extensions = Arrays.asList( extension );
IMimeType mimeType = new MimeType( mimeTypeName, extensions );
mimeType.setConverter( mock( Converter.class ) );
List<IMimeType> mimeTypeList = Arrays.asList( mimeType );
NameBaseMimeResolver mimeResolver = new NameBaseMimeResolver();
mimeResolver.addMimeType( mimeType );
SolutionFileImportHelper.testMimeResolver = mimeResolver;
userProvider = new UserProvider();
mockRepository = new MockUnifiedRepository( userProvider );
fileHandler = new RepositoryFileImportFileHandler( mimeTypeList );
fileHandler.setRepository( mockRepository );
fileHandler.setDefaultAclHandler( new DefaultAclHandler() );
fileHandler.setKnownExtensions( Arrays.asList( "prpt" ) );
IPlatformImporter mockPlatformImporter = mock( IPlatformImporter.class );
when( mockPlatformImporter.getRepositoryImportLogger() ).thenReturn( new Log4JRepositoryImportLogger() );
ImportSession.iPlatformImporter = mockPlatformImporter;
importSession = fileHandler.getImportSession();
importSession.initialize();
mockBundle = mock( RepositoryFileImportBundle.class );
when( mockBundle.getPath() ).thenReturn( path );
when( mockBundle.getName() ).thenReturn( fileName );
when( mockBundle.getMimeType() ).thenReturn( mimeTypeName );
when( mockBundle.isFolder() ).thenReturn( folder );
}
public class ImportTester {
private final boolean fileExists;
private final boolean overwriteFileIfExists;
private final boolean hasManifest;
private final boolean applyAclSettings;
private final boolean overwriteAclSettings;
private final boolean setRetainOwnership;
private final String path;
private final String targetName;
private final String mimename;
private final String mimeExtension = MIME_EXTENSION;
private final boolean folder;
public ImportTester( boolean fileExists,
boolean overwriteFileIfExists, boolean hasManifest,
boolean applyAclSettings, boolean overwriteAclSettings,
boolean setRetainOwnership, boolean folder, String path,
String targetName, String mimename ) {
this.fileExists = fileExists;
this.overwriteFileIfExists = overwriteFileIfExists;
this.hasManifest = hasManifest;
this.applyAclSettings = applyAclSettings;
this.overwriteAclSettings = overwriteAclSettings;
this.setRetainOwnership = setRetainOwnership;
this.folder = folder;
this.path = path;
this.targetName = targetName;
this.mimename = mimename;
}
public ImportTester initialSetup() {
setup( mimename, mimeExtension, path, targetName, folder );
return this;
}
public void execute() throws Exception {
if ( fileExists ) {
// First we need to import something into our blank repo
ImportTestBuilder importTesterBuilder = new ImportTestBuilder();
importTesterBuilder.path( this.path ).folder( this.folder ).build().execute();
importSession.initialize(); // Don't carry the import state into the real import
}
RepositoryFile repoFile = new RepositoryFile.Builder( targetName )
.path( path ).folder( this.folder ).build();
when( mockBundle.isOverwriteInRepository() ).thenReturn( overwriteFileIfExists );
when( mockBundle.overwriteInRepossitory() ).thenReturn( overwriteFileIfExists );
when( mockBundle.getFile() ).thenReturn( repoFile );
ExportManifest manifest = null;
if ( hasManifest ) {
// Setup manifest
RepositoryFileAcl acl = createRepositoryFileAcl2();
when( mockBundle.getAcl() ).thenReturn( acl );
manifest = createExportManifest( repoFile, acl );
}
// setup importFlags
importSession.setManifest( manifest );
importSession.setApplyAclSettings( applyAclSettings );
importSession.setOverwriteAclSettings( overwriteAclSettings );
importSession.setRetainOwnership( setRetainOwnership );
fileHandler.importFile( mockBundle );
}
}
/*
* Facilitates the creation of an ImportTester instance.
*/
public class ImportTestBuilder {
boolean fileExists;
boolean hasManifest;
boolean applyAclSettings;
boolean overwriteAclSettings;
boolean retainOwnership;
boolean overwriteFileIfExists;
boolean folder;
//by default it is simular with home folder
String path = PATH;
//by default it is correct name
String targetName = TARGET_RESOURCE_NAME;
String mimename = MIMENAME;
public ImportTestBuilder mimename( final String mimename ) {
this.mimename = mimename;
return this;
}
public ImportTestBuilder targetName( final String targetName ) {
this.targetName = targetName;
return this;
}
public ImportTestBuilder path( final String path ) {
this.path = path;
return this;
}
public ImportTestBuilder fileExists( final boolean fileExists1 ) {
this.fileExists = fileExists1;
return this;
}
public ImportTestBuilder overwriteFileIfExists( final boolean overwriteFileIfExists1 ) {
this.overwriteFileIfExists = overwriteFileIfExists1;
return this;
}
public ImportTestBuilder hasManifest( final boolean hasManifest1 ) {
this.hasManifest = hasManifest1;
return this;
}
public ImportTestBuilder applyAclSettings( final boolean applyAclSettings1 ) {
this.applyAclSettings = applyAclSettings1;
return this;
}
public ImportTestBuilder overwriteAclSettings( final boolean overwriteAclSettings1 ) {
this.overwriteAclSettings = overwriteAclSettings1;
return this;
}
public ImportTestBuilder retainOwnership( final boolean retainOwnership1 ) {
this.retainOwnership = retainOwnership1;
return this;
}
public ImportTestBuilder folder( final boolean folder1 ) {
this.folder = folder1;
return this;
}
public ImportTester build() {
ImportTester tester =
new ImportTester( fileExists, overwriteFileIfExists,
hasManifest, applyAclSettings, overwriteAclSettings,
retainOwnership, folder, path, targetName, mimename );
return tester;
}
}
public class UserProvider implements ICurrentUserProvider {
public String getUser() {
return USER_NAME;
}
public List<String> getRoles() {
return Arrays.asList( "__everyone__", "role2" );
}
}
public class DefaultAclHandler implements IRepositoryDefaultAclHandler {
@Override
public RepositoryFileAcl createDefaultAcl( RepositoryFile repositoryFile ) {
return new RepositoryFileAcl.Builder( USER_NAME ).entriesInheriting( true ).build();
}
}
}