package im.actor.core.modules.encryption;
import java.io.IOException;
import java.util.ArrayList;
import im.actor.core.api.ApiEncryptedBox;
import im.actor.core.api.ApiEncryptedBoxSignature;
import im.actor.core.api.ApiEncryptedMessage;
import im.actor.core.api.ApiEncyptedBoxKey;
import im.actor.core.api.ApiMessage;
import im.actor.core.entity.Peer;
import im.actor.core.modules.ModuleContext;
import im.actor.core.modules.encryption.entity.EncryptedBox;
import im.actor.core.modules.encryption.entity.EncryptedBoxKey;
import im.actor.core.modules.ModuleActor;
import im.actor.runtime.*;
import im.actor.runtime.Runtime;
import im.actor.runtime.actors.ask.AskCallback;
import im.actor.runtime.function.Function;
import im.actor.runtime.promise.Promise;
public class EncryptedMsgActor extends ModuleActor {
private static final String TAG = "MessageEncryptionActor";
public EncryptedMsgActor(ModuleContext context) {
super(context);
}
private Promise doEncrypt(int uid, ApiMessage message) throws IOException {
Log.d(TAG, "doEncrypt");
// return ask(context().getEncryption().getEncryptedChatManager(uid), new EncryptedPeerActor.EncryptBox(message.buildContainer()))
// .map(new Function<EncryptedPeerActor.EncryptBoxResponse, EncryptedMessage>() {
// @Override
// public EncryptedMessage apply(EncryptedPeerActor.EncryptBoxResponse encryptBoxResponse) {
// Log.d(TAG, "doEncrypt:onResult");
// ArrayList<ApiEncyptedBoxKey> boxKeys = new ArrayList<ApiEncyptedBoxKey>();
// for (EncryptedBoxKey b : encryptBoxResponse.getBox().getKeys()) {
// boxKeys.add(new ApiEncyptedBoxKey(b.getUid(),
// b.getKeyGroupId(), "curve25519", b.getEncryptedKey()));
// }
// ApiEncryptedBox apiEncryptedBox = new ApiEncryptedBox(0, boxKeys, "aes-kuznechik", encryptBoxResponse.getBox().getEncryptedPackage(),
// new ArrayList<ApiEncryptedBoxSignature>());
// ApiEncryptedMessage apiEncryptedMessage = new ApiEncryptedMessage(apiEncryptedBox);
// return new EncryptedMessage(apiEncryptedMessage);
// }
// });
// TODO: Implement
return null;
}
public void onDecrypt(int uid, ApiEncryptedMessage message) {
Log.d(TAG, "onDecrypt:" + uid);
final long start = im.actor.runtime.Runtime.getActorTime();
ArrayList<EncryptedBoxKey> encryptedBoxKeys = new ArrayList<EncryptedBoxKey>();
for (ApiEncyptedBoxKey key : message.getBox().getKeys()) {
if (key.getUsersId() == myUid()) {
encryptedBoxKeys.add(new EncryptedBoxKey(key.getUsersId(), key.getKeyGroupId(),
key.getAlgType(), key.getEncryptedKey()));
}
}
final EncryptedBox encryptedBox = new EncryptedBox(encryptedBoxKeys.toArray(new EncryptedBoxKey[0]), message.getBox().getEncPackage());
// TODO: Implement
// ask(context().getEncryption().getEncryptedChatManager(uid), new EncryptedPeerActor.DecryptBox(encryptedBox), new AskCallback() {
// @Override
// public void onResult(Object obj) {
// Log.d(TAG, "onDecrypt:onResult in " + (Runtime.getActorTime() - start) + " ms");
// EncryptedPeerActor.DecryptBoxResponse re = (EncryptedPeerActor.DecryptBoxResponse) obj;
// try {
// ApiMessage message = ApiMessage.fromBytes(re.getData());
// Log.d(TAG, "onDecrypt:onResult " + message);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//
// @Override
// public void onError(Exception e) {
// Log.d(TAG, "onDecrypt:onError");
// e.printStackTrace();
// }
// });
}
@Override
public Promise onAsk(Object message) throws Exception {
if (message instanceof EncryptMessage) {
return doEncrypt(((EncryptMessage) message).getUid(), ((EncryptMessage) message).getMessage());
} else {
return super.onAsk(message);
}
}
@Override
public void onReceive(Object message) {
Log.d(TAG, "msg: " + message);
if (message instanceof InMessage) {
InMessage inMessage = (InMessage) message;
onDecrypt(inMessage.senderUid, inMessage.encryptedMessage);
} else {
super.onReceive(message);
}
}
public static class InMessage {
private Peer peer;
private long date;
private int senderUid;
private long rid;
private ApiEncryptedMessage encryptedMessage;
public InMessage(Peer peer, long date, int senderUid, long rid, ApiEncryptedMessage encryptedMessage) {
this.peer = peer;
this.date = date;
this.senderUid = senderUid;
this.rid = rid;
this.encryptedMessage = encryptedMessage;
}
}
public static class EncryptMessage {
private int uid;
private ApiMessage message;
public EncryptMessage(int uid, ApiMessage message) {
this.uid = uid;
this.message = message;
}
public int getUid() {
return uid;
}
public ApiMessage getMessage() {
return message;
}
}
public static class EncryptedMessage {
private ApiEncryptedMessage encryptedMessage;
public EncryptedMessage(ApiEncryptedMessage encryptedMessage) {
this.encryptedMessage = encryptedMessage;
}
public ApiEncryptedMessage getEncryptedMessage() {
return encryptedMessage;
}
}
public static class DecryptMessage {
private ApiEncryptedMessage encryptedMessage;
public DecryptMessage(ApiEncryptedMessage encryptedMessage) {
this.encryptedMessage = encryptedMessage;
}
public ApiEncryptedMessage getEncryptedMessage() {
return encryptedMessage;
}
}
}