├── README.md ├── release.sh ├── test.sh ├── .gitignore ├── ftpserver ├── src │ └── main │ │ ├── java │ │ └── org │ │ │ └── eftp │ │ │ └── ftpserver │ │ │ └── business │ │ │ ├── RESTConfig.java │ │ │ ├── monitoring │ │ │ └── boundary │ │ │ │ ├── EventTracker.java │ │ │ │ └── StatisticsResource.java │ │ │ ├── files │ │ │ └── boundary │ │ │ │ ├── Files.java │ │ │ │ └── FilesResources.java │ │ │ ├── ConstraintViolationMapper.java │ │ │ ├── management │ │ │ └── boundary │ │ │ │ └── ManagementResource.java │ │ │ ├── hooks │ │ │ ├── control │ │ │ │ ├── HookInvoker.java │ │ │ │ └── FtpEventListener.java │ │ │ └── boundary │ │ │ │ ├── HooksResource.java │ │ │ │ └── EventBroadcastRessource.java │ │ │ └── configuration │ │ │ └── boundary │ │ │ └── ConfigurationResource.java │ │ ├── webapp │ │ ├── WEB-INF │ │ │ ├── beans.xml │ │ │ ├── glassfish-web.xml │ │ │ └── web.xml │ │ └── index.html │ │ └── resources │ │ └── META-INF │ │ └── persistence.xml ├── nb-configuration.xml └── pom.xml ├── ftpservice ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── beans.xml │ │ └── java │ │ │ └── org │ │ │ └── eftp │ │ │ └── ftpserver │ │ │ └── business │ │ │ ├── logger │ │ │ └── boundary │ │ │ │ ├── Log.java │ │ │ │ └── LoggerProducer.java │ │ │ ├── plugins │ │ │ ├── boundary │ │ │ │ ├── Plugin.java │ │ │ │ └── FtpletHook.java │ │ │ └── entity │ │ │ │ └── CommandInstance.java │ │ │ ├── users │ │ │ ├── entity │ │ │ │ ├── FtpGroup.java │ │ │ │ ├── FtpPermission.java │ │ │ │ ├── FtpWritePermission.java │ │ │ │ ├── FtpTransferRatePermision.java │ │ │ │ ├── FtpConcurrentLoginPermission.java │ │ │ │ └── FtpUser.java │ │ │ ├── boundary │ │ │ │ ├── UserManagementInitializer.java │ │ │ │ └── JPAUserStore.java │ │ │ └── control │ │ │ │ ├── Digester.java │ │ │ │ └── UserManagerIntegrationAdapter.java │ │ │ ├── monitoring │ │ │ └── boundary │ │ │ │ └── CallTracker.java │ │ │ ├── hooks │ │ │ ├── entity │ │ │ │ ├── HookValidator.java │ │ │ │ ├── Checks.java │ │ │ │ └── Hook.java │ │ │ └── boundary │ │ │ │ └── HooksRegistry.java │ │ │ ├── files │ │ │ └── boundary │ │ │ │ └── InstrumendFileSystemFactory.java │ │ │ ├── configuration │ │ │ ├── entity │ │ │ │ └── ConfigurationEntry.java │ │ │ ├── boundary │ │ │ │ ├── ConfigurationStartup.java │ │ │ │ └── ConfigurationExposer.java │ │ │ └── control │ │ │ │ └── ConfigurationStore.java │ │ │ ├── concurrency │ │ │ └── control │ │ │ │ └── ManagedThreadPoolExecutorExposer.java │ │ │ └── boot │ │ │ ├── boundary │ │ │ └── FTPServerWrapper.java │ │ │ └── control │ │ │ └── ManagedFtpServerContext.java │ └── test │ │ ├── java │ │ └── org │ │ │ └── eftp │ │ │ └── ftpserver │ │ │ └── business │ │ │ ├── PersistenceSupport.java │ │ │ ├── hooks │ │ │ ├── entity │ │ │ │ ├── HookTest.java │ │ │ │ └── HookIT.java │ │ │ └── boundary │ │ │ │ └── HooksRegistryIT.java │ │ │ └── users │ │ │ └── control │ │ │ └── DigesterTester.java │ │ └── resources │ │ └── META-INF │ │ └── persistence.xml └── pom.xml ├── hook-test-client ├── src │ └── main │ │ ├── java │ │ └── org │ │ │ └── e2ftp │ │ │ └── testclient │ │ │ ├── business │ │ │ ├── RESTConfiguration.java │ │ │ └── hooks │ │ │ │ └── boundary │ │ │ │ ├── HookMgmt.java │ │ │ │ ├── CallbacksResource.java │ │ │ │ └── Authenticator.java │ │ │ └── presentation │ │ │ └── Index.java │ │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── index.xhtml ├── nb-configuration.xml └── pom.xml ├── ftpservice-api ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── eftp │ │ │ └── events │ │ │ ├── FtpEventName.java │ │ │ ├── Command.java │ │ │ └── FtpEvent.java │ └── test │ │ └── java │ │ └── org │ │ └── eftp │ │ └── ftpserverapi │ │ └── AppTest.java └── pom.xml ├── ftpserver-st ├── src │ └── test │ │ └── java │ │ └── org │ │ └── eftp │ │ └── ftpserver │ │ ├── business │ │ ├── RESTSupport.java │ │ ├── monitoring │ │ │ └── boundary │ │ │ │ └── StatisticsResourceIT.java │ │ ├── Authenticator.java │ │ ├── configuration │ │ │ └── ConfigurationResourceIT.java │ │ ├── hooks │ │ │ └── boundary │ │ │ │ ├── EventBroadcastRessourceIT.java │ │ │ │ └── HooksResourceIT.java │ │ ├── files │ │ │ └── boundary │ │ │ │ └── FilesIT.java │ │ └── management │ │ │ └── ManagementResourceIT.java │ │ └── st │ │ └── FTPServerWrapperIT.java └── pom.xml └── pom.xml /README.md: -------------------------------------------------------------------------------- 1 | e2ftp 2 | ===== 3 | 4 | FTP Server On Java EE 7 5 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mvn -B release:clean release:prepare -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mvn failsafe:integration-test failsafe:verify -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | release.properties 3 | pom.xml.releaseBackup 4 | derby.log -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/RESTConfig.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business; 2 | 3 | import javax.ws.rs.ApplicationPath; 4 | import javax.ws.rs.core.Application; 5 | 6 | /** 7 | * 8 | * @author adam-bien.com 9 | */ 10 | @ApplicationPath("api") 11 | public class RESTConfig extends Application {} 12 | -------------------------------------------------------------------------------- /ftpserver/src/main/webapp/WEB-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /ftpserver/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Start Page 5 | 6 | 7 | 8 |

FTP Server is up

9 |

Statistics

10 |

Configuration

11 |

Management

