Commit 2ced252a authored by Matija Obreza's avatar Matija Obreza
Browse files

FilenameValidator added

parent e75ce2b7
......@@ -21,8 +21,15 @@ package org.genesys2.server.filerepository;
* The Class FileRepositoryException.
*/
public abstract class FileRepositoryException extends Exception {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
public FileRepositoryException() {
}
public FileRepositoryException(String message) {
super(message);
}
}
......@@ -23,13 +23,7 @@ public class InvalidRepositoryPathException extends FileRepositoryException {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
private String invalidPath;
public InvalidRepositoryPathException(String path) {
this.invalidPath = path;
}
public String getInvalidPath() {
return invalidPath;
public InvalidRepositoryPathException(String message) {
super(message);
}
}
......@@ -19,6 +19,8 @@ package org.genesys2.server.filerepository.service;
import java.io.IOException;
import java.util.List;
import org.genesys2.server.filerepository.InvalidRepositoryPathException;
// TODO: Auto-generated Javadoc
/**
* The Interface BytesStorageService.
......@@ -61,15 +63,17 @@ public interface BytesStorageService {
* @param filename the filename
* @return true, if successful
* @throws IOException when things go wrong on bytes storage level
* @throws InvalidRepositoryPathException when path or filename are not valid
*/
boolean exists(String path, String filename) throws IOException;
boolean exists(String path, String filename) throws IOException, InvalidRepositoryPathException;
/**
* List all filenames at specified path. Does not include subfolders.
*
* @param path the path
* @return the list
* @throws InvalidRepositoryPathException when invalid path is provided
*/
List<String> listFiles(String path);
List<String> listFiles(String path) throws InvalidRepositoryPathException;
}
/*
* Copyright 2016 Global Crop Diversity Trust, www.croptrust.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.genesys2.server.filerepository.service.impl;
/**
* Make sure filenames are okay.
*/
public class FilenameValidator {
/**
* Checks if the filename is acceptable.
*
* @param filename
* @return true when OK, false otherwise.
*/
public static boolean isValidFilename(final String filename) {
return filename != null && filename.length() > 0 && !filename.contains("/") && !filename.contains("\\");
}
}
......@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.genesys2.server.filerepository.InvalidRepositoryPathException;
import org.genesys2.server.filerepository.model.ImageGallery;
import org.genesys2.server.filerepository.model.RepositoryImage;
import org.genesys2.server.filerepository.persistence.ImageGalleryPersistence;
......@@ -132,14 +133,18 @@ public class ImageGalleryServiceImpl implements ImageGalleryService {
// Remove _thumbs
final String thumbPath = imageGallery.getPath() + THUMB_PATH;
bytesStorageService.listFiles(thumbPath).forEach(filename -> {
try {
LOG.debug("Removing _thumb path={} filename={}", thumbPath, filename);
bytesStorageService.remove(thumbPath, filename);
} catch (final Exception e) {
LOG.error("Failed to remove bytes path=" + thumbPath + " filename=" + filename, e);
}
});
try {
bytesStorageService.listFiles(thumbPath).forEach(filename -> {
try {
LOG.debug("Removing _thumb path={} filename={}", thumbPath, filename);
bytesStorageService.remove(thumbPath, filename);
} catch (final Exception e) {
LOG.error("Failed to remove bytes path=" + thumbPath + " filename=" + filename, e);
}
});
} catch (InvalidRepositoryPathException e) {
// Shouldn't have a gallery with invalid path, but hell
}
imageGalleryPersistence.delete(imageGallery);
......@@ -235,9 +240,10 @@ public class ImageGalleryServiceImpl implements ImageGalleryService {
* @param height the height
* @param repositoryImage the repository image
* @throws IOException Signals that an I/O exception has occurred.
* @throws InvalidRepositoryPathException if path is messed up
*/
private void ensureThumbnail(final String thumbPath, final Integer width, final Integer height,
final RepositoryImage repositoryImage) throws IOException {
final RepositoryImage repositoryImage) throws IOException, InvalidRepositoryPathException {
final String filename = getThumbnailFilename(width, height, repositoryImage.getUuid());
if (!bytesStorageService.exists(thumbPath, filename)) {
......
......@@ -33,6 +33,7 @@ import java.util.stream.Collectors;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.genesys2.server.filerepository.InvalidRepositoryPathException;
import org.genesys2.server.filerepository.service.BytesStorageService;
import org.genesys2.server.filerepository.service.s3.ListBucketResult;
import org.slf4j.Logger;
......@@ -145,8 +146,8 @@ public class S3StorageServiceImpl implements BytesStorageService {
if (!PathValidator.isValidPath(path))
throw new IOException("Path is not valid");
if (filename == null)
throw new IOException("File name is null");
if (!FilenameValidator.isValidFilename(filename))
throw new IOException("File name is not valid: " + filename);
if (LOG.isDebugEnabled()) {
LOG.debug("Getting bytes path={} filename={}", path, filename);
......@@ -163,7 +164,7 @@ public class S3StorageServiceImpl implements BytesStorageService {
* @return the url
*/
private String getUrl(final String path, final String filename) {
String url=String.format("https://%s%s", getHost(), getPath(path) + filename);
String url = String.format("https://%s%s", getHost(), getPath(path) + filename);
if (LOG.isTraceEnabled()) {
LOG.trace("getUrl path={} filename={} result={}", path, filename, url);
}
......@@ -291,28 +292,28 @@ public class S3StorageServiceImpl implements BytesStorageService {
// LOG.debug("==========================request
// end================================================");
final ClientHttpResponse response = execution.execute(request, body);
//
// StringBuilder inputStringBuilder = new StringBuilder();
// BufferedReader bufferedReader = new BufferedReader(new
// InputStreamReader(response.getBody(), "UTF-8"));
// String line = bufferedReader.readLine();
// while (line != null) {
// inputStringBuilder.append(line);
// inputStringBuilder.append('\n');
// line = bufferedReader.readLine();
// }
// LOG.debug("============================response
// begin==========================================");
// LOG.debug("status code: " + response.getStatusCode());
// LOG.debug("status text: " + response.getStatusText());
// LOG.debug("Response Body : " +
// inputStringBuilder.toString());
// LOG.debug("=======================response
// end=================================================");
return response;
});
final ClientHttpResponse response = execution.execute(request, body);
//
// StringBuilder inputStringBuilder = new StringBuilder();
// BufferedReader bufferedReader = new BufferedReader(new
// InputStreamReader(response.getBody(), "UTF-8"));
// String line = bufferedReader.readLine();
// while (line != null) {
// inputStringBuilder.append(line);
// inputStringBuilder.append('\n');
// line = bufferedReader.readLine();
// }
// LOG.debug("============================response
// begin==========================================");
// LOG.debug("status code: " + response.getStatusCode());
// LOG.debug("status text: " + response.getStatusText());
// LOG.debug("Response Body : " +
// inputStringBuilder.toString());
// LOG.debug("=======================response
// end=================================================");
return response;
});
restTemplate.setInterceptors(interceptors);
return restTemplate;
......@@ -324,9 +325,15 @@ public class S3StorageServiceImpl implements BytesStorageService {
* @param path the path
* @param filename the filename
* @return true, if successful
* @throws InvalidRepositoryPathException when path or filename are weird
* @throws IOException when other stuff is bad
*/
@Override
public boolean exists(final String path, final String filename) throws IOException {
public boolean exists(final String path, final String filename) throws IOException, InvalidRepositoryPathException {
PathValidator.checkValidPath(path);
if (!FilenameValidator.isValidFilename(filename))
throw new InvalidRepositoryPathException("Filename is not valid: " + filename);
try {
if (LOG.isTraceEnabled()) {
LOG.trace("Fetching HEAD for url={}", getUrl(path, filename));
......@@ -354,11 +361,14 @@ public class S3StorageServiceImpl implements BytesStorageService {
*
* @param path the repository path
* @return list of filenames at specified path
* @throws InvalidRepositoryPathException when path is messed up
*/
@Override
public List<String> listFiles(final String path) {
public List<String> listFiles(final String path) throws InvalidRepositoryPathException {
LOG.debug("Listing S3 bucket for host={} path={}", getHost(), path);
PathValidator.checkValidPath(path);
final String s3prefix = getPath(path).substring(1);
final ListBucketResult listBucketResult = restTemplate
......@@ -378,7 +388,7 @@ public class S3StorageServiceImpl implements BytesStorageService {
listBucketResult.getContents().forEach(content -> {
LOG.debug("Object prefix={} len={} filename={}", content.getKey(), content.getSize(),
content.getKey().substring(s3prefix.length()));
});
});
}
}
......
......@@ -24,6 +24,7 @@ import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import org.genesys2.server.filerepository.InvalidRepositoryPathException;
import org.genesys2.server.filerepository.config.DatabaseConfig;
import org.genesys2.server.filerepository.config.ServiceBeanConfig;
import org.junit.Ignore;
......@@ -90,9 +91,10 @@ public class S3StorageServiceTest {
* @throws IOException Signals that an I/O exception has occurred.
* @throws InvalidKeyException the invalid key exception
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws InvalidRepositoryPathException
*/
@Test
public void testList() throws IOException, InvalidKeyException, NoSuchAlgorithmException {
public void testList() throws IOException, InvalidKeyException, NoSuchAlgorithmException, InvalidRepositoryPathException {
for (int i = 1; i <= 20; i++) {
bytesStorageService.upsert(PATH, i + FILENAME, SOME_BYTES);
}
......@@ -304,10 +306,12 @@ public class S3StorageServiceTest {
/**
* Ensure 404 exception is not thrown for non-existent file.
* @throws IOException
*
* @throws IOException
* @throws InvalidRepositoryPathException
*/
@Test
public void testExistsWithoutExceptions() throws IOException {
public void testExistsWithoutExceptions() throws IOException, InvalidRepositoryPathException {
assertThat("File should not exist", bytesStorageService.exists(PATH, "file-should-not-exist"), is(false));
}
......@@ -315,9 +319,10 @@ public class S3StorageServiceTest {
* Ensure 404 exception is not thrown for non-existent file.
*
* @throws IOException
* @throws InvalidRepositoryPathException
*/
@Test
public void testExistsNoYesNo() throws IOException {
public void testExistsNoYesNo() throws IOException, InvalidRepositoryPathException {
assertThat("File should not exist", bytesStorageService.exists(PATH, FILENAME), is(false));
bytesStorageService.upsert(PATH, FILENAME, SOME_BYTES);
......@@ -334,11 +339,12 @@ public class S3StorageServiceTest {
* Ensure we are able to have a space in the repository path
*
* @throws IOException
* @throws InvalidRepositoryPathException
*/
@Test
public void testSpaceInPath() throws IOException {
String pathWithSpace=PATH + "IRGC 11111/";
public void testSpaceInPath() throws IOException, InvalidRepositoryPathException {
String pathWithSpace = PATH + "IRGC 11111/";
bytesStorageService.upsert(pathWithSpace, FILENAME, SOME_BYTES);
assertThat("File must exist", bytesStorageService.exists(pathWithSpace, FILENAME), is(true));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment