use of im.actor.core.api.ApiUserOutPeer in project actor-platform by actorapp.
the class BookImportActor method performImportIfRequired.
private void performImportIfRequired() {
if (ENABLE_LOG) {
Log.d(TAG, "performImportIfRequired called");
}
if (isUploadingContacts) {
if (ENABLE_LOG) {
Log.d(TAG, "performImportIfRequired:exiting:already importing");
}
return;
}
if (importQueue.size() == 0) {
if (ENABLE_LOG) {
Log.d(TAG, "performImportIfRequired:exiting:nothing to import");
}
// Marking as everything is imported
context().getConductor().getConductor().onPhoneBookImported();
return;
}
//
// Performing import
//
isUploadingContacts = true;
final ArrayList<ApiPhoneToImport> phoneToImports = new ArrayList<>();
final ArrayList<ApiEmailToImport> emailToImports = new ArrayList<>();
for (int i = 0; i < MAX_IMPORT_SIZE && importQueue.size() > 0; i++) {
ImportQueueItem importQueueItem = importQueue.remove(0);
if (importQueueItem instanceof ImportEmailQueueItem) {
emailToImports.add(new ApiEmailToImport(((ImportEmailQueueItem) importQueueItem).getEmail(), ((ImportEmailQueueItem) importQueueItem).getName()));
} else if (importQueueItem instanceof ImportPhoneQueueItem) {
phoneToImports.add(new ApiPhoneToImport(((ImportPhoneQueueItem) importQueueItem).getPhoneNumber(), ((ImportPhoneQueueItem) importQueueItem).getName()));
} else {
throw new RuntimeException();
}
}
request(new RequestImportContacts(phoneToImports, emailToImports, ApiSupportConfiguration.OPTIMIZATIONS), new RpcCallback<ResponseImportContacts>() {
@Override
public void onResult(ResponseImportContacts response) {
for (ApiPhoneToImport phoneToImport : phoneToImports) {
storage.markAsImported(phoneToImport.getPhoneNumber());
importingPhones.remove(phoneToImport.getPhoneNumber());
}
for (ApiEmailToImport emailToImport : emailToImports) {
storage.markAsImported(emailToImport.getEmail());
importingEmails.remove(emailToImport.getEmail());
}
context().getContactsModule().getBookImportState().put(0, storage.toByteArray());
//
if (response.getUsers().size() != 0 || response.getUserPeers().size() != 0) {
if (ENABLE_LOG) {
Log.d(TAG, "Import success with " + (response.getUsers().size() + response.getUserPeers().size()) + " new contacts");
}
if (response.getUserPeers().size() != 0) {
// Optimized version
ArrayList<Integer> uids = new ArrayList<>();
for (ApiUserOutPeer u : response.getUserPeers()) {
uids.add(u.getUid());
}
updates().loadRequiredPeers(response.getUserPeers(), new ArrayList<>()).flatMap(v -> updates().applyUpdate(response.getSeq(), response.getState(), new UpdateContactsAdded(uids)));
} else {
// Old version
ArrayList<Integer> uids = new ArrayList<>();
for (ApiUser u : response.getUsers()) {
uids.add(u.getId());
}
updates().onUpdateReceived(new FatSeqUpdate(response.getSeq(), response.getState(), UpdateContactsAdded.HEADER, new UpdateContactsAdded(uids).toByteArray(), response.getUsers(), new ArrayList<>()));
}
} else {
if (ENABLE_LOG) {
Log.d(TAG, "Import success, but no new contacts found");
}
}
//
// Launching next iteration
//
isUploadingContacts = false;
performImportIfRequired();
}
@Override
public void onError(RpcException e) {
// TODO: Better error handling
if (ENABLE_LOG) {
Log.d(TAG, "Import failure");
}
e.printStackTrace();
//
// Launching next iteration
//
isUploadingContacts = false;
performImportIfRequired();
}
});
}
use of im.actor.core.api.ApiUserOutPeer in project actor-platform by actorapp.
the class KeyManagerActor method fetchUserPreKey.
/**
* Fetching user's random pre key
*
* @param uid User's id
* @param keyGroupId User's key group id
*/
private Promise<PublicKey> fetchUserPreKey(final int uid, final int keyGroupId) {
return pickUserGroup(uid, keyGroupId).flatMap(new Function<Tuple2<UserKeysGroup, UserKeys>, Promise<PublicKey>>() {
@Override
public Promise<PublicKey> apply(final Tuple2<UserKeysGroup, UserKeys> keyGroups) {
return api(new RequestLoadPrePublicKeys(new ApiUserOutPeer(uid, getUser(uid).getAccessHash()), keyGroupId)).map(new Function<ResponsePublicKeys, PublicKey>() {
@Override
public PublicKey apply(ResponsePublicKeys response) {
if (response.getPublicKey().size() == 0) {
throw new RuntimeException("User doesn't have pre keys");
}
ApiEncryptionKey key = response.getPublicKey().get(0);
ApiEncryptionKeySignature sig = null;
for (ApiEncryptionKeySignature s : response.getSignatures()) {
if (s.getKeyId() == key.getKeyId() && "Ed25519".equals(s.getSignatureAlg())) {
sig = s;
break;
}
}
if (sig == null) {
throw new RuntimeException("Unable to find public key on server");
}
byte[] keyHash = RatchetKeySignature.hashForSignature(key.getKeyId(), key.getKeyAlg(), key.getKeyMaterial());
if (!Curve25519.verifySignature(keyGroups.getT1().getIdentityKey().getPublicKey(), keyHash, sig.getSignature())) {
throw new RuntimeException("Key signature does not isMatch");
}
return new PublicKey(key.getKeyId(), key.getKeyAlg(), key.getKeyMaterial());
}
});
}
});
}
use of im.actor.core.api.ApiUserOutPeer in project actor-platform by actorapp.
the class KeyManagerActor method fetchUserPreKey.
/**
* Fetching user's pre key by key id
*
* @param uid User's id
* @param keyGroupId User's key group id
* @param keyId Key id
*/
private Promise<PublicKey> fetchUserPreKey(final int uid, final int keyGroupId, final long keyId) {
User user = users().getValue(uid);
if (user == null) {
throw new RuntimeException("Unable to find user #" + uid);
}
return pickUserGroup(uid, keyGroupId).flatMap(new Function<Tuple2<UserKeysGroup, UserKeys>, Promise<PublicKey>>() {
@Override
public Promise<PublicKey> apply(final Tuple2<UserKeysGroup, UserKeys> keysGroup) {
for (PublicKey p : keysGroup.getT1().getEphemeralKeys()) {
if (p.getKeyId() == keyId) {
return Promise.success(p);
}
}
//
// Downloading pre key
//
ArrayList<Long> ids = new ArrayList<Long>();
ids.add(keyId);
final UserKeysGroup finalKeysGroup = keysGroup.getT1();
return api(new RequestLoadPublicKey(new ApiUserOutPeer(uid, getUser(uid).getAccessHash()), keyGroupId, ids)).map(new Function<ResponsePublicKeys, PublicKey>() {
@Override
public PublicKey apply(ResponsePublicKeys responsePublicKeys) {
if (responsePublicKeys.getPublicKey().size() == 0) {
throw new RuntimeException("Unable to find public key on server");
}
ApiEncryptionKeySignature sig = null;
for (ApiEncryptionKeySignature s : responsePublicKeys.getSignatures()) {
if (s.getKeyId() == keyId && "Ed25519".equals(s.getSignatureAlg())) {
sig = s;
break;
}
}
if (sig == null) {
throw new RuntimeException("Unable to find public key on server");
}
ApiEncryptionKey key = responsePublicKeys.getPublicKey().get(0);
byte[] keyHash = RatchetKeySignature.hashForSignature(key.getKeyId(), key.getKeyAlg(), key.getKeyMaterial());
if (!Curve25519.verifySignature(keysGroup.getT1().getIdentityKey().getPublicKey(), keyHash, sig.getSignature())) {
throw new RuntimeException("Key signature does not isMatch");
}
PublicKey pkey = new PublicKey(keyId, key.getKeyAlg(), key.getKeyMaterial());
UserKeysGroup userKeysGroup = finalKeysGroup.addPublicKey(pkey);
cacheUserKeys(keysGroup.getT2().removeUserKeyGroup(userKeysGroup.getKeyGroupId()).addUserKeyGroup(userKeysGroup));
return pkey;
}
});
}
});
}
use of im.actor.core.api.ApiUserOutPeer in project actor-platform by actorapp.
the class KeyManagerActor method fetchUserGroups.
//
// User keys fetching
//
/**
* Fetching all user's key groups
*
* @param uid User's id
*/
private Promise<UserKeys> fetchUserGroups(final int uid) {
User user = users().getValue(uid);
if (user == null) {
throw new RuntimeException("Unable to find user #" + uid);
}
final UserKeys userKeys = getCachedUserKeys(uid);
if (userKeys != null) {
return Promise.success(userKeys);
}
return api(new RequestLoadPublicKeyGroups(new ApiUserOutPeer(uid, user.getAccessHash()))).map(new Function<ResponsePublicKeyGroups, ArrayList<UserKeysGroup>>() {
@Override
public ArrayList<UserKeysGroup> apply(ResponsePublicKeyGroups response) {
ArrayList<UserKeysGroup> keysGroups = new ArrayList<>();
for (ApiEncryptionKeyGroup keyGroup : response.getPublicKeyGroups()) {
UserKeysGroup validatedKeysGroup = validateUserKeysGroup(uid, keyGroup);
if (validatedKeysGroup != null) {
keysGroups.add(validatedKeysGroup);
}
}
return keysGroups;
}
}).map(new Function<ArrayList<UserKeysGroup>, UserKeys>() {
@Override
public UserKeys apply(ArrayList<UserKeysGroup> userKeysGroups) {
UserKeys userKeys = new UserKeys(uid, userKeysGroups.toArray(new UserKeysGroup[userKeysGroups.size()]));
cacheUserKeys(userKeys);
return userKeys;
}
});
}
use of im.actor.core.api.ApiUserOutPeer in project actor-platform by actorapp.
the class PresenceActor method onCheckQueue.
private void onCheckQueue() {
if (isRequesting) {
return;
}
if (pendingPeers.size() == 0) {
return;
}
ArrayList<Peer> destPeers = new ArrayList<>(pendingPeers);
pendingPeers.clear();
ArrayList<ApiUserOutPeer> outUserPeers = new ArrayList<>();
ArrayList<ApiGroupOutPeer> outGroupPeers = new ArrayList<>();
for (Peer p : destPeers) {
if (p.getPeerType() == PeerType.GROUP) {
Group g = getGroup(p.getPeerId());
if (g != null) {
outGroupPeers.add(new ApiGroupOutPeer(p.getPeerId(), g.getAccessHash()));
}
} else if (p.getPeerType() == PeerType.PRIVATE) {
User u = getUser(p.getPeerId());
if (u != null) {
outUserPeers.add(new ApiUserOutPeer(p.getPeerId(), u.getAccessHash()));
}
}
}
ArrayList<Promise<ResponseVoid>> requests = new ArrayList<>();
if (outUserPeers.size() > 0) {
requests.add(api(new RequestSubscribeToOnline(outUserPeers)));
}
if (outGroupPeers.size() > 0) {
requests.add(api(new RequestSubscribeToGroupOnline(outGroupPeers)));
}
if (requests.size() > 0) {
isRequesting = true;
PromisesArray.ofPromises(requests).zip().then(responseVoids -> {
isRequesting = false;
onCheckQueue();
}).failure(e -> {
isRequesting = false;
onCheckQueue();
});
}
}
Aggregations