Search in sources :

Example 6 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class RegistrationRepository method registerAccountInternal.

@WorkerThread
private void registerAccountInternal(@NonNull RegistrationData registrationData, @NonNull VerifyAccountResponse response, @Nullable String pin, @Nullable KbsPinData kbsData) throws IOException {
    ACI aci = ACI.parseOrThrow(response.getUuid());
    PNI pni = PNI.parseOrThrow(response.getPni());
    boolean hasPin = response.isStorageCapable();
    SignalStore.account().setAci(aci);
    SignalStore.account().setPni(pni);
    ApplicationDependencies.getProtocolStore().aci().sessions().archiveAllSessions();
    ApplicationDependencies.getProtocolStore().pni().sessions().archiveAllSessions();
    SenderKeyUtil.clearAllState(context);
    SignalServiceAccountManager accountManager = AccountManagerFactory.createAuthenticated(context, aci, pni, registrationData.getE164(), SignalServiceAddress.DEFAULT_DEVICE_ID, registrationData.getPassword());
    SignalServiceAccountDataStoreImpl aciProtocolStore = ApplicationDependencies.getProtocolStore().aci();
    SignalServiceAccountDataStoreImpl pniProtocolStore = ApplicationDependencies.getProtocolStore().pni();
    generateAndRegisterPreKeys(ServiceIdType.ACI, accountManager, aciProtocolStore, SignalStore.account().aciPreKeys());
    generateAndRegisterPreKeys(ServiceIdType.PNI, accountManager, pniProtocolStore, SignalStore.account().pniPreKeys());
    if (registrationData.isFcm()) {
        accountManager.setGcmId(Optional.fromNullable(registrationData.getFcmToken()));
    }
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    RecipientId selfId = Recipient.externalPush(aci, registrationData.getE164(), true).getId();
    recipientDatabase.setProfileSharing(selfId, true);
    recipientDatabase.markRegisteredOrThrow(selfId, aci);
    recipientDatabase.setPni(selfId, pni);
    recipientDatabase.setProfileKey(selfId, registrationData.getProfileKey());
    ApplicationDependencies.getRecipientCache().clearSelf();
    SignalStore.account().setE164(registrationData.getE164());
    SignalStore.account().setFcmToken(registrationData.getFcmToken());
    SignalStore.account().setFcmEnabled(registrationData.isFcm());
    long now = System.currentTimeMillis();
    saveOwnIdentityKey(selfId, aciProtocolStore, now);
    saveOwnIdentityKey(selfId, pniProtocolStore, now);
    SignalStore.account().setServicePassword(registrationData.getPassword());
    SignalStore.account().setRegistered(true);
    TextSecurePreferences.setPromptedPushRegistration(context, true);
    TextSecurePreferences.setUnauthorizedReceived(context, false);
    PinState.onRegistration(context, kbsData, pin, hasPin);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ACI(org.whispersystems.signalservice.api.push.ACI) SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) PNI(org.whispersystems.signalservice.api.push.PNI) SignalServiceAccountDataStoreImpl(org.thoughtcrime.securesms.crypto.storage.SignalServiceAccountDataStoreImpl) WorkerThread(androidx.annotation.WorkerThread)

Example 7 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class CdshService method parseResponse.

private static Map<String, ACI> parseResponse(List<String> addressBook, byte[] plaintextResponse) throws IOException {
    Map<String, ACI> results = new HashMap<>();
    try (DataInputStream uuidInputStream = new DataInputStream(new ByteArrayInputStream(plaintextResponse))) {
        for (String candidate : addressBook) {
            long candidateUuidHigh = uuidInputStream.readLong();
            long candidateUuidLow = uuidInputStream.readLong();
            if (candidateUuidHigh != 0 || candidateUuidLow != 0) {
                results.put('+' + candidate, ACI.from(new UUID(candidateUuidHigh, candidateUuidLow)));
            }
        }
    }
    return results;
}
Also used : HashMap(java.util.HashMap) ByteArrayInputStream(java.io.ByteArrayInputStream) ACI(org.whispersystems.signalservice.api.push.ACI) ByteString(okio.ByteString) DataInputStream(java.io.DataInputStream) UUID(java.util.UUID)

