That fuck shit the fascists are using
at master 150 lines 4.8 kB view raw
1package org.tm.archive.database 2 3import android.content.Context 4import android.database.Cursor 5import androidx.core.content.contentValuesOf 6import org.signal.core.util.delete 7import org.signal.core.util.deleteAll 8import org.signal.core.util.logging.Log 9import org.signal.core.util.readToSet 10import org.signal.core.util.requireInt 11import org.signal.core.util.requireString 12import org.signal.core.util.select 13import org.signal.core.util.withinTransaction 14import org.signal.libsignal.protocol.SignalProtocolAddress 15import org.tm.archive.recipients.Recipient 16import org.tm.archive.recipients.RecipientId 17import org.whispersystems.signalservice.api.push.DistributionId 18 19/** 20 * Keeps track of which recipients are aware of which distributionIds. For the storage of sender 21 * keys themselves, see [SenderKeyTable]. 22 */ 23class SenderKeySharedTable internal constructor(context: Context?, databaseHelper: SignalDatabase?) : DatabaseTable(context, databaseHelper) { 24 companion object { 25 private val TAG = Log.tag(SenderKeySharedTable::class.java) 26 const val TABLE_NAME = "sender_key_shared" 27 private const val ID = "_id" 28 const val DISTRIBUTION_ID = "distribution_id" 29 const val ADDRESS = "address" 30 const val DEVICE = "device" 31 const val TIMESTAMP = "timestamp" 32 const val CREATE_TABLE = """ 33 CREATE TABLE $TABLE_NAME ( 34 $ID INTEGER PRIMARY KEY AUTOINCREMENT, 35 $DISTRIBUTION_ID TEXT NOT NULL, 36 $ADDRESS TEXT NOT NULL, 37 $DEVICE INTEGER NOT NULL, 38 $TIMESTAMP INTEGER DEFAULT 0, 39 UNIQUE($DISTRIBUTION_ID,$ADDRESS, $DEVICE) ON CONFLICT REPLACE 40 ) 41 """ 42 } 43 44/** 45 * Mark that a distributionId has been shared with the provided recipients 46 */ 47 fun markAsShared(distributionId: DistributionId, addresses: Collection<SignalProtocolAddress>) { 48 writableDatabase.withinTransaction { db -> 49 for (address in addresses) { 50 val values = contentValuesOf( 51 ADDRESS to address.name, 52 DEVICE to address.deviceId, 53 DISTRIBUTION_ID to distributionId.toString(), 54 TIMESTAMP to System.currentTimeMillis() 55 ) 56 db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE) 57 } 58 } 59 } 60 61 /** 62 * Get the set of recipientIds that know about the distributionId in question. 63 */ 64 fun getSharedWith(distributionId: DistributionId): Set<SignalProtocolAddress> { 65 return readableDatabase 66 .select(ADDRESS, DEVICE) 67 .from(TABLE_NAME) 68 .where("$DISTRIBUTION_ID = ?", distributionId) 69 .run() 70 .readToSet { cursor -> 71 SignalProtocolAddress( 72 cursor.requireString(ADDRESS), 73 cursor.requireInt(DEVICE) 74 ) 75 } 76 } 77 78 /** 79 * Clear the shared statuses for all provided addresses. 80 */ 81 fun delete(distributionId: DistributionId, addresses: Collection<SignalProtocolAddress>) { 82 writableDatabase.withinTransaction { db -> 83 for (address in addresses) { 84 db.delete(TABLE_NAME) 85 .where("$DISTRIBUTION_ID = ? AND $ADDRESS = ? AND $DEVICE = ?", distributionId, address.name, address.deviceId) 86 .run() 87 } 88 } 89 } 90 91 /** 92 * Clear all shared statuses for a given distributionId. 93 */ 94 fun deleteAllFor(distributionId: DistributionId) { 95 writableDatabase 96 .delete(TABLE_NAME) 97 .where("$DISTRIBUTION_ID = ?", distributionId) 98 .run() 99 } 100 101 /** 102 * Clear the shared status for all distributionIds for a set of addresses. 103 */ 104 fun deleteAllFor(addresses: Collection<SignalProtocolAddress>) { 105 writableDatabase.withinTransaction { db -> 106 for (address in addresses) { 107 db.delete(TABLE_NAME) 108 .where("$ADDRESS = ? AND $DEVICE = ?", address.name, address.deviceId) 109 .run() 110 } 111 } 112 } 113 114 /** 115 * Clear the shared status for all distributionIds for a given recipientId. 116 */ 117 fun deleteAllFor(recipientId: RecipientId) { 118 val recipient = Recipient.resolved(recipientId) 119 if (recipient.hasServiceId()) { 120 if (recipient.hasAci()) { 121 writableDatabase 122 .delete(TABLE_NAME) 123 .where("$ADDRESS = ?", recipient.requireAci().toString()) 124 .run() 125 } 126 if (recipient.hasPni()) { 127 writableDatabase 128 .delete(TABLE_NAME) 129 .where("$ADDRESS = ?", recipient.requirePni().toString()) 130 .run() 131 } 132 } else { 133 Log.w(TAG, "Recipient doesn't have a ServiceId! $recipientId") 134 } 135 } 136 137 /** 138 * Clears all database content. 139 */ 140 fun deleteAll() { 141 writableDatabase.deleteAll(TABLE_NAME) 142 } 143 144 /** 145 * Gets the shared state of all of our sender keys. Used for debugging. 146 */ 147 fun getAllSharedWithCursor(): Cursor { 148 return readableDatabase.query(TABLE_NAME, null, null, null, null, null, "$DISTRIBUTION_ID, $ADDRESS, $DEVICE") 149 } 150}