package fr.eyal.datalib.sample.netflix;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.Random;
import java.util.SortedSet;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import fr.eyal.lib.data.communication.rest.ParameterMap;
public class NetflixUtils {
public static final String HMACSHA1_NAME_WEB = "HMAC-SHA1";
public static final String HMACSHA1_NAME = "HmacSHA1";
public static final String RSA_SHA1 = "SHA1withRSA";
public static final String ENCODING_UTF8 = "UTF-8";
public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
public static final int MAX_NONCE_SIZE = 20;
public static final int MIN_NONCE_SIZE = 5;
public static final int GENRE_ACTION = 296;
public static final int GENRE_ANIMATION = 623;
public static final int GENRE_BLURAY = 2444;
public static final int GENRE_CHILDREN = 302;
public static final int GENRE_CLASSIC = 306;
public static final int GENRE_COMEDY = 307;
public static final int GENRE_DOCUMENTARY = 864;
public static final int GENRE_DRAMA = 315;
public static final int GENRE_FAITH = 2108;
public static final int GENRE_FOREIGN = 2514;
public static final int GENRE_GAY = 330;
public static final int GENRE_HORROR = 338;
public static final int GENRE_INDEPENDENT = 343;
public static final int GENRE_MUSIC = 2310;
public static final int GENRE_ROMANCE = 371;
public static final int GENRE_SCIFI = 373;
public static final int GENRE_SPECIAL = 2223;
public static final int GENRE_SPORT = 2190;
public static final int GENRE_TELEVISION = 2197;
public static final int GENRE_THRILLER = 387;
/**
* Generates a random string
*
* @return a random string
*/
public static String getNonce(){
Random random = new Random();
return getNonce(MIN_NONCE_SIZE+random.nextInt(MAX_NONCE_SIZE-MIN_NONCE_SIZE+1));
}
/**
* Generates a random string
*
* @param size the size of the string
*
* @return a random string
*/
public static String getNonce(int size){
StringBuilder builder = new StringBuilder(size);
Random random = new Random();
for (int i = 0; i < size; i++) {
builder.append(ALPHABET.charAt(random.nextInt(ALPHABET.length())));
}
return builder.toString();
}
public static String byteToHex(final byte[] hash)
{
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
/**
* Generate an OAuth signature depending on the request content
*
* @param restAction the rest action to execute GET, POST, PUT, DELETE, HEAD
* @param url the scheme + authority + path of the request
* @param params the parameters of the request
*
* @return returns the OAuth signature to add to the request
*
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String getOAuthSignature(String restAction, String url, ParameterMap params) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException{
String parameters = getParametersString(params);
String signature;
signature = restAction+"&"+URLEncoder.encode(url, NetflixUtils.ENCODING_UTF8)+"&"+URLEncoder.encode(parameters, NetflixUtils.ENCODING_UTF8);
String keyString = NetflixConfig.CONSUMER_SECRET + '&';
byte[] keyBytes = keyString.getBytes(NetflixUtils.ENCODING_UTF8);
SecretKey key = new SecretKeySpec(keyBytes, HMACSHA1_NAME);
Mac mac = Mac.getInstance(HMACSHA1_NAME);
mac.init(key);
byte[] text = signature.getBytes(NetflixUtils.ENCODING_UTF8);
byte[] result = mac.doFinal(text);
String sign = new String(Base64.encodeBase64(result));
//we don't URL encode the signature because it is encoded by the Datalib process
signature = sign; //URLEncoder.encode(sign, NetflixUtils.ENCODING_UTF8);
return signature;
}
public static String getParametersString(ParameterMap params) {
StringBuilder builder = new StringBuilder();
SortedSet<String> keys = params.keySet(true);
for (String key : keys) {
builder.append(key);
builder.append('=');
builder.append(params.get(key));
builder.append('&');
}
//we remove the last & character
builder.deleteCharAt(builder.length()-1);
return builder.toString();
}
}