extensions/net.sf.basedb.ftp/trunk/src/net/sf/basedb/clients/ftp/BaseUserManager.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
915 11 Dec 08 nicklas 27 import java.util.ArrayList;
915 11 Dec 08 nicklas 28 import java.util.List;
915 11 Dec 08 nicklas 29
714 30 May 08 nicklas 30 import org.apache.ftpserver.ftplet.Authentication;
714 30 May 08 nicklas 31 import org.apache.ftpserver.ftplet.AuthenticationFailedException;
714 30 May 08 nicklas 32 import org.apache.ftpserver.ftplet.Authority;
714 30 May 08 nicklas 33 import org.apache.ftpserver.ftplet.FtpException;
714 30 May 08 nicklas 34 import org.apache.ftpserver.ftplet.User;
714 30 May 08 nicklas 35 import org.apache.ftpserver.ftplet.UserManager;
714 30 May 08 nicklas 36 import org.apache.ftpserver.usermanager.AnonymousAuthentication;
714 30 May 08 nicklas 37 import org.apache.ftpserver.usermanager.UsernamePasswordAuthentication;
915 11 Dec 08 nicklas 38 import org.apache.ftpserver.usermanager.impl.ConcurrentLoginPermission;
915 11 Dec 08 nicklas 39 import org.apache.ftpserver.usermanager.impl.TransferRatePermission;
915 11 Dec 08 nicklas 40 import org.apache.ftpserver.usermanager.impl.WritePermission;
716 02 Jun 08 nicklas 41 import org.slf4j.Logger;
716 02 Jun 08 nicklas 42 import org.slf4j.LoggerFactory;
714 30 May 08 nicklas 43
716 02 Jun 08 nicklas 44 /**
716 02 Jun 08 nicklas 45   A user manager implementation for hooking into BASE. This is a read-only
716 02 Jun 08 nicklas 46   user manager, and all methods that makes modifications will throw an
716 02 Jun 08 nicklas 47   {@link UnsupportedOperationException}. A lot of the other methods are
716 02 Jun 08 nicklas 48   also hampered, eg {@link #doesExist(String), {@link #getAllUserNames()}, etc., 
716 02 Jun 08 nicklas 49   since before we can get information out from BASE a user must be logged in.
716 02 Jun 08 nicklas 50   <p>
716 02 Jun 08 nicklas 51   
716 02 Jun 08 nicklas 52   The only method that really does what it is intended to is the 
716 02 Jun 08 nicklas 53   {@link #authenticate(Authentication)} method. This is probably no harm
716 02 Jun 08 nicklas 54   since this is the only method are really interested in.
716 02 Jun 08 nicklas 55   <p>
716 02 Jun 08 nicklas 56   
716 02 Jun 08 nicklas 57   As long as the BASE FTP Server hasn't been registered as a client
716 02 Jun 08 nicklas 58   application with BASE, only the root user is allowed to login. Once
716 02 Jun 08 nicklas 59   the root user does that, the 
716 02 Jun 08 nicklas 60   {@link BaseFtpServer#registerAsClient(net.sf.basedb.core.SessionControl)}
716 02 Jun 08 nicklas 61   is called to register the FTP Server. After that everybody can use the FTP
716 02 Jun 08 nicklas 62   Server.
716 02 Jun 08 nicklas 63   
716 02 Jun 08 nicklas 64   @author Nicklas
716 02 Jun 08 nicklas 65   @version 1.0
716 02 Jun 08 nicklas 66 */
714 30 May 08 nicklas 67 public class BaseUserManager 
714 30 May 08 nicklas 68   implements UserManager 
714 30 May 08 nicklas 69 {
716 02 Jun 08 nicklas 70   private static final Logger log = LoggerFactory.getLogger(BaseUserManager.class);
714 30 May 08 nicklas 71
714 30 May 08 nicklas 72   private boolean ftpClientIsInstalled;
716 02 Jun 08 nicklas 73   
716 02 Jun 08 nicklas 74   private int maxUploadRate = 0;
716 02 Jun 08 nicklas 75   private int maxDownloadRate = 0;
714 30 May 08 nicklas 76
716 02 Jun 08 nicklas 77   /**
716 02 Jun 08 nicklas 78     Creates a new user manager for BASE.
716 02 Jun 08 nicklas 79   */
714 30 May 08 nicklas 80   public BaseUserManager()
714 30 May 08 nicklas 81   {
716 02 Jun 08 nicklas 82     this.ftpClientIsInstalled = BaseFtpServer.isRegisteredAsClient();
714 30 May 08 nicklas 83   }
714 30 May 08 nicklas 84   
714 30 May 08 nicklas 85   /*
714 30 May 08 nicklas 86     From the UserManager interface
714 30 May 08 nicklas 87     ------------------------------
714 30 May 08 nicklas 88   */
714 30 May 08 nicklas 89   /**
714 30 May 08 nicklas 90     @throws UnsupportedOperationException Always
714 30 May 08 nicklas 91   */
714 30 May 08 nicklas 92   @Override
714 30 May 08 nicklas 93   public void delete(String login) 
714 30 May 08 nicklas 94     throws FtpException 
714 30 May 08 nicklas 95   {
714 30 May 08 nicklas 96     throw new UnsupportedOperationException("delete");
714 30 May 08 nicklas 97   }
714 30 May 08 nicklas 98   
714 30 May 08 nicklas 99   /**
714 30 May 08 nicklas 100     Always TRUE since we can't check if a user exists or not
714 30 May 08 nicklas 101     without logging in.
714 30 May 08 nicklas 102   */
714 30 May 08 nicklas 103   @Override
714 30 May 08 nicklas 104   public boolean doesExist(String login) 
714 30 May 08 nicklas 105     throws FtpException 
714 30 May 08 nicklas 106   {
714 30 May 08 nicklas 107     return true;
714 30 May 08 nicklas 108   }
714 30 May 08 nicklas 109   
714 30 May 08 nicklas 110   /**
714 30 May 08 nicklas 111     Always null, since administration is not allowed using
714 30 May 08 nicklas 112     the FTP server.
714 30 May 08 nicklas 113   */
714 30 May 08 nicklas 114   @Override
714 30 May 08 nicklas 115   public String getAdminName() 
714 30 May 08 nicklas 116     throws FtpException 
714 30 May 08 nicklas 117   {
714 30 May 08 nicklas 118     return null;
714 30 May 08 nicklas 119   }
714 30 May 08 nicklas 120   
714 30 May 08 nicklas 121   /**
714 30 May 08 nicklas 122     Always FALSE since administration is not allowed using
714 30 May 08 nicklas 123     the FTP server.
714 30 May 08 nicklas 124   */
714 30 May 08 nicklas 125   @Override
714 30 May 08 nicklas 126   public boolean isAdmin(String login) 
714 30 May 08 nicklas 127     throws FtpException 
714 30 May 08 nicklas 128   {
714 30 May 08 nicklas 129     return false;
714 30 May 08 nicklas 130   }
714 30 May 08 nicklas 131
714 30 May 08 nicklas 132   /**
714 30 May 08 nicklas 133     @throws UnsupportedOperationException Always
714 30 May 08 nicklas 134   */
714 30 May 08 nicklas 135   @Override
714 30 May 08 nicklas 136   public void save(User user)
714 30 May 08 nicklas 137     throws FtpException 
714 30 May 08 nicklas 138   {
714 30 May 08 nicklas 139     throw new UnsupportedOperationException("save");
714 30 May 08 nicklas 140   }
714 30 May 08 nicklas 141
714 30 May 08 nicklas 142   /**
714 30 May 08 nicklas 143     Return an empty array.
714 30 May 08 nicklas 144   */
714 30 May 08 nicklas 145   @Override
714 30 May 08 nicklas 146   public String[] getAllUserNames() 
714 30 May 08 nicklas 147     throws FtpException 
714 30 May 08 nicklas 148   {
714 30 May 08 nicklas 149     return new String[0];
714 30 May 08 nicklas 150   }
714 30 May 08 nicklas 151   
714 30 May 08 nicklas 152   /**
714 30 May 08 nicklas 153     Get a non-logged in {@link BaseUser} object.
714 30 May 08 nicklas 154   */
714 30 May 08 nicklas 155   @Override
714 30 May 08 nicklas 156   public User getUserByName(String login)
714 30 May 08 nicklas 157   {
714 30 May 08 nicklas 158     return getBaseUser(login);
714 30 May 08 nicklas 159   }
714 30 May 08 nicklas 160   
714 30 May 08 nicklas 161   /**
714 30 May 08 nicklas 162     We only support {@link UsernamePasswordAuthentication}
714 30 May 08 nicklas 163     authentications. If the authentication is sucessful this method will
714 30 May 08 nicklas 164     return a logged in {@link BaseUser} object.
714 30 May 08 nicklas 165   */
714 30 May 08 nicklas 166   @Override
714 30 May 08 nicklas 167   public User authenticate(Authentication authentication)
714 30 May 08 nicklas 168     throws AuthenticationFailedException
714 30 May 08 nicklas 169   {
714 30 May 08 nicklas 170     BaseUser user = null;
714 30 May 08 nicklas 171         if (authentication instanceof UsernamePasswordAuthentication) 
714 30 May 08 nicklas 172         {
714 30 May 08 nicklas 173         UsernamePasswordAuthentication auth = (UsernamePasswordAuthentication)authentication;
714 30 May 08 nicklas 174         
714 30 May 08 nicklas 175         String login = auth.getUsername();
714 30 May 08 nicklas 176         String pwd = auth.getPassword();
1399 10 Oct 11 nicklas 177         String project = null;
714 30 May 08 nicklas 178         String ip = auth.getUserMetadata().getInetAddress().getHostAddress();
714 30 May 08 nicklas 179         
1399 10 Oct 11 nicklas 180         /* 
1399 10 Oct 11 nicklas 181           If login has pattern like 'username<project>' we extract the
1399 10 Oct 11 nicklas 182           login and project from it.
1399 10 Oct 11 nicklas 183          */
1399 10 Oct 11 nicklas 184         if (login != null && login.endsWith(">"))
1399 10 Oct 11 nicklas 185         {
1399 10 Oct 11 nicklas 186           int index = login.indexOf("<");
1399 10 Oct 11 nicklas 187           if (index > 0 && index < login.length()-1)
1399 10 Oct 11 nicklas 188           {
1399 10 Oct 11 nicklas 189             project = login.substring(index+1, login.length()-1);
1399 10 Oct 11 nicklas 190             login = login.substring(0,  index);
1399 10 Oct 11 nicklas 191           }
1399 10 Oct 11 nicklas 192         }
1399 10 Oct 11 nicklas 193         
716 02 Jun 08 nicklas 194         log.info("Trying to authenticate: login=" + login);
716 02 Jun 08 nicklas 195         log.debug("password=" + pwd);
1399 10 Oct 11 nicklas 196         log.debug("project=" + project);
716 02 Jun 08 nicklas 197         log.debug("ip=" + ip);
716 02 Jun 08 nicklas 198         
714 30 May 08 nicklas 199         user = getBaseUser(login);
714 30 May 08 nicklas 200         try
714 30 May 08 nicklas 201         {
714 30 May 08 nicklas 202           user.login(pwd, ip, ftpClientIsInstalled ? BaseFtpServer.CLIENT_ID : null);
716 02 Jun 08 nicklas 203           log.info("Login successful: login=" + login);
1399 10 Oct 11 nicklas 204           if (project != null) user.setProject(project);
714 30 May 08 nicklas 205         }
714 30 May 08 nicklas 206         catch (Exception ex)
714 30 May 08 nicklas 207         {
716 02 Jun 08 nicklas 208           log.warn("Login failed: login="+login, ex);
714 30 May 08 nicklas 209           throw new AuthenticationFailedException(ex.getMessage(), ex);
714 30 May 08 nicklas 210         }
714 30 May 08 nicklas 211         }
714 30 May 08 nicklas 212         else if (authentication instanceof AnonymousAuthentication) 
714 30 May 08 nicklas 213         {
716 02 Jun 08 nicklas 214           String msg = "Anonymous login is not allowed.";
716 02 Jun 08 nicklas 215           log.warn(msg);
716 02 Jun 08 nicklas 216           throw new AuthenticationFailedException(msg);
714 30 May 08 nicklas 217         } 
714 30 May 08 nicklas 218         else 
714 30 May 08 nicklas 219         {
716 02 Jun 08 nicklas 220           String msg = "Unsupported authentication method: " + authentication;
716 02 Jun 08 nicklas 221           log.warn(msg);
716 02 Jun 08 nicklas 222             throw new IllegalArgumentException(msg);
714 30 May 08 nicklas 223         }
714 30 May 08 nicklas 224     return user;
714 30 May 08 nicklas 225   }
714 30 May 08 nicklas 226   // -------------------------------
714 30 May 08 nicklas 227   
716 02 Jun 08 nicklas 228   /**
716 02 Jun 08 nicklas 229     Get the current maximum transfer rate for uploads.
716 02 Jun 08 nicklas 230     @return The transfer rate in bytes/second, or 0 if unlimited
716 02 Jun 08 nicklas 231   */
716 02 Jun 08 nicklas 232   public int getMaxUploadRate()
716 02 Jun 08 nicklas 233   {
716 02 Jun 08 nicklas 234     return maxUploadRate;
716 02 Jun 08 nicklas 235   }
716 02 Jun 08 nicklas 236   
716 02 Jun 08 nicklas 237   /**
716 02 Jun 08 nicklas 238     Set the maximum transfer rate for uploads. This will only affect
716 02 Jun 08 nicklas 239     new users. 
716 02 Jun 08 nicklas 240     @param uploadRate The transfer rate in bytes/second, or 0 if unlimited
716 02 Jun 08 nicklas 241   */
716 02 Jun 08 nicklas 242   public void setMaxUploadRate(int uploadRate)
716 02 Jun 08 nicklas 243   {
716 02 Jun 08 nicklas 244     this.maxUploadRate = uploadRate;
716 02 Jun 08 nicklas 245   }
716 02 Jun 08 nicklas 246   
716 02 Jun 08 nicklas 247   /**
716 02 Jun 08 nicklas 248     Get the current maximum transfer rate for downloads.
716 02 Jun 08 nicklas 249     @return The transfer rate in bytes/second, or 0 if unlimited
716 02 Jun 08 nicklas 250   */
716 02 Jun 08 nicklas 251   public int getMaxDownloadRate()
716 02 Jun 08 nicklas 252   {
716 02 Jun 08 nicklas 253     return maxDownloadRate;
716 02 Jun 08 nicklas 254   }
716 02 Jun 08 nicklas 255   
716 02 Jun 08 nicklas 256   /**
716 02 Jun 08 nicklas 257     Set the maximum transfer rate for downloads. This will only affect
716 02 Jun 08 nicklas 258     new users. 
716 02 Jun 08 nicklas 259     @param downloadRate The transfer rate in bytes/second, or 0 if unlimited
716 02 Jun 08 nicklas 260   */
716 02 Jun 08 nicklas 261   public void setMaxDownloadRate(int downloadRate)
716 02 Jun 08 nicklas 262   {
716 02 Jun 08 nicklas 263     this.maxDownloadRate = downloadRate;
716 02 Jun 08 nicklas 264   }
716 02 Jun 08 nicklas 265   
716 02 Jun 08 nicklas 266   /**
716 02 Jun 08 nicklas 267     Set the maximum transfer rate for uploads and downloads. 
716 02 Jun 08 nicklas 268     This will only affect new users. 
716 02 Jun 08 nicklas 269     @param transferRate The transfer rate in bytes/second, or 0 if unlimited
716 02 Jun 08 nicklas 270   */
716 02 Jun 08 nicklas 271   public void setTransferRate(int transferRate)
716 02 Jun 08 nicklas 272   {
716 02 Jun 08 nicklas 273     this.maxDownloadRate = transferRate;
716 02 Jun 08 nicklas 274     this.maxUploadRate = transferRate;
716 02 Jun 08 nicklas 275   }
716 02 Jun 08 nicklas 276
714 30 May 08 nicklas 277   private BaseUser getBaseUser(String login)
714 30 May 08 nicklas 278   {
716 02 Jun 08 nicklas 279     if (log.isDebugEnabled())
716 02 Jun 08 nicklas 280     {
716 02 Jun 08 nicklas 281       log.debug("Creating new user: login=" + login);
716 02 Jun 08 nicklas 282       log.debug("Transfer rate: upload=" + maxUploadRate + "; download=" + maxDownloadRate);
716 02 Jun 08 nicklas 283     }
915 11 Dec 08 nicklas 284     List<Authority> auth = new ArrayList<Authority>();
915 11 Dec 08 nicklas 285     auth.add(new ConcurrentLoginPermission(0, 0));
915 11 Dec 08 nicklas 286     auth.add(new WritePermission());
915 11 Dec 08 nicklas 287     auth.add(new TransferRatePermission(maxDownloadRate, maxUploadRate));
714 30 May 08 nicklas 288     BaseUser u = new BaseUser(login, auth);    
714 30 May 08 nicklas 289     return u;
714 30 May 08 nicklas 290   }
714 30 May 08 nicklas 291
714 30 May 08 nicklas 292 }