Example 8 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class DirectoryHelper method refreshNumbers.

@WorkerThread
private static void refreshNumbers(@NonNull Context context, @NonNull Set<String> databaseNumbers, @NonNull Set<String> systemNumbers, boolean notifyOfNewUsers, boolean removeSystemContactEntryForMissing) throws IOException {
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    Set<String> allNumbers = SetUtil.union(databaseNumbers, systemNumbers);
    if (allNumbers.isEmpty()) {
        Log.w(TAG, "No numbers to refresh!");
        return;
    }
    Stopwatch stopwatch = new Stopwatch("refresh");
    DirectoryResult result;
    if (FeatureFlags.cdsh()) {
        result = ContactDiscoveryV3.getDirectoryResult(databaseNumbers, systemNumbers);
    } else {
        result = ContactDiscoveryV2.getDirectoryResult(context, databaseNumbers, systemNumbers);
    }
    stopwatch.split("network");
    if (result.getNumberRewrites().size() > 0) {
        Log.i(TAG, "[getDirectoryResult] Need to rewrite some numbers.");
        recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
    }
    Map<RecipientId, ACI> aciMap = recipientDatabase.bulkProcessCdsResult(result.getRegisteredNumbers());
    Set<String> activeNumbers = result.getRegisteredNumbers().keySet();
    Set<RecipientId> activeIds = aciMap.keySet();
    Set<RecipientId> inactiveIds = Stream.of(allNumbers).filterNot(activeNumbers::contains).filterNot(n -> result.getNumberRewrites().containsKey(n)).filterNot(n -> result.getIgnoredNumbers().contains(n)).map(recipientDatabase::getOrInsertFromE164).collect(Collectors.toSet());
    stopwatch.split("process-cds");
    UnlistedResult unlistedResult = filterForUnlistedUsers(context, inactiveIds);
    inactiveIds.removeAll(unlistedResult.getPossiblyActive());
    if (unlistedResult.getRetries().size() > 0) {
        Log.i(TAG, "Some profile fetches failed to resolve. Assuming not-inactive for now and scheduling a retry.");
        RetrieveProfileJob.enqueue(unlistedResult.getRetries());
    }
    stopwatch.split("handle-unlisted");
    Set<RecipientId> preExistingRegisteredUsers = new HashSet<>(recipientDatabase.getRegistered());
    recipientDatabase.bulkUpdatedRegisteredStatus(aciMap, inactiveIds);
    stopwatch.split("update-registered");
    updateContactsDatabase(context, activeIds, removeSystemContactEntryForMissing, result.getNumberRewrites());
    stopwatch.split("contacts-db");
    if (TextSecurePreferences.isMultiDevice(context)) {
        ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob());
    }
    if (TextSecurePreferences.hasSuccessfullyRetrievedDirectory(context) && notifyOfNewUsers) {
        Set<RecipientId> systemContacts = new HashSet<>(recipientDatabase.getSystemContacts());
        Set<RecipientId> newlyRegisteredSystemContacts = new HashSet<>(activeIds);
        newlyRegisteredSystemContacts.removeAll(preExistingRegisteredUsers);
        newlyRegisteredSystemContacts.retainAll(systemContacts);
        notifyNewUsers(context, newlyRegisteredSystemContacts);
    } else {
        TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(context, true);
    }
    stopwatch.stop(TAG);
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) NonNull(androidx.annotation.NonNull) R(org.thoughtcrime.securesms.R) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) Manifest(android.Manifest) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) ContactsContract(android.provider.ContactsContract) BulkOperationsHandle(org.thoughtcrime.securesms.database.RecipientDatabase.BulkOperationsHandle) RegisteredState(org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) StorageSyncHelper(org.thoughtcrime.securesms.storage.StorageSyncHelper) ContentResolver(android.content.ContentResolver) Map(java.util.Map) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress) Recipient(org.thoughtcrime.securesms.recipients.Recipient) AccountManager(android.accounts.AccountManager) ACI(org.whispersystems.signalservice.api.push.ACI) Account(android.accounts.Account) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Collection(java.util.Collection) Set(java.util.Set) SetUtil(org.thoughtcrime.securesms.util.SetUtil) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) FeatureFlags(org.thoughtcrime.securesms.util.FeatureFlags) List(java.util.List) Nullable(androidx.annotation.Nullable) StorageSyncJob(org.thoughtcrime.securesms.jobs.StorageSyncJob) ProfileService(org.whispersystems.signalservice.api.services.ProfileService) BuildConfig(org.thoughtcrime.securesms.BuildConfig) InsertResult(org.thoughtcrime.securesms.database.MessageDatabase.InsertResult) Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) Util(org.thoughtcrime.securesms.util.Util) WorkerThread(androidx.annotation.WorkerThread) RemoteException(android.os.RemoteException) RetrieveProfileJob(org.thoughtcrime.securesms.jobs.RetrieveProfileJob) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) HashSet(java.util.HashSet) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) Pair(org.whispersystems.libsignal.util.Pair) NotificationChannels(org.thoughtcrime.securesms.notifications.NotificationChannels) ProfileUtil(org.thoughtcrime.securesms.util.ProfileUtil) Calendar(java.util.Calendar) Observable(io.reactivex.rxjava3.core.Observable) RegistrationUtil(org.thoughtcrime.securesms.registration.RegistrationUtil) ContactsDatabase(org.thoughtcrime.securesms.contacts.ContactsDatabase) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) Cursor(android.database.Cursor) Collectors(com.annimon.stream.Collectors) Permissions(org.thoughtcrime.securesms.permissions.Permissions) UuidUtil(org.whispersystems.signalservice.api.util.UuidUtil) TextUtils(android.text.TextUtils) IOException(java.io.IOException) ServiceResponse(org.whispersystems.signalservice.internal.ServiceResponse) OperationApplicationException(android.content.OperationApplicationException) Optional(org.whispersystems.libsignal.util.guava.Optional) TimeUnit(java.util.concurrent.TimeUnit) CursorUtil(org.thoughtcrime.securesms.util.CursorUtil) IncomingJoinedMessage(org.thoughtcrime.securesms.sms.IncomingJoinedMessage) ContactAccessor(org.thoughtcrime.securesms.contacts.ContactAccessor) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) PhoneNumberFormatter(org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) ACI(org.whispersystems.signalservice.api.push.ACI) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) HashSet(java.util.HashSet) WorkerThread(androidx.annotation.WorkerThread)