12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/monitoring/boundary/EventTracker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.monitoring.boundary; 5 | 6 | import javax.ejb.Stateless; 7 | import javax.enterprise.event.Observes; 8 | import javax.inject.Inject; 9 | import org.eftp.events.Command; 10 | import org.eftp.events.FtpEvent; 11 | import org.eftp.ftpserver.business.logger.boundary.Log; 12 | 13 | /** 14 | * 15 | * @author adam-bien.com 16 | */ 17 | @Stateless 18 | public class EventTracker { 19 | 20 | @Inject 21 | Log LOG; 22 | 23 | public void onFtpEvent(@Observes @Command FtpEvent event) { 24 | LOG.info("Received event: " + event); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ftpservice/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 20 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/files/boundary/Files.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.files.boundary; 5 | 6 | import java.io.File; 7 | import javax.ejb.Stateless; 8 | import javax.inject.Inject; 9 | import org.eftp.ftpserver.business.users.boundary.JPAUserStore; 10 | import org.eftp.ftpserver.business.users.entity.FtpUser; 11 | 12 | /** 13 | * 14 | * @author adam-bien.com 15 | */ 16 | @Stateless 17 | public class Files { 18 | 19 | @Inject 20 | JPAUserStore userStore; 21 | 22 | public File getFile(String userName, String fileName) { 23 | FtpUser user = this.userStore.find(userName); 24 | if (user == null) { 25 | return null; 26 | } 27 | String homeDir = user.getHomeDir(); 28 | return new File(homeDir, fileName); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ftpserver/src/main/webapp/WEB-INF/glassfish-web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | admin 6 | admin 7 | 8 | 9 | listener 10 | listener 11 | 12 | 13 | user 14 | user 15 | 16 | 17 | 18 | 19 | Keep a copy of the generated servlet class' java code. 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/ConstraintViolationMapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business; 5 | 6 | import javax.ejb.TransactionRolledbackLocalException; 7 | import javax.validation.ConstraintViolationException; 8 | import javax.ws.rs.core.Response; 9 | import javax.ws.rs.core.Response.Status; 10 | import javax.ws.rs.ext.ExceptionMapper; 11 | import javax.ws.rs.ext.Provider; 12 | 13 | /** 14 | * 15 | * @author adam-bien.com 16 | */ 17 | @Provider 18 | public class ConstraintViolationMapper implements ExceptionMapper { 19 | 20 | @Override 21 | public Response toResponse(TransactionRolledbackLocalException exception) { 22 | if (exception.getCausedByException() instanceof ConstraintViolationException) { 23 | return Response.status(Status.BAD_REQUEST).header("x-error-detail", exception.getMessage()).build(); 24 | } else { 25 | return Response.status(Status.INTERNAL_SERVER_ERROR).header("x-error-detail", exception.getMessage()).build(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/management/boundary/ManagementResource.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.management.boundary; 2 | 3 | import javax.ejb.Stateless; 4 | import javax.inject.Inject; 5 | import javax.ws.rs.DELETE; 6 | import javax.ws.rs.GET; 7 | import javax.ws.rs.POST; 8 | import javax.ws.rs.PUT; 9 | import javax.ws.rs.Path; 10 | import org.eftp.ftpserver.business.boot.boundary.FTPServerWrapper; 11 | 12 | /** 13 | * 14 | * @author ZeTo 15 | */ 16 | @Stateless 17 | @Path("management") 18 | public class ManagementResource { 19 | 20 | @Inject 21 | private FTPServerWrapper ftpServer; 22 | 23 | @GET 24 | public boolean isRunning() { 25 | return this.ftpServer.isRunning(); 26 | } 27 | 28 | @POST 29 | public void startFTPServer() { 30 | this.ftpServer.start(); 31 | } 32 | 33 | @PUT 34 | public void restart() { 35 | this.ftpServer.restart(); 36 | } 37 | 38 | @DELETE 39 | public void stop() { 40 | this.ftpServer.stop(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /hook-test-client/src/main/java/org/e2ftp/testclient/business/RESTConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.e2ftp.testclient.business; 5 | 6 | /* 7 | * #%L 8 | * hook-test-client 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.ws.rs.ApplicationPath; 27 | import javax.ws.rs.core.Application; 28 | 29 | /** 30 | * 31 | * @author adam-bien.com 32 | */ 33 | @ApplicationPath("api") 34 | public class RESTConfiguration extends Application { 35 | } 36 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/hooks/control/HookInvoker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.control; 5 | 6 | import java.util.concurrent.Future; 7 | import javax.annotation.PostConstruct; 8 | import javax.ejb.AsyncResult; 9 | import javax.ejb.Asynchronous; 10 | import javax.ejb.Stateless; 11 | import javax.json.JsonObject; 12 | import javax.ws.rs.client.Client; 13 | import javax.ws.rs.client.ClientBuilder; 14 | import javax.ws.rs.client.Entity; 15 | import javax.ws.rs.core.Response; 16 | import org.eftp.events.FtpEvent; 17 | import org.eftp.ftpserver.business.hooks.entity.Hook; 18 | 19 | /** 20 | * 21 | * @author adam-bien.com 22 | */ 23 | @Stateless 24 | public class HookInvoker { 25 | 26 | private Client client; 27 | 28 | @PostConstruct 29 | public void initClient() { 30 | this.client = ClientBuilder.newClient(); 31 | } 32 | 33 | @Asynchronous 34 | public Future callback(Hook hook, FtpEvent event) { 35 | final Entity jsonEvent = Entity.json(event.asJson()); 36 | final String uri = hook.getUri(); 37 | Response response = this.client.target(uri).request().post(jsonEvent); 38 | return new AsyncResult<>(response); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/logger/boundary/Log.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.logger.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.logging.Logger; 27 | import javax.inject.Inject; 28 | 29 | /** 30 | * 31 | * @author adam-bien.com 32 | */ 33 | public class Log { 34 | 35 | private Logger logger; 36 | 37 | @Inject 38 | public Log(Logger logger) { 39 | this.logger = logger; 40 | } 41 | 42 | public void info(String message) { 43 | this.logger.info(message); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ftpservice-api/src/main/java/org/eftp/events/FtpEventName.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.events; 5 | 6 | /* 7 | * #%L 8 | * ftpservice-api 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | /** 27 | * 28 | * @author adam-bien.com 29 | */ 30 | public enum FtpEventName { 31 | 32 | LOGIN, SITE, 33 | RENAME_END, RENAME_START, 34 | UPLOAD_UNIQUE_START, UPLOAD_UNIQUE_END, 35 | APPEND_START, APPEND_END, 36 | MKDIR_START, MKDIR_END, 37 | RMDIR_START, RMDIR_END, 38 | DOWNLOAD_START, DOWNLOAD_END, 39 | UPLOAD_START, UPLOAD_END, 40 | DELETE_END, DELETE_START, 41 | DISCONNECT, CONNECT, 42 | EVERYTHING; 43 | } 44 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/plugins/boundary/Plugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.plugins.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.lang.annotation.ElementType; 27 | import java.lang.annotation.Retention; 28 | import java.lang.annotation.RetentionPolicy; 29 | import java.lang.annotation.Target; 30 | import javax.inject.Qualifier; 31 | 32 | /** 33 | * 34 | * @author adam-bien.com 35 | */ 36 | @Qualifier 37 | @Target({ElementType.FIELD, ElementType.TYPE}) 38 | @Retention(RetentionPolicy.RUNTIME) 39 | public @interface Plugin { 40 | } 41 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/logger/boundary/LoggerProducer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.logger.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.logging.Logger; 27 | import javax.enterprise.inject.Produces; 28 | import javax.enterprise.inject.spi.InjectionPoint; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | public class LoggerProducer { 35 | 36 | @Produces 37 | public Logger produce(InjectionPoint ip) { 38 | String clazz = ip.getMember().getDeclaringClass().getName(); 39 | return Logger.getLogger(clazz); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/hooks/control/FtpEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.control; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import javax.ejb.Stateless; 9 | import javax.enterprise.event.Observes; 10 | import javax.inject.Inject; 11 | import org.eftp.events.Command; 12 | import org.eftp.events.FtpEvent; 13 | import org.eftp.events.FtpEventName; 14 | import org.eftp.ftpserver.business.hooks.boundary.HooksRegistry; 15 | import org.eftp.ftpserver.business.hooks.entity.Hook; 16 | 17 | /** 18 | * 19 | * @author adam-bien.com 20 | */ 21 | @Stateless 22 | public class FtpEventListener { 23 | 24 | @Inject 25 | HookInvoker hookInvoker; 26 | 27 | @Inject 28 | HooksRegistry registry; 29 | 30 | public void onFtpEventArrival(@Observes @Command FtpEvent event) { 31 | List allListeners = new ArrayList<>(); 32 | List everythingListeners = registry.findByCommand(FtpEventName.EVERYTHING); 33 | List hooks = registry.findByCommand(event.getCommand()); 34 | allListeners.addAll(everythingListeners); 35 | allListeners.addAll(hooks); 36 | for (Hook hook : allListeners) { 37 | this.hookInvoker.callback(hook, event); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ftpservice-api/src/main/java/org/eftp/events/Command.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.events; 5 | 6 | /* 7 | * #%L 8 | * ftpservice-api 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.lang.annotation.ElementType; 27 | import java.lang.annotation.Retention; 28 | import java.lang.annotation.RetentionPolicy; 29 | import java.lang.annotation.Target; 30 | import javax.inject.Qualifier; 31 | 32 | /** 33 | * 34 | * @author adam-bien.com 35 | */ 36 | @Qualifier 37 | @Retention(RetentionPolicy.RUNTIME) 38 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 39 | public @interface Command { 40 | 41 | FtpEventName value() default FtpEventName.EVERYTHING; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/files/boundary/FilesResources.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.files.boundary; 5 | 6 | import java.io.File; 7 | import java.security.Principal; 8 | import javax.ejb.Stateless; 9 | import javax.inject.Inject; 10 | import javax.ws.rs.GET; 11 | import javax.ws.rs.Path; 12 | import javax.ws.rs.PathParam; 13 | import javax.ws.rs.Produces; 14 | import javax.ws.rs.WebApplicationException; 15 | import javax.ws.rs.core.MediaType; 16 | import javax.ws.rs.core.Response; 17 | import javax.ws.rs.core.Response.Status; 18 | 19 | /** 20 | * 21 | * @author adam-bien.com 22 | */ 23 | @Stateless 24 | @Path("files") 25 | public class FilesResources { 26 | 27 | @Inject 28 | Files files; 29 | 30 | @Inject 31 | Principal principal; 32 | 33 | @GET 34 | @Path("/{file-name}") 35 | @Produces(MediaType.APPLICATION_OCTET_STREAM) 36 | public Response getFile(@PathParam("file-name") String fileName) { 37 | String userName = principal.getName(); 38 | File file = files.getFile(userName, fileName); 39 | if (file == null || !file.exists()) { 40 | throw new WebApplicationException(Status.NOT_FOUND); 41 | } 42 | return Response.ok(file).header("Content-Disposition", "attachment; filename=" + file.getName()).build(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/entity/FtpGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.Entity; 27 | import javax.persistence.GeneratedValue; 28 | import javax.persistence.Id; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | @Entity 35 | public class FtpGroup { 36 | 37 | @Id 38 | @GeneratedValue 39 | private long id; 40 | private String name; 41 | 42 | public String getName() { 43 | return name; 44 | } 45 | 46 | public void setName(String name) { 47 | this.name = name; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/entity/FtpPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.Entity; 27 | import javax.persistence.GeneratedValue; 28 | import javax.persistence.Id; 29 | import org.apache.ftpserver.ftplet.Authority; 30 | 31 | /** 32 | * 33 | * @author adam-bien.com 34 | */ 35 | @Entity 36 | public abstract class FtpPermission { 37 | 38 | @Id 39 | @GeneratedValue 40 | private long id; 41 | 42 | public long getId() { 43 | return id; 44 | } 45 | 46 | public abstract Authority getAuthority(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ftpservice/src/test/java/org/eftp/ftpserver/business/PersistenceSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.EntityManager; 27 | import javax.persistence.EntityTransaction; 28 | import javax.persistence.Persistence; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | public class PersistenceSupport { 35 | 36 | protected EntityManager em; 37 | protected EntityTransaction tx; 38 | 39 | public void initEM() { 40 | this.em = Persistence.createEntityManagerFactory("it").createEntityManager(); 41 | this.tx = this.em.getTransaction(); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/configuration/boundary/ConfigurationResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.configuration.boundary; 5 | 6 | import java.util.List; 7 | import javax.ejb.Stateless; 8 | import javax.inject.Inject; 9 | import javax.ws.rs.DELETE; 10 | import javax.ws.rs.GET; 11 | import javax.ws.rs.PUT; 12 | import javax.ws.rs.Path; 13 | import javax.ws.rs.PathParam; 14 | import org.eftp.ftpserver.business.configuration.control.ConfigurationStore; 15 | import org.eftp.ftpserver.business.configuration.entity.ConfigurationEntry; 16 | 17 | /** 18 | * 19 | * @author adam-bien.com 20 | */ 21 | @Stateless 22 | @Path("configuration") 23 | public class ConfigurationResource { 24 | 25 | @Inject 26 | ConfigurationStore cs; 27 | 28 | @GET 29 | public List all() { 30 | return this.cs.allEntries(); 31 | } 32 | 33 | @GET 34 | @Path("{name}") 35 | public ConfigurationEntry find(@PathParam("name") String name) { 36 | return this.cs.findEntry(name); 37 | } 38 | 39 | @DELETE 40 | @Path("{name}") 41 | public void remove(@PathParam("name") String name) { 42 | this.cs.remove(name); 43 | } 44 | 45 | @PUT 46 | public void saveOrUpdate(ConfigurationEntry newEntry) { 47 | this.cs.saveOrUpdate(newEntry); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/monitoring/boundary/CallTracker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.monitoring.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.inject.Inject; 27 | import javax.interceptor.AroundInvoke; 28 | import javax.interceptor.InvocationContext; 29 | import org.eftp.ftpserver.business.logger.boundary.Log; 30 | 31 | /** 32 | * 33 | * @author adam-bien.com 34 | */ 35 | public class CallTracker { 36 | 37 | @Inject 38 | Log LOG; 39 | 40 | @AroundInvoke 41 | public Object log(InvocationContext ic) throws Exception { 42 | LOG.info(String.valueOf(ic.getMethod())); 43 | return ic.proceed(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ftpserver/src/main/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ftpservice 5 | org.eftp.ftpserver.business.configuration.entity.ConfigurationEntry 6 | org.eftp.ftpserver.business.users.entity.FtpGroup 7 | org.eftp.ftpserver.business.users.entity.FtpUser 8 | org.eftp.ftpserver.business.users.entity.FtpConcurrentLoginPermission 9 | org.eftp.ftpserver.business.users.entity.FtpTransferRatePermision 10 | org.eftp.ftpserver.business.users.entity.FtpWritePermission 11 | org.eftp.ftpserver.business.users.entity.FtpPermission 12 | org.eftp.ftpserver.business.hooks.entity.Hook 13 | true 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/plugins/entity/CommandInstance.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.plugins.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.enterprise.util.AnnotationLiteral; 27 | import org.eftp.events.Command; 28 | import org.eftp.events.FtpEventName; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | public class CommandInstance extends AnnotationLiteral implements Command { 35 | 36 | private FtpEventName name; 37 | 38 | public CommandInstance(FtpEventName name) { 39 | this.name = name; 40 | } 41 | 42 | @Override 43 | public FtpEventName value() { 44 | return this.name; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/hooks/entity/HookValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.validation.ConstraintValidator; 27 | import javax.validation.ConstraintValidatorContext; 28 | 29 | /** 30 | * 31 | * @author adam-bien.com 32 | */ 33 | public class HookValidator implements ConstraintValidator { 34 | 35 | private Checks annotation; 36 | 37 | @Override 38 | public void initialize(Checks annotation) { 39 | this.annotation = annotation; 40 | } 41 | 42 | @Override 43 | public boolean isValid(Hook hook, ConstraintValidatorContext context) { 44 | return hook.isValid(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ftpserver/nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | 1.7-web 17 | gfv3ee6 18 | ide 19 | 20 | 21 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/files/boundary/InstrumendFileSystemFactory.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.files.boundary; 2 | 3 | /* 4 | * #%L 5 | * ftpservice 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | 23 | import org.apache.ftpserver.filesystem.nativefs.impl.NativeFileSystemView; 24 | import org.apache.ftpserver.ftplet.FileSystemFactory; 25 | import org.apache.ftpserver.ftplet.FileSystemView; 26 | import org.apache.ftpserver.ftplet.FtpException; 27 | import org.apache.ftpserver.ftplet.User; 28 | 29 | /** 30 | * 31 | * @author adam-bien.com 32 | */ 33 | public class InstrumendFileSystemFactory implements FileSystemFactory { 34 | 35 | @Override 36 | public FileSystemView createFileSystemView(User user) throws FtpException { 37 | return new NativeFileSystemView(user, true); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ftpservice-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.eftp 6 | e2ftp 7 | 0.0.3-SNAPSHOT 8 | 9 | org.eftp 10 | ftpservice-api 11 | 0.0.3-SNAPSHOT 12 | 13 | 14 | org.apache.ftpserver 15 | ftplet-api 16 | 1.0.6 17 | provided 18 | 19 | 20 | javax 21 | javaee-api 22 | 7.0 23 | provided 24 | 25 | 26 | junit 27 | junit 28 | 4.11 29 | test 30 | 31 | 32 | 33 | UTF-8 34 | 35 | ftpservice-api 36 | 37 | -------------------------------------------------------------------------------- /ftpservice/src/test/java/org/eftp/ftpserver/business/hooks/entity/HookTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import org.eftp.events.FtpEventName; 27 | import static org.junit.Assert.assertFalse; 28 | import static org.junit.Assert.assertTrue; 29 | import org.junit.Test; 30 | 31 | /** 32 | * 33 | * @author adam-bien.com 34 | */ 35 | public class HookTest { 36 | 37 | @Test 38 | public void validUri() { 39 | Hook cut = new Hook("http://localhost", FtpEventName.EVERYTHING); 40 | assertTrue(cut.isValid()); 41 | } 42 | 43 | @Test 44 | public void invalidUri() { 45 | Hook cut = new Hook("asdf", FtpEventName.EVERYTHING); 46 | assertFalse(cut.isValid()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/boundary/UserManagementInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.annotation.PostConstruct; 27 | import javax.ejb.Singleton; 28 | import javax.ejb.Startup; 29 | import javax.inject.Inject; 30 | import org.eftp.ftpserver.business.logger.boundary.Log; 31 | 32 | /** 33 | * 34 | * @author adam-bien.com 35 | */ 36 | @Startup 37 | @Singleton 38 | public class UserManagementInitializer { 39 | 40 | @Inject 41 | JPAUserStore userStore; 42 | 43 | @Inject 44 | Log LOG; 45 | 46 | @PostConstruct 47 | public void setupDefaults() { 48 | LOG.info("Establishing default settings for users"); 49 | userStore.createDefaultUser(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/RESTSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.ws.rs.client.Client; 27 | import javax.ws.rs.client.ClientBuilder; 28 | import javax.ws.rs.client.WebTarget; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | public abstract class RESTSupport { 35 | 36 | protected Client client; 37 | protected WebTarget mainTarget; 38 | private String user; 39 | private String password; 40 | 41 | public void init(String uri, String user, String password) { 42 | this.user = user; 43 | this.password = password; 44 | this.client = ClientBuilder.newClient().register(new Authenticator(user, password)); 45 | this.mainTarget = this.client.target(uri); 46 | } 47 | 48 | public abstract void init(); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /ftpservice-api/src/test/java/org/eftp/ftpserverapi/AppTest.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserverapi; 2 | 3 | /* 4 | * #%L 5 | * ftpservice-api 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | 23 | import junit.framework.Test; 24 | import junit.framework.TestCase; 25 | import junit.framework.TestSuite; 26 | 27 | /** 28 | * Unit test for simple App. 29 | */ 30 | public class AppTest 31 | extends TestCase 32 | { 33 | /** 34 | * Create the test case 35 | * 36 | * @param testName name of the test case 37 | */ 38 | public AppTest( String testName ) 39 | { 40 | super( testName ); 41 | } 42 | 43 | /** 44 | * @return the suite of tests being tested 45 | */ 46 | public static Test suite() 47 | { 48 | return new TestSuite( AppTest.class ); 49 | } 50 | 51 | /** 52 | * Rigourous Test :-) 53 | */ 54 | public void testApp() 55 | { 56 | assertTrue( true ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /hook-test-client/nb-configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | 1.7-web 17 | gfv3ee6 18 | Facelets 19 | ide 20 | 21 | 22 | -------------------------------------------------------------------------------- /ftpserver/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.eftp 5 | ftpserver 6 | 0.0.3-SNAPSHOT 7 | war 8 | 9 | 10 | org.eftp 11 | ftpservice 12 | 0.0.3-SNAPSHOT 13 | compile 14 | 15 | 16 | javax 17 | javaee-api 18 | 7.0 19 | provided 20 | 21 | 22 | 23 | 24 | 25 | org.apache.maven.plugins 26 | maven-compiler-plugin 27 | 3.1 28 | 29 | 1.7 30 | 1.7 31 | 32 | 33 | 34 | ftpserver 35 | 36 | 37 | UTF-8 38 | 39 | 40 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/hooks/entity/Checks.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.lang.annotation.Documented; 27 | import java.lang.annotation.ElementType; 28 | import java.lang.annotation.Retention; 29 | import java.lang.annotation.RetentionPolicy; 30 | import java.lang.annotation.Target; 31 | import javax.validation.Constraint; 32 | import javax.validation.Payload; 33 | 34 | /** 35 | * 36 | * @author adam-bien.com 37 | */ 38 | @Documented 39 | @Constraint(validatedBy = HookValidator.class) 40 | @Target({ElementType.PARAMETER}) 41 | @Retention(RetentionPolicy.RUNTIME) 42 | public @interface Checks { 43 | 44 | String message() default "{org.eftp.ftpserver.business.monitoring.boundary.Checks}"; 45 | 46 | Class[] groups() default {}; 47 | 48 | Class[] payload() default {}; 49 | } 50 | -------------------------------------------------------------------------------- /ftpservice/src/test/java/org/eftp/ftpserver/business/users/control/DigesterTester.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.control; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import static org.hamcrest.CoreMatchers.is; 27 | import static org.hamcrest.CoreMatchers.not; 28 | import static org.junit.Assert.assertThat; 29 | import org.junit.Test; 30 | 31 | /** 32 | * 33 | * @author adam-bien.com 34 | */ 35 | public class DigesterTester { 36 | 37 | @Test 38 | public void digest() { 39 | String first = Digester.computeHash("aa"); 40 | String second = Digester.computeHash("aa"); 41 | String different = Digester.computeHash("ab"); 42 | assertThat(first, is(second)); 43 | assertThat(first, is(not(different))); 44 | System.out.println("First: " + first); 45 | System.out.println("Second: " + second); 46 | System.out.println("Different: " + different); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/entity/FtpWritePermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.Entity; 27 | import org.apache.ftpserver.ftplet.Authority; 28 | import org.apache.ftpserver.usermanager.impl.WritePermission; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | @Entity 35 | public class FtpWritePermission extends FtpPermission { 36 | 37 | private String permissionRoot; 38 | 39 | public FtpWritePermission() { 40 | this("/"); 41 | } 42 | 43 | public FtpWritePermission(String permissionRoot) { 44 | this.permissionRoot = permissionRoot; 45 | } 46 | 47 | public String getPermissionRoot() { 48 | return permissionRoot; 49 | } 50 | 51 | public void setPermissionRoot(String permissionRoot) { 52 | this.permissionRoot = permissionRoot; 53 | } 54 | 55 | @Override 56 | public Authority getAuthority() { 57 | return new WritePermission(permissionRoot); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /hook-test-client/src/main/java/org/e2ftp/testclient/business/hooks/boundary/HookMgmt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.e2ftp.testclient.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * hook-test-client 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.ejb.Stateless; 27 | import javax.json.Json; 28 | import javax.json.JsonObject; 29 | import javax.ws.rs.client.Client; 30 | import javax.ws.rs.client.ClientBuilder; 31 | import javax.ws.rs.client.Entity; 32 | import javax.ws.rs.client.WebTarget; 33 | import javax.ws.rs.core.MediaType; 34 | 35 | /** 36 | * 37 | * @author adam-bien.com 38 | */ 39 | @Stateless 40 | public class HookMgmt { 41 | 42 | public void register(String user, String password, String ftpServerUri, String callBackUri) { 43 | Client client = ClientBuilder.newClient().register(new Authenticator(user, password)); 44 | WebTarget registryTarget = client.target(ftpServerUri); 45 | 46 | JsonObject newEntry = Json.createObjectBuilder().add("command", "everything").add("uri", callBackUri).build(); 47 | registryTarget.request().post(Entity.entity(newEntry, MediaType.APPLICATION_JSON)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/monitoring/boundary/StatisticsResourceIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.monitoring.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.json.JsonObject; 27 | import javax.ws.rs.client.Client; 28 | import javax.ws.rs.core.MediaType; 29 | import org.eftp.ftpserver.business.RESTSupport; 30 | import static org.junit.Assert.assertFalse; 31 | import org.junit.Before; 32 | import org.junit.Test; 33 | 34 | /** 35 | * 36 | * @author adam-bien.com 37 | */ 38 | public class StatisticsResourceIT extends RESTSupport { 39 | 40 | private Client client; 41 | 42 | private static final String STATISTICS_URI = "http://localhost:8080/ftpserver/api/statistics"; 43 | 44 | @Override 45 | @Before 46 | public void init() { 47 | super.init(STATISTICS_URI, "duke", "duke"); 48 | } 49 | 50 | @Test 51 | public void fetchStatistics() { 52 | JsonObject statistics = this.mainTarget.request(MediaType.APPLICATION_JSON).get(JsonObject.class); 53 | assertFalse(statistics.isEmpty()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /hook-test-client/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | 24 | javax.faces.PROJECT_STAGE 25 | Development 26 | 27 | 28 | Faces Servlet 29 | javax.faces.webapp.FacesServlet 30 | 1 31 | 32 | 33 | Faces Servlet 34 | /faces/* 35 | 36 | 37 | 38 | 30 39 | 40 | 41 | 42 | faces/index.xhtml 43 | 44 | 45 | -------------------------------------------------------------------------------- /ftpserver-st/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.eftp 6 | e2ftp 7 | 0.0.3-SNAPSHOT 8 | 9 | org.eftp 10 | ftpserver-st 11 | 0.0.3-SNAPSHOT 12 | ftpserver-st 13 | 14 | 15 | junit 16 | junit 17 | 4.11 18 | test 19 | 20 | 21 | commons-net 22 | commons-net 23 | 3.3 24 | test 25 | 26 | 27 | org.glassfish.jersey.core 28 | jersey-client 29 | 2.0 30 | 31 | 32 | org.glassfish 33 | javax.json 34 | 1.0 35 | 36 | 37 | org.glassfish.jersey.media 38 | jersey-media-json-processing 39 | 2.0 40 | 41 | 42 | 43 | UTF-8 44 | 45 | 46 | -------------------------------------------------------------------------------- /ftpservice/src/test/java/org/eftp/ftpserver/business/hooks/entity/HookIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import org.eftp.events.FtpEventName; 27 | import org.eftp.ftpserver.business.PersistenceSupport; 28 | import org.junit.Assert; 29 | import static org.junit.Assert.assertNull; 30 | import org.junit.Before; 31 | import org.junit.Test; 32 | 33 | /** 34 | * 35 | * @author adam-bien.com 36 | */ 37 | public class HookIT extends PersistenceSupport { 38 | 39 | @Before 40 | public void init() { 41 | super.initEM(); 42 | } 43 | 44 | @Test 45 | public void crud() { 46 | Hook cut = new Hook("asdf", FtpEventName.EVERYTHING); 47 | this.tx.begin(); 48 | cut = this.em.merge(cut); 49 | this.tx.commit(); 50 | long id = cut.getId(); 51 | 52 | Hook found = this.em.find(Hook.class, id); 53 | Assert.assertSame(cut, found); 54 | 55 | this.tx.begin(); 56 | this.em.remove(found); 57 | this.tx.commit(); 58 | 59 | found = this.em.find(Hook.class, id); 60 | assertNull(found); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /hook-test-client/src/main/java/org/e2ftp/testclient/business/hooks/boundary/CallbacksResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.e2ftp.testclient.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * hook-test-client 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import javax.annotation.PostConstruct; 29 | import javax.ejb.ConcurrencyManagement; 30 | import javax.ejb.ConcurrencyManagementType; 31 | import javax.ejb.Singleton; 32 | import javax.json.JsonObject; 33 | import javax.ws.rs.POST; 34 | import javax.ws.rs.Path; 35 | 36 | /** 37 | * 38 | * @author adam-bien.com 39 | */ 40 | @Path("callbacks") 41 | @Singleton 42 | @ConcurrencyManagement(ConcurrencyManagementType.BEAN) 43 | public class CallbacksResource { 44 | 45 | private List callbacks; 46 | 47 | @PostConstruct 48 | public void init() { 49 | this.callbacks = new ArrayList<>(); 50 | } 51 | 52 | @POST 53 | public void onCallaback(JsonObject object) { 54 | this.callbacks.add(object); 55 | } 56 | 57 | public List getCallbackObject() { 58 | return callbacks; 59 | } 60 | 61 | public void clear() { 62 | this.callbacks.clear(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /hook-test-client/src/main/webapp/index.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | 26 | 27 | FTP Hook Tester 28 | 29 | 30 | 31 | 32 | User:
33 | Password:
34 | Callback URI:
35 | Server URI:
36 | Last Callback:
37 | 38 | 39 | 40 |
41 |
42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/configuration/entity/ConfigurationEntry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.configuration.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.Column; 27 | import javax.persistence.Entity; 28 | import javax.persistence.Id; 29 | import javax.xml.bind.annotation.XmlAccessType; 30 | import javax.xml.bind.annotation.XmlAccessorType; 31 | import javax.xml.bind.annotation.XmlRootElement; 32 | 33 | /** 34 | * 35 | * @author adam-bien.com 36 | */ 37 | @Entity 38 | @XmlRootElement 39 | @XmlAccessorType(XmlAccessType.FIELD) 40 | public class ConfigurationEntry { 41 | 42 | @Id 43 | private String name; 44 | @Column(name = "c_value") 45 | private String value; 46 | 47 | public ConfigurationEntry(String name, String value) { 48 | this.name = name; 49 | this.value = value; 50 | } 51 | 52 | public ConfigurationEntry() { 53 | } 54 | 55 | public String getName() { 56 | return name; 57 | } 58 | 59 | public void setName(String name) { 60 | this.name = name; 61 | } 62 | 63 | public String getValue() { 64 | return value; 65 | } 66 | 67 | public void setValue(String value) { 68 | this.value = value; 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /hook-test-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | e2ftp 6 | org.eftp 7 | 0.0.3-SNAPSHOT 8 | 9 | 10 | org.e2ftp 11 | hook-test-client 12 | 0.3-SNAPSHOT 13 | war 14 | 15 | hook-test-client 16 | 17 | 18 | UTF-8 19 | 20 | 21 | 22 | 23 | javax 24 | javaee-web-api 25 | 7.0 26 | provided 27 | 28 | 29 | 30 | 31 | 32 | 33 | org.apache.maven.plugins 34 | maven-compiler-plugin 35 | 3.1 36 | 37 | 1.7 38 | 1.7 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-war-plugin 44 | 2.3 45 | 46 | false 47 | 48 | 49 | 50 | hook-test-client 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/concurrency/control/ManagedThreadPoolExecutorExposer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.concurrency.control; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.concurrent.LinkedBlockingQueue; 27 | import java.util.concurrent.ThreadPoolExecutor; 28 | import java.util.concurrent.TimeUnit; 29 | import javax.annotation.PostConstruct; 30 | import javax.ejb.Singleton; 31 | import javax.enterprise.inject.Produces; 32 | import javax.inject.Inject; 33 | 34 | /** 35 | * 36 | * @author adam-bien.com 37 | */ 38 | @Singleton 39 | public class ManagedThreadPoolExecutorExposer { 40 | 41 | @Inject 42 | private int corePoolSize; 43 | @Inject 44 | private int maximumPoolSize; 45 | 46 | @Inject 47 | private long keepAliveTimeInHours; 48 | 49 | @Inject 50 | private int incomingRequestQueueDepth; 51 | 52 | private ThreadPoolExecutor executor; 53 | 54 | @PostConstruct 55 | public void init() { 56 | LinkedBlockingQueue workQueue = new LinkedBlockingQueue<>(incomingRequestQueueDepth); 57 | this.executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTimeInHours, TimeUnit.DAYS, workQueue); 58 | } 59 | 60 | @Produces 61 | public ThreadPoolExecutor poolExecutor() { 62 | return this.executor; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ftpservice/src/test/java/org/eftp/ftpserver/business/hooks/boundary/HooksRegistryIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.List; 27 | import org.eftp.events.FtpEventName; 28 | import org.eftp.ftpserver.business.PersistenceSupport; 29 | import org.eftp.ftpserver.business.hooks.entity.Hook; 30 | import static org.junit.Assert.assertTrue; 31 | import org.junit.Before; 32 | import org.junit.Test; 33 | 34 | /** 35 | * 36 | * @author adam-bien.com 37 | */ 38 | public class HooksRegistryIT extends PersistenceSupport { 39 | 40 | HooksRegistry cut; 41 | 42 | @Before 43 | public void init() { 44 | super.initEM(); 45 | this.cut = new HooksRegistry(); 46 | this.cut.em = super.em; 47 | 48 | } 49 | 50 | @Test 51 | public void findByCommand() { 52 | List foundHooks = this.cut.findByCommand(FtpEventName.EVERYTHING); 53 | assertTrue(foundHooks.isEmpty()); 54 | 55 | Hook hook = new Hook("http://localhost", FtpEventName.EVERYTHING); 56 | this.tx.begin(); 57 | long id = this.cut.saveOrUpdate(hook); 58 | this.tx.commit(); 59 | 60 | hook = this.cut.find(id); 61 | 62 | foundHooks = this.cut.findByCommand(FtpEventName.EVERYTHING); 63 | assertTrue(foundHooks.contains(hook)); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/control/Digester.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.control; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.io.UnsupportedEncodingException; 27 | import java.math.BigInteger; 28 | import java.security.MessageDigest; 29 | import java.security.NoSuchAlgorithmException; 30 | 31 | /** 32 | * 33 | * @author adam-bien.com 34 | */ 35 | public class Digester { 36 | 37 | private static final String CHARSET = "UTF-8"; 38 | private static final String ALGORITHM = "SHA-256"; 39 | 40 | public static String computeHash(String password) { 41 | MessageDigest messageDigest = null; 42 | final byte[] bytes; 43 | try { 44 | messageDigest = MessageDigest.getInstance(ALGORITHM); 45 | } catch (NoSuchAlgorithmException ex) { 46 | throw new IllegalStateException("Cannot find digest algorithm: " + ALGORITHM, ex); 47 | } 48 | try { 49 | bytes = password.getBytes(CHARSET); 50 | } catch (UnsupportedEncodingException ex) { 51 | throw new IllegalStateException("Charset: " + CHARSET + " is not supported", ex); 52 | } 53 | messageDigest.update(bytes); 54 | byte[] digest = messageDigest.digest(); 55 | BigInteger bigInteger = new BigInteger(1, digest); 56 | return String.format("%x", bigInteger); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/entity/FtpTransferRatePermision.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.Entity; 27 | import org.apache.ftpserver.ftplet.Authority; 28 | import org.apache.ftpserver.usermanager.impl.TransferRatePermission; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | @Entity 35 | public class FtpTransferRatePermision extends FtpPermission { 36 | 37 | private int maxDownloadRate; 38 | private int maxUploadRate; 39 | 40 | public FtpTransferRatePermision(int maxDownloadRate, int maxUploadRate) { 41 | this.maxDownloadRate = maxDownloadRate; 42 | this.maxUploadRate = maxUploadRate; 43 | } 44 | 45 | public FtpTransferRatePermision() { 46 | } 47 | 48 | public int getMaxDownloadRate() { 49 | return maxDownloadRate; 50 | } 51 | 52 | public void setMaxDownloadRate(int maxDownloadRate) { 53 | this.maxDownloadRate = maxDownloadRate; 54 | } 55 | 56 | public int getMaxUploadRate() { 57 | return maxUploadRate; 58 | } 59 | 60 | public void setMaxUploadRate(int maxUploadRate) { 61 | this.maxUploadRate = maxUploadRate; 62 | } 63 | 64 | @Override 65 | public Authority getAuthority() { 66 | return new TransferRatePermission(maxDownloadRate, maxUploadRate); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/configuration/boundary/ConfigurationStartup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.configuration.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.annotation.PostConstruct; 27 | import javax.ejb.Singleton; 28 | import javax.ejb.Startup; 29 | import javax.inject.Inject; 30 | import org.eftp.ftpserver.business.configuration.control.ConfigurationStore; 31 | import org.eftp.ftpserver.business.logger.boundary.Log; 32 | 33 | /** 34 | * 35 | * @author adam-bien.com 36 | */ 37 | @Startup 38 | @Singleton 39 | public class ConfigurationStartup { 40 | 41 | @Inject 42 | ConfigurationStore store; 43 | 44 | @Inject 45 | Log LOG; 46 | 47 | @PostConstruct 48 | public void establishDefaults() { 49 | LOG.info("Establishing defaults"); 50 | this.store.saveOrUpdate("serverPort", "8888"); 51 | this.store.saveOrUpdate("maxLogins", "10"); 52 | this.store.saveOrUpdate("anonymousLoginEnabled", "false"); 53 | this.store.saveOrUpdate("corePoolSize", String.valueOf(2)); 54 | this.store.saveOrUpdate("maximumPoolSize", String.valueOf(8)); 55 | this.store.saveOrUpdate("keepAliveTimeInHours", String.valueOf(1)); 56 | this.store.saveOrUpdate("incomingRequestQueueDepth", String.valueOf(10)); 57 | this.store.saveOrUpdate("startServerOnStartup", "true"); 58 | 59 | LOG.info("Default values are written"); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /hook-test-client/src/main/java/org/e2ftp/testclient/business/hooks/boundary/Authenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.e2ftp.testclient.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * hook-test-client 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.io.IOException; 27 | import java.io.UnsupportedEncodingException; 28 | import javax.ws.rs.client.ClientRequestContext; 29 | import javax.ws.rs.client.ClientRequestFilter; 30 | import javax.ws.rs.core.MultivaluedMap; 31 | import javax.xml.bind.DatatypeConverter; 32 | 33 | /** 34 | * 35 | * @author adam-bien.com 36 | */ 37 | public class Authenticator implements ClientRequestFilter { 38 | 39 | private String user; 40 | private String password; 41 | 42 | public Authenticator(String user, String password) { 43 | this.user = user; 44 | this.password = password; 45 | } 46 | 47 | @Override 48 | public void filter(ClientRequestContext requestContext) throws IOException { 49 | MultivaluedMap headers = requestContext.getHeaders(); 50 | final String basicAuthentication = getBasicAuthentication(); 51 | headers.add("Authorization", basicAuthentication); 52 | 53 | } 54 | 55 | private String getBasicAuthentication() { 56 | String token = this.user + ":" + this.password; 57 | try { 58 | return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8")); 59 | } catch (UnsupportedEncodingException ex) { 60 | throw new IllegalStateException("Cannot encode with UTF-8", ex); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/Authenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.io.IOException; 27 | import java.io.UnsupportedEncodingException; 28 | import javax.ws.rs.client.ClientRequestContext; 29 | import javax.ws.rs.client.ClientRequestFilter; 30 | import javax.ws.rs.core.MultivaluedMap; 31 | import javax.xml.bind.DatatypeConverter; 32 | 33 | /** 34 | * 35 | * @author adam-bien.com 36 | */ 37 | public class Authenticator implements ClientRequestFilter { 38 | 39 | private String user; 40 | private String password; 41 | 42 | public Authenticator(String user, String password) { 43 | this.user = user; 44 | this.password = password; 45 | } 46 | 47 | public void filter(ClientRequestContext requestContext) throws IOException { 48 | MultivaluedMap headers = requestContext.getHeaders(); 49 | final String basicAuthentication = getBasicAuthentication(); 50 | System.out.println("Sending: " + basicAuthentication); 51 | headers.add("Authorization", basicAuthentication); 52 | 53 | } 54 | 55 | private String getBasicAuthentication() { 56 | String token = this.user + ":" + this.password; 57 | try { 58 | return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8")); 59 | } catch (UnsupportedEncodingException ex) { 60 | throw new IllegalStateException("Cannot encode with UTF-8", ex); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /ftpservice/src/test/resources/META-INF/persistence.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | 24 | org.eclipse.persistence.jpa.PersistenceProvider 25 | org.eftp.ftpserver.business.hooks.entity.Hook 26 | org.eftp.ftpserver.business.configuration.entity.ConfigurationEntry 27 | org.eftp.ftpserver.business.users.entity.FtpConcurrentLoginPermission 28 | org.eftp.ftpserver.business.users.entity.FtpGroup 29 | org.eftp.ftpserver.business.users.entity.FtpPermission 30 | org.eftp.ftpserver.business.users.entity.FtpTransferRatePermision 31 | org.eftp.ftpserver.business.users.entity.FtpUser 32 | org.eftp.ftpserver.business.users.entity.FtpWritePermission 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/entity/FtpConcurrentLoginPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.persistence.Entity; 27 | import org.apache.ftpserver.ftplet.Authority; 28 | import org.apache.ftpserver.usermanager.impl.ConcurrentLoginPermission; 29 | 30 | /** 31 | * 32 | * @author adam-bien.com 33 | */ 34 | @Entity 35 | public class FtpConcurrentLoginPermission extends FtpPermission { 36 | 37 | private int maxConcurrentLogins; 38 | private int maxConcurrentLoginsPerIP; 39 | 40 | public FtpConcurrentLoginPermission(int maxConcurrentLogins, int maxConcurrentLoginsPerIP) { 41 | this.maxConcurrentLogins = maxConcurrentLogins; 42 | this.maxConcurrentLoginsPerIP = maxConcurrentLoginsPerIP; 43 | } 44 | 45 | public FtpConcurrentLoginPermission() { 46 | } 47 | 48 | public int getMaxConcurrentLogins() { 49 | return maxConcurrentLogins; 50 | } 51 | 52 | public void setMaxConcurrentLogins(int maxConcurrentLogins) { 53 | this.maxConcurrentLogins = maxConcurrentLogins; 54 | } 55 | 56 | public int getMaxConcurrentLoginsPerIP() { 57 | return maxConcurrentLoginsPerIP; 58 | } 59 | 60 | public void setMaxConcurrentLoginsPerIP(int maxConcurrentLoginsPerIP) { 61 | this.maxConcurrentLoginsPerIP = maxConcurrentLoginsPerIP; 62 | } 63 | 64 | @Override 65 | public Authority getAuthority() { 66 | return new ConcurrentLoginPermission(maxConcurrentLogins, maxConcurrentLoginsPerIP); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/hooks/entity/Hook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.net.MalformedURLException; 27 | import java.net.URL; 28 | import javax.persistence.Entity; 29 | import javax.persistence.EnumType; 30 | import javax.persistence.Enumerated; 31 | import javax.persistence.GeneratedValue; 32 | import javax.persistence.Id; 33 | import javax.persistence.NamedQuery; 34 | import org.eftp.events.FtpEventName; 35 | 36 | /** 37 | * 38 | * @author adam-bien.com 39 | */ 40 | @Entity 41 | @NamedQuery(name = Hook.findByCommand, query = "SELECT h from Hook h where h.command = :command") 42 | public class Hook { 43 | 44 | private static final String PREFIX = "org.eftp.ftpserver.business.hooks.entity."; 45 | public static final String findByCommand = PREFIX + "findByCommand"; 46 | 47 | @Id 48 | @GeneratedValue 49 | private long id; 50 | private String uri; 51 | 52 | @Enumerated(EnumType.STRING) 53 | private FtpEventName command; 54 | 55 | public Hook(String uri, FtpEventName command) { 56 | this.uri = uri; 57 | this.command = command; 58 | } 59 | 60 | public Hook() { 61 | } 62 | 63 | public long getId() { 64 | return id; 65 | } 66 | 67 | public String getUri() { 68 | return uri; 69 | } 70 | 71 | public FtpEventName getCommand() { 72 | return command; 73 | } 74 | 75 | public void setCommand(FtpEventName command) { 76 | this.command = command; 77 | } 78 | 79 | boolean isValid() { 80 | try { 81 | new URL(this.uri); 82 | } catch (MalformedURLException ex) { 83 | return false; 84 | } 85 | return this.command != null; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/configuration/boundary/ConfigurationExposer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.configuration.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.enterprise.inject.Produces; 27 | import javax.enterprise.inject.spi.InjectionPoint; 28 | import javax.inject.Inject; 29 | import org.eftp.ftpserver.business.configuration.control.ConfigurationStore; 30 | import org.eftp.ftpserver.business.logger.boundary.Log; 31 | 32 | /** 33 | * 34 | * @author adam-bien.com 35 | */ 36 | public class ConfigurationExposer { 37 | 38 | @Inject 39 | ConfigurationStore store; 40 | 41 | @Inject 42 | Log LOG; 43 | 44 | @Produces 45 | public Integer getInt(InjectionPoint ip) { 46 | final String stringValue = getString(ip); 47 | if (stringValue == null) { 48 | return 0; 49 | } 50 | return Integer.parseInt(stringValue); 51 | } 52 | 53 | @Produces 54 | public Long getLong(InjectionPoint ip) { 55 | final String stringValue = getString(ip); 56 | if (stringValue == null) { 57 | return 0l; 58 | } 59 | return Long.parseLong(stringValue); 60 | } 61 | 62 | @Produces 63 | public Boolean getBoolean(InjectionPoint ip) { 64 | final String stringValue = getString(ip); 65 | if (stringValue == null) { 66 | return false; 67 | } 68 | return Boolean.parseBoolean(stringValue); 69 | } 70 | 71 | @Produces 72 | public String getString(InjectionPoint ip) { 73 | String fieldName = ip.getMember().getName(); 74 | String configurationValue = this.store.find(fieldName); 75 | LOG.info("Found value " + configurationValue + " for : " + fieldName); 76 | return configurationValue; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/hooks/boundary/HooksResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.boundary; 5 | 6 | import java.net.URI; 7 | import java.util.List; 8 | import javax.ejb.Stateless; 9 | import javax.inject.Inject; 10 | import javax.json.Json; 11 | import javax.json.JsonArray; 12 | import javax.json.JsonArrayBuilder; 13 | import javax.json.JsonObject; 14 | import javax.ws.rs.DELETE; 15 | import javax.ws.rs.GET; 16 | import javax.ws.rs.POST; 17 | import javax.ws.rs.Path; 18 | import javax.ws.rs.PathParam; 19 | import javax.ws.rs.core.Context; 20 | import javax.ws.rs.core.Response; 21 | import javax.ws.rs.core.UriInfo; 22 | import org.eftp.events.FtpEventName; 23 | import org.eftp.ftpserver.business.hooks.entity.Hook; 24 | 25 | /** 26 | * 27 | * @author adam-bien.com 28 | */ 29 | @Stateless 30 | @Path("hooks") 31 | public class HooksResource { 32 | 33 | @Inject 34 | HooksRegistry hr; 35 | 36 | @POST 37 | public Response register(JsonObject callback, @Context UriInfo info) { 38 | long id = hr.saveOrUpdate(convert(callback)); 39 | final URI creationUri = info.getRequestUriBuilder().path(String.valueOf(id)).build(); 40 | return Response.created(creationUri).build(); 41 | } 42 | 43 | @GET 44 | @Path("{id}") 45 | public JsonObject find(@PathParam("id") long id) { 46 | Hook hook = hr.find(id); 47 | return convert(hook); 48 | } 49 | 50 | @GET 51 | public JsonArray all() { 52 | JsonArrayBuilder builder = Json.createArrayBuilder(); 53 | List allHooks = hr.all(); 54 | for (Hook hook : allHooks) { 55 | builder.add(convert(hook)); 56 | } 57 | return builder.build(); 58 | } 59 | 60 | @DELETE 61 | @Path("{id}") 62 | public void delete(@PathParam("id") long id) { 63 | hr.remove(id); 64 | } 65 | 66 | Hook convert(JsonObject object) { 67 | String command = object.getString("command", FtpEventName.EVERYTHING.toString()); 68 | String uri = object.getString("uri"); 69 | return new Hook(uri, FtpEventName.valueOf(command.toUpperCase())); 70 | } 71 | 72 | JsonObject convert(Hook hook) { 73 | if (hook == null) { 74 | return null; 75 | } 76 | return Json.createObjectBuilder(). 77 | add("command", hook.getCommand().toString()). 78 | add("uri", hook.getUri()). 79 | add("id", hook.getId()). 80 | build(); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/hooks/boundary/HooksRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.List; 27 | import javax.ejb.Stateless; 28 | import javax.persistence.EntityManager; 29 | import javax.persistence.PersistenceContext; 30 | import javax.persistence.TypedQuery; 31 | import javax.persistence.criteria.CriteriaBuilder; 32 | import javax.persistence.criteria.CriteriaQuery; 33 | import javax.persistence.criteria.Root; 34 | import org.eftp.events.FtpEventName; 35 | import org.eftp.ftpserver.business.hooks.entity.Checks; 36 | import org.eftp.ftpserver.business.hooks.entity.Hook; 37 | 38 | /** 39 | * 40 | * @author adam-bien.com 41 | */ 42 | @Stateless 43 | public class HooksRegistry { 44 | 45 | @PersistenceContext 46 | EntityManager em; 47 | 48 | public long saveOrUpdate(@Checks Hook hook) { 49 | return this.em.merge(hook).getId(); 50 | } 51 | 52 | public Hook find(long id) { 53 | return this.em.find(Hook.class, id); 54 | } 55 | 56 | public void remove(long id) { 57 | Hook reference = this.em.getReference(Hook.class, id); 58 | this.em.remove(reference); 59 | } 60 | 61 | public List all() { 62 | CriteriaBuilder cb = em.getCriteriaBuilder(); 63 | CriteriaQuery cq = cb.createQuery(Hook.class); 64 | Root rootEntry = cq.from(Hook.class); 65 | CriteriaQuery all = cq.select(rootEntry); 66 | TypedQuery allQuery = em.createQuery(all); 67 | return allQuery.getResultList(); 68 | } 69 | 70 | public List findByCommand(FtpEventName name) { 71 | return this.em.createNamedQuery(Hook.findByCommand, Hook.class). 72 | setParameter("command", name). 73 | getResultList(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | org.eftp 5 | e2ftp 6 | 0.0.3-SNAPSHOT 7 | pom 8 | e2ftp 9 | 10 | e2ftp 11 | http://e2ftp.adam-bien.com 12 | 13 | 2013 14 | 15 | 16 | The Apache Software License, Version 2.0 17 | http://www.apache.org/licenses/LICENSE-2.0.txt 18 | repo 19 | 20 | 21 | 22 | ftpservice-api 23 | ftpservice 24 | ftpserver 25 | ftpserver-st 26 | hook-test-client 27 | 28 | 29 | 30 | 31 | org.codehaus.mojo 32 | license-maven-plugin 33 | 1.4 34 | 35 | true 36 | 37 | 38 | 39 | add-apache-headers 40 | 41 | update-file-header 42 | 43 | process-sources 44 | 45 | apache_v2 46 | 47 | 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-release-plugin 53 | 2.4.1 54 | 55 | 56 | 57 | 58 | scm:git:git@github.com:AdamBien/e2ftp.git 59 | scm:git:git@github.com:AdamBien/e2ftp.git 60 | scm:git:git@github.com:AdamBien/e2ftp.git 61 | HEAD 62 | 63 | -------------------------------------------------------------------------------- /ftpserver/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 30 6 | 7 | 8 | 9 | Admin API 10 | 11 | Configuration 12 | 13 | /api/configuration/* 14 | /api/management/* 15 | 16 | 17 | Statistics 18 | 19 | /api/statistics/* 20 | 21 | 22 | 23 | admin 24 | listener 25 | 26 | 27 | 28 | Hooks and Events API 29 | 30 | Events Broadcast 31 | 32 | /api/events/* 33 | 34 | 35 | Persistent Callback API 36 | 37 | /api/hooks/* 38 | 39 | 40 | File Access 41 | 42 | /api/files/* 43 | 44 | 45 | 46 | listener 47 | 48 | 49 | 50 | BASIC 51 | ftpRealm 52 | 53 | 54 | 55 | admin 56 | 57 | 58 | A FTP user 59 | user 60 | 61 | 62 | This role is allowed to setup hooks and listen to FTP events 63 | listener 64 | 65 | 66 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/monitoring/boundary/StatisticsResource.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.monitoring.boundary; 2 | 3 | import java.util.concurrent.ThreadPoolExecutor; 4 | import javax.ejb.Stateless; 5 | import javax.inject.Inject; 6 | import javax.json.Json; 7 | import javax.json.JsonObject; 8 | import javax.json.JsonObjectBuilder; 9 | import javax.ws.rs.GET; 10 | import javax.ws.rs.Path; 11 | import org.apache.ftpserver.ftplet.FtpStatistics; 12 | 13 | /** 14 | * 15 | * @author adam-bien.com 16 | */ 17 | @Stateless 18 | @Path("statistics") 19 | public class StatisticsResource { 20 | 21 | @Inject 22 | FtpStatistics statistics; 23 | 24 | @Inject 25 | ThreadPoolExecutor executor; 26 | 27 | private static final String EXECUTOR_PREFIX = "ExecutorService."; 28 | 29 | @GET 30 | public JsonObject all() { 31 | JsonObjectBuilder builder = Json.createObjectBuilder(); 32 | builder.add("currentAnonymousLoginNumber", this.statistics.getCurrentAnonymousLoginNumber()); 33 | builder.add("currentConnectionNumber", this.statistics.getCurrentConnectionNumber()); 34 | builder.add("currentLoginNumber", this.statistics.getCurrentLoginNumber()); 35 | builder.add("totalAnonymousLoginNumber", this.statistics.getTotalAnonymousLoginNumber()); 36 | builder.add("totalConnectionNumber", this.statistics.getTotalConnectionNumber()); 37 | builder.add("totalDeleteNumber", this.statistics.getTotalDeleteNumber()); 38 | builder.add("totalDirectoryCreated", this.statistics.getTotalDirectoryCreated()); 39 | builder.add("totalDirectoryRemoved", this.statistics.getTotalDirectoryRemoved()); 40 | builder.add("totalDownloadNumber", this.statistics.getTotalDownloadNumber()); 41 | builder.add("totalDownloadSize", this.statistics.getTotalDownloadSize()); 42 | builder.add("totalFailedLoginNumber", this.statistics.getTotalFailedLoginNumber()); 43 | builder.add("totalLoginNumber", this.statistics.getTotalLoginNumber()); 44 | builder.add("totalUploadNumber", this.statistics.getTotalUploadNumber()); 45 | builder.add("totalUploadSize", this.statistics.getTotalUploadSize()); 46 | builder.add("startTime", this.statistics.getStartTime().toString()); 47 | builder.add(EXECUTOR_PREFIX + "activeCount", executor.getActiveCount()); 48 | builder.add(EXECUTOR_PREFIX + "completedTaskCount", executor.getCompletedTaskCount()); 49 | builder.add(EXECUTOR_PREFIX + "corePoolSize", executor.getCorePoolSize()); 50 | builder.add(EXECUTOR_PREFIX + "largestPoolSize", executor.getLargestPoolSize()); 51 | builder.add(EXECUTOR_PREFIX + "maximumPoolSize", executor.getMaximumPoolSize()); 52 | builder.add(EXECUTOR_PREFIX + "poolSize", executor.getPoolSize()); 53 | builder.add(EXECUTOR_PREFIX + "taskCount", executor.getTaskCount()); 54 | builder.add(EXECUTOR_PREFIX + "taskQueueSize", executor.getQueue().size()); 55 | return builder.build(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/configuration/ConfigurationResourceIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.configuration; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.json.Json; 27 | import javax.json.JsonArray; 28 | import javax.json.JsonObject; 29 | import javax.ws.rs.client.Entity; 30 | import javax.ws.rs.core.MediaType; 31 | import javax.ws.rs.core.Response; 32 | import org.eftp.ftpserver.business.RESTSupport; 33 | import static org.hamcrest.CoreMatchers.is; 34 | import static org.junit.Assert.assertFalse; 35 | import static org.junit.Assert.assertThat; 36 | import org.junit.Before; 37 | import org.junit.Test; 38 | 39 | /** 40 | * 41 | * @author adam-bien.com 42 | */ 43 | public class ConfigurationResourceIT extends RESTSupport { 44 | 45 | private static final String CONFIGURATION_URI = "http://localhost:8080/ftpserver/api/configuration"; 46 | 47 | @Before 48 | public void init() { 49 | super.init(CONFIGURATION_URI, "duke", "duke"); 50 | } 51 | 52 | @Test 53 | public void crud() { 54 | JsonArray allEntries = this.mainTarget.request(MediaType.APPLICATION_JSON).get(JsonArray.class); 55 | assertFalse(allEntries.isEmpty()); 56 | System.out.println("-- " + allEntries); 57 | String name = "hugo " + System.currentTimeMillis(); 58 | //creation 59 | JsonObject newEntry = Json.createObjectBuilder().add("name", name).add("value", 42).build(); 60 | Response putResponse = this.mainTarget.request().put(Entity.entity(newEntry, MediaType.APPLICATION_JSON)); 61 | assertThat(putResponse.getStatus(), is(204)); 62 | 63 | //fetch 64 | Response fetchResponse = this.mainTarget.path(name).request(MediaType.APPLICATION_JSON).get(Response.class); 65 | assertThat(fetchResponse.getStatus(), is(200)); 66 | JsonObject value = fetchResponse.readEntity(JsonObject.class); 67 | assertThat(value.getString("value"), is("42")); 68 | 69 | //removal 70 | Response deleteResponse = this.mainTarget.path(name).request(MediaType.APPLICATION_JSON).delete(); 71 | assertThat(deleteResponse.getStatus(), is(204)); 72 | 73 | //empty fetch 74 | Response emptyFetchResponse = this.mainTarget.path(name).request(MediaType.APPLICATION_JSON).get(Response.class); 75 | assertThat(emptyFetchResponse.getStatus(), is(204)); 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ftpservice/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.eftp 6 | e2ftp 7 | 0.0.3-SNAPSHOT 8 | 9 | org.eftp 10 | ftpservice 11 | 0.0.3-SNAPSHOT 12 | 13 | 14 | junit 15 | junit 16 | 4.10 17 | test 18 | 19 | 20 | org.eclipse.persistence 21 | eclipselink 22 | 2.5.0 23 | test 24 | 25 | 26 | org.apache.derby 27 | derby 28 | 10.10.1.1 29 | test 30 | 31 | 32 | javax 33 | javaee-api 34 | 7.0 35 | provided 36 | 37 | 38 | org.apache.ftpserver 39 | ftpserver-core 40 | 1.0.6 41 | compile 42 | 43 | 44 | org.slf4j 45 | slf4j-api 46 | 1.7.5 47 | compile 48 | 49 | 50 | org.slf4j 51 | slf4j-jdk14 52 | 1.7.5 53 | compile 54 | 55 | 56 | org.eftp 57 | ftpservice-api 58 | 0.0.3-SNAPSHOT 59 | compile 60 | 61 | 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-compiler-plugin 67 | 2.3.2 68 | 69 | 1.7 70 | 1.7 71 | 72 | 73 | 74 | ftpservice 75 | 76 | 77 | UTF-8 78 | 79 | 80 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/configuration/control/ConfigurationStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.configuration.control; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.List; 27 | import javax.inject.Inject; 28 | import javax.persistence.EntityManager; 29 | import javax.persistence.PersistenceContext; 30 | import javax.persistence.TypedQuery; 31 | import javax.persistence.criteria.CriteriaBuilder; 32 | import javax.persistence.criteria.CriteriaQuery; 33 | import javax.persistence.criteria.Root; 34 | import org.eftp.ftpserver.business.configuration.entity.ConfigurationEntry; 35 | import org.eftp.ftpserver.business.logger.boundary.Log; 36 | 37 | /** 38 | * 39 | * @author adam-bien.com 40 | */ 41 | public class ConfigurationStore { 42 | 43 | @PersistenceContext 44 | EntityManager em; 45 | 46 | @Inject 47 | Log LOG; 48 | 49 | public String find(String name) { 50 | ConfigurationEntry entry = findEntry(name); 51 | if (entry != null) { 52 | return entry.getValue(); 53 | } 54 | return null; 55 | 56 | } 57 | 58 | public ConfigurationEntry findEntry(String name) { 59 | return this.em.find(ConfigurationEntry.class, name); 60 | } 61 | 62 | public void setIfNotExist(String name, String value) { 63 | String actualValue = find(name); 64 | if (actualValue == null) { 65 | saveOrUpdate(name, value); 66 | LOG.info("Saving default value: " + name + " value " + value); 67 | } 68 | } 69 | 70 | public ConfigurationEntry saveOrUpdate(ConfigurationEntry entry) { 71 | return this.em.merge(entry); 72 | } 73 | 74 | public void remove(String name) { 75 | ConfigurationEntry ref = this.em.getReference(ConfigurationEntry.class, name); 76 | this.em.remove(ref); 77 | } 78 | 79 | public void saveOrUpdate(String name, String value) { 80 | saveOrUpdate(new ConfigurationEntry(name, value)); 81 | } 82 | 83 | public List allEntries() { 84 | CriteriaBuilder cb = em.getCriteriaBuilder(); 85 | CriteriaQuery cq = cb.createQuery(ConfigurationEntry.class); 86 | Root rootEntry = cq.from(ConfigurationEntry.class); 87 | CriteriaQuery all = cq.select(rootEntry); 88 | TypedQuery allQuery = em.createQuery(all); 89 | return allQuery.getResultList(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/hooks/boundary/EventBroadcastRessourceIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.io.IOException; 27 | import java.util.Timer; 28 | import java.util.TimerTask; 29 | import java.util.logging.Level; 30 | import java.util.logging.Logger; 31 | import javax.json.JsonObject; 32 | import javax.ws.rs.core.Response; 33 | import org.eftp.ftpserver.business.RESTSupport; 34 | import org.eftp.ftpserver.st.FTPServerWrapperIT; 35 | import static org.hamcrest.CoreMatchers.is; 36 | import static org.junit.Assert.assertNotNull; 37 | import static org.junit.Assert.assertThat; 38 | import org.junit.Before; 39 | import org.junit.Test; 40 | 41 | /** 42 | * 43 | * @author adam-bien.com 44 | */ 45 | public class EventBroadcastRessourceIT extends RESTSupport { 46 | 47 | private static final String CONFIGURATION_URI = "http://localhost:8080/ftpserver/api/events"; 48 | 49 | @Before 50 | @Override 51 | public void init() { 52 | super.init(CONFIGURATION_URI, "duke", "duke"); 53 | } 54 | 55 | @Test(timeout = 30000) 56 | public void receiveNotification() { 57 | Timer timer = new Timer(); 58 | timer.schedule(new TimerTask() { 59 | @Override 60 | public void run() { 61 | FTPServerWrapperIT wrapper = new FTPServerWrapperIT(); 62 | wrapper.init(); 63 | try { 64 | wrapper.sendAndReceive(); 65 | System.out.println("-----Sending and receiving----"); 66 | } catch (IOException ex) { 67 | throw new IllegalStateException("Cannot upload file", ex); 68 | } finally { 69 | try { 70 | wrapper.cleanup(); 71 | } catch (IOException ex) { 72 | Logger.getLogger(EventBroadcastRessourceIT.class.getName()).log(Level.SEVERE, null, ex); 73 | } 74 | } 75 | 76 | } 77 | }, 1000); 78 | System.out.println("-----Waiting for events----"); 79 | Response response = super.mainTarget.path("EVERYTHING").request().get(Response.class); 80 | assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode())); 81 | JsonObject readEvent = response.readEntity(JsonObject.class); 82 | assertNotNull(readEvent); 83 | timer.cancel(); 84 | timer.purge(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /hook-test-client/src/main/java/org/e2ftp/testclient/presentation/Index.java: -------------------------------------------------------------------------------- 1 | package org.e2ftp.testclient.presentation; 2 | 3 | /* 4 | * #%L 5 | * hook-test-client 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | 23 | import java.util.List; 24 | import javax.annotation.PostConstruct; 25 | import javax.enterprise.inject.Model; 26 | import javax.inject.Inject; 27 | import javax.json.JsonObject; 28 | import org.e2ftp.testclient.business.hooks.boundary.CallbacksResource; 29 | import org.e2ftp.testclient.business.hooks.boundary.HookMgmt; 30 | 31 | /** 32 | * 33 | * @author adam-bien.com 34 | */ 35 | @Model 36 | public class Index { 37 | 38 | private static final String HOOK_URI = "http://localhost:8080/ftpserver/api/hooks"; 39 | 40 | private String serverUri = HOOK_URI; 41 | private String callbackUri = "http://localhost:8080/hook-test-client/api/callbacks"; 42 | 43 | private String user; 44 | private String password; 45 | 46 | @Inject 47 | HookMgmt hookMgmt; 48 | 49 | @Inject 50 | CallbacksResource resource; 51 | 52 | @PostConstruct 53 | public void initialize() { 54 | this.user = "duke"; 55 | this.password = "duke"; 56 | } 57 | 58 | public String getServerUri() { 59 | return serverUri; 60 | } 61 | 62 | public void setServerUri(String serverUri) { 63 | this.serverUri = serverUri; 64 | } 65 | 66 | public String getCallbackUri() { 67 | return callbackUri; 68 | } 69 | 70 | public void setCallbackUri(String callbackUri) { 71 | this.callbackUri = callbackUri; 72 | } 73 | 74 | public String getUser() { 75 | return user; 76 | } 77 | 78 | public void setUser(String user) { 79 | this.user = user; 80 | } 81 | 82 | public String getPassword() { 83 | return password; 84 | } 85 | 86 | public void setPassword(String password) { 87 | this.password = password; 88 | } 89 | 90 | public String getCallback() { 91 | String retVal = "-nothing received yet-"; 92 | List list = resource.getCallbackObject(); 93 | if (!list.isEmpty()) { 94 | retVal = list.toString(); 95 | } 96 | return retVal; 97 | } 98 | 99 | public Object register() { 100 | this.hookMgmt.register(user, password, serverUri, callbackUri); 101 | return null; 102 | } 103 | 104 | public Object clear() { 105 | this.resource.clear(); 106 | return null; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/files/boundary/FilesIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.files.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.io.BufferedReader; 27 | import java.io.File; 28 | import java.io.FileReader; 29 | import java.io.IOException; 30 | import javax.ws.rs.client.Client; 31 | import javax.ws.rs.client.ClientBuilder; 32 | import javax.ws.rs.client.WebTarget; 33 | import javax.ws.rs.core.Response; 34 | import org.eftp.ftpserver.business.RESTSupport; 35 | import org.eftp.ftpserver.st.FTPServerWrapperIT; 36 | import static org.hamcrest.CoreMatchers.is; 37 | import static org.junit.Assert.assertThat; 38 | import static org.junit.Assert.assertTrue; 39 | import org.junit.Before; 40 | import org.junit.Test; 41 | 42 | /** 43 | * 44 | * @author adam-bien.com 45 | */ 46 | public class FilesIT extends RESTSupport { 47 | 48 | private static final String URI = "http://localhost:8080/ftpserver/api/files/"; 49 | 50 | private FTPServerWrapperIT support; 51 | 52 | @Before 53 | @Override 54 | public void init() { 55 | super.init(URI, "duke", "duke"); 56 | this.support = new FTPServerWrapperIT(); 57 | this.support.init(); 58 | } 59 | 60 | @Test 61 | public void downloadWithUnknownUser() { 62 | Client unauthenticated = ClientBuilder.newClient(); 63 | WebTarget unauthenticatedTarget = unauthenticated.target(URI); 64 | Response response = unauthenticatedTarget.path("-should-not-exist-").request().get(); 65 | assertThat(response.getStatus(), is(401)); 66 | } 67 | 68 | @Test 69 | public void downloadWithNotExistingFile() { 70 | Response response = super.mainTarget.path("-should-not-exist-").request().get(); 71 | assertThat(response.getStatus(), is(404)); 72 | } 73 | 74 | @Test 75 | public void downloadFile() throws IOException { 76 | String fileName = "download-test" + System.currentTimeMillis() + ".txt"; 77 | String content = "random content: " + System.currentTimeMillis(); 78 | this.support.connect(); 79 | this.support.sendFile(fileName, content); 80 | Response response = super.mainTarget.path(fileName).request().get(); 81 | assertThat(response.getStatus(), is(200)); 82 | assertTrue(response.bufferEntity()); 83 | File readFile = response.readEntity(File.class); 84 | FileReader reader = new FileReader(readFile); 85 | BufferedReader br = new BufferedReader(reader); 86 | String actual = br.readLine(); 87 | System.out.println("Read content: " + actual); 88 | assertThat(actual, is(content)); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/management/ManagementResourceIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.management; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.ws.rs.client.Entity; 27 | import javax.ws.rs.core.Form; 28 | import javax.ws.rs.core.MediaType; 29 | import javax.ws.rs.core.Response; 30 | import org.eftp.ftpserver.business.RESTSupport; 31 | import static org.hamcrest.CoreMatchers.is; 32 | import static org.junit.Assert.assertThat; 33 | import static org.junit.Assert.assertTrue; 34 | import static org.junit.Assert.assertFalse; 35 | import org.junit.Before; 36 | import org.junit.Test; 37 | 38 | /** 39 | * 40 | * @author ZeTo 41 | */ 42 | public class ManagementResourceIT extends RESTSupport { 43 | 44 | private static final String MANAGEMENT_URI = "http://localhost:8080/ftpserver/api/management"; 45 | 46 | @Override 47 | @Before 48 | public void init() { 49 | super.init(MANAGEMENT_URI, "duke", "duke"); 50 | // make sure server is started 51 | this.mainTarget.request(MediaType.WILDCARD).post(Entity.form(new Form())); 52 | } 53 | 54 | @Test 55 | public void checkServerIsRunning() { 56 | boolean isRunning = this.mainTarget.request(MediaType.WILDCARD).get(Boolean.class); 57 | assertTrue(isRunning); 58 | } 59 | 60 | @Test 61 | public void testStopServer() { 62 | Response stopServerResponse = this.mainTarget.request(MediaType.WILDCARD).delete(); 63 | assertThat(stopServerResponse.getStatus(), is(204)); 64 | } 65 | 66 | @Test 67 | public void testStartServer() { 68 | // stop the server 69 | Response stopServerResponse = this.mainTarget.request(MediaType.WILDCARD).delete(); 70 | assertThat(stopServerResponse.getStatus(), is(204)); 71 | 72 | // server should not run at this point 73 | boolean isRunning = this.mainTarget.request(MediaType.WILDCARD).get(Boolean.class); 74 | assertFalse(isRunning); 75 | 76 | // start it again 77 | Response startServerResponse = this.mainTarget.request(MediaType.WILDCARD).post(Entity.form(new Form())); 78 | assertThat(startServerResponse.getStatus(), is(204)); 79 | 80 | // check if server is running 81 | isRunning = this.mainTarget.request(MediaType.WILDCARD).get(Boolean.class); 82 | assertTrue(isRunning); 83 | } 84 | 85 | @Test 86 | public void testRestartServer() { 87 | // restart the server 88 | Response restartServerResponse = this.mainTarget.request(MediaType.WILDCARD).put(Entity.form(new Form())); 89 | assertThat(restartServerResponse.getStatus(), is(204)); 90 | 91 | // server should run after restart 92 | boolean isRunning = this.mainTarget.request(MediaType.WILDCARD).get(Boolean.class); 93 | assertTrue(isRunning); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/st/FTPServerWrapperIT.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.st; 2 | 3 | /* 4 | * #%L 5 | * ftpserver-st 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | 23 | import java.io.ByteArrayInputStream; 24 | import java.io.ByteArrayOutputStream; 25 | import java.io.IOException; 26 | import org.apache.commons.net.ftp.FTPClient; 27 | import org.apache.commons.net.ftp.FTPFile; 28 | import static org.hamcrest.CoreMatchers.is; 29 | import org.junit.After; 30 | import static org.junit.Assert.assertFalse; 31 | import static org.junit.Assert.assertNotNull; 32 | import static org.junit.Assert.assertThat; 33 | import static org.junit.Assert.assertTrue; 34 | import org.junit.Before; 35 | import org.junit.Test; 36 | 37 | public class FTPServerWrapperIT { 38 | 39 | private FTPClient client; 40 | private static final String HOST = "localhost"; 41 | private static final int PORT = 8888; 42 | private static final String USER = "duke"; 43 | private static final String PASSWORD = "duke"; 44 | 45 | @Before 46 | public void init() { 47 | this.client = new FTPClient(); 48 | } 49 | 50 | @Test 51 | public void connectAndDisconnect() throws IOException { 52 | this.client.connect(HOST, PORT); 53 | this.client.disconnect(); 54 | } 55 | 56 | @Test 57 | public void login() throws IOException { 58 | connect(); 59 | } 60 | 61 | @Test 62 | public void list() throws IOException { 63 | connect(); 64 | FTPFile[] listDirectories = this.client.listDirectories(); 65 | assertNotNull(listDirectories); 66 | assertTrue(listDirectories.length > 0); 67 | } 68 | 69 | @Test 70 | public void sendAndReceive() throws IOException { 71 | connect(); 72 | String remoteFile = "e2ftp-client" + System.currentTimeMillis() + ".txt"; 73 | final String expected = "just a test"; 74 | sendFile(remoteFile, expected); 75 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 76 | this.client.retrieveFile(remoteFile, baos); 77 | byte[] actual = baos.toByteArray(); 78 | assertNotNull(actual); 79 | assertThat(new String(actual), is(expected)); 80 | this.client.deleteFile(remoteFile); 81 | 82 | baos = new ByteArrayOutputStream(); 83 | boolean fileExists = this.client.retrieveFile(remoteFile, baos); 84 | assertFalse(fileExists); 85 | } 86 | 87 | public void sendFile(String file, String content) throws IOException { 88 | ByteArrayInputStream bais = new ByteArrayInputStream(content.getBytes()); 89 | this.client.storeFile(file, bais); 90 | } 91 | 92 | @After 93 | public void cleanup() throws IOException { 94 | this.client.disconnect(); 95 | } 96 | 97 | public void connect() throws IOException { 98 | this.client.connect(HOST, PORT); 99 | this.client.login(USER, PASSWORD); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/boot/boundary/FTPServerWrapper.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.boot.boundary; 2 | 3 | /* 4 | * #%L 5 | * ftpservice 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | import javax.annotation.PostConstruct; 23 | import javax.annotation.PreDestroy; 24 | import javax.ejb.DependsOn; 25 | import javax.ejb.Singleton; 26 | import javax.ejb.Startup; 27 | import javax.inject.Inject; 28 | import org.apache.ftpserver.ConnectionConfigFactory; 29 | import org.apache.ftpserver.FtpServer; 30 | import org.apache.ftpserver.ftplet.FtpException; 31 | import org.apache.ftpserver.impl.DefaultFtpServer; 32 | import org.apache.ftpserver.listener.ListenerFactory; 33 | import org.eftp.ftpserver.business.boot.control.ManagedFtpServerContext; 34 | import org.eftp.ftpserver.business.users.control.UserManagerIntegrationAdapter; 35 | 36 | /** 37 | * 38 | * @author adam-bien.com 39 | */ 40 | @Startup 41 | @Singleton 42 | @DependsOn("ConfigurationStartup") 43 | public class FTPServerWrapper { 44 | 45 | protected FtpServer ftpServer; 46 | @Inject 47 | protected int serverPort; 48 | @Inject 49 | protected int maxLogins; 50 | @Inject 51 | private boolean anonymousLoginEnabled; 52 | 53 | @Inject 54 | protected boolean startServerOnStartup; 55 | @Inject 56 | UserManagerIntegrationAdapter userManager; 57 | 58 | @Inject 59 | ManagedFtpServerContext managedContext; 60 | 61 | @PostConstruct 62 | public void init() { 63 | if (startServerOnStartup) { 64 | this.start(); 65 | } 66 | } 67 | 68 | @PreDestroy 69 | public void shutdown() { 70 | this.stop(); 71 | } 72 | 73 | public void start() { 74 | if (this.ftpServer == null || this.ftpServer.isStopped()) { 75 | ConnectionConfigFactory ccf = new ConnectionConfigFactory(); 76 | ccf.setMaxLogins(maxLogins); 77 | ccf.setAnonymousLoginEnabled(true); 78 | ccf.setMaxThreads(2); 79 | ccf.setMaxAnonymousLogins(maxLogins); 80 | this.managedContext.setConnectionConfig(ccf.createConnectionConfig()); 81 | this.managedContext.setUserManager(userManager); 82 | ListenerFactory factory = new ListenerFactory(); 83 | factory.setPort(serverPort); 84 | this.managedContext.addListener("default", factory.createListener()); 85 | this.ftpServer = new DefaultFtpServer(this.managedContext); 86 | try { 87 | this.ftpServer.start(); 88 | } catch (FtpException ex) { 89 | throw new IllegalStateException("Cannot start server: ", ex); 90 | } 91 | } 92 | } 93 | 94 | public void stop() { 95 | if (this.isRunning()) { 96 | this.ftpServer.stop(); 97 | } 98 | } 99 | 100 | public void restart() { 101 | this.stop(); 102 | this.start(); 103 | } 104 | 105 | public boolean isRunning() { 106 | return !this.ftpServer.isStopped(); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/control/UserManagerIntegrationAdapter.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.users.control; 2 | 3 | /* 4 | * #%L 5 | * ftpservice 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | 23 | import java.util.List; 24 | import javax.inject.Inject; 25 | import org.apache.ftpserver.ftplet.Authentication; 26 | import org.apache.ftpserver.ftplet.AuthenticationFailedException; 27 | import org.apache.ftpserver.ftplet.FtpException; 28 | import org.apache.ftpserver.ftplet.User; 29 | import org.apache.ftpserver.ftplet.UserManager; 30 | import org.apache.ftpserver.usermanager.AnonymousAuthentication; 31 | import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication; 32 | import org.eftp.ftpserver.business.users.boundary.JPAUserStore; 33 | import org.eftp.ftpserver.business.users.entity.FtpUser; 34 | 35 | /** 36 | * 37 | * @author adam-bien.com 38 | */ 39 | public class UserManagerIntegrationAdapter implements UserManager { 40 | 41 | @Inject 42 | JPAUserStore userStore; 43 | 44 | @Override 45 | public User getUserByName(String string) throws FtpException { 46 | return userStore.find(string).getBaseUser(); 47 | 48 | } 49 | 50 | @Override 51 | public String[] getAllUserNames() throws FtpException { 52 | List allUsers = this.userStore.allUsers(); 53 | String userNames[] = new String[allUsers.size()]; 54 | int counter = 0; 55 | for (FtpUser ftpUser : allUsers) { 56 | userNames[counter++] = ftpUser.getUserName(); 57 | } 58 | return userNames; 59 | } 60 | 61 | @Override 62 | public void delete(String userName) throws FtpException { 63 | this.userStore.remove(userName); 64 | } 65 | 66 | @Override 67 | public void save(User user) throws FtpException { 68 | throw new UnsupportedOperationException("User management only supported through JPA store"); 69 | } 70 | 71 | @Override 72 | public boolean doesExist(String userName) throws FtpException { 73 | FtpUser found = this.userStore.find(userName); 74 | return found != null; 75 | } 76 | 77 | @Override 78 | public User authenticate(Authentication a) throws AuthenticationFailedException { 79 | if (a instanceof UsernamePasswordAuthentication) { 80 | UsernamePasswordAuthentication upa = (UsernamePasswordAuthentication) a; 81 | FtpUser user = this.userStore.find(upa.getUsername(), upa.getPassword()); 82 | return user.getBaseUser(); 83 | } else if (a instanceof AnonymousAuthentication) { 84 | FtpUser found = this.userStore.find("anonymous"); 85 | if (found != null) { 86 | return found.getBaseUser(); 87 | } 88 | 89 | } 90 | return null; 91 | } 92 | 93 | @Override 94 | public String getAdminName() throws FtpException { 95 | FtpUser adminUser = this.userStore.findAdmin(); 96 | if (adminUser != null) { 97 | return adminUser.getUserName(); 98 | } 99 | return null; 100 | } 101 | 102 | @Override 103 | public boolean isAdmin(String userName) throws FtpException { 104 | return this.userStore.isAdmin(userName); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /ftpservice-api/src/main/java/org/eftp/events/FtpEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.events; 5 | 6 | /* 7 | * #%L 8 | * ftpservice-api 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import javax.json.Json; 27 | import javax.json.JsonObject; 28 | import javax.json.JsonObjectBuilder; 29 | import org.apache.ftpserver.ftplet.FtpRequest; 30 | import org.apache.ftpserver.ftplet.FtpSession; 31 | import org.apache.ftpserver.ftplet.User; 32 | 33 | /** 34 | * 35 | * @author adam-bien.com 36 | */ 37 | public class FtpEvent { 38 | 39 | private final FtpSession session; 40 | private final FtpRequest request; 41 | private final FtpEventName command; 42 | 43 | public FtpEvent(FtpEventName command, FtpSession session, FtpRequest request) { 44 | this.command = command; 45 | this.session = session; 46 | this.request = request; 47 | } 48 | 49 | public FtpEvent(FtpEventName command, FtpSession session) { 50 | this(command, session, null); 51 | } 52 | 53 | public FtpEvent(FtpSession session) { 54 | this(FtpEventName.EVERYTHING, session, null); 55 | } 56 | 57 | public FtpSession getSession() { 58 | return session; 59 | } 60 | 61 | public FtpRequest getRequest() { 62 | return request; 63 | } 64 | 65 | public FtpEventName getCommand() { 66 | return command; 67 | } 68 | 69 | public String getRequestCommand() { 70 | if (this.request == null) { 71 | return null; 72 | } 73 | return this.request.getCommand(); 74 | } 75 | 76 | public String getRequestLine() { 77 | if (this.request == null) { 78 | return null; 79 | } 80 | return this.request.getRequestLine(); 81 | } 82 | 83 | public String getArgument() { 84 | if (this.request == null) { 85 | return null; 86 | } 87 | return this.request.getArgument(); 88 | } 89 | 90 | public User getUser() { 91 | if (this.session == null) { 92 | return null; 93 | } 94 | return this.session.getUser(); 95 | } 96 | 97 | @Override 98 | public String toString() { 99 | return "FtpEvent{" + "session=" + session + ", request=" + request + '}'; 100 | } 101 | 102 | public JsonObject asJson() { 103 | User user = this.getUser(); 104 | String ftpCommand = this.getRequestCommand(); 105 | JsonObjectBuilder builder = Json.createObjectBuilder(); 106 | if (ftpCommand != null) { 107 | builder.add("ftpCommand", ftpCommand); 108 | } 109 | 110 | if (request != null) { 111 | if (request.hasArgument()) { 112 | builder.add("ftpArgument", request.getArgument()); 113 | } 114 | } 115 | if (user != null) { 116 | builder.add("userName", user.getName()); 117 | builder.add("homeDirectory", user.getHomeDirectory()); 118 | } 119 | if (session != null) { 120 | String clientAddress = session.getClientAddress().getHostString(); 121 | builder.add("clientAddress", clientAddress); 122 | } 123 | builder.add("command", this.command.name()); 124 | return builder.build(); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /ftpserver/src/main/java/org/eftp/ftpserver/business/hooks/boundary/EventBroadcastRessource.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.hooks.boundary; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.concurrent.TimeUnit; 7 | import java.util.logging.Logger; 8 | import javax.ejb.ConcurrencyManagement; 9 | import javax.ejb.ConcurrencyManagementType; 10 | import javax.ejb.Singleton; 11 | import javax.enterprise.event.Observes; 12 | import javax.inject.Inject; 13 | import javax.json.JsonObject; 14 | import javax.ws.rs.GET; 15 | import javax.ws.rs.Path; 16 | import javax.ws.rs.PathParam; 17 | import javax.ws.rs.Produces; 18 | import javax.ws.rs.container.AsyncResponse; 19 | import javax.ws.rs.container.Suspended; 20 | import javax.ws.rs.container.TimeoutHandler; 21 | import javax.ws.rs.core.MediaType; 22 | import javax.ws.rs.core.Response; 23 | import org.eftp.events.Command; 24 | import org.eftp.events.FtpEvent; 25 | import org.eftp.events.FtpEventName; 26 | 27 | /** 28 | * 29 | * @author adam-bien.com 30 | */ 31 | @Path("events") 32 | @Singleton 33 | @Produces(MediaType.APPLICATION_JSON) 34 | @ConcurrencyManagement(ConcurrencyManagementType.BEAN) 35 | public class EventBroadcastRessource { 36 | 37 | private final ConcurrentHashMap> listeners = new ConcurrentHashMap<>(); 38 | private final static int TIMEOUT_IN_SECONDS = 20; 39 | 40 | @Inject 41 | Logger LOG; 42 | 43 | @GET 44 | @Path("{event-name}") 45 | public void registerForNotifications(@PathParam("event-name") String name, 46 | @Suspended AsyncResponse response) { 47 | FtpEventName commandName = FtpEventName.valueOf(name.toUpperCase()); 48 | registerListener(commandName, response); 49 | setupTimeout(commandName, response); 50 | 51 | } 52 | 53 | public void onFtpEventArrival(@Observes @Command FtpEvent event) { 54 | List commandListeners = findListenersForCommand(event); 55 | final FtpEventName command = event.getCommand(); 56 | LOG.info("Received listeners " + commandListeners + " for command: " + command); 57 | JsonObject jsonEvent = event.asJson(); 58 | for (AsyncResponse asyncResponse : commandListeners) { 59 | asyncResponse.resume(jsonEvent); 60 | cleanup(command, asyncResponse); 61 | } 62 | } 63 | 64 | List findListenersForCommand(FtpEvent event) { 65 | List retVal = new ArrayList<>(); 66 | List jokers = listeners.get(FtpEventName.EVERYTHING); 67 | List specific = listeners.get(event.getCommand()); 68 | if (jokers != null) { 69 | retVal.addAll(jokers); 70 | } 71 | if (specific != null) { 72 | retVal.addAll(specific); 73 | } 74 | return retVal; 75 | } 76 | 77 | void setupTimeout(final FtpEventName commandName, AsyncResponse response) { 78 | response.setTimeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS); 79 | response.setTimeoutHandler(new TimeoutHandler() { 80 | 81 | @Override 82 | public void handleTimeout(AsyncResponse asyncResponse) { 83 | asyncResponse.resume(Response.status(Response.Status.NO_CONTENT).build()); 84 | cleanup(commandName, asyncResponse); 85 | } 86 | }); 87 | } 88 | 89 | void registerListener(FtpEventName commandName, AsyncResponse response) { 90 | List commandListeners = listeners.get(commandName); 91 | if (commandListeners == null) { 92 | commandListeners = new ArrayList<>(); 93 | listeners.put(commandName, commandListeners); 94 | } 95 | LOG.info("Registering listener for: " + commandName); 96 | commandListeners.add(response); 97 | } 98 | 99 | void cleanup(FtpEventName commandName, AsyncResponse response) { 100 | List commandListeners = listeners.get(commandName); 101 | if (commandListeners != null) { 102 | commandListeners.remove(response); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/entity/FtpUser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.entity; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | import javax.persistence.CascadeType; 29 | import javax.persistence.Column; 30 | import javax.persistence.Entity; 31 | import javax.persistence.Id; 32 | import javax.persistence.JoinColumn; 33 | import javax.persistence.NamedQueries; 34 | import javax.persistence.NamedQuery; 35 | import javax.persistence.OneToMany; 36 | import org.apache.ftpserver.ftplet.Authority; 37 | import org.apache.ftpserver.usermanager.impl.BaseUser; 38 | import static org.eftp.ftpserver.business.users.control.Digester.computeHash; 39 | 40 | /** 41 | * 42 | * @author adam-bien.com 43 | */ 44 | @Entity 45 | @NamedQueries({ 46 | @NamedQuery(name = FtpUser.isAdmin, query = "SELECT f FROM FtpUser f where f.admin = TRUE"), 47 | @NamedQuery(name = FtpUser.authenticate, query = "SELECT f FROM FtpUser f where f.userName = :userName and f.password = :password"),}) 48 | public class FtpUser { 49 | 50 | private static final String PREFIX = "org.eftp.ftpserver.business.users.entity.FtpUser."; 51 | public static final String isAdmin = PREFIX + "isAdmin"; 52 | public static final String authenticate = PREFIX + "authenticate"; 53 | 54 | @Id 55 | @Column(name = "c_username") 56 | private String userName; 57 | private String password; 58 | 59 | @Column(name = "c_admin") 60 | private boolean admin; 61 | private int maxIdleTimeSec; 62 | private String homeDir; 63 | private boolean enabled; 64 | 65 | @JoinColumn(name = "c_username") 66 | @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) 67 | private List permissions; 68 | 69 | @OneToMany 70 | @JoinColumn(name = "c_username") 71 | private List groups; 72 | 73 | public FtpUser(String userName, String password) { 74 | this(); 75 | this.userName = userName; 76 | this.password = computeHash(password); 77 | } 78 | 79 | public FtpUser() { 80 | this.groups = new ArrayList<>(); 81 | this.permissions = new ArrayList<>(); 82 | } 83 | 84 | public boolean changePassword(String oldPassword, String newPassword) { 85 | String oldHashed = computeHash(oldPassword); 86 | String newHashed = computeHash(newPassword); 87 | if (this.password.equals(oldHashed)) { 88 | this.password = newHashed; 89 | return true; 90 | } else { 91 | return false; 92 | } 93 | } 94 | 95 | public String getUserName() { 96 | return userName; 97 | } 98 | 99 | public String getPassword() { 100 | return password; 101 | } 102 | 103 | public int getMaxIdleTimeSec() { 104 | return maxIdleTimeSec; 105 | } 106 | 107 | public void setMaxIdleTimeSec(int maxIdleTimeSec) { 108 | this.maxIdleTimeSec = maxIdleTimeSec; 109 | } 110 | 111 | public String getHomeDir() { 112 | return homeDir; 113 | } 114 | 115 | public void setHomeDir(String homeDir) { 116 | this.homeDir = homeDir; 117 | } 118 | 119 | public boolean isIsEnabled() { 120 | return enabled; 121 | } 122 | 123 | public void setIsEnabled(boolean isEnabled) { 124 | this.enabled = isEnabled; 125 | } 126 | 127 | public void addPermission(FtpPermission permission) { 128 | this.permissions.add(permission); 129 | } 130 | 131 | public void addGroup(FtpGroup group) { 132 | this.groups.add(group); 133 | } 134 | 135 | public boolean isAdmin() { 136 | return admin; 137 | } 138 | 139 | public void setAdmin(boolean admin) { 140 | this.admin = admin; 141 | } 142 | 143 | public BaseUser getBaseUser() { 144 | BaseUser baseUser = new BaseUser(); 145 | baseUser.setHomeDirectory(homeDir); 146 | baseUser.setName(userName); 147 | baseUser.setPassword(password); 148 | baseUser.setMaxIdleTime(maxIdleTimeSec); 149 | baseUser.setEnabled(this.enabled); 150 | baseUser.setAuthorities(getAuthorities()); 151 | return baseUser; 152 | } 153 | 154 | public List getAuthorities() { 155 | List retVal = new ArrayList<>(); 156 | for (FtpPermission permission : this.permissions) { 157 | retVal.add(permission.getAuthority()); 158 | } 159 | return retVal; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /ftpserver-st/src/test/java/org/eftp/ftpserver/business/hooks/boundary/HooksResourceIT.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.hooks.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpserver-st 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.List; 27 | import javax.json.Json; 28 | import javax.json.JsonArray; 29 | import javax.json.JsonObject; 30 | import javax.ws.rs.client.Entity; 31 | import javax.ws.rs.core.MediaType; 32 | import javax.ws.rs.core.Response; 33 | import org.eftp.ftpserver.business.RESTSupport; 34 | import static org.hamcrest.CoreMatchers.is; 35 | import static org.junit.Assert.assertNotNull; 36 | import static org.junit.Assert.assertThat; 37 | import org.junit.Before; 38 | import org.junit.Test; 39 | 40 | /** 41 | * 42 | * @author adam-bien.com 43 | */ 44 | public class HooksResourceIT extends RESTSupport { 45 | 46 | private static final String CONFIGURATION_URI = "http://localhost:8080/ftpserver/api/hooks"; 47 | 48 | @Before 49 | @Override 50 | public void init() { 51 | super.init(CONFIGURATION_URI, "duke", "duke"); 52 | } 53 | 54 | @Test 55 | public void crud() { 56 | JsonArray allEntries = this.mainTarget.request(MediaType.APPLICATION_JSON).get(JsonArray.class); 57 | assertNotNull(allEntries); 58 | System.out.println("-- " + allEntries); 59 | final String createdUri = "http://localhost" + System.currentTimeMillis(); 60 | 61 | //creation 62 | JsonObject newEntry = Json.createObjectBuilder().add("command", "everything").add("uri", createdUri).build(); 63 | Response postResponse = this.mainTarget.request().post(Entity.entity(newEntry, MediaType.APPLICATION_JSON)); 64 | assertThat(postResponse.getStatus(), is(201)); 65 | List locationValues = postResponse.getHeaders().get("Location"); 66 | assertThat(locationValues.size(), is(1)); 67 | String uri = (String) locationValues.get(0); 68 | System.out.println("---------> " + uri); 69 | //fetch 70 | Response fetchResponse = this.client.target(uri).request(MediaType.APPLICATION_JSON).get(Response.class); 71 | assertThat(fetchResponse.getStatus(), is(200)); 72 | JsonObject value = fetchResponse.readEntity(JsonObject.class); 73 | assertThat(value.getString("uri"), is(createdUri)); 74 | long id = value.getJsonNumber("id").longValue(); 75 | System.out.println("id --->" + id); 76 | 77 | //removal 78 | Response deleteResponse = this.mainTarget.path(String.valueOf(id)).request(MediaType.APPLICATION_JSON).delete(); 79 | assertThat(deleteResponse.getStatus(), is(204)); 80 | 81 | //empty fetch 82 | Response emptyFetchResponse = this.mainTarget.path(String.valueOf(id)).request(MediaType.APPLICATION_JSON).get(Response.class); 83 | assertThat(emptyFetchResponse.getStatus(), is(204)); 84 | } 85 | 86 | @Test 87 | public void creationWithInvalidURI() { 88 | final String createdUri = "INVALID" + System.currentTimeMillis(); 89 | //creation 90 | JsonObject newEntry = Json.createObjectBuilder().add("command", "everything").add("uri", createdUri).build(); 91 | Response putResponse = this.mainTarget.request().post(Entity.entity(newEntry, MediaType.APPLICATION_JSON)); 92 | assertThat(putResponse.getStatus(), is(Response.Status.BAD_REQUEST.getStatusCode())); 93 | } 94 | 95 | @Test 96 | public void creationWithoutCommand() { 97 | final String createdUri = "http://localhost" + System.currentTimeMillis(); 98 | //creation 99 | JsonObject newEntry = Json.createObjectBuilder().add("uri", createdUri).build(); 100 | 101 | Response postResponse = this.mainTarget.request().post(Entity.entity(newEntry, MediaType.APPLICATION_JSON)); 102 | assertThat(postResponse.getStatus(), is(201)); 103 | 104 | List locationValues = postResponse.getHeaders().get("Location"); 105 | assertThat(locationValues.size(), is(1)); 106 | String uri = (String) locationValues.get(0); 107 | 108 | //fetch 109 | Response fetchResponse = this.client.target(uri).request(MediaType.APPLICATION_JSON).get(Response.class); 110 | assertThat(fetchResponse.getStatus(), is(200)); 111 | JsonObject value = fetchResponse.readEntity(JsonObject.class); 112 | assertThat(value.getString("command"), is("EVERYTHING")); 113 | 114 | //cleanup 115 | Response deleteResponse = this.client.target(uri).request(MediaType.APPLICATION_JSON).delete(); 116 | assertThat(deleteResponse.getStatus(), is(204)); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/users/boundary/JPAUserStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.users.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.util.List; 27 | import javax.ejb.Stateless; 28 | import javax.inject.Inject; 29 | import javax.persistence.EntityManager; 30 | import javax.persistence.PersistenceContext; 31 | import javax.persistence.TypedQuery; 32 | import javax.persistence.criteria.CriteriaBuilder; 33 | import javax.persistence.criteria.CriteriaQuery; 34 | import javax.persistence.criteria.Root; 35 | import org.eftp.ftpserver.business.logger.boundary.Log; 36 | import org.eftp.ftpserver.business.users.control.Digester; 37 | import org.eftp.ftpserver.business.users.entity.FtpConcurrentLoginPermission; 38 | import org.eftp.ftpserver.business.users.entity.FtpGroup; 39 | import org.eftp.ftpserver.business.users.entity.FtpUser; 40 | import org.eftp.ftpserver.business.users.entity.FtpWritePermission; 41 | 42 | /** 43 | * 44 | * @author adam-bien.com 45 | */ 46 | @Stateless 47 | public class JPAUserStore { 48 | 49 | @PersistenceContext 50 | EntityManager em; 51 | 52 | @Inject 53 | Log LOG; 54 | 55 | private static final String DEFAULT_USER_DIRECTORY = System.getProperty("java.io.tmpdir"); 56 | private static final int DEFAULT_NUMBER_OF_CONCURRENT_LOGINS = 8; 57 | private static final int DEFAULT_NUMBER_OF_CONCURRENT_LOGINS_FROM_SAME_IP = 8; 58 | 59 | public FtpUser find(String userName) { 60 | return this.em.find(FtpUser.class, userName); 61 | } 62 | 63 | public FtpUser findAdmin() { 64 | return this.em.createNamedQuery(FtpUser.isAdmin, FtpUser.class).getSingleResult(); 65 | } 66 | 67 | public void create(FtpUser user) { 68 | this.em.persist(user); 69 | } 70 | 71 | public void remove(String userName) { 72 | FtpUser user = this.em.getReference(FtpUser.class, userName); 73 | this.em.remove(user); 74 | } 75 | 76 | public boolean changePassword(String userName, String oldPassword, String newPassword) { 77 | FtpUser user = find(userName); 78 | return user.changePassword(oldPassword, newPassword); 79 | } 80 | 81 | public void createDefaultUser() { 82 | if (allUsers().isEmpty()) { 83 | LOG.info("Userstore is empty, creating the default user"); 84 | FtpUser defaultUser = getDefaultUser("duke", "duke"); 85 | em.persist(defaultUser); 86 | } else { 87 | LOG.info("At least a user already exists, nothing todo"); 88 | } 89 | } 90 | 91 | public FtpUser getDefaultUser(String user, String password) { 92 | FtpGroup adminGroup = new FtpGroup(); 93 | adminGroup.setName("admin"); 94 | adminGroup = this.em.merge(adminGroup); 95 | 96 | FtpGroup listenerGroup = new FtpGroup(); 97 | listenerGroup.setName("listener"); 98 | listenerGroup = this.em.merge(listenerGroup); 99 | 100 | FtpGroup userGroup = new FtpGroup(); 101 | userGroup.setName("user"); 102 | userGroup = this.em.merge(userGroup); 103 | 104 | FtpUser defaultUser = new FtpUser(user, password); 105 | defaultUser.addGroup(userGroup); 106 | defaultUser.addGroup(listenerGroup); 107 | defaultUser.addGroup(adminGroup); 108 | defaultUser.setIsEnabled(true); 109 | defaultUser.setHomeDir(DEFAULT_USER_DIRECTORY); 110 | defaultUser.addPermission(new FtpWritePermission()); 111 | defaultUser.addPermission(new FtpConcurrentLoginPermission(DEFAULT_NUMBER_OF_CONCURRENT_LOGINS, DEFAULT_NUMBER_OF_CONCURRENT_LOGINS_FROM_SAME_IP)); 112 | defaultUser.setMaxIdleTimeSec(3600); 113 | return defaultUser; 114 | } 115 | 116 | public List allUsers() { 117 | CriteriaBuilder cb = em.getCriteriaBuilder(); 118 | CriteriaQuery cq = cb.createQuery(FtpUser.class); 119 | Root rootEntry = cq.from(FtpUser.class); 120 | CriteriaQuery all = cq.select(rootEntry); 121 | TypedQuery allQuery = em.createQuery(all); 122 | return allQuery.getResultList(); 123 | } 124 | 125 | public boolean isAdmin(String userName) { 126 | FtpUser user = find(userName); 127 | return (user != null && user.isAdmin()); 128 | 129 | } 130 | 131 | public FtpUser find(String username, String password) { 132 | String hashed = Digester.computeHash(password); 133 | return this.em.createNamedQuery(FtpUser.authenticate, FtpUser.class).setParameter("userName", username).setParameter("password", hashed).getSingleResult(); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/boot/control/ManagedFtpServerContext.java: -------------------------------------------------------------------------------- 1 | package org.eftp.ftpserver.business.boot.control; 2 | 3 | /* 4 | * #%L 5 | * ftpservice 6 | * %% 7 | * Copyright (C) 2013 e2ftp 8 | * %% 9 | * Licensed under the Apache License, Version 2.0 (the "License"); 10 | * you may not use this file except in compliance with the License. 11 | * You may obtain a copy of the License at 12 | * 13 | * http://www.apache.org/licenses/LICENSE-2.0 14 | * 15 | * Unless required by applicable law or agreed to in writing, software 16 | * distributed under the License is distributed on an "AS IS" BASIS, 17 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | * See the License for the specific language governing permissions and 19 | * limitations under the License. 20 | * #L% 21 | */ 22 | 23 | import java.util.Map; 24 | import java.util.concurrent.BlockingQueue; 25 | import java.util.concurrent.ThreadPoolExecutor; 26 | import javax.annotation.PostConstruct; 27 | import javax.annotation.Resource; 28 | import javax.ejb.ConcurrencyManagement; 29 | import javax.ejb.ConcurrencyManagementType; 30 | import javax.ejb.LocalBean; 31 | import javax.ejb.Singleton; 32 | import javax.enterprise.concurrent.ManagedThreadFactory; 33 | import javax.enterprise.inject.Instance; 34 | import javax.enterprise.inject.Produces; 35 | import javax.inject.Inject; 36 | import javax.interceptor.Interceptors; 37 | import org.apache.ftpserver.ConnectionConfig; 38 | import org.apache.ftpserver.command.CommandFactory; 39 | import org.apache.ftpserver.ftplet.FileSystemFactory; 40 | import org.apache.ftpserver.ftplet.FtpStatistics; 41 | import org.apache.ftpserver.ftplet.Ftplet; 42 | import org.apache.ftpserver.ftplet.UserManager; 43 | import org.apache.ftpserver.ftpletcontainer.FtpletContainer; 44 | import org.apache.ftpserver.ftpletcontainer.impl.DefaultFtpletContainer; 45 | import org.apache.ftpserver.impl.DefaultFtpServerContext; 46 | import org.apache.ftpserver.impl.FtpServerContext; 47 | import org.apache.ftpserver.listener.Listener; 48 | import org.apache.ftpserver.message.MessageResource; 49 | import org.eftp.ftpserver.business.files.boundary.InstrumendFileSystemFactory; 50 | import org.eftp.ftpserver.business.logger.boundary.Log; 51 | import org.eftp.ftpserver.business.monitoring.boundary.CallTracker; 52 | import org.eftp.ftpserver.business.plugins.boundary.Plugin; 53 | import org.eftp.ftpserver.business.users.control.UserManagerIntegrationAdapter; 54 | 55 | /** 56 | * 57 | * @author adam-bien.com 58 | */ 59 | @LocalBean 60 | @Singleton 61 | @Interceptors(CallTracker.class) 62 | @ConcurrencyManagement(ConcurrencyManagementType.BEAN) 63 | public class ManagedFtpServerContext implements FtpServerContext { 64 | 65 | BlockingQueue workQueue; 66 | 67 | @Resource 68 | ManagedThreadFactory threadFactory; 69 | 70 | @Inject 71 | InstrumendFileSystemFactory fileSystemFactory; 72 | 73 | private DefaultFtpServerContext delegate; 74 | 75 | @Inject 76 | private ThreadPoolExecutor executor; 77 | 78 | private DefaultFtpletContainer ftpletContainer; 79 | 80 | @Inject 81 | @Plugin 82 | private Instance hooks; 83 | 84 | @Inject 85 | Log LOG; 86 | 87 | @PostConstruct 88 | public void init() { 89 | this.delegate = new DefaultFtpServerContext(); 90 | this.delegate.setFileSystemManager(fileSystemFactory); 91 | this.ftpletContainer = (DefaultFtpletContainer) this.delegate.getFtpletContainer(); 92 | this.installPlugins(); 93 | } 94 | 95 | @Override 96 | public ConnectionConfig getConnectionConfig() { 97 | return delegate.getConnectionConfig(); 98 | } 99 | 100 | @Override 101 | public MessageResource getMessageResource() { 102 | return delegate.getMessageResource(); 103 | } 104 | 105 | @Override 106 | public FtpletContainer getFtpletContainer() { 107 | return delegate.getFtpletContainer(); 108 | } 109 | 110 | @Override 111 | public Listener getListener(String string) { 112 | return delegate.getListener(string); 113 | } 114 | 115 | @Override 116 | public Map getListeners() { 117 | return delegate.getListeners(); 118 | } 119 | 120 | @Override 121 | public CommandFactory getCommandFactory() { 122 | return delegate.getCommandFactory(); 123 | } 124 | 125 | @Override 126 | public void dispose() { 127 | delegate.dispose(); 128 | } 129 | 130 | @Override 131 | public UserManager getUserManager() { 132 | return delegate.getUserManager(); 133 | } 134 | 135 | @Override 136 | public FileSystemFactory getFileSystemManager() { 137 | return this.fileSystemFactory; 138 | } 139 | 140 | @Override 141 | @Produces 142 | public FtpStatistics getFtpStatistics() { 143 | return delegate.getFtpStatistics(); 144 | } 145 | 146 | @Override 147 | public Ftplet getFtplet(String string) { 148 | return delegate.getFtplet(string); 149 | } 150 | 151 | @Override 152 | public ThreadPoolExecutor getThreadPoolExecutor() { 153 | return this.executor; 154 | } 155 | 156 | public void setConnectionConfig(ConnectionConfig createConnectionConfig) { 157 | this.delegate.setConnectionConfig(createConnectionConfig); 158 | } 159 | 160 | public void setUserManager(UserManagerIntegrationAdapter userManager) { 161 | this.delegate.setUserManager(userManager); 162 | } 163 | 164 | public void addListener(String adefault, Listener createListener) { 165 | this.delegate.addListener(adefault, createListener); 166 | } 167 | 168 | void installPlugins() { 169 | for (Ftplet ftplet : hooks) { 170 | LOG.info("Installing: " + ftplet); 171 | this.ftpletContainer.getFtplets().put(ftplet.getClass().getName(), ftplet); 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /ftpservice/src/main/java/org/eftp/ftpserver/business/plugins/boundary/FtpletHook.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | */ 4 | package org.eftp.ftpserver.business.plugins.boundary; 5 | 6 | /* 7 | * #%L 8 | * ftpservice 9 | * %% 10 | * Copyright (C) 2013 e2ftp 11 | * %% 12 | * Licensed under the Apache License, Version 2.0 (the "License"); 13 | * you may not use this file except in compliance with the License. 14 | * You may obtain a copy of the License at 15 | * 16 | * http://www.apache.org/licenses/LICENSE-2.0 17 | * 18 | * Unless required by applicable law or agreed to in writing, software 19 | * distributed under the License is distributed on an "AS IS" BASIS, 20 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 | * See the License for the specific language governing permissions and 22 | * limitations under the License. 23 | * #L% 24 | */ 25 | 26 | import java.io.IOException; 27 | import javax.enterprise.event.Event; 28 | import javax.inject.Inject; 29 | import org.apache.ftpserver.ftplet.DefaultFtplet; 30 | import org.apache.ftpserver.ftplet.FtpException; 31 | import org.apache.ftpserver.ftplet.FtpRequest; 32 | import org.apache.ftpserver.ftplet.FtpSession; 33 | import org.apache.ftpserver.ftplet.FtpletResult; 34 | import org.eftp.events.Command; 35 | import org.eftp.events.FtpEvent; 36 | import org.eftp.events.FtpEventName; 37 | import org.eftp.ftpserver.business.plugins.entity.CommandInstance; 38 | 39 | /** 40 | * 41 | * @author adam-bien.com 42 | */ 43 | @Plugin 44 | public class FtpletHook extends DefaultFtplet { 45 | 46 | @Inject 47 | Event events; 48 | 49 | @Inject 50 | @Command 51 | Event all; 52 | 53 | @Override 54 | public FtpletResult onLogin(FtpSession session, FtpRequest request) throws FtpException, IOException { 55 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.LOGIN, session, request); 56 | this.broadcast(ftpEvent); 57 | return super.onLogin(session, request); 58 | } 59 | 60 | @Override 61 | public FtpletResult onSite(FtpSession session, FtpRequest request) throws FtpException, IOException { 62 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.SITE, session, request); 63 | this.broadcast(ftpEvent); 64 | return super.onSite(session, request); 65 | } 66 | 67 | @Override 68 | public FtpletResult onRenameEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 69 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.RENAME_END, session, request); 70 | this.broadcast(ftpEvent); 71 | return super.onRenameEnd(session, request); 72 | } 73 | 74 | @Override 75 | public FtpletResult onRenameStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 76 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.RENAME_END, session, request); 77 | this.broadcast(ftpEvent); 78 | return super.onRenameStart(session, request); 79 | } 80 | 81 | @Override 82 | public FtpletResult onUploadUniqueEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 83 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.UPLOAD_UNIQUE_END, session, request); 84 | this.broadcast(ftpEvent); 85 | return super.onUploadUniqueEnd(session, request); 86 | } 87 | 88 | @Override 89 | public FtpletResult onUploadUniqueStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 90 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.UPLOAD_UNIQUE_START, session, request); 91 | this.broadcast(ftpEvent); 92 | return super.onUploadUniqueStart(session, request); 93 | } 94 | 95 | @Override 96 | public FtpletResult onAppendEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 97 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.APPEND_END, session, request); 98 | this.broadcast(ftpEvent); 99 | return super.onAppendEnd(session, request); 100 | } 101 | 102 | @Override 103 | public FtpletResult onAppendStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 104 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.APPEND_START, session, request); 105 | this.broadcast(ftpEvent); 106 | return super.onAppendStart(session, request); 107 | } 108 | 109 | @Override 110 | public FtpletResult onMkdirEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 111 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.MKDIR_END, session, request); 112 | this.broadcast(ftpEvent); 113 | return super.onMkdirEnd(session, request); 114 | } 115 | 116 | @Override 117 | public FtpletResult onMkdirStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 118 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.MKDIR_START, session, request); 119 | this.broadcast(ftpEvent); 120 | return super.onMkdirStart(session, request); 121 | } 122 | 123 | @Override 124 | public FtpletResult onRmdirEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 125 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.RMDIR_END, session, request); 126 | this.broadcast(ftpEvent); 127 | return super.onRmdirEnd(session, request); 128 | } 129 | 130 | @Override 131 | public FtpletResult onRmdirStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 132 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.RMDIR_START, session, request); 133 | this.broadcast(ftpEvent); 134 | return super.onRmdirStart(session, request); 135 | } 136 | 137 | @Override 138 | public FtpletResult onDownloadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 139 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.DOWNLOAD_END, session, request); 140 | this.broadcast(ftpEvent); 141 | return super.onDownloadEnd(session, request); 142 | } 143 | 144 | @Override 145 | public FtpletResult onDownloadStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 146 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.DOWNLOAD_START, session, request); 147 | this.broadcast(ftpEvent); 148 | return super.onDownloadStart(session, request); 149 | } 150 | 151 | @Override 152 | public FtpletResult onUploadEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 153 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.UPLOAD_END, session, request); 154 | this.broadcast(ftpEvent); 155 | return super.onUploadEnd(session, request); 156 | } 157 | 158 | @Override 159 | public FtpletResult onUploadStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 160 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.UPLOAD_START, session, request); 161 | this.broadcast(ftpEvent); 162 | return super.onUploadStart(session, request); 163 | } 164 | 165 | @Override 166 | public FtpletResult onDeleteEnd(FtpSession session, FtpRequest request) throws FtpException, IOException { 167 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.DELETE_END, session, request); 168 | this.broadcast(ftpEvent); 169 | return super.onDeleteEnd(session, request); 170 | } 171 | 172 | @Override 173 | public FtpletResult onDeleteStart(FtpSession session, FtpRequest request) throws FtpException, IOException { 174 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.DELETE_START, session, request); 175 | this.broadcast(ftpEvent); 176 | return super.onDeleteStart(session, request); 177 | } 178 | 179 | @Override 180 | public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException { 181 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.DISCONNECT, session); 182 | this.broadcast(ftpEvent); 183 | return super.onDisconnect(session); 184 | } 185 | 186 | @Override 187 | public FtpletResult onConnect(FtpSession session) throws FtpException, IOException { 188 | final FtpEvent ftpEvent = new FtpEvent(FtpEventName.CONNECT, session); 189 | this.broadcast(ftpEvent); 190 | return super.onConnect(session); 191 | } 192 | 193 | void broadcast(FtpEvent ftpEvent) { 194 | sendToDedicatedChannel(ftpEvent); 195 | this.all.fire(ftpEvent); 196 | } 197 | 198 | void sendToDedicatedChannel(FtpEvent ftpEvent) { 199 | events.select(new CommandInstance(ftpEvent.getCommand())).fire(ftpEvent); 200 | } 201 | 202 | } 203 | --------------------------------------------------------------------------------