package co.gem.round;
import co.gem.round.coinop.MultiWallet;
import co.gem.round.coinop.util.Network;
import co.gem.round.crypto.EncryptedMessage;
import co.gem.round.crypto.PassphraseBox;
import co.gem.round.patchboard.Client;
import co.gem.round.patchboard.Resource;
import com.google.gson.JsonObject;
import org.spongycastle.crypto.InvalidCipherTextException;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
/**
* UserCollection provides functionality to create users and generate a collection of users.
* @author Julian Vergel de Dios (julian@gem.co) on 12/18/14.
*/
public class UserCollection extends BaseCollection<User> {
public UserCollection(Resource resource, Round round) { super(resource, round); }
/**
* Create a User on the Gem platform. At the time of user creation a default HD multi-sig wallet is created
* labeled "default". The wallet requires a passphrase to encrypt the primary key and the network for address
* creation.
* @param email of the user
* @param firstName of the user
* @param lastName of the user
* @param passphrase to encrypt the primary seed
* @return String deviceToken, used to authenticate device
* @throws Client.UnexpectedStatusCodeException
* @throws IOException
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
*/
public String create(String email, String firstName, String lastName, String passphrase,
String deviceName) throws NoSuchAlgorithmException, Client.UnexpectedStatusCodeException,
InvalidKeySpecException, IOException, NoSuchPaddingException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, NoSuchProviderException, InvalidCipherTextException {
return create(email, firstName, lastName, passphrase, deviceName, null);
}
/**
* Create a User on the Gem platform. At the time of user creation a default HD multi-sig wallet is created
* labeled "default". The wallet requires a passphrase to encrypt the primary key and the network for address
* creation.
* @param email of the user
* @param firstName of the user
* @param lastName of the user
* @param passphrase to encrypt the primary seed
* @param redirectUri the user is sent to after confirming his/her email
* @return String deviceToken, used to authenticate device
* @throws Client.UnexpectedStatusCodeException
* @throws IOException
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
*/
public String create(String email, String firstName, String lastName, String passphrase,
String deviceName, String redirectUri)
throws Client.UnexpectedStatusCodeException, IOException, InvalidKeySpecException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidAlgorithmParameterException, BadPaddingException, NoSuchPaddingException, InvalidKeyException, NoSuchProviderException, InvalidCipherTextException {
MultiWallet multiWallet = MultiWallet.generate(Network.blockchainNetwork("bitcoin"));
String primaryPrivateSeed = multiWallet.serializedPrimaryPrivateSeed();
EncryptedMessage encryptedPrivateSeed = PassphraseBox.encrypt(passphrase, primaryPrivateSeed);
JsonObject wallet = new JsonObject();
wallet.addProperty("name", "default");
wallet.addProperty("primary_public_seed", multiWallet.serializedPrimaryPublicKey());
wallet.add("primary_private_seed", encryptedPrivateSeed.asJsonObject());
JsonObject payload = new JsonObject();
if (redirectUri != null) {
// payload.addProperty("redirect_uri", redirectUri);
}
payload.addProperty("email", email);
payload.addProperty("device_name", deviceName);
payload.add("default_wallet", wallet);
payload.addProperty("first_name", firstName);
payload.addProperty("last_name", lastName);
Resource resource = this.resource.action("create", payload);
return resource.attributes().get("metadata").getAsJsonObject().get("device_token").getAsString();
}
@Override
public void populateCollection(Iterable<Resource> collection) {
for (Resource resource : collection) {
User user = new User(resource, round);
add(user.email(), user);
}
}
}