PropertyUserStore should extract packed config file #1520
Signed-off-by: olivier lamy <olamy@webtide.com>
This commit is contained in:
parent
2679715a30
commit
e9f75e81d9
|
@ -28,8 +28,10 @@ import org.eclipse.jetty.util.resource.Resource;
|
|||
import org.eclipse.jetty.util.security.Credential;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
@ -38,6 +40,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
/**
|
||||
* PropertyUserStore
|
||||
|
@ -57,6 +61,8 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
|
|||
{
|
||||
private static final Logger LOG = Log.getLogger(PropertyUserStore.class);
|
||||
|
||||
private static final String JAR_FILE = "jar:file:";
|
||||
|
||||
protected Path _configPath;
|
||||
protected Resource _configResource;
|
||||
|
||||
|
@ -111,7 +117,7 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
|
|||
|
||||
/**
|
||||
* Set the Config Path from a String reference to a file
|
||||
* @param configFile the config file
|
||||
* @param configFile the config file can a be a file path or a reference to a file within a jar file <code>jar:file:</code>
|
||||
*/
|
||||
public void setConfigPath(String configFile)
|
||||
{
|
||||
|
@ -119,10 +125,55 @@ public class PropertyUserStore extends UserStore implements PathWatcher.Listener
|
|||
{
|
||||
_configPath = null;
|
||||
}
|
||||
else
|
||||
else if (new File( configFile ).exists())
|
||||
{
|
||||
_configPath = new File(configFile).toPath();
|
||||
}
|
||||
if ( !new File( configFile ).exists() && configFile.startsWith( JAR_FILE ))
|
||||
{
|
||||
// format of the url is jar:file:/foo/bar/beer.jar!/mountain_goat/pale_ale.txt
|
||||
// ideally we'd like to extract this to Resource class?
|
||||
try
|
||||
{
|
||||
_configPath = extractPackedFile( configFile );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
throw new RuntimeException( "cannot extract file from url:" + configFile, e );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Path extractPackedFile( String configFile )
|
||||
throws IOException
|
||||
{
|
||||
|
||||
int fileIndex = configFile.indexOf( "!" );
|
||||
String filePath = configFile.substring( JAR_FILE.length(), fileIndex );
|
||||
String entryPath = configFile.substring( fileIndex + 1, configFile.length() );
|
||||
|
||||
try (FileInputStream fileInputStream = new FileInputStream( new File( filePath ) ))
|
||||
{
|
||||
ZipInputStream zin = new ZipInputStream( fileInputStream );
|
||||
for ( ZipEntry e; ( e = zin.getNextEntry() ) != null; )
|
||||
{
|
||||
if ( e.getName().equals( entryPath ) )
|
||||
{
|
||||
Path extractedPath = Files.createTempFile( "users_store", ".tmp" );
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
try (OutputStream textOutputStream = Files.newOutputStream( extractedPath ))
|
||||
{
|
||||
while ( ( bytesRead = zin.read( buffer ) ) != -1 )
|
||||
{
|
||||
textOutputStream.write( buffer, 0, bytesRead );
|
||||
}
|
||||
}
|
||||
return extractedPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException( "cannot find file from url " + configFile );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,20 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.security;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.toolchain.test.OS;
|
||||
import org.eclipse.jetty.toolchain.test.TestingDir;
|
||||
|
@ -40,6 +26,25 @@ import org.hamcrest.Matcher;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
public class PropertyUserStoreTest
|
||||
{
|
||||
private final class UserCount implements PropertyUserStore.UserListener
|
||||
|
@ -97,15 +102,55 @@ public class PropertyUserStoreTest
|
|||
Path dir = testdir.getPath().toRealPath();
|
||||
FS.ensureDirExists(dir.toFile());
|
||||
File users = dir.resolve("users.txt").toFile();
|
||||
|
||||
try (Writer writer = new BufferedWriter(new FileWriter(users)))
|
||||
|
||||
writeUser( users );
|
||||
return users;
|
||||
}
|
||||
|
||||
private String initUsersPackedFileText()
|
||||
throws Exception
|
||||
{
|
||||
Path dir = testdir.getPath().toRealPath();
|
||||
FS.ensureDirExists( dir.toFile() );
|
||||
File users = dir.resolve( "users.txt" ).toFile();
|
||||
writeUser( users );
|
||||
File usersJar = dir.resolve( "users.jar" ).toFile();
|
||||
String entryPath = "/mountain_goat/pale_ale.txt";
|
||||
try (FileInputStream fileInputStream = new FileInputStream( users ))
|
||||
{
|
||||
try (OutputStream outputStream = new FileOutputStream( usersJar ))
|
||||
{
|
||||
try (JarOutputStream jarOutputStream = new JarOutputStream( outputStream ))
|
||||
{
|
||||
// add fake entry
|
||||
jarOutputStream.putNextEntry( new JarEntry( "/foo/wine" ) );
|
||||
|
||||
JarEntry jarEntry = new JarEntry( entryPath );
|
||||
jarOutputStream.putNextEntry( jarEntry );
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ( ( bytesRead = fileInputStream.read( buffer ) ) != -1 )
|
||||
{
|
||||
jarOutputStream.write( buffer, 0, bytesRead );
|
||||
}
|
||||
// add fake entry
|
||||
jarOutputStream.putNextEntry( new JarEntry( "/foo/cheese" ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return "jar:file:" + usersJar.getCanonicalPath() + "!" + entryPath;
|
||||
}
|
||||
|
||||
private void writeUser(File usersFile)
|
||||
throws Exception
|
||||
{
|
||||
try (Writer writer = new BufferedWriter(new FileWriter(usersFile)))
|
||||
{
|
||||
writer.append("tom: tom, roleA\n");
|
||||
writer.append("dick: dick, roleB\n");
|
||||
writer.append("harry: harry, roleA, roleB\n");
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private void addAdditionalUser(File usersFile, String userRef) throws Exception
|
||||
|
@ -137,6 +182,30 @@ public class PropertyUserStoreTest
|
|||
userCount.awaitCount(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyUserStoreLoadFromJarFile() throws Exception
|
||||
{
|
||||
final UserCount userCount = new UserCount();
|
||||
final String usersFile = initUsersPackedFileText();
|
||||
|
||||
PropertyUserStore store = new PropertyUserStore();
|
||||
store.setConfigPath(usersFile);
|
||||
|
||||
store.registerUserListener(userCount);
|
||||
|
||||
store.start();
|
||||
|
||||
assertThat("Failed to retrieve UserIdentity directly from PropertyUserStore", //
|
||||
store.getUserIdentity("tom"), notNullValue());
|
||||
assertThat("Failed to retrieve UserIdentity directly from PropertyUserStore", //
|
||||
store.getUserIdentity("dick"), notNullValue());
|
||||
assertThat("Failed to retrieve UserIdentity directly from PropertyUserStore", //
|
||||
store.getUserIdentity("harry"), notNullValue());
|
||||
userCount.assertThatCount(is(3));
|
||||
userCount.awaitCount(3);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testPropertyUserStoreLoadUpdateUser() throws Exception
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue