extensions/net.sf.basedb.ftp/trunk/src/net/sf/basedb/clients/ftp/BaseFtpServer.java

Code
Comments
Other
Rev Date Author Line
716 02 Jun 08 nicklas 1 /**
716 02 Jun 08 nicklas 2   $Id $
716 02 Jun 08 nicklas 3
716 02 Jun 08 nicklas 4   Copyright (C) 2008 Nicklas Nordborg
716 02 Jun 08 nicklas 5
1381 15 Aug 11 martin 6   This file is part of the FTP Server extension for BASE.
716 02 Jun 08 nicklas 7   Available at http://baseplugins.thep.lu.se/
1381 15 Aug 11 martin 8   BASE main site: http://base.thep.lu.se/
1381 15 Aug 11 martin 9   -----------------------------------------------------------
1381 15 Aug 11 martin 10   
1381 15 Aug 11 martin 11   This is free software; you can redistribute it and/or
716 02 Jun 08 nicklas 12   modify it under the terms of the GNU General Public License
1381 15 Aug 11 martin 13   as published by the Free Software Foundation; either version 3
716 02 Jun 08 nicklas 14   of the License, or (at your option) any later version.
1381 15 Aug 11 martin 15   
1381 15 Aug 11 martin 16   The software is distributed in the hope that it will be useful,
716 02 Jun 08 nicklas 17   but WITHOUT ANY WARRANTY; without even the implied warranty of
716 02 Jun 08 nicklas 18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
716 02 Jun 08 nicklas 19   GNU General Public License for more details.
1381 15 Aug 11 martin 20   
1381 15 Aug 11 martin 21   You should have received a copy of the GNU General Public License
1381 15 Aug 11 martin 22   along with BASE. If not, see <http://www.gnu.org/licenses/>.
716 02 Jun 08 nicklas 23
716 02 Jun 08 nicklas 24 */
714 30 May 08 nicklas 25 package net.sf.basedb.clients.ftp;
714 30 May 08 nicklas 26
714 30 May 08 nicklas 27 import java.util.EnumSet;
714 30 May 08 nicklas 28
2312 04 Apr 14 nicklas 29
2312 04 Apr 14 nicklas 30
741 13 Aug 08 nicklas 31 //import org.apache.ftpserver.ConfigurableFtpServerContext;
714 30 May 08 nicklas 32 import org.apache.ftpserver.FtpServer;
741 13 Aug 08 nicklas 33 //import org.apache.ftpserver.config.PropertiesConfiguration;
741 13 Aug 08 nicklas 34 //import org.apache.ftpserver.ftplet.Configuration;
716 02 Jun 08 nicklas 35 import org.slf4j.Logger;
716 02 Jun 08 nicklas 36 import org.slf4j.LoggerFactory;
741 13 Aug 08 nicklas 37 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
741 13 Aug 08 nicklas 38 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
741 13 Aug 08 nicklas 39 import org.springframework.core.io.ClassPathResource;
741 13 Aug 08 nicklas 40 import org.springframework.core.io.DefaultResourceLoader;
714 30 May 08 nicklas 41
714 30 May 08 nicklas 42 import net.sf.basedb.core.Application;
714 30 May 08 nicklas 43 import net.sf.basedb.core.Client;
714 30 May 08 nicklas 44 import net.sf.basedb.core.DbControl;
714 30 May 08 nicklas 45 import net.sf.basedb.core.Group;
714 30 May 08 nicklas 46 import net.sf.basedb.core.GroupPermissions;
2312 04 Apr 14 nicklas 47 import net.sf.basedb.core.Item;
714 30 May 08 nicklas 48 import net.sf.basedb.core.ItemKey;
714 30 May 08 nicklas 49 import net.sf.basedb.core.ItemNotFoundException;
714 30 May 08 nicklas 50 import net.sf.basedb.core.Permission;
714 30 May 08 nicklas 51 import net.sf.basedb.core.SessionControl;
714 30 May 08 nicklas 52 import net.sf.basedb.core.SystemItems;
2312 04 Apr 14 nicklas 53 import net.sf.basedb.core.User;
714 30 May 08 nicklas 54
716 02 Jun 08 nicklas 55 /**
716 02 Jun 08 nicklas 56   The main FTP Server class for BASE. It encapsulates the
716 02 Jun 08 nicklas 57   {@link FtpServer} from Apache, and forces some BASE-specific
716 02 Jun 08 nicklas 58   configuration settings. Eg.
716 02 Jun 08 nicklas 59
716 02 Jun 08 nicklas 60   <ul>
716 02 Jun 08 nicklas 61   <li>User manager: {@link BaseUserManager}
915 11 Dec 08 nicklas 62   <li>File system manager: {@link BaseFileSystemFactory}
716 02 Jun 08 nicklas 63   <li>Ftplet: {@link BaseFtplet}
716 02 Jun 08 nicklas 64   <li>Anonymous login is disabled
716 02 Jun 08 nicklas 65   </ul>
716 02 Jun 08 nicklas 66   
716 02 Jun 08 nicklas 67   This class also has some utility method for checking if the
716 02 Jun 08 nicklas 68   <code>net.sf.basedb.clients.ftp</code> {@link Client} has been
716 02 Jun 08 nicklas 69   registered in BASE. If not, only the root user is allowed to connect,
716 02 Jun 08 nicklas 70   but once the root user does that, the ftp client is automatically
716 02 Jun 08 nicklas 71   registereded and made available to everyone.
716 02 Jun 08 nicklas 72   
716 02 Jun 08 nicklas 73   @author Nicklas
716 02 Jun 08 nicklas 74   @version 1.0
716 02 Jun 08 nicklas 75 */
714 30 May 08 nicklas 76 public class BaseFtpServer 
714 30 May 08 nicklas 77 {
714 30 May 08 nicklas 78
716 02 Jun 08 nicklas 79   private static final Logger log = LoggerFactory.getLogger(BaseFtpServer.class);
716 02 Jun 08 nicklas 80   
716 02 Jun 08 nicklas 81   /**
716 02 Jun 08 nicklas 82     The {@link Client#getExternalId()} for FTP server.
716 02 Jun 08 nicklas 83   */
714 30 May 08 nicklas 84   public static final String CLIENT_ID = "net.sf.basedb.clients.ftp";
714 30 May 08 nicklas 85   
714 30 May 08 nicklas 86   /**
714 30 May 08 nicklas 87     Check if the FTP server has been registered as a client
714 30 May 08 nicklas 88     application in BASE.
714 30 May 08 nicklas 89     @return TRUE if the FTP server is registered, FALSE otherwise
714 30 May 08 nicklas 90   */
716 02 Jun 08 nicklas 91   public static boolean isRegisteredAsClient()
714 30 May 08 nicklas 92   {
714 30 May 08 nicklas 93     boolean installed = false;
714 30 May 08 nicklas 94     try
714 30 May 08 nicklas 95     {
714 30 May 08 nicklas 96       SessionControl sc = Application.newSessionControl(CLIENT_ID, null, null);
714 30 May 08 nicklas 97       sc.close();
714 30 May 08 nicklas 98       installed = true;
714 30 May 08 nicklas 99     }
714 30 May 08 nicklas 100     catch (ItemNotFoundException ex)
716 02 Jun 08 nicklas 101     {
716 02 Jun 08 nicklas 102       log.info("FTP Server is not registered as BASE client application", ex);
716 02 Jun 08 nicklas 103     }
714 30 May 08 nicklas 104     return installed;
714 30 May 08 nicklas 105   }
714 30 May 08 nicklas 106   
716 02 Jun 08 nicklas 107   /**
716 02 Jun 08 nicklas 108     Register the FTP server as a client application in BASE. The 
716 02 Jun 08 nicklas 109     application will be shared to {@link Group#EVERYONE}.
716 02 Jun 08 nicklas 110     @param sc The session control of a logged in user which must have
2312 04 Apr 14 nicklas 111       permissions to create a {@link Client} item or permission
2312 04 Apr 14 nicklas 112       to impersonate a user (eg. root)
716 02 Jun 08 nicklas 113   */
716 02 Jun 08 nicklas 114   public static void registerAsClient(SessionControl sc)
714 30 May 08 nicklas 115   {
2312 04 Apr 14 nicklas 116     boolean closeSessionControl = false;
2312 04 Apr 14 nicklas 117     if (!sc.hasPermission(Permission.CREATE, Item.CLIENT))
2312 04 Apr 14 nicklas 118     {
2312 04 Apr 14 nicklas 119       if (!sc.hasSystemPermission(Permission.ACT_AS_ANOTHER_USER))
2312 04 Apr 14 nicklas 120       {
2312 04 Apr 14 nicklas 121         // We lack the proper permissions to register the ftp client
2312 04 Apr 14 nicklas 122         return;
2312 04 Apr 14 nicklas 123       }
2312 04 Apr 14 nicklas 124       sc = sc.impersonateLogin(SystemItems.getId(User.ROOT), "FTP Server auto-login to register FTP client");
2312 04 Apr 14 nicklas 125       closeSessionControl = true;
2312 04 Apr 14 nicklas 126     }
2312 04 Apr 14 nicklas 127     
714 30 May 08 nicklas 128     Client client = null;
714 30 May 08 nicklas 129     DbControl dc = sc.newDbControl();
714 30 May 08 nicklas 130     try
714 30 May 08 nicklas 131     {
714 30 May 08 nicklas 132       client = Client.getByExternalId(dc, CLIENT_ID);
716 02 Jun 08 nicklas 133       log.info("FTP Server is already registered as BASE client application");
714 30 May 08 nicklas 134     }
714 30 May 08 nicklas 135     catch (ItemNotFoundException ex)
714 30 May 08 nicklas 136     {
716 02 Jun 08 nicklas 137       log.info("Registering FTP Server as BASE client application with ID:" + CLIENT_ID);
714 30 May 08 nicklas 138       Group everyone = Group.getById(dc, SystemItems.getId(Group.EVERYONE));
714 30 May 08 nicklas 139       GroupPermissions gp = new GroupPermissions();
714 30 May 08 nicklas 140       gp.setPermissions(everyone, EnumSet.of(Permission.USE));
714 30 May 08 nicklas 141       ItemKey everyoneUse = ItemKey.getNewOrExisting(dc, null, gp);
714 30 May 08 nicklas 142       
714 30 May 08 nicklas 143       client = Client.getNew(dc, CLIENT_ID);
714 30 May 08 nicklas 144       client.setName("FTP Server");
714 30 May 08 nicklas 145       client.setDescription("Enables FTP access to the BASE file system.");
714 30 May 08 nicklas 146       client.setItemKey(everyoneUse);
714 30 May 08 nicklas 147       dc.saveItem(client);
714 30 May 08 nicklas 148       dc.commit();
716 02 Jun 08 nicklas 149       log.info("FTP Server successfully registered as BASE client application");
714 30 May 08 nicklas 150     }
714 30 May 08 nicklas 151     finally
714 30 May 08 nicklas 152     {
714 30 May 08 nicklas 153       if (dc != null) dc.close();
2312 04 Apr 14 nicklas 154       if (closeSessionControl) sc.close();
714 30 May 08 nicklas 155     }
714 30 May 08 nicklas 156   }
714 30 May 08 nicklas 157
741 13 Aug 08 nicklas 158   private final String configFile;
714 30 May 08 nicklas 159   private FtpServer server;
714 30 May 08 nicklas 160   
716 02 Jun 08 nicklas 161   /**
716 02 Jun 08 nicklas 162     Create a new FTP Server. The configuration properties will be copied and
716 02 Jun 08 nicklas 163     BASE-specific settings as described in the class documentation will be 
716 02 Jun 08 nicklas 164     added. To start the FTP server call {@link #start()}.
716 02 Jun 08 nicklas 165     
741 13 Aug 08 nicklas 166     @param config The path to configuration file (classpath based)
716 02 Jun 08 nicklas 167     @throws Exception If there is any problem
716 02 Jun 08 nicklas 168   */
741 13 Aug 08 nicklas 169   public BaseFtpServer(String configFile)
714 30 May 08 nicklas 170     throws Exception
714 30 May 08 nicklas 171   {
741 13 Aug 08 nicklas 172     this.configFile = configFile;
714 30 May 08 nicklas 173   }
716 02 Jun 08 nicklas 174
716 02 Jun 08 nicklas 175   /**
716 02 Jun 08 nicklas 176     Checks if the FTP Server is running.
716 02 Jun 08 nicklas 177   */
714 30 May 08 nicklas 178   public boolean isRunning()
714 30 May 08 nicklas 179   {
714 30 May 08 nicklas 180     return server != null && !server.isStopped() && !server.isSuspended();
714 30 May 08 nicklas 181   }
716 02 Jun 08 nicklas 182
716 02 Jun 08 nicklas 183   /**
716 02 Jun 08 nicklas 184     Starts the FTP server if it is not already running.
716 02 Jun 08 nicklas 185   */
714 30 May 08 nicklas 186   public void start()
714 30 May 08 nicklas 187   {
714 30 May 08 nicklas 188     if (isRunning()) return;
716 02 Jun 08 nicklas 189     log.info("Starting BASE FTP Server");
741 13 Aug 08 nicklas 190
714 30 May 08 nicklas 191     try
714 30 May 08 nicklas 192     {
741 13 Aug 08 nicklas 193       ClassLoader classLoader = FtpServer.class.getClassLoader();
741 13 Aug 08 nicklas 194       
741 13 Aug 08 nicklas 195       DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
741 13 Aug 08 nicklas 196       factory.setBeanClassLoader(classLoader);
741 13 Aug 08 nicklas 197       XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
741 13 Aug 08 nicklas 198       reader.setResourceLoader(new DefaultResourceLoader(classLoader));
741 13 Aug 08 nicklas 199       reader.loadBeanDefinitions(new ClassPathResource(configFile, classLoader));
741 13 Aug 08 nicklas 200       server = (FtpServer)factory.getBean("server");
741 13 Aug 08 nicklas 201       
741 13 Aug 08 nicklas 202       //System.out.println("Start FTP server: " + server);
741 13 Aug 08 nicklas 203       //System.out.println("port: " + server.getListener("default").getPort());
741 13 Aug 08 nicklas 204       
714 30 May 08 nicklas 205       server.start();
714 30 May 08 nicklas 206     }
714 30 May 08 nicklas 207     catch (Exception ex)
714 30 May 08 nicklas 208     {
719 05 Jun 08 nicklas 209       server = null;
716 02 Jun 08 nicklas 210       log.error("Could not start FTP Server", ex);
714 30 May 08 nicklas 211       throw new RuntimeException(ex);
714 30 May 08 nicklas 212     }
716 02 Jun 08 nicklas 213     log.info("BASE FTP Server has been started");
714 30 May 08 nicklas 214   }
714 30 May 08 nicklas 215   
716 02 Jun 08 nicklas 216   /**
716 02 Jun 08 nicklas 217     Stop the FTP server.
716 02 Jun 08 nicklas 218   */
714 30 May 08 nicklas 219   public void stop()
714 30 May 08 nicklas 220   {
716 02 Jun 08 nicklas 221     log.info("Stopping BASE FTP Server");
716 02 Jun 08 nicklas 222     if (server != null)
716 02 Jun 08 nicklas 223     {
719 05 Jun 08 nicklas 224       try
719 05 Jun 08 nicklas 225       {
719 05 Jun 08 nicklas 226         server.stop();
719 05 Jun 08 nicklas 227       }
719 05 Jun 08 nicklas 228       catch (Throwable t)
719 05 Jun 08 nicklas 229       {
719 05 Jun 08 nicklas 230         log.warn("Error when stopping FTP Server", t);
719 05 Jun 08 nicklas 231       }
716 02 Jun 08 nicklas 232       server = null;
716 02 Jun 08 nicklas 233     }
716 02 Jun 08 nicklas 234     log.info("BASE FTP Server has been stopped");
741 13 Aug 08 nicklas 235   }  
714 30 May 08 nicklas 236 }