Search in sources :

Example 41 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by signalapp.

the class PushDecryptJob method handleProfileKey.

private void handleProfileKey(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceDataMessage message) {
    RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context);
    Address sourceAddress = Address.fromExternal(context, envelope.getSource());
    Recipient recipient = Recipient.from(context, sourceAddress, false);
    if (recipient.getProfileKey() == null || !MessageDigest.isEqual(recipient.getProfileKey(), message.getProfileKey().get())) {
        database.setProfileKey(recipient, message.getProfileKey().get());
        ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileJob(context, recipient));
    }
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) Address(org.thoughtcrime.securesms.database.Address) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) Recipient(org.thoughtcrime.securesms.recipients.Recipient)

Example 42 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

the class StorageForcePushJob method onRun.

@Override
protected void onRun() throws IOException, RetryLaterException {
    if (SignalStore.account().isLinkedDevice()) {
        Log.i(TAG, "Only the primary device can force push");
        return;
    }
    StorageKey storageServiceKey = SignalStore.storageService().getOrCreateStorageKey();
    SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    UnknownStorageIdDatabase storageIdDatabase = SignalDatabase.unknownStorageIds();
    long currentVersion = accountManager.getStorageManifestVersion();
    Map<RecipientId, StorageId> oldContactStorageIds = recipientDatabase.getContactStorageSyncIdsMap();
    long newVersion = currentVersion + 1;
    Map<RecipientId, StorageId> newContactStorageIds = generateContactStorageIds(oldContactStorageIds);
    List<SignalStorageRecord> inserts = Stream.of(oldContactStorageIds.keySet()).map(recipientDatabase::getRecordForSync).withoutNulls().map(s -> StorageSyncModels.localToRemoteRecord(s, Objects.requireNonNull(newContactStorageIds.get(s.getId())).getRaw())).toList();
    SignalStorageRecord accountRecord = StorageSyncHelper.buildAccountRecord(context, Recipient.self().fresh());
    List<StorageId> allNewStorageIds = new ArrayList<>(newContactStorageIds.values());
    inserts.add(accountRecord);
    allNewStorageIds.add(accountRecord.getId());
    SignalStorageManifest manifest = new SignalStorageManifest(newVersion, allNewStorageIds);
    StorageSyncValidations.validateForcePush(manifest, inserts, Recipient.self().fresh());
    try {
        if (newVersion > 1) {
            Log.i(TAG, String.format(Locale.ENGLISH, "Force-pushing data. Inserting %d IDs.", inserts.size()));
            if (accountManager.resetStorageRecords(storageServiceKey, manifest, inserts).isPresent()) {
                Log.w(TAG, "Hit a conflict. Trying again.");
                throw new RetryLaterException();
            }
        } else {
            Log.i(TAG, String.format(Locale.ENGLISH, "First version, normal push. Inserting %d IDs.", inserts.size()));
            if (accountManager.writeStorageRecords(storageServiceKey, manifest, inserts, Collections.emptyList()).isPresent()) {
                Log.w(TAG, "Hit a conflict. Trying again.");
                throw new RetryLaterException();
            }
        }
    } catch (InvalidKeyException e) {
        Log.w(TAG, "Hit an invalid key exception, which likely indicates a conflict.");
        throw new RetryLaterException(e);
    }
    Log.i(TAG, "Force push succeeded. Updating local manifest version to: " + newVersion);
    SignalStore.storageService().setManifest(manifest);
    recipientDatabase.applyStorageIdUpdates(newContactStorageIds);
    recipientDatabase.applyStorageIdUpdates(Collections.singletonMap(Recipient.self().getId(), accountRecord.getId()));
    storageIdDatabase.deleteAll();
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) StorageSyncValidations(org.thoughtcrime.securesms.storage.StorageSyncValidations) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) Stream(com.annimon.stream.Stream) NonNull(androidx.annotation.NonNull) Data(org.thoughtcrime.securesms.jobmanager.Data) StorageSyncModels(org.thoughtcrime.securesms.storage.StorageSyncModels) HashMap(java.util.HashMap) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ArrayList(java.util.ArrayList) StorageKey(org.whispersystems.signalservice.api.storage.StorageKey) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) StorageSyncHelper(org.thoughtcrime.securesms.storage.StorageSyncHelper) Locale(java.util.Locale) Map(java.util.Map) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalStorageManifest(org.whispersystems.signalservice.api.storage.SignalStorageManifest) StorageId(org.whispersystems.signalservice.api.storage.StorageId) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) UnknownStorageIdDatabase(org.thoughtcrime.securesms.database.UnknownStorageIdDatabase) NetworkConstraint(org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint) IOException(java.io.IOException) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) Log(org.signal.core.util.logging.Log) List(java.util.List) Job(org.thoughtcrime.securesms.jobmanager.Job) SignalStorageRecord(org.whispersystems.signalservice.api.storage.SignalStorageRecord) Collections(java.util.Collections) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) SignalStorageManifest(org.whispersystems.signalservice.api.storage.SignalStorageManifest) SignalServiceAccountManager(org.whispersystems.signalservice.api.SignalServiceAccountManager) ArrayList(java.util.ArrayList) SignalStorageRecord(org.whispersystems.signalservice.api.storage.SignalStorageRecord) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) StorageId(org.whispersystems.signalservice.api.storage.StorageId) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) UnknownStorageIdDatabase(org.thoughtcrime.securesms.database.UnknownStorageIdDatabase) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) StorageKey(org.whispersystems.signalservice.api.storage.StorageKey)