Example 9 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class DirectoryHelper method refreshDirectoryFor.

@WorkerThread
public static RegisteredState refreshDirectoryFor(@NonNull Context context, @NonNull Recipient recipient, boolean notifyOfNewUsers) throws IOException {
    Stopwatch stopwatch = new Stopwatch("single");
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    RegisteredState originalRegisteredState = recipient.resolve().getRegistered();
    RegisteredState newRegisteredState;
    if (recipient.hasServiceId() && !recipient.hasE164()) {
        boolean isRegistered = ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId());
        stopwatch.split("aci-network");
        if (isRegistered) {
            boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
            if (idChanged) {
                Log.w(TAG, "ID changed during refresh by UUID.");
            }
        } else {
            recipientDatabase.markUnregistered(recipient.getId());
        }
        stopwatch.split("aci-disk");
        stopwatch.stop(TAG);
        return isRegistered ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
    }
    if (!recipient.getE164().isPresent()) {
        Log.w(TAG, "No ACI or E164?");
        return RegisteredState.NOT_REGISTERED;
    }
    DirectoryResult result = ContactDiscoveryV2.getDirectoryResult(context, recipient.getE164().get());
    stopwatch.split("e164-network");
    if (result.getNumberRewrites().size() > 0) {
        Log.i(TAG, "[getDirectoryResult] Need to rewrite some numbers.");
        recipientDatabase.updatePhoneNumbers(result.getNumberRewrites());
    }
    if (result.getRegisteredNumbers().size() > 0) {
        ACI aci = result.getRegisteredNumbers().values().iterator().next();
        if (aci != null) {
            boolean idChanged = recipientDatabase.markRegistered(recipient.getId(), aci);
            if (idChanged) {
                recipient = Recipient.resolved(recipientDatabase.getByServiceId(aci).get());
            }
        } else {
            Log.w(TAG, "Registered number set had a null ACI!");
        }
    } else if (recipient.hasServiceId() && recipient.isRegistered() && hasCommunicatedWith(recipient)) {
        if (ApplicationDependencies.getSignalServiceAccountManager().isIdentifierRegistered(recipient.requireServiceId())) {
            recipientDatabase.markRegistered(recipient.getId(), recipient.requireServiceId());
        } else {
            recipientDatabase.markUnregistered(recipient.getId());
        }
        stopwatch.split("e164-unlisted-network");
    } else {
        recipientDatabase.markUnregistered(recipient.getId());
    }
    if (Permissions.hasAll(context, Manifest.permission.WRITE_CONTACTS)) {
        updateContactsDatabase(context, Collections.singletonList(recipient.getId()), false, result.getNumberRewrites());
    }
    newRegisteredState = result.getRegisteredNumbers().size() > 0 ? RegisteredState.REGISTERED : RegisteredState.NOT_REGISTERED;
    if (newRegisteredState != originalRegisteredState) {
        ApplicationDependencies.getJobManager().add(new MultiDeviceContactUpdateJob());
        ApplicationDependencies.getJobManager().add(new StorageSyncJob());
        if (notifyOfNewUsers && newRegisteredState == RegisteredState.REGISTERED && recipient.resolve().isSystemContact()) {
            notifyNewUsers(context, Collections.singletonList(recipient.getId()));
        }
        StorageSyncHelper.scheduleSyncForDataChange();
    }
    stopwatch.split("e164-disk");
    stopwatch.stop(TAG);
    return newRegisteredState;
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) MultiDeviceContactUpdateJob(org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob) StorageSyncJob(org.thoughtcrime.securesms.jobs.StorageSyncJob) RegisteredState(org.thoughtcrime.securesms.database.RecipientDatabase.RegisteredState) ACI(org.whispersystems.signalservice.api.push.ACI) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) WorkerThread(androidx.annotation.WorkerThread)

