diff options
author | Nils Schwabe | 2014-06-16 17:42:51 +0200 |
---|---|---|
committer | Nils Schwabe | 2014-06-16 17:42:51 +0200 |
commit | 09a0f7f6184b680c7e208104d7e8fcacde27a00d (patch) | |
tree | b0ce867cdcb9319e9b69da1419f8c7b427442854 | |
parent | Started to implement download of images (diff) | |
download | masterserver-09a0f7f6184b680c7e208104d7e8fcacde27a00d.tar.gz masterserver-09a0f7f6184b680c7e208104d7e8fcacde27a00d.tar.xz masterserver-09a0f7f6184b680c7e208104d7e8fcacde27a00d.zip |
Add FtpUsers are now in sync with DB
8 files changed, 132 insertions, 39 deletions
diff --git a/src/main/java/org/openslx/imagemaster/App.java b/src/main/java/org/openslx/imagemaster/App.java index e40dae3..7f004fd 100644 --- a/src/main/java/org/openslx/imagemaster/App.java +++ b/src/main/java/org/openslx/imagemaster/App.java @@ -10,6 +10,7 @@ import org.openslx.imagemaster.ftp.FtpCredentialsScheduler; import org.openslx.imagemaster.ftp.ImageProcessor; import org.openslx.imagemaster.ftp.MasterFtpServer; import org.openslx.imagemaster.thrift.server.BinaryListener; +import org.slf4j.LoggerFactory; public class App { @@ -19,6 +20,13 @@ public class App private static List<Thread> servers = new ArrayList<>(); public static final MasterFtpServer ftpServer = new MasterFtpServer(); + + static { + // TODO: + // This is a temporary workaround for this annoying log4j error msg. + // It's initializing the logger before anything else is done. + LoggerFactory.getLogger("ROOT"); + } public static void main( String[] args ) { @@ -53,9 +61,15 @@ public class App f = new Thread( ftpServer, "FtpServer" ); servers.add( f ); f.start(); - + + // add ftp users from database + ftpServer.addDbFtpUsers(); + // start FtpCredentialsScheduler FtpCredentialsScheduler.startScheduling(); + + // testtesteset + ftpServer.addUser( "asdfasdfasdf", MasterFtpServer.Mode.DOWNLOADING, "windows7.vmdk" ); // Run more servers // ... diff --git a/src/main/java/org/openslx/imagemaster/db/DbFtpUser.java b/src/main/java/org/openslx/imagemaster/db/DbFtpUser.java index ea8a79f..088109e 100644 --- a/src/main/java/org/openslx/imagemaster/db/DbFtpUser.java +++ b/src/main/java/org/openslx/imagemaster/db/DbFtpUser.java @@ -1,5 +1,6 @@ package org.openslx.imagemaster.db; +import java.sql.Timestamp; import java.util.List; @@ -9,28 +10,38 @@ public class DbFtpUser public final String password; public final String mode; public final String filename; + public final String sessionId; + public final Timestamp timestamp; - public DbFtpUser(String username, String password, String mode, String filename) + public DbFtpUser(String username, String password, String mode, String filename, String sessionId, Timestamp timestamp) { this.username = username; this.password = password; this.mode = mode; this.filename = filename; + this.sessionId = sessionId; + this.timestamp = timestamp; } public static List<DbFtpUser> getAllUsers() { - return MySQL.findAll( DbFtpUser.class, "SELECT username, password, mode, filename from ftpUser" ); + return MySQL.findAll( DbFtpUser.class, "SELECT username, password, mode, filename, sessionid, timestamp from ftpUser" ); } public static void addUser(DbFtpUser user) { - MySQL.update( "INSERT INTO ftpUser username, password, mode, filename VALUES (? , ?, ?, ?)", - user.username, user.password, user.mode, user.filename); + MySQL.update( "INSERT INTO ftpUser (username, password, mode, filename, sessionid, timestamp) VALUES (?, ?, ?, ?, ?, ?)", + user.username, user.password, user.mode, user.filename, user.sessionId, user.timestamp); } public static DbFtpUser getUserByName(String username) { - return MySQL.findUniqueOrNull( DbFtpUser.class, "SELECT username, password, mode, filename FROM ftpUser WHERE username=?", username ); + return MySQL.findUniqueOrNull( DbFtpUser.class, "SELECT username, password, mode, filename, sessionid, timestamp FROM ftpUser WHERE username=?", username ); + } + + public static boolean removeUserByName(String username) + { + int result = MySQL.update( "DELETE FROM ftpUser WHERE username=? LIMIT 1", username ); + return result == 1; } } diff --git a/src/main/java/org/openslx/imagemaster/db/DbImage.java b/src/main/java/org/openslx/imagemaster/db/DbImage.java index 2cf3922..59701e4 100644 --- a/src/main/java/org/openslx/imagemaster/db/DbImage.java +++ b/src/main/java/org/openslx/imagemaster/db/DbImage.java @@ -24,7 +24,6 @@ public class DbImage public final String longDescription; public final Timestamp timestamp; public final String ftpUser; - public final String ftpPassword; public final long fileSize; @@ -44,14 +43,13 @@ public class DbImage this.longDescription = null; this.timestamp = new Timestamp( 0 ); this.ftpUser = null; - this.ftpPassword = null; this.fileSize = 0; } public DbImage(String UUID, int imageVersion, String imageName, String imagePath, Timestamp imageCreateTime, Timestamp imageUpdateTime, int imageOwner, String contentOperatingSystem, boolean isValid, boolean isDeleted, String shortDescription, String longDescription, - Timestamp timestamp, String ftpUser, String ftpPassword, long fileSize) + Timestamp timestamp, String ftpUser, long fileSize) { this.UUID = UUID; this.imageVersion = imageVersion; @@ -67,7 +65,6 @@ public class DbImage this.longDescription = longDescription; this.timestamp = timestamp; this.ftpUser = ftpUser; - this.ftpPassword = ftpPassword; this.fileSize = fileSize; } diff --git a/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java b/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java index 8359e5a..20772ff 100644 --- a/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java +++ b/src/main/java/org/openslx/imagemaster/ftp/ImageProcessor.java @@ -6,10 +6,8 @@ import java.util.Iterator; import java.util.List; import org.apache.log4j.Logger; -import org.openslx.imagemaster.App; import org.openslx.imagemaster.Globals; import org.openslx.imagemaster.Globals.PropInt; -import org.openslx.imagemaster.db.DbFtpUser; import org.openslx.imagemaster.db.DbImage; import org.openslx.imagemaster.db.DbUser; import org.openslx.imagemaster.thrift.iface.ImageData; @@ -45,8 +43,6 @@ public class ImageProcessor DbImage.delete( dbImage.UUID ); log.info( "Deleted dbimage from db: " + dbImage.UUID + " due to timeout"); } else { - // re add users to ftpserver - App.ftpServer.addUser( dbImage.ftpUser, DbFtpUser.getUserByName( dbImage.ftpUser ).password, MasterFtpServer.Mode.UPLOADING, "" ); log.info( "Added user '" + dbImage.ftpUser + "' to list again." ); // add image to process list again diff --git a/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java b/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java index f8b8ca1..8ed64d6 100644 --- a/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java +++ b/src/main/java/org/openslx/imagemaster/ftp/MasterFtpServer.java @@ -1,6 +1,7 @@ package org.openslx.imagemaster.ftp; import java.io.File; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -23,6 +24,7 @@ import org.apache.ftpserver.usermanager.impl.WritePermission; import org.apache.log4j.Logger; import org.openslx.imagemaster.Globals; import org.openslx.imagemaster.Globals.PropString; +import org.openslx.imagemaster.db.DbFtpUser; import org.openslx.imagemaster.thrift.iface.FtpCredentials; import org.openslx.imagemaster.util.RandomString; import org.openslx.imagemaster.util.Util; @@ -40,7 +42,18 @@ public class MasterFtpServer implements Runnable public enum Mode { - UPLOADING, DOWNLOADING + UPLOADING, DOWNLOADING; + + @Override + public String toString() { + if (this == UPLOADING) { + return "uploading"; + } else if (this == DOWNLOADING) { + return "downloading"; + } else { + return ""; + } + } } /** @@ -54,12 +67,14 @@ public class MasterFtpServer implements Runnable private final Long createTime; private final Mode mode; private final String fileName; + private final String serverSessionId; - public Infos(Long createTime, Mode mode, String fileName) + public Infos(Long createTime, Mode mode, String fileName, String serverSessionId) { this.createTime = createTime; this.mode = mode; this.fileName = fileName; + this.serverSessionId = serverSessionId; } public Long getCreateTime() @@ -76,6 +91,10 @@ public class MasterFtpServer implements Runnable { return this.fileName; } + + public String getServerSessionId() { + return this.serverSessionId; + } } public void init( int port ) @@ -125,9 +144,10 @@ public class MasterFtpServer implements Runnable * @param password * @param mode * @param fileName the filename of the file, that is allowed to access (if downloading) + * @param add user to db * @return */ - public boolean addUser( String username, String password, Mode mode, String fileName) + public boolean addUser( String serverSessionId, String username, String password, Mode mode, String fileName, boolean toDb) { String dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username + "/"; @@ -154,8 +174,9 @@ public class MasterFtpServer implements Runnable try { userManager.save( user ); synchronized ( users ) { - users.put( username, new Infos( System.currentTimeMillis(), mode, file) ); - + users.put( username, new Infos( System.currentTimeMillis(), mode, file, serverSessionId) ); + if (toDb) + DbFtpUser.addUser( new DbFtpUser( username, password, mode.toString(), fileName, serverSessionId, new Timestamp(System.currentTimeMillis()) ) ); } } catch ( FtpException e ) { return false; @@ -171,8 +192,6 @@ public class MasterFtpServer implements Runnable String generatedUser = RandomString.generate( 10, false ); String generatedPass = RandomString.generate( 16, true ); - String dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" - + generatedUser + "/"; BaseUser user = new BaseUser(); user.setName( generatedUser ); @@ -180,29 +199,32 @@ public class MasterFtpServer implements Runnable List<Authority> authorities = new ArrayList<Authority>(); String file = ""; + String dir = ""; if (mode == Mode.UPLOADING) { - // uploading satellite needs a folder + // generate the home dir + dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + generatedUser + "/"; if ( !new File( dir ).mkdir() ) { return null; } - user.setHomeDirectory( dir ); // uploading satellite is allowed to write authorities.add( new WritePermission() ); } else if (mode == Mode.DOWNLOADING) { // the downloading satellite may access the whole dir, but this is restricted in MasterFtplet - user.setHomeDirectory( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) ); + dir = Globals.getPropertyString( Globals.PropString.FTPBASEDIR ); // downloading satellite is only allowed to read file = fileName; } + user.setHomeDirectory( dir ); user.setAuthorities( authorities ); try { userManager.save( user ); ftpCredentials = new FtpCredentials( generatedUser, generatedPass ); synchronized ( users ) { - users.put( ftpCredentials.username, new Infos( System.currentTimeMillis(), mode, file) ); + users.put( ftpCredentials.username, new Infos( System.currentTimeMillis(), mode, file, serverSessionId) ); + DbFtpUser.addUser( new DbFtpUser( generatedUser, generatedPass, mode.toString(), fileName, serverSessionId, new Timestamp(System.currentTimeMillis()) ) ); } } catch ( FtpException e ) { // TODO: handle this @@ -235,6 +257,7 @@ public class MasterFtpServer implements Runnable // remove user from map (cache) synchronized ( users ) { users.remove( username ); + DbFtpUser.removeUserByName( username ); } // remove his home dir File dir = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + username ); @@ -256,4 +279,31 @@ public class MasterFtpServer implements Runnable e1.printStackTrace(); } } + + public void addDbFtpUsers() + { + List<DbFtpUser> list = DbFtpUser.getAllUsers(); + Iterator<DbFtpUser> iter = list.iterator(); + + int n = 0; + + while (iter.hasNext()) { + DbFtpUser user = iter.next(); + Mode mode; + if ( user.mode.equalsIgnoreCase( "downloading" ) ) { + mode = Mode.DOWNLOADING; + } else { + mode = Mode.UPLOADING; + } + // don't readd user if it timeouted + if ( (System.currentTimeMillis() - user.timestamp.getTime()) < FtpCredentialsScheduler.timeout ) { + this.addUser( user.sessionId, user.username, user.password, mode, user.filename, false ); + n++; + } else { + DbFtpUser.removeUserByName( user.username ); + } + } + + log.info( "Added " + n + " FTP users from DB." ); + } } diff --git a/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java b/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java index 31d39dc..ce4a2e6 100644 --- a/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java +++ b/src/main/java/org/openslx/imagemaster/ftp/MasterFtplet.java @@ -1,6 +1,9 @@ package org.openslx.imagemaster.ftp; import java.io.IOException; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; import org.apache.ftpserver.ftplet.FtpException; import org.apache.ftpserver.ftplet.FtpReply; @@ -9,13 +12,14 @@ import org.apache.ftpserver.ftplet.FtpSession; import org.apache.ftpserver.ftplet.Ftplet; import org.apache.ftpserver.ftplet.FtpletContext; import org.apache.ftpserver.ftplet.FtpletResult; -import org.apache.ftpserver.ftplet.User; import org.apache.log4j.Logger; import org.openslx.imagemaster.App; +import org.openslx.imagemaster.ftp.MasterFtpServer.Infos; +import org.openslx.imagemaster.serversession.ServerSessionManager; public class MasterFtplet implements Ftplet { - private static Logger log = Logger.getLogger( Ftplet.class ); + private static Logger log = Logger.getLogger( MasterFtplet.class ); @Override public void init( FtpletContext ftpletContext ) throws FtpException @@ -34,26 +38,36 @@ public class MasterFtplet implements Ftplet throws FtpException, IOException { if ( session.getUser() != null ) { - log.info( session.getUser().getName() + " issued command: " + request.getRequestLine() ); // check if masterserver is still knowing this user if (App.ftpServer.users.containsKey( session.getUser().getName() )) { MasterFtpServer.Infos infos = App.ftpServer.users.get( session.getUser().getName() ); - if (infos.getMode() == MasterFtpServer.Mode.DOWNLOADING) { - if (request.getCommand() == "RETR") { + if (infos.getMode() == MasterFtpServer.Mode.DOWNLOADING) { // filter the downloading clients + if (request.getCommand().equals("RETR")) { // check if user is getting the right file - if (infos.getFileName() != request.getArgument()) { - throw new FtpException( "550 File unavailable." ); + if (!infos.getFileName().equals(request.getArgument())) { + // the client tries to retrieve a file, that he is not allowed to get + String organization = ServerSessionManager.getSession( App.ftpServer.users.get( session.getUser().getName() ).getServerSessionId() ).getOrganization(); + log.info( "A user from organization '" + organization + "' tried to download a file (" + request.getArgument() + "), that he was not allowed to." ); + throw new FtpException( "550 File unavailable." ); // after the exception, the client will be automatically be disconnected } + } else if ( request.getCommand().equals( "MLSD" ) // list dirs + || request.getCommand().equals( "NSLT" ) // list files + || request.getCommand().equals( "CWD" ) // change working dir + ) { + + // TODO: block all other commands except login and retrieve + return FtpletResult.DISCONNECT; // disconnect the client on wrong command } - // TODO: block all other commands except login and retrieve } } else { // user is not valid anymore throw new FtpException( "430 Invalid username or password." ); // ERROR CODE 430 --> invalid username or password + // after the exception, the client will be automatically be disconnected } } - return null; + + return FtpletResult.DEFAULT; } @Override @@ -61,7 +75,7 @@ public class MasterFtplet implements Ftplet FtpReply reply ) throws FtpException, IOException { // not used - return null; + return FtpletResult.DEFAULT; } @Override @@ -71,15 +85,17 @@ public class MasterFtplet implements Ftplet if (session.getUser() != null) { log.info( session.getUser().getName() + " connected" ); } - return null; + return FtpletResult.DEFAULT; } @Override public FtpletResult onDisconnect( FtpSession session ) throws FtpException, IOException { - // not used - return null; + if (session.getUser() != null) { + log.info( session.getUser().getName() + " disconnected" ); + } + return FtpletResult.DEFAULT; } } diff --git a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java index c8a3a4a..9ad1fcb 100644 --- a/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java +++ b/src/main/java/org/openslx/imagemaster/thrift/server/ImageServerHandler.java @@ -77,4 +77,11 @@ public class ImageServerHandler implements ImageServer.Iface return ApiServer.getImage( uuid, serverSessionId ); } + @Override + public boolean finishedDownload( String ftpUser ) throws TException + { + // TODO Auto-generated method stub + return false; + } + } diff --git a/src/main/thrift/imagemaster.thrift b/src/main/thrift/imagemaster.thrift index 224ed75..26001da 100644 --- a/src/main/thrift/imagemaster.thrift +++ b/src/main/thrift/imagemaster.thrift @@ -110,7 +110,9 @@ service ImageServer { bool finshedUpload(1:string ftpUser, 2:ImageData imageDescription) throws (1: ImageDataException failure), - FtpCredentials getImage(1:UUID uuid, 2:string serverSessionId) throws (1:AuthorizationException failure, 2: ImageDataException failure2) + FtpCredentials getImage(1:UUID uuid, 2:string serverSessionId) throws (1:AuthorizationException failure, 2: ImageDataException failure2), + + bool finishedDownload(1:string ftpUser) } |