Example 43 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

the class RetrieveProfileJob method setProfileKeyCredential.

private void setProfileKeyCredential(@NonNull Recipient recipient, @NonNull ProfileKey recipientProfileKey, @NonNull ProfileKeyCredential credential) {
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    recipientDatabase.setProfileKeyCredential(recipient.getId(), recipientProfileKey, credential);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase)

Example 44 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

the class RetrieveProfileJob method setUnidentifiedAccessMode.

private void setUnidentifiedAccessMode(Recipient recipient, String unidentifiedAccessVerifier, boolean unrestrictedUnidentifiedAccess) {
    RecipientDatabase recipientDatabase = SignalDatabase.recipients();
    ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey());
    if (unrestrictedUnidentifiedAccess && unidentifiedAccessVerifier != null) {
        if (recipient.getUnidentifiedAccessMode() != UnidentifiedAccessMode.UNRESTRICTED) {
            Log.i(TAG, "Marking recipient UD status as unrestricted.");
            recipientDatabase.setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.UNRESTRICTED);
        }
    } else if (profileKey == null || unidentifiedAccessVerifier == null) {
        if (recipient.getUnidentifiedAccessMode() != UnidentifiedAccessMode.DISABLED) {
            Log.i(TAG, "Marking recipient UD status as disabled.");
            recipientDatabase.setUnidentifiedAccessMode(recipient.getId(), UnidentifiedAccessMode.DISABLED);
        }
    } else {
        ProfileCipher profileCipher = new ProfileCipher(profileKey);
        boolean verifiedUnidentifiedAccess;
        try {
            verifiedUnidentifiedAccess = profileCipher.verifyUnidentifiedAccess(Base64.decode(unidentifiedAccessVerifier));
        } catch (IOException e) {
            Log.w(TAG, e);
            verifiedUnidentifiedAccess = false;
        }
        UnidentifiedAccessMode mode = verifiedUnidentifiedAccess ? UnidentifiedAccessMode.ENABLED : UnidentifiedAccessMode.DISABLED;
        if (recipient.getUnidentifiedAccessMode() != mode) {
            Log.i(TAG, "Marking recipient UD status as " + mode.name() + " after verification.");
            recipientDatabase.setUnidentifiedAccessMode(recipient.getId(), mode);
        }
    }
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) ProfileCipher(org.whispersystems.signalservice.api.crypto.ProfileCipher) IOException(java.io.IOException) UnidentifiedAccessMode(org.thoughtcrime.securesms.database.RecipientDatabase.UnidentifiedAccessMode) ProfileKey(org.signal.zkgroup.profiles.ProfileKey)

Example 45 with RecipientDatabase

use of org.thoughtcrime.securesms.database.RecipientDatabase in project Signal-Android by WhisperSystems.

the class ContactRecordProcessor method getMatching.

@Override
@NonNull
Optional<SignalContactRecord> getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) {
    SignalServiceAddress address = remote.getAddress();
    Optional<RecipientId> byUuid = recipientDatabase.getByServiceId(address.getServiceId());
    Optional<RecipientId> byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent();
    return byUuid.or(byE164).transform(recipientDatabase::getRecordForSync).transform(settings -> {
        if (settings.getStorageId() != null) {
            return StorageSyncModels.localToRemoteRecord(settings);
        } else {
            Log.w(TAG, "Newly discovering a registered user via storage service. Saving a storageId for them.");
            recipientDatabase.updateStorageId(settings.getId(), keyGenerator.generate());
            RecipientRecord updatedSettings = Objects.requireNonNull(recipientDatabase.getRecordForSync(settings.getId()));
            return StorageSyncModels.localToRemoteRecord(updatedSettings);
        }
    }).transform(r -> r.getContact().get());
}
Also used : Context(android.content.Context) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Arrays(java.util.Arrays) ACI(org.whispersystems.signalservice.api.push.ACI) NonNull(androidx.annotation.NonNull) RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) IdentityState(org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState) Optional(org.whispersystems.libsignal.util.guava.Optional) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) Nullable(androidx.annotation.Nullable) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalContactRecord(org.whispersystems.signalservice.api.storage.SignalContactRecord) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) RecipientRecord(org.thoughtcrime.securesms.database.model.RecipientRecord) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) RecipientRecord(org.thoughtcrime.securesms.database.model.RecipientRecord) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) NonNull(androidx.annotation.NonNull)

Aggregations

RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)72 Recipient (org.thoughtcrime.securesms.recipients.Recipient)32 WorkerThread (androidx.annotation.WorkerThread)30 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)20 NonNull (androidx.annotation.NonNull)18 IOException (java.io.IOException)14 Nullable (androidx.annotation.Nullable)10 ArrayList (java.util.ArrayList)10 Log (org.signal.core.util.logging.Log)10 SignalDatabase (org.thoughtcrime.securesms.database.SignalDatabase)10 ACI (org.whispersystems.signalservice.api.push.ACI)10 Context (android.content.Context)8 Stream (com.annimon.stream.Stream)8 Collections (java.util.Collections)8 List (java.util.List)8 TimeUnit (java.util.concurrent.TimeUnit)8 ProfileKey (org.signal.zkgroup.profiles.ProfileKey)8 ApplicationDependencies (org.thoughtcrime.securesms.dependencies.ApplicationDependencies)8 Optional (org.whispersystems.libsignal.util.guava.Optional)8 HashSet (java.util.HashSet)7