Skip to content
Snippets Groups Projects
Commit 47bfb9ad authored by fabiovandewaeter's avatar fabiovandewaeter
Browse files

save

parent 087e32fe
No related branches found
No related tags found
No related merge requests found
Showing with 410 additions and 73 deletions
......@@ -53,6 +53,25 @@
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......
......@@ -12,6 +12,7 @@ import java.util.ArrayList;
import fil.sr2.flopbox.utils.*;
/** The class with the paths */
@Path("/ftps")
public class FTPResource {
......
......@@ -4,6 +4,7 @@ import java.util.*;
import fil.sr2.flopbox.utils.*;
/** Take care of the FTP servers and their aliases */
public class FTPServerRepository {
private static FTPServerRepository instance = new FTPServerRepository();
private Map<String, FTPServerConfig> serverMap = new HashMap<>();
......
......@@ -17,6 +17,7 @@ import java.io.ByteArrayInputStream;
import fil.sr2.flopbox.utils.*;
/** Class with methods used in FTPResource */
public class FTPService {
public FtpNode getResourceTree(String alias, String path, String user, String pass)
......
package fil.sr2.flopbox;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource" path)
*/
@Path("myresource")
public class MyResource {
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* @return String that will be returned as a text/plain response.
*/
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getIt() {
return "Got it!";
}
}
......@@ -10,6 +10,7 @@ import jakarta.ws.rs.core.*;
import jakarta.ws.rs.container.*;
import jakarta.ws.rs.ext.Provider;
/** Handles user authentication to the Flopbox proxy */
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthFilter implements ContainerRequestFilter {
......
package fil.sr2.flopbox.utils;
/** An exception for FTP problems */
public class FTPException extends Exception {
private final int status;
......
package fil.sr2.flopbox.utils;
/** Represents the configuration of a FTP server */
public class FTPServerConfig {
private String alias;
private String host;
......
package fil.sr2.flopbox;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import java.io.File;
public class EmbeddedFTPServer {
private FtpServerFactory serverFactory;
private FtpServer server;
private PropertiesUserManagerFactory userManagerFactory;
private int port;
public EmbeddedFTPServer(int port) {
this.port = port;
serverFactory = new FtpServerFactory();
ListenerFactory listenerFactory = new ListenerFactory();
listenerFactory.setPort(port);
serverFactory.addListener("default", listenerFactory.createListener());
userManagerFactory = new PropertiesUserManagerFactory();
serverFactory.setUserManager(userManagerFactory.createUserManager());
}
public void start() throws FtpException {
server = serverFactory.createServer();
server.start();
}
public void stop() {
if (server != null) {
server.stop();
}
}
public void addUser(String username, String password, File homeDir) throws FtpException {
BaseUser user = new BaseUser();
user.setName(username);
user.setPassword(password);
user.setHomeDirectory(homeDir.getAbsolutePath());
serverFactory.getUserManager().save(user);
}
public int getPort() {
return port;
}
}
package fil.sr2.flopbox;
import fil.sr2.flopbox.utils.FTPException;
import org.apache.commons.io.FileUtils;
import org.junit.*;
import org.mockito.Mockito;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import jakarta.ws.rs.core.UriInfo;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.Method;
import static org.junit.Assert.*;
import fil.sr2.flopbox.*;
import fil.sr2.flopbox.utils.*;
public class FTPResourceTest {
private static EmbeddedFTPServer embeddedFTPServer;
private static File ftpHomeDir;
private static final String USER = "testuser";
private static final String PASS = "testpass";
private static final String ALIAS = "testserver";
private static int ftpPort;
@BeforeClass
public static void setUpClass() throws Exception {
ftpHomeDir = Files.createTempDirectory("ftp-test").toFile();
ftpPort = 2123;
embeddedFTPServer = new EmbeddedFTPServer(ftpPort);
embeddedFTPServer.addUser(USER, PASS, ftpHomeDir);
embeddedFTPServer.start();
}
@AfterClass
public static void tearDownClass() throws Exception {
embeddedFTPServer.stop();
FileUtils.deleteDirectory(ftpHomeDir);
}
@Before
public void setUp() throws IOException {
// Reset repository and add test server
FTPServerRepository repo = FTPServerRepository.getInstance();
repo.getAllServers().forEach(s -> repo.removeServer(s.getAlias()));
FTPServerConfig config = new FTPServerConfig(ALIAS, "localhost", ftpPort);
repo.addServer(config);
// Create a test file in FTP home
File testFile = new File(ftpHomeDir, "testfile.txt");
FileUtils.writeStringToFile(testFile, "test content", StandardCharsets.UTF_8);
}
@After
public void tearDown() throws IOException {
// Clean FTP home directory
FileUtils.cleanDirectory(ftpHomeDir);
}
@Test
public void testListFTPServers() {
FTPResource resource = new FTPResource();
Response response = resource.listFTPServers();
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
List<FTPServerConfig> servers = (List<FTPServerConfig>) response.getEntity();
assertTrue(servers.stream().anyMatch(s -> ALIAS.equals(s.getAlias())));
}
@Test
public void testAddFTPServerDuplicate() {
FTPResource resource = new FTPResource();
UriInfo uriInfo = Mockito.mock(UriInfo.class);
Mockito.when(uriInfo.getAbsolutePathBuilder()).thenReturn(new UriBuilderMock());
FTPServerConfig config = new FTPServerConfig(ALIAS, "localhost", 21);
Response response = resource.addFTPServer(config, uriInfo);
assertEquals(Response.Status.CONFLICT.getStatusCode(), response.getStatus());
}
@Test
public void testRemoveFTPServerSuccess() {
FTPResource resource = new FTPResource();
Response response = resource.removeFTPServer(ALIAS);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
assertNull(FTPServerRepository.getInstance().getServer(ALIAS));
}
@Test
public void testUpdateFTPServerSuccess() {
FTPResource resource = new FTPResource();
FTPServerConfig newConfig = new FTPServerConfig(ALIAS, "localhost", 2122);
Response response = resource.updateFTPServer(ALIAS, newConfig);
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
assertEquals(2122, FTPServerRepository.getInstance().getServer(ALIAS).getPort());
}
@Test
public void testGetFTPRoot() {
FTPResource resource = new FTPResource();
Response response = resource.getFTPRoot(ALIAS, USER, PASS);
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
FTPService.FtpNode root = (FTPService.FtpNode) response.getEntity();
assertTrue(root.children.stream().anyMatch(node -> "testfile.txt".equals(node.name)));
}
@Test
public void testGetFTPResourceFile() {
FTPResource resource = new FTPResource();
Response response = resource.getFTPResource(ALIAS, "testfile.txt", USER, PASS);
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
assertEquals("text/plain", response.getHeaderString("Content-Type"));
assertTrue(((byte[]) response.getEntity()).length > 0);
}
@Test
public void testUploadFile() throws IOException {
FTPResource resource = new FTPResource();
String path = "uploaded.txt";
InputStream stream = new ByteArrayInputStream("content".getBytes());
Response response = resource.uploadFile(ALIAS, path, USER, PASS, stream);
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
File uploaded = new File(ftpHomeDir, path);
assertTrue(uploaded.exists());
}
@Test
public void testDeleteResource() throws IOException {
File toDelete = new File(ftpHomeDir, "to_delete.txt");
toDelete.createNewFile();
FTPResource resource = new FTPResource();
Response response = resource.deleteResource(ALIAS, "to_delete.txt", USER, PASS);
assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
assertFalse(toDelete.exists());
}
@Test
public void testSearchFiles() {
FTPResource resource = new FTPResource();
Response response = resource.searchFiles("testfile.txt", USER, PASS);
assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
Map<String, List<String>> results = (Map<String, List<String>>) response.getEntity();
assertFalse(results.isEmpty());
}
@Test
public void testInvalidCredentials() {
FTPResource resource = new FTPResource();
Response response = resource.getFTPRoot(ALIAS, "wrong", "wrong");
assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
}
private static class UriBuilderMock extends UriBuilder {
// Add the missing method
@Override
public URI buildFromEncodedMap(Map<String, ?> values) {
return URI.create("http://localhost:8080/ftps");
}
@Override
public URI buildFromMap(Map<String, ?> values) {
return URI.create("http://localhost:8080/ftps");
}
@Override
public URI buildFromMap(Map<String, ?> values, boolean encodeSlashInPath) {
return URI.create("http://localhost:8080/ftps");
}
// Change parameter from Class<?> to raw Class
@Override
public UriBuilder path(Class resource) {
return this;
}
// Change parameter from Class<?> to raw Class
@Override
public UriBuilder path(Class resource, String method) {
return this;
}
@Override
public UriBuilder path(String path) {
return this;
}
@Override
public URI build(Object... values) {
return URI.create("http://localhost:8080/ftps");
}
@Override
public URI build(Object[] values, boolean encodeSlashInPath) {
return URI.create("http://localhost:8080/ftps");
}
@Override
public URI buildFromEncoded(Object... values) {
return URI.create("http://localhost:8080/ftps");
}
@Override
public String toTemplate() {
return "http://localhost:8080/ftps";
}
@Override
public UriBuilder clone() {
return this;
}
@Override
public UriBuilder uri(URI uri) {
return this;
}
@Override
public UriBuilder uri(String uri) {
return this;
}
@Override
public UriBuilder scheme(String scheme) {
return this;
}
@Override
public UriBuilder schemeSpecificPart(String ssp) {
return this;
}
@Override
public UriBuilder userInfo(String ui) {
return this;
}
@Override
public UriBuilder host(String host) {
return this;
}
@Override
public UriBuilder port(int port) {
return this;
}
@Override
public UriBuilder replacePath(String path) {
return this;
}
@Override
public UriBuilder path(Method method) {
return this;
}
@Override
public UriBuilder segment(String... segments) {
return this;
}
@Override
public UriBuilder replaceMatrix(String matrix) {
return this;
}
@Override
public UriBuilder matrixParam(String name, Object... values) {
return this;
}
@Override
public UriBuilder replaceMatrixParam(String name, Object... values) {
return this;
}
@Override
public UriBuilder replaceQuery(String query) {
return this;
}
@Override
public UriBuilder queryParam(String name, Object... values) {
return this;
}
@Override
public UriBuilder replaceQueryParam(String name, Object... values) {
return this;
}
@Override
public UriBuilder fragment(String fragment) {
return this;
}
@Override
public UriBuilder resolveTemplate(String name, Object value) {
return this;
}
@Override
public UriBuilder resolveTemplate(String name, Object value, boolean encodeSlashInPath) {
return this;
}
@Override
public UriBuilder resolveTemplateFromEncoded(String name, Object value) {
return this;
}
@Override
public UriBuilder resolveTemplates(Map<String, Object> templateValues) {
return this;
}
@Override
public UriBuilder resolveTemplates(Map<String, Object> templateValues, boolean encodeSlashInPath) {
return this;
}
@Override
public UriBuilder resolveTemplatesFromEncoded(Map<String, Object> templateValues) {
return this;
}
}
}
package fil.sr2.flopbox;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.WebTarget;
import org.glassfish.grizzly.http.server.HttpServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MyResourceTest {
private HttpServer server;
private WebTarget target;
@Before
public void setUp() throws Exception {
// start the server
server = Main.startServer();
// create the client
Client c = ClientBuilder.newClient();
// uncomment the following line if you want to enable
// support for JSON in the client (you also have to uncomment
// dependency on jersey-media-json module in pom.xml and Main.startServer())
// --
// c.configuration().enable(new org.glassfish.jersey.media.json.JsonJaxbFeature());
target = c.target(Main.BASE_URI);
}
@After
public void tearDown() throws Exception {
server.stop();
}
/**
* Test to see that the message "Got it!" is sent in the response.
*/
@Test
public void testGetIt() {
String responseMsg = target.path("myresource").request().get(String.class);
assertEquals("Got it!", responseMsg);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment