|
|
package org.openslx.imagemaster.server;
import java.io.File;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.openslx.imagemaster.Globals;
import org.openslx.imagemaster.db.DbSatellite;
import org.openslx.imagemaster.db.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.AuthorizationException;
import org.openslx.imagemaster.thrift.iface.FtpCredentials;
import org.openslx.imagemaster.thrift.iface.ImageData;
import org.openslx.imagemaster.thrift.iface.InvalidTokenException;
import org.openslx.imagemaster.thrift.iface.ServerSessionData;
import org.openslx.imagemaster.thrift.iface.SessionData;
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 {
private static Logger log = Logger.getLogger(ApiServer.class);
/**
* 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(ImageData imageDescription,
ServerSessionData serverSessionData) throws AuthorizationException,
TException {
if (ServerSessionManager.getSession(serverSessionData.sessionId) == null) {
throw new AuthenticationException(AuthenticationError.GENERIC_ERROR, "No valid serverSessionData");
}
String generatedUser = RandomString.generate(10, false);
String generatedPass = RandomString.generate(16, true);
if (!ImageProcessor.addImageDataToProcess(imageDescription, generatedUser)) {
throw new TException("ImageData is not valid.");
}
String dir = Globals.properties.getProperty("ftp_base_dir") + "/"
+ generatedUser + "/";
if (new File(dir).mkdir()) {
Globals.ftpServer.addUser(generatedUser, generatedPass, dir, true);
log.info("Generated user/pass: " + generatedUser + "\t"
+ generatedPass + "\n with home dir: " + dir);
}
return new FtpCredentials(generatedUser, generatedPass);
}
/**
* 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 TException
*/
public static String startServerAuthentication(String organization)
throws TException {
// TODO: Proper exceptions
if (organization == null || organization == "") {
throw new TException("Empty organization");
}
if (DbSatellite.fromOrganization(organization) == null) {
throw new TException("Unkown 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,
String challengeResponse) throws AuthenticationException,
TException {
// TODO: Proper exceptions
if (organization == null || challengeResponse == null) {
throw new TException("Empty organization org challengeResponse");
}
DbSatellite satellite = DbSatellite.fromOrganization(organization);
if (satellite == null) {
throw new TException("Unkown organization");
}
final ServerUser serverUser = ServerAuthenticator.serverAuthenticate(
organization, satellite.getAddress(), challengeResponse);
final ServerSession session = new ServerSession(serverUser);
return ServerSessionManager.addSession(session);
}
}
|