mirror of
https://github.com/oxen-io/session-android.git
synced 2025-06-09 14:38:33 +00:00
Cleanup bad recipients.
This commit is contained in:
parent
89e075c56e
commit
95333eccd4
@ -0,0 +1,92 @@
|
|||||||
|
package org.thoughtcrime.securesms.database.helpers;
|
||||||
|
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import net.sqlcipher.database.SQLiteDatabase;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class RecipientIdCleanupHelper {
|
||||||
|
|
||||||
|
private static final String TAG = Log.tag(RecipientIdCleanupHelper.class);
|
||||||
|
|
||||||
|
public static void execute(@NonNull SQLiteDatabase db) {
|
||||||
|
Log.i(TAG, "Beginning migration.");
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
Pattern pattern = Pattern.compile("^[0-9\\-+]+$");
|
||||||
|
Set<String> deletionCandidates = new HashSet<>();
|
||||||
|
|
||||||
|
try (Cursor cursor = db.query("recipient", new String[] { "_id", "phone" }, "group_id IS NULL AND email IS NULL", null, null, null, null)) {
|
||||||
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
String id = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
|
||||||
|
String phone = cursor.getString(cursor.getColumnIndexOrThrow("phone"));
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(phone) || !pattern.matcher(phone).matches()) {
|
||||||
|
Log.i(TAG, "Recipient ID " + id + " has non-numeric characters and can potentially be deleted.");
|
||||||
|
|
||||||
|
if (!isIdUsed(db, "identities", "address", id) &&
|
||||||
|
!isIdUsed(db, "sessions", "address", id) &&
|
||||||
|
!isIdUsed(db, "thread", "recipient_ids", id) &&
|
||||||
|
!isIdUsed(db, "sms", "address", id) &&
|
||||||
|
!isIdUsed(db, "mms", "address", id) &&
|
||||||
|
!isIdUsed(db, "mms", "quote_author", id) &&
|
||||||
|
!isIdUsed(db, "group_receipts", "address", id) &&
|
||||||
|
!isIdUsed(db, "groups", "recipient_id", id))
|
||||||
|
{
|
||||||
|
Log.i(TAG, "Determined ID " + id + " is unused in non-group membership. Marking for potential deletion.");
|
||||||
|
deletionCandidates.add(id);
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "Found that ID " + id + " is actually used in another table.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> deletions = findUnusedInGroupMembership(db, deletionCandidates);
|
||||||
|
|
||||||
|
for (String deletion : deletions) {
|
||||||
|
Log.i(TAG, "Deleting ID " + deletion);
|
||||||
|
db.delete("recipient", "_id = ?", new String[] { String.valueOf(deletion) });
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "Migration took " + (System.currentTimeMillis() - startTime) + " ms.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isIdUsed(@NonNull SQLiteDatabase db, @NonNull String tableName, @NonNull String columnName, String id) {
|
||||||
|
try (Cursor cursor = db.query(tableName, new String[] { columnName }, columnName + " = ?", new String[] { id }, null, null, null, "1")) {
|
||||||
|
boolean used = cursor != null && cursor.moveToFirst();
|
||||||
|
if (used) {
|
||||||
|
Log.i(TAG, "Recipient " + id + " was used in (" + tableName + ", " + columnName + ")");
|
||||||
|
}
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<String> findUnusedInGroupMembership(@NonNull SQLiteDatabase db, Set<String> candidates) {
|
||||||
|
Set<String> unused = new HashSet<>(candidates);
|
||||||
|
|
||||||
|
try (Cursor cursor = db.rawQuery("SELECT members FROM groups", null)) {
|
||||||
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
String serializedMembers = cursor.getString(cursor.getColumnIndexOrThrow("members"));
|
||||||
|
String[] members = DelimiterUtil.split(serializedMembers, ',');
|
||||||
|
|
||||||
|
for (String member : members) {
|
||||||
|
if (unused.remove(member)) {
|
||||||
|
Log.i(TAG, "Recipient " + member + " was found in a group membership list.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unused;
|
||||||
|
}
|
||||||
|
}
|
@ -39,13 +39,9 @@ import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob;
|
|||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
|
||||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.util.DelimiterUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@ -78,8 +74,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
private static final int VIEW_ONCE_ONLY = 23;
|
private static final int VIEW_ONCE_ONLY = 23;
|
||||||
private static final int RECIPIENT_IDS = 24;
|
private static final int RECIPIENT_IDS = 24;
|
||||||
private static final int RECIPIENT_SEARCH = 25;
|
private static final int RECIPIENT_SEARCH = 25;
|
||||||
|
private static final int RECIPIENT_CLEANUP = 26;
|
||||||
|
|
||||||
private static final int DATABASE_VERSION = 25;
|
private static final int DATABASE_VERSION = 26;
|
||||||
private static final String DATABASE_NAME = "signal.db";
|
private static final String DATABASE_NAME = "signal.db";
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
@ -513,6 +510,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < RECIPIENT_CLEANUP) {
|
||||||
|
RecipientIdCleanupHelper.execute(db);
|
||||||
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction();
|
db.endTransaction();
|
||||||
|
@ -38,12 +38,13 @@ public class ApplicationMigrations {
|
|||||||
|
|
||||||
private static final int LEGACY_CANONICAL_VERSION = 455;
|
private static final int LEGACY_CANONICAL_VERSION = 455;
|
||||||
|
|
||||||
public static final int CURRENT_VERSION = 3;
|
public static final int CURRENT_VERSION = 4;
|
||||||
|
|
||||||
private static final class Version {
|
private static final class Version {
|
||||||
static final int LEGACY = 1;
|
static final int LEGACY = 1;
|
||||||
static final int RECIPIENT_ID = 2;
|
static final int RECIPIENT_ID = 2;
|
||||||
static final int RECIPIENT_SEARCH = 3;
|
static final int RECIPIENT_SEARCH = 3;
|
||||||
|
static final int RECIPIENT_CLEANUP = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,6 +169,10 @@ public class ApplicationMigrations {
|
|||||||
jobs.put(Version.RECIPIENT_SEARCH, new RecipientSearchMigrationJob());
|
jobs.put(Version.RECIPIENT_SEARCH, new RecipientSearchMigrationJob());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastSeenVersion < Version.RECIPIENT_CLEANUP) {
|
||||||
|
jobs.put(Version.RECIPIENT_CLEANUP, new DatabaseMigrationJob());
|
||||||
|
}
|
||||||
|
|
||||||
return jobs;
|
return jobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user