package org.openslx.imagemaster.db;
import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.openslx.encryption.AsymKeyHolder;
import org.openslx.imagemaster.thrift.iface.OrganizationData;
/**
* Represents a satellite in the database.
* Is used to authenticate the satellite.
*/
public class DbSatellite
{
private static final Logger LOG = Logger.getLogger( DbSatellite.class );
private String organizationId, address, name, publickeyString, authMethod;
private PublicKey publickey = null;
private List<String> suffixList = null;
public DbSatellite( String organizationId, String address, String name, String authMethod, String publickeyString )
{
this.organizationId = organizationId;
this.address = address;
this.name = name;
this.publickeyString = publickeyString;
}
public static DbSatellite fromOrganizationId( String organizationId )
{
return MySQL
.findUniqueOrNull(
DbSatellite.class,
"SELECT satellite.organizationid, satellite.address, satellite.name, satellite.authmethod, satellite.publickey FROM satellite WHERE satellite.organizationid = ? LIMIT 1",
organizationId );
}
public static DbSatellite fromSuffix( String suffix )
{
return MySQL
.findUniqueOrNull(
DbSatellite.class,
"SELECT satellite.organizationid, satellite.address, satellite.name, satellite.authmethod, satellite.publickey FROM satellite"
+ " INNER JOIN satellite_suffix USING (organizationid)"
+ " WHERE satellite_suffix.suffix = ? LIMIT 1",
suffix );
}
/**
* Return all known satellites/organizations as List of {@link OrganizationData}, which can be
* used directly by the thrift API.
*
* @return list of all known organizations/satellites
*/
public static List<OrganizationData> asOrganizationDataList()
{
List<DbSatellite> sats = MySQL.findAll(
DbSatellite.class,
"SELECT satellite.organizationid, satellite.address, satellite.name, satellite.authmethod, satellite.publickey FROM satellite" );
List<OrganizationData> orgData = new ArrayList<>();
for ( DbSatellite sat : sats ) {
orgData.add( new OrganizationData( sat.getOrganizationId(), sat.getName(), sat.getAuthenticationMethod(), sat.getSuffixList() ) );
}
return orgData;
}
public static DbSatellite fromPrefix( String prefix )
{
return null;
}
/*
* Member methods
*/
public String getAddress()
{
return address;
}
public String getName()
{
return name;
}
public String getOrganizationId()
{
return organizationId;
}
public String getAuthenticationMethod()
{
return authMethod;
}
public List<String> getSuffixList()
{
if ( this.suffixList == null )
this.suffixList = DbSatelliteSuffix.forSatellite( this );
return this.suffixList;
}
/**
* Get the public key of this organization, if known and valid.
*
* @return Public key, null on error or not known
*/
public PublicKey getPubkey()
{
if ( publickey == null && publickeyString != null ) {
String parts[] = publickeyString.split( " " );
BigInteger mod = null;
BigInteger exp = null;
for ( int i = 0; i < parts.length; ++i ) {
if ( parts[i].startsWith( "mod:" ) ) {
// modulus found.
mod = new BigInteger( parts[i].substring( 4 ) );
}
if ( parts[i].startsWith( "exp:" ) ) {
// exponent found.
exp = new BigInteger( parts[i].substring( 4 ) );
}
}
if ( mod == null ) {
LOG.error( "No modulus for building public key was found." );
return null;
}
if ( exp == null ) {
LOG.error( "No public exponent for building public key was found." );
return null;
}
try {
publickey = new AsymKeyHolder( null, exp, mod ).getPublicKey();
} catch ( InvalidKeySpecException | NoSuchAlgorithmException e ) {
LOG.info( "PubKey of " + this.name + " is not valid.", e );
} catch ( NumberFormatException e ) {
LOG.info( "PubKey of " + this.name + " is corrupted in database!", e );
}
}
return publickey;
}
public void updateAddress( String address, String organization )
{
this.address = address;
this.organizationId = organization;
MySQL.update( "UPDATE satellite SET address = ? WHERE organizationid = ?", address, organization );
}
}