Example 10 with ACI

use of org.whispersystems.signalservice.api.push.ACI in project Signal-Android by WhisperSystems.

the class SignalServiceContent method createReaction.

private static SignalServiceDataMessage.Reaction createReaction(SignalServiceProtos.DataMessage content) {
    if (!content.hasReaction() || !content.getReaction().hasEmoji() || !content.getReaction().hasTargetAuthorUuid() || !content.getReaction().hasTargetSentTimestamp()) {
        return null;
    }
    SignalServiceProtos.DataMessage.Reaction reaction = content.getReaction();
    ACI uuid = ACI.parseOrNull(reaction.getTargetAuthorUuid());
    if (uuid == null) {
        Log.w(TAG, "Cannot parse author UUID on reaction");
        return null;
    }
    return new SignalServiceDataMessage.Reaction(reaction.getEmoji(), reaction.getRemove(), new SignalServiceAddress(uuid), reaction.getTargetSentTimestamp());
}
Also used : ACI(org.whispersystems.signalservice.api.push.ACI) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress)

Aggregations

ACI (org.whispersystems.signalservice.api.push.ACI)32 Test (org.junit.Test)13 IOException (java.io.IOException)7 WorkerThread (androidx.annotation.WorkerThread)6 HashMap (java.util.HashMap)5 NonNull (androidx.annotation.NonNull)4 ByteString (com.google.protobuf.ByteString)4 ByteArrayInputStream (java.io.ByteArrayInputStream)4 DataInputStream (java.io.DataInputStream)4 Map (java.util.Map)4 PNI (org.whispersystems.signalservice.api.push.PNI)4 ServiceResponse (org.whispersystems.signalservice.internal.ServiceResponse)4 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 SignatureException (java.security.SignatureException)3 Collections (java.util.Collections)3 HashSet (java.util.HashSet)3 List (java.util.List)3 UUID (java.util.UUID)3 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)3 UnauthenticatedResponseException (org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException)3