1 package org.openslx.imagemaster.thrift.server;
4 import java.nio.ByteBuffer;
5 import java.security.Key;
6 import java.security.NoSuchAlgorithmException;
7 import java.security.spec.InvalidKeySpecException;
8 import java.sql.SQLException;
9 import java.util.ArrayList;
10 import java.util.List;
12 import org.apache.logging.log4j.LogManager;
13 import org.apache.logging.log4j.Logger;
14 import org.apache.thrift.TException;
15 import org.
openslx.bwlp.thrift.iface.AuthorizationError;
16 import org.
openslx.bwlp.thrift.iface.ClientSessionData;
17 import org.
openslx.bwlp.thrift.iface.ImageDetailsRead;
18 import org.
openslx.bwlp.thrift.iface.ImagePublishData;
19 import org.
openslx.bwlp.thrift.iface.ImageSummaryRead;
20 import org.
openslx.bwlp.thrift.iface.InvocationError;
21 import org.
openslx.bwlp.thrift.iface.MasterServer;
22 import org.
openslx.bwlp.thrift.iface.MasterSoftware;
23 import org.
openslx.bwlp.thrift.iface.MasterTag;
24 import org.
openslx.bwlp.thrift.iface.OperatingSystem;
25 import org.
openslx.bwlp.thrift.iface.Organization;
26 import org.
openslx.bwlp.thrift.iface.Satellite;
27 import org.
openslx.bwlp.thrift.iface.ServerSessionData;
28 import org.
openslx.bwlp.thrift.iface.SessionData;
29 import org.
openslx.bwlp.thrift.iface.TAuthorizationException;
30 import org.
openslx.bwlp.thrift.iface.TInvalidTokenException;
31 import org.
openslx.bwlp.thrift.iface.TInvocationException;
32 import org.
openslx.bwlp.thrift.iface.TNotFoundException;
33 import org.
openslx.bwlp.thrift.iface.TTransferRejectedException;
34 import org.
openslx.bwlp.thrift.iface.TransferInformation;
35 import org.
openslx.bwlp.thrift.iface.TransferStatus;
37 import org.
openslx.bwlp.thrift.iface.Virtualizer;
39 import org.
openslx.filetransfer.util.ChunkList;
40 import org.
openslx.filetransfer.util.FileChunk;
61 import org.
openslx.thrifthelper.ImagePublishDataEx;
75 public SessionData
authenticate( String login, String password )
throws TAuthorizationException, TInvocationException
78 String serverAddress = null;
79 if ( csd.satellites != null && !csd.satellites.isEmpty() ) {
80 for ( Satellite sat : csd.satellites ) {
81 if ( sat.addressList == null || sat.addressList.isEmpty() )
83 if ( serverAddress == null || ( sat.displayName != null && sat.displayName.equals(
"default" ) ) ) {
84 serverAddress = sat.addressList.get( 0 );
88 return new SessionData( csd.sessionId, csd.authToken, serverAddress );
101 throws TAuthorizationException, TInvocationException
103 if ( login == null || password == null ) {
104 throw new TAuthorizationException(
105 AuthorizationError.INVALID_CREDENTIALS,
106 "Empty username or password!" );
121 if ( session == null )
127 public List<UserInfo>
findUser( String sessionId, String organizationId, String searchTerm )
128 throws TAuthorizationException, TInvocationException
132 throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED,
"Session ID not valid" );
134 if ( searchTerm == null || searchTerm.length() < 2 || searchTerm.replaceAll(
"[%_]",
"" ).length() < 2 )
135 return new ArrayList<>( 0 );
141 throws TAuthorizationException, TInvocationException
144 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
145 "This is a read-only failover master-server. Image up-/downloads are not available." );
148 if ( session == null )
149 throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED,
"Session ID not valid" );
153 }
catch ( SQLException e ) {
154 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database failure" );
160 throws TAuthorizationException, TNotFoundException, TInvocationException
163 if ( session == null )
164 throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED,
"Session ID not valid" );
168 }
catch ( SQLException e ) {
169 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database failure" );
196 if ( session == null )
197 throw new TInvalidTokenException();
219 if ( satellite == null )
220 throw new TAuthorizationException( AuthorizationError.INVALID_ORGANIZATION,
"Unknown satellite id: " + satelliteId );
222 throw new TAuthorizationException( AuthorizationError.INVALID_KEY,
"There is no public key known for your satellite." );
235 throws TAuthorizationException, TInvocationException
237 if ( challengeResponse == null )
238 throw new TAuthorizationException( AuthorizationError.INVALID_ORGANIZATION,
"Empty organization or challengeResponse" );
240 if ( satellite == null )
241 throw new TAuthorizationException( AuthorizationError.INVALID_ORGANIZATION,
"Unknown satellite id: " + satelliteId );
243 throw new TAuthorizationException( AuthorizationError.INVALID_KEY,
"There is no public key known for your satellite." );
252 public ImagePublishData
getImageData( String serverSessionId, String imageVersionId )
253 throws TAuthorizationException, TInvocationException, TNotFoundException
256 if ( session == null )
257 throw new TAuthorizationException( AuthorizationError.INVALID_TOKEN,
"Unknown session id/token" );
261 }
catch ( SQLException e ) {
262 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database error" );
267 public TransferInformation
submitImage( String userToken, ImagePublishData img, List<ByteBuffer> blockHashes )
268 throws TAuthorizationException, TInvocationException, TTransferRejectedException
272 throw new TTransferRejectedException(
"This is a read-only failover master-server. Image up-/downloads are not available." );
276 if ( session == null )
277 throw new TAuthorizationException( AuthorizationError.INVALID_TOKEN,
"Given user token not known to the server" );
283 throw new TInvocationException( InvocationError.INVALID_DATA,
"Image name not set" );
284 if ( img.fileSize <= 0 )
285 throw new TInvocationException( InvocationError.INVALID_DATA,
"File size is too small" );
287 throw new TInvocationException( InvocationError.MISSING_DATA,
"ImagePublishData has invalid imageBaseId" );
289 throw new TInvocationException( InvocationError.MISSING_DATA,
"ImagePublishData has invalid imageVersionId" );
290 if ( img.owner == null || img.owner.userId == null )
291 throw new TInvocationException( InvocationError.MISSING_DATA,
"Missing owner or owner is anonymous" );
292 if ( img.uploader == null || img.uploader.userId == null )
293 throw new TInvocationException( InvocationError.MISSING_DATA,
"Missing uploader or uploader is anonymous" );
295 boolean listComplete =
false;
296 if ( blockHashes != null && blockHashes.size() == FileChunk.fileSizeToChunkCount( img.fileSize ) ) {
298 for ( ByteBuffer bb : blockHashes ) {
299 if ( bb == null || bb.remaining() != FileChunk.SHA1_LENGTH ) {
300 listComplete =
false;
306 throw new TInvocationException( InvocationError.INVALID_DATA,
"Chunk hash list missing or incomplete" );
309 if ( existingUpload != null ) {
310 LOGGER.info(
"Satellite tried to register already existing upload for version " + img.imageVersionId +
" - is "
311 + existingUpload.getId() );
315 ImagePublishDataEx existing;
318 if ( existing != null ) {
319 if ( existing.fileSize != img.fileSize )
320 throw new TInvocationException( InvocationError.INVALID_DATA,
"Image already exists; file size mismatch" );
322 if ( !ChunkList.hashListsEqualBbBb( blockHashes, existingHashes ) )
323 throw new TInvocationException( InvocationError.INVALID_DATA,
"Image already exists; block hashes mismatch" );
325 }
catch ( SQLException e ) {
326 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Internal database error" );
331 throw new TInvocationException( InvocationError.INVALID_DATA,
"Content operating system not set" );
333 throw new TInvocationException( InvocationError.INVALID_DATA,
"Content virtualizer system not set" );
336 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Storage offline" );
341 }
catch ( TException t ) {
346 if ( existing == null ) {
349 }
catch ( SQLException e1 ) {
353 throw new TInvocationException( InvocationError.INVALID_DATA,
"The image already exists on the server" );
355 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database error" );
361 }
catch ( SQLException e ) {
362 LOGGER.warn(
"Could not insert block hashes of image " + img.imageVersionId +
" to db" );
368 public TransferInformation
downloadImage( String sessionId, String imageVersionId )
369 throws TAuthorizationException, TInvocationException, TNotFoundException, TTransferRejectedException
373 throw new TTransferRejectedException(
"This is a read-only failover master-server. Image up-/downloads are not available." );
377 if ( session == null )
378 throw new TAuthorizationException( AuthorizationError.INVALID_TOKEN,
"Given user token not known to the server" );
380 ImagePublishDataEx img;
381 List<ByteBuffer> blockHashes;
389 }
catch ( SQLException e ) {
390 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database error" );
392 if ( img == null || !img.exIsValid )
393 throw new TNotFoundException();
395 ti.machineDescription = img.machineDescription;
396 ti.blockHashes = blockHashes;
405 }
catch ( SQLException e ) {
406 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database error" );
415 }
catch ( SQLException e ) {
416 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database error" );
425 }
catch ( SQLException e ) {
426 throw new TInvocationException( InvocationError.INTERNAL_SERVER_ERROR,
"Database error" );
431 public List<MasterTag>
getTags(
long startDate )
throws TInvocationException
438 public List<MasterSoftware>
getSoftware(
long startDate )
throws TInvocationException
445 public int registerSatellite( String userToken, String displayName, List<String> addresses, String modulus,
446 String exponent, ByteBuffer certSha256 )
throws TInvocationException
448 if ( userToken == null || exponent == null || modulus == null )
449 throw new TInvocationException( InvocationError.MISSING_DATA,
"A required parameter is null" );
451 if ( session == null || session.
getUserInfo() == null )
452 throw new TInvocationException( InvocationError.UNKNOWN_USER,
"Not a valid user token" );
453 String organizationId = session.
getUserInfo().organizationId;
457 }
catch ( NoSuchAlgorithmException | InvalidKeySpecException e ) {
458 LOGGER.warn(
"Invalid public key in registerOrganization for " + organizationId +
" (By " + session.
getLogin() +
")", e );
459 throw new TInvocationException( InvocationError.INVALID_DATA,
"Cannot reconstruct public key" );
462 if ( existing != null ) {
464 if ( existingKey != null &&
Util.
keysEqual( newKey, existingKey ) )
469 }
catch ( SQLException e ) {
470 throw new TInvocationException();
475 public boolean updateSatellite( String serverSessionId, String displayName, List<String> addresses )
476 throws TAuthorizationException, TInvocationException
479 if ( session == null )
480 throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED,
"No valid serverSessionId" );
489 if ( upload == null )
490 throw new TInvalidTokenException();
491 return upload.getStatus();
495 public UserInfo
getUser( String userToken, String userId )
496 throws TAuthorizationException, TNotFoundException, TInvocationException
499 if ( session == null )
500 throw new TAuthorizationException( AuthorizationError.NOT_AUTHENTICATED,
"No valid user token" );
503 UserInfo queriedUser =
new UserInfo( userId, null, null, null, null );
505 if ( queriedUser == null )
506 throw new TNotFoundException(
"Unknown userid" );
static boolean isDuplicateKeyException(SQLException e)
UserInfo getUser(String userToken, String userId)
static ByteBuffer startServerAuthentication(int satelliteId)
Start the server authentification.
static List< ImageSummaryRead > getPublicList(int page)
void invalidateSession(String sessionId)
TransferStatus queryUploadStatus(String uploadToken)
static String getImageDir()
static ServerSessionData addSession(ServerSession serverSession)
static ImageDetailsRead getImageDetails(String imageBaseId)
static Session getSessionFromToken(String token)
Get from userToken, known to satellite servers.
static int add(UserInfo user, String displayName, List< String > address, String modulus, String exponent)
static List< Virtualizer > getVirtualizerList()
List< UserInfo > findUser(String sessionId, String organizationId, String searchTerm)
Manages all server sessions and kicks timed out sessions.
static List< UserInfo > findUser(String organizationId, String searchTerm)
Authenticating a server with message signing.
int registerSatellite(String userToken, String displayName, List< String > addresses, String modulus, String exponent, ByteBuffer certSha256)
static List< Organization > getAll()
Return all known satellites/organizations as List of OrganizationData, which can be used directly by ...
List< Organization > getOrganizations()
static void insertChunkList(String imageVersionId, List< FileChunk > all, boolean missing)
static ServerSession getSession(String sessionId)
static IncomingTransfer getUploadByToken(String uploadToken)
Representing an image in the database.
static ClientSessionData getSessionFromAccessCode(String accessCode)
Get the according session data (satToken, masterToken) for given access code, which was supplied by t...
Represents a user that can login against the masterserver.
Represents an organization in the database.
static ImagePublishDataEx getImageVersion(String imageVersionId)
static boolean isReadOnlyMode()
static UserInfo authenticate(String username, String password)
Authenticate the user against whatever backend.
ClientSessionData localAccountLogin(String login, String password)
Request for authentication.
static final Logger LOGGER
boolean isServerAuthenticated(String serverSessionId)
Class to handle all incoming and outgoing connections.
static void invalidate(String sessionId)
static List< OperatingSystem > getOsList()
static BigInteger tryToParseBigInt(String s)
Tries to parse a bigint.
static UserInfo getFirstPublishingUserOrDummy(UserInfo...user)
Given a list of users, return the first one that isn't anonymous, which means they opted in for globa...
static ClientSessionData addSession(Session session)
List< MasterSoftware > getSoftware(long startDate)
synchronized void cancel()
static IncomingTransfer getExistingUpload(ImagePublishData imageData, List< ByteBuffer > crcSums)
static void createImageVersion(ImagePublishData img, String relLocalPath)
Class to hold global constants and properties from 'config/global.properties'.
static boolean virtExists(String virtId)
Authenticates a user against a backend (mysql here)
Simple representation of a user session.
TransferInformation submitImage(String userToken, ImagePublishData img, List< ByteBuffer > blockHashes)
static boolean osExists(int osId)
static boolean isUUID(String id)
TransferInformation getTransferInfo()
ImagePublishData getImageData(String serverSessionId, String imageVersionId)
static TransferInformation registerDownload(ImagePublishDataEx img)
static void assertTutor(UserInfo userInfo)
static void serverAuthenticate(LocalSatellite satellite, ByteBuffer challengeResponse)
Authenticate with the challengeResponse.
static void removeUpload(IncomingTransfer transfer)
TransferInformation downloadImage(String sessionId, String imageVersionId)
static Session getSessionFromSessionIdOrToken(String sessionId)
ServerSessionData serverAuthenticate(int satelliteId, ByteBuffer challengeResponse)
Authenticate the uni/hs satellite server with the encrypted string.
boolean updateSatellite(String serverSessionId, String displayName, List< String > addresses)
List< Virtualizer > getVirtualizers()
static UserInfo getFirstPublishingUser(UserInfo...user)
Given a list of users, return the first one that isn't anonymous, which means they opted in for globa...
SessionData authenticate(String login, String password)
ImageDetailsRead getImageDetails(String sessionId, String imageBaseId)
Class for managing active user sessions.
Some utilities to make our lives easier.
static LocalSatellite get(int satelliteId)
List< MasterTag > getTags(long startDate)
static Session getSessionFromSessionId(String sessionId)
Get from sessionId, only known by client/user and us.
static boolean isEmpty(String str)
UserInfo getUserFromToken(String token)
Request information about user for given token.
List< ImageSummaryRead > getPublicImages(String sessionId, int page)
List< OperatingSystem > getOperatingSystems()
static List< ByteBuffer > getBlockHashes(String imageVersionId)
void setUsedSatellite(String sessionId, String satelliteName)
User tells us which satellite they connected to.
Holds the session id of the server and manages the timeout.
static boolean keysEqual(Key k1, Key k2)
Checks whether the two given keys are equal.
ClientSessionData getSessionFromAccessCode(String accessCode)
static IncomingTransfer registerUpload(ImagePublishData img, List< ByteBuffer > blockHashes, ImagePublishDataEx existing)
Register new incoming transfer from a satellite server.
ByteBuffer startServerAuthentication(int satelliteId)
Start the server authentication of a uni/hs satellite server.
static void createImageBase(ImagePublishData img)