package org.openslx.imagemaster.server;
import java.nio.ByteBuffer;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.imagemaster.db.DbImage;
import org.openslx.imagemaster.db.DbSatellite;
import org.openslx.imagemaster.serverconnection.ImageProcessor;
import org.openslx.imagemaster.serversession.ServerAuthenticator;
import org.openslx.imagemaster.serversession.ServerSession;
import org.openslx.imagemaster.serversession.ServerSessionManager;
import org.openslx.imagemaster.serversession.ServerUser;
import org.openslx.imagemaster.session.Authenticator;
import org.openslx.imagemaster.session.Session;
import org.openslx.imagemaster.session.SessionManager;
import org.openslx.imagemaster.session.User;
import org.openslx.imagemaster.thrift.iface.AuthenticationError;
import org.openslx.imagemaster.thrift.iface.AuthenticationException;
import org.openslx.imagemaster.thrift.iface.AuthorizationError;
import org.openslx.imagemaster.thrift.iface.AuthorizationException;
import org.openslx.imagemaster.thrift.iface.DownloadInfos;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.ImageDataError;
import org.openslx.imagemaster.thrift.iface.ImageDataException;
import org.openslx.imagemaster.thrift.iface.InvalidTokenException;
import org.openslx.imagemaster.thrift.iface.ServerAuthenticationError;
import org.openslx.imagemaster.thrift.iface.ServerAuthenticationException;
import org.openslx.imagemaster.thrift.iface.ServerSessionData;
import org.openslx.imagemaster.thrift.iface.SessionData;
import org.openslx.imagemaster.thrift.iface.UploadException;
import org.openslx.imagemaster.thrift.iface.UploadInfos;
import org.openslx.imagemaster.thrift.iface.UserInfo;
import org.openslx.imagemaster.util.RandomString;
/**
* API Server This is where all the requests from the outside arrive. We don't
* handle them directly in the Thrift handlers, as we might be adding other APIs
* later, like JSON/SOAP/REST/HTTP/XML or some other stuff. They'd all just
* interface with this static class here. Note that we use the exceptions from
* the thrift interface that you can simply catch in any other API handler and
* eg. transform into error codes, if the API doesn't support exceptions.
*
* This will be accessed from multiple threads, so use synchronization when
* needed (or in doubt)
*/
public class ApiServer
{
/**
* Request for authentication
*
* @param login The user's login in the form "user@organization.com"
* @param password user's password
* @return SessionData struct with session id/token iff login successful
* @throws AuthenticationException if login not successful
*/
public static SessionData authenticate( String login, String password )
throws AuthenticationException
{
if ( login == null || password == null ) {
throw new AuthenticationException(
AuthenticationError.INVALID_CREDENTIALS,
"Empty username or password!" );
}
final User user = Authenticator.authenticate( login, password );
final Session session = new Session( user );
return SessionManager.addSession( session );
}
/**
* Request information about user for given token
*
* @param token a user's token
* @return UserInfo struct for given token's user
* @throws InvalidTokenException if no user matches the given token
*/
public static UserInfo getUserFromToken( String token )
throws InvalidTokenException
{
final Session session = SessionManager.getSession( token );
if ( session == null )
throw new InvalidTokenException();
return new UserInfo( session.getUserId(), session.getFirstName(),
session.getLastName(), session.getEMail() );
}
// /**
// * Request ftp credentials to upload a new image to the masterserver.
// *
// * @param imageDescription MetaData of the new image
// * @param serverSessionData the session data of the authenticated uni/hs server
// * @return the genereated ftp credentials
// * @throws AuthorizationException if the uni/hs server has no valid session
// * @throws TException
// */
// public static FtpCredentials submitImage( String serverSessionId,
// ImageData imageDescription ) throws AuthorizationException, ImageDataException
// {
// if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
// throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
// }
//
// // create new user
// FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId , MasterFtpServer.Mode.UPLOADING, "");
//
// if ( ftpCredentials == null ) {
// log.error( "Could not create ftp credentials" );
// return null;
// }
//
// try {
// ImageProcessor.addImageDataToProcess( imageDescription, ftpCredentials.username, ftpCredentials.password );
// } catch (ImageDataException e) {
// App.ftpServer.removeUser( serverSessionId );
// throw new ImageDataException( ImageDataError.INVALID_DATA, e.getMessage() );
// }
//
// return ftpCredentials;
// }
public static UploadInfos submitImage( String serverSessionId, ImageData imageDescription ) throws AuthorizationException, ImageDataException, UploadException
{
// first check session of server
if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessioId" );
}
// then let the image processor decide what to do
return ImageProcessor.getUploadInfos(serverSessionId, imageDescription);
}
public static DownloadInfos getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
{
// first check session of server
if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionId" );
}
if (!DbImage.exists( uuid )) {
throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "UUID is not known by this server." );
}
String path = DbImage.getImageByUUID( uuid ).imagePath;
// TODO: init the updownloader class
return new DownloadInfos( RandomString.generate( 100, false ) );
}
/**
* Start the server authentication of a uni/hs satellite server.
*
* @param organization the organization that the server belongs to
* @return a random string that needs to be encrypted with the private
* key of the requesting satellite server
* @throws ServerAuthenticationException when organization is invalid/unknown
*/
public static String startServerAuthentication( String organization )
throws ServerAuthenticationException
{
if ( organization == null || organization == "" ) {
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization" );
}
if ( DbSatellite.fromOrganization( organization ) == null ) {
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization" );
}
return ServerAuthenticator.startServerAuthentication( organization );
}
/**
* Authenticate the uni/hs satellite server with the encrypted string.
*
* @param organization the organization that the server belongs to
* @param challengeResponse the encrypted string
* @return session data iff the authentication was successful
* @throws AuthenticationException
* @throws TException
*/
public static ServerSessionData serverAuthenticate( String organization,
ByteBuffer challengeResponse ) throws AuthenticationException,
TException
{
if ( organization == null || challengeResponse == null ) {
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Empty organization or challengeResponse" );
}
DbSatellite satellite = DbSatellite.fromOrganization( organization );
if ( satellite == null ) {
throw new ServerAuthenticationException( ServerAuthenticationError.INVALID_ORGANIZATION, "Unknown organization" );
}
final ServerUser serverUser = ServerAuthenticator.serverAuthenticate(
organization, satellite.getAddress(), challengeResponse );
final ServerSession session = new ServerSession( serverUser );
return ServerSessionManager.addSession( session );
}
// /**
// * Tell the masterserver that the image upload finished.
// *
// * @param ftpUser the user that was used to upload
// * @param imageDescription the description of the uploaded image
// * @return if nothing went wrong
// * @throws ImageDataException if image was not submitted before
// * @throws AuthorizationException if no valid session exists
// */
// public static boolean finishedUpload( String ftpUser, ImageData imageDescription ) throws ImageDataException
// {
// // check if user is valid
// synchronized ( App.ftpServer.users ) {
// if (!App.ftpServer.users.containsKey( ftpUser )) {
// throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "Image with this data was not submitted before." );
// } else {
// if ( App.ftpServer.users.get( ftpUser ).getMode() == MasterFtpServer.Mode.DOWNLOADING ) {
// throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "Your were downloading and not uploading." );
// }
// }
// }
//
// // process the image
// File userDirectory = new File( Globals.getPropertyString( Globals.PropString.FTPBASEDIR ) + "/" + ftpUser );
// File[] list = userDirectory.listFiles();
//
// if ( list == null || list.length != 1 ) {
// // user uploaded too many files
// return false;
// }
//
// log.info( ftpUser + " is done with upload" );
//
// ImageProcessor.processImageAfterUpload( ftpUser, list[0].getName() );
//
// // remove user that is not needed anymore
// App.ftpServer.removeUser( ftpUser );
// log.info( "Removed user: " + ftpUser );
//
// return true;
// }
// public static FtpCredentials getImage( String uuid, String serverSessionId ) throws AuthorizationException, ImageDataException
// {
// if ( ServerSessionManager.getSession( serverSessionId ) == null ) {
// throw new AuthorizationException( AuthorizationError.NOT_AUTHENTICATED, "No valid serverSessionData" );
// }
//
// // check if image exists
// DbImage image = DbImage.getImageByUUID( uuid );
//
// if (image == null) throw new ImageDataException( ImageDataError.UNKNOWN_IMAGE, "No image found with uuid '" + uuid + "'");
//
// FtpCredentials ftpCredentials = App.ftpServer.addUser( serverSessionId, MasterFtpServer.Mode.DOWNLOADING, new File(image.imagePath).getName() );
//
// // TODO: what is happening here?
// if (ftpCredentials == null) return null;
//
// return ftpCredentials;
// }
// public static boolean finishedDownload( String ftpUser )
// {
// if ( !App.ftpServer.users.containsKey( ftpUser ))
// return false;
//
// log.info( "User: '" + ftpUser + "' finished download and gets deleted." );
//
// // download is done, user can be removed now
// App.ftpServer.removeUser( ftpUser );
//
// return true;
// }
}