// Path: vilebot/src/main/java/com/oldterns/vilebot/util/HMAC.java
// public class HMAC
// {
// 
//     private static Logger logger = LoggerFactory.getLogger( HMAC.class );
// 
//     /**
//      * Generate an HMAC signature from message and key, using the SHA2 512 bit hash algo.
//      * 
//      * @param message The message to be signed
//      * @param key The key
//      * @return HMAC signature of message using key if no error, else null
//      */
//     public static String generateHMAC( String message, String key )
//     {
//         try
//         {
//             return generateHMAC( "HmacSHA512", message, key );
//         }
//         catch ( NoSuchAlgorithmException e )
//         {
//             logger.error( e.getMessage() );
//             logger.error( "Hash algorithim unsupported" );
//         }
//         return null;
//     }
// 
//     /**
//      * Generate an HMAC signature from message and key, using the given hash algo.
//      * 
//      * @param algo An Hmac Algorithm to use, see {@link Mac#getInstance(String)}
//      * @param message The message to be signed
//      * @param key The key
//      * @return HMAC signature of message using key if no error, else null
//      */
//     public static String generateHMAC( String algo, String message, String key )
//         throws NoSuchAlgorithmException
//     {
//         Mac mac = Mac.getInstance( algo );
//         SecretKeySpec secret = new SecretKeySpec( key.getBytes(), algo );
//         try
//         {
//             mac.init( secret );
// 
//             byte[] digest = mac.doFinal( message.getBytes() );
//             return bytesToHex( digest );
//         }
//         catch ( InvalidKeyException e )
//         {
//             logger.error( e.getMessage() );
//             logger.error( "Can't init Mac instance with key" );
//         }
//         return null;
//     }
// 
//     /**
//      * http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
//      * 
//      * @param bytes byte array
//      * @return String of byte array converted to hex characters. Lower case alphabet.
//      */
//     private static String bytesToHex( byte[] bytes )
//     {
//         final char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
//         char[] hexChars = new char[bytes.length * 2];
//         int v;
//         for ( int j = 0; j < bytes.length; j++ )
//         {
//             v = bytes[j] & 0xFF;
//             hexChars[j * 2] = hexArray[v >>> 4];
//             hexChars[j * 2 + 1] = hexArray[v & 0x0F];
//         }
//         return new String( hexChars );
//     }
// }


import java.util.UUID;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import com.oldterns.vilebot.util.HMAC;
        try
        {
            boolean newUser;

            Transaction trans;
            do
            {
                // Can't use intermediate results of a Redis transaction in that transaction, so watch the keys and do
                // the query before opening the transaction. The transaction will fail on exec() call if the keys
                // changed.
                jedis.watch( keyOfPassHash, keyOfPassSaltsHash );
                boolean exists = jedis.hexists( keyOfPassHash, username );

                trans = jedis.multi();
                // Create a salt as well as the new password entry if the user is new
                if ( !exists )
                {
                    newUser = true;

                    String salt = generateSalt();
                    trans.hset( keyOfPassSaltsHash, username, salt );

                    String hash = hash( password, salt );
                    trans.hset( keyOfPassHash, username, hash );
                }
                else
                    newUser = false;
            }
            while ( trans.exec() == null );

// Path: vilebot/src/main/java/com/oldterns/vilebot/util/HMAC.java
// public class HMAC
// {
// 
//     private static Logger logger = LoggerFactory.getLogger( HMAC.class );
// 
//     /**
//      * Generate an HMAC signature from message and key, using the SHA2 512 bit hash algo.
//      * 
//      * @param message The message to be signed
//      * @param key The key
//      * @return HMAC signature of message using key if no error, else null
//      */
//     public static String generateHMAC( String message, String key )
//     {
//         try
//         {
//             return generateHMAC( "HmacSHA512", message, key );
//         }
//         catch ( NoSuchAlgorithmException e )
//         {
//             logger.error( e.getMessage() );
//             logger.error( "Hash algorithim unsupported" );
//         }
//         return null;
//     }
// 
//     /**
//      * Generate an HMAC signature from message and key, using the given hash algo.
//      * 
//      * @param algo An Hmac Algorithm to use, see {@link Mac#getInstance(String)}
//      * @param message The message to be signed
//      * @param key The key
//      * @return HMAC signature of message using key if no error, else null
//      */
//     public static String generateHMAC( String algo, String message, String key )
//         throws NoSuchAlgorithmException
//     {
//         Mac mac = Mac.getInstance( algo );
//         SecretKeySpec secret = new SecretKeySpec( key.getBytes(), algo );
//         try
//         {
//             mac.init( secret );
// 
//             byte[] digest = mac.doFinal( message.getBytes() );
//             return bytesToHex( digest );
//         }
//         catch ( InvalidKeyException e )
//         {
//             logger.error( e.getMessage() );
//             logger.error( "Can't init Mac instance with key" );
//         }
//         return null;
//     }
// 
//     /**
//      * http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
//      * 
//      * @param bytes byte array
//      * @return String of byte array converted to hex characters. Lower case alphabet.
//      */
//     private static String bytesToHex( byte[] bytes )
//     {
//         final char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
//         char[] hexChars = new char[bytes.length * 2];
//         int v;
//         for ( int j = 0; j < bytes.length; j++ )
//         {
//             v = bytes[j] & 0xFF;
//             hexChars[j * 2] = hexArray[v >>> 4];
//             hexChars[j * 2 + 1] = hexArray[v & 0x0F];
//         }
//         return new String( hexChars );
//     }
// }


// Path: vilebot/src/main/java/com/oldterns/vilebot/db/PasswordDB.java
import java.util.UUID;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;
import com.oldterns.vilebot.util.HMAC;

        try
        {
            boolean newUser;

            Transaction trans;
            do
            {
                // Can't use intermediate results of a Redis transaction in that transaction, so watch the keys and do
                // the query before opening the transaction. The transaction will fail on exec() call if the keys
                // changed.
                jedis.watch( keyOfPassHash, keyOfPassSaltsHash );
                boolean exists = jedis.hexists( keyOfPassHash, username );

                trans = jedis.multi();
                // Create a salt as well as the new password entry if the user is new
                if ( !exists )
                {
                    newUser = true;

                    String salt = generateSalt();
                    trans.hset( keyOfPassSaltsHash, username, salt );

                    String hash = hash( password, salt );
                    trans.hset( keyOfPassHash, username, hash );
                }
                else
                    newUser = false;
            }
            while ( trans.exec() == null );

            return newUser;