summaryrefslogtreecommitdiffstats
path: root/src/main/java/org/openslx/imagemaster/server/ApiServer.java
blob: 104d98d6dd82242e387d6405fcd8fb79c72be627 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package org.openslx.imagemaster.server;

import java.nio.ByteBuffer;
import java.util.List;

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;

/**
 * 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() );
	}

	public static UploadInfos submitImage( String serverSessionId, ImageData imageDescription, List<Integer> crcSums )
			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, crcSums );
	}

	public static DownloadInfos getImage( String uuid, String serverSessionId, List<Integer> requestedBlocks ) 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." );
		}

		// then let the image processor decide what to do
		return ImageProcessor.getDownloadInfos( serverSessionId, uuid, requestedBlocks );
	}

	/**
	 * 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.isEmpty() ) {
			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 ServerAuthenticationException,
			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 );
	}

	public static boolean isServerAuthenticated( String serverSessionId )
	{
		return ( ServerSessionManager.getSession( serverSessionId ) != null );
	}
}