mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-23 00:17:34 +00:00
Handle negative directory case and unlisted contacts.
This commit is contained in:
parent
75cca3add1
commit
2d083208cc
@ -15,8 +15,8 @@ import org.whispersystems.textsecure.util.Util;
|
|||||||
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -53,20 +53,7 @@ public class Directory {
|
|||||||
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
this.databaseHelper = new DatabaseHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsNumbers(List<String> e164numbers) {
|
public boolean isActiveNumber(String e164number) throws NotInDirectoryException {
|
||||||
if (e164numbers == null || e164numbers.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String e164number : e164numbers) {
|
|
||||||
if (!containsNumber(e164number))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsNumber(String e164number) {
|
|
||||||
if (e164number == null || e164number.length() == 0) {
|
if (e164number == null || e164number.length() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -82,29 +69,33 @@ public class Directory {
|
|||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
return cursor.getInt(0) == 1;
|
return cursor.getInt(0) == 1;
|
||||||
|
} else {
|
||||||
|
throw new NotInDirectoryException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
cursor.close();
|
cursor.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setActiveTokens(List<String> tokens) {
|
public void setToken(String token, boolean active) {
|
||||||
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(TOKEN, token);
|
||||||
|
values.put(REGISTERED, active ? 1 : 0);
|
||||||
|
values.put(TIMESTAMP, System.currentTimeMillis());
|
||||||
|
db.replace(TABLE_NAME, null, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTokens(List<String> activeTokens, Collection<String> inactiveTokens) {
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
db.beginTransaction();
|
db.beginTransaction();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ContentValues clear = new ContentValues();
|
for (String token : activeTokens) {
|
||||||
clear.put(REGISTERED, 0);
|
Log.w("Directory", "Adding active token: " + token);
|
||||||
clear.put(TIMESTAMP, timestamp);
|
|
||||||
db.update(TABLE_NAME, clear, null, null);
|
|
||||||
|
|
||||||
|
|
||||||
for (String token : tokens) {
|
|
||||||
Log.w("Directory", "Adding token: " + token);
|
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put(TOKEN, token);
|
values.put(TOKEN, token);
|
||||||
values.put(REGISTERED, 1);
|
values.put(REGISTERED, 1);
|
||||||
@ -112,6 +103,14 @@ public class Directory {
|
|||||||
db.replace(TABLE_NAME, null, values);
|
db.replace(TABLE_NAME, null, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (String token : inactiveTokens) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(TOKEN, token);
|
||||||
|
values.put(REGISTERED, 0);
|
||||||
|
values.put(TIMESTAMP, timestamp);
|
||||||
|
db.replace(TABLE_NAME, null, values);
|
||||||
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction();
|
db.endTransaction();
|
||||||
@ -135,6 +134,15 @@ public class Directory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursor.close();
|
||||||
|
|
||||||
|
cursor = databaseHelper.getReadableDatabase().query(TABLE_NAME, new String[] {TOKEN},
|
||||||
|
null, null, null, null, null);
|
||||||
|
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
results.add(cursor.getString(0));
|
||||||
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
@ -142,7 +150,7 @@ public class Directory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getToken(String e164number) {
|
public String getToken(String e164number) {
|
||||||
try {
|
try {
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
MessageDigest digest = MessageDigest.getInstance("SHA1");
|
||||||
byte[] token = Util.trim(digest.digest(e164number.getBytes()), 10);
|
byte[] token = Util.trim(digest.digest(e164number.getBytes()), 10);
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
package org.whispersystems.textsecure.directory;
|
||||||
|
|
||||||
|
public class NotInDirectoryException extends Throwable {
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package org.whispersystems.textsecure.push;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class NotFoundException extends IOException {
|
||||||
|
public NotFoundException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,8 @@ public class PushServiceSocket {
|
|||||||
private static final String REGISTER_GCM_PATH = "/v1/accounts/gcm/";
|
private static final String REGISTER_GCM_PATH = "/v1/accounts/gcm/";
|
||||||
private static final String PREKEY_PATH = "/v1/keys/%s";
|
private static final String PREKEY_PATH = "/v1/keys/%s";
|
||||||
|
|
||||||
private static final String DIRECTORY_PATH = "/v1/directory/";
|
private static final String DIRECTORY_TOKENS_PATH = "/v1/directory/tokens";
|
||||||
|
private static final String DIRECTORY_VERIFY_PATH = "/v1/directory/%s";
|
||||||
private static final String MESSAGE_PATH = "/v1/messages/";
|
private static final String MESSAGE_PATH = "/v1/messages/";
|
||||||
private static final String ATTACHMENT_PATH = "/v1/attachments/%s";
|
private static final String ATTACHMENT_PATH = "/v1/attachments/%s";
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ public class PushServiceSocket {
|
|||||||
public List<String> retrieveDirectory(Set<String> contactTokens) {
|
public List<String> retrieveDirectory(Set<String> contactTokens) {
|
||||||
try {
|
try {
|
||||||
ContactTokenList contactTokenList = new ContactTokenList(new LinkedList(contactTokens));
|
ContactTokenList contactTokenList = new ContactTokenList(new LinkedList(contactTokens));
|
||||||
String response = makeRequest(DIRECTORY_PATH, "PUT", new Gson().toJson(contactTokenList));
|
String response = makeRequest(DIRECTORY_TOKENS_PATH, "PUT", new Gson().toJson(contactTokenList));
|
||||||
ContactTokenList activeTokens = new Gson().fromJson(response, ContactTokenList.class);
|
ContactTokenList activeTokens = new Gson().fromJson(response, ContactTokenList.class);
|
||||||
|
|
||||||
return activeTokens.getContacts();
|
return activeTokens.getContacts();
|
||||||
@ -182,6 +183,15 @@ public class PushServiceSocket {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRegisteredUser(String contactToken) throws IOException {
|
||||||
|
try {
|
||||||
|
makeRequest(String.format(DIRECTORY_VERIFY_PATH, contactToken), "GET", null);
|
||||||
|
return true;
|
||||||
|
} catch (NotFoundException nfe) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void downloadExternalFile(String url, File localDestination)
|
private void downloadExternalFile(String url, File localDestination)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
@ -284,6 +294,10 @@ public class PushServiceSocket {
|
|||||||
throw new AuthorizationFailedException("Authorization failed!");
|
throw new AuthorizationFailedException("Authorization failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connection.getResponseCode() == 404) {
|
||||||
|
throw new NotFoundException("Not found");
|
||||||
|
}
|
||||||
|
|
||||||
if (connection.getResponseCode() != 200) {
|
if (connection.getResponseCode() != 200) {
|
||||||
throw new IOException("Bad response: " + connection.getResponseCode() + " " + connection.getResponseMessage());
|
throw new IOException("Bad response: " + connection.getResponseCode() + " " + connection.getResponseMessage());
|
||||||
}
|
}
|
||||||
|
@ -286,8 +286,8 @@ public class RegistrationService extends Service {
|
|||||||
List<String> activeTokens = socket.retrieveDirectory(contactTokens);
|
List<String> activeTokens = socket.retrieveDirectory(contactTokens);
|
||||||
|
|
||||||
if (activeTokens != null) {
|
if (activeTokens != null) {
|
||||||
Directory.getInstance(this).setActiveTokens(activeTokens);
|
contactTokens.removeAll(activeTokens);
|
||||||
// NumberFilter.getInstance(this).update(directory.first, directory.second);
|
Directory.getInstance(this).setTokens(activeTokens, contactTokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
|||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.whispersystems.textsecure.crypto.MasterSecret;
|
import org.whispersystems.textsecure.crypto.MasterSecret;
|
||||||
import org.whispersystems.textsecure.directory.Directory;
|
import org.whispersystems.textsecure.directory.Directory;
|
||||||
|
import org.whispersystems.textsecure.directory.NotInDirectoryException;
|
||||||
|
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -57,7 +59,7 @@ public class UniversalTransport {
|
|||||||
Recipient recipient = message.getIndividualRecipient();
|
Recipient recipient = message.getIndividualRecipient();
|
||||||
String number = Util.canonicalizeNumber(context, recipient.getNumber());
|
String number = Util.canonicalizeNumber(context, recipient.getNumber());
|
||||||
|
|
||||||
if (Directory.getInstance(context).containsNumber(number)) {
|
if (isPushTransport(number)) {
|
||||||
try {
|
try {
|
||||||
Log.w("UniversalTransport", "Delivering with GCM...");
|
Log.w("UniversalTransport", "Delivering with GCM...");
|
||||||
pushTransport.deliver(message);
|
pushTransport.deliver(message);
|
||||||
@ -78,7 +80,7 @@ public class UniversalTransport {
|
|||||||
|
|
||||||
List<String> destinations = getMediaDestinations(mediaMessage);
|
List<String> destinations = getMediaDestinations(mediaMessage);
|
||||||
|
|
||||||
if (Directory.getInstance(context).containsNumbers(destinations)) {
|
if (isPushTransport(destinations)) {
|
||||||
try {
|
try {
|
||||||
Log.w("UniversalTransport", "Delivering media message with GCM...");
|
Log.w("UniversalTransport", "Delivering media message with GCM...");
|
||||||
pushTransport.deliver(mediaMessage, destinations);
|
pushTransport.deliver(mediaMessage, destinations);
|
||||||
@ -117,4 +119,36 @@ public class UniversalTransport {
|
|||||||
return destinations;
|
return destinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isPushTransport(String destination) {
|
||||||
|
Directory directory = Directory.getInstance(context);
|
||||||
|
|
||||||
|
try {
|
||||||
|
return directory.isActiveNumber(destination);
|
||||||
|
} catch (NotInDirectoryException e) {
|
||||||
|
try {
|
||||||
|
String localNumber = TextSecurePreferences.getLocalNumber(context);
|
||||||
|
String pushPassword = TextSecurePreferences.getPushServerPassword(context);
|
||||||
|
String contactToken = directory.getToken(destination);
|
||||||
|
PushServiceSocket socket = new PushServiceSocket(context, localNumber, pushPassword);
|
||||||
|
boolean registeredUser = socket.isRegisteredUser(contactToken);
|
||||||
|
|
||||||
|
directory.setToken(contactToken, registeredUser);
|
||||||
|
|
||||||
|
return registeredUser;
|
||||||
|
} catch (IOException e1) {
|
||||||
|
Log.w("UniversalTransport", e1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPushTransport(List<String> destinations) {
|
||||||
|
for (String destination : destinations) {
|
||||||
|
if (!isPushTransport(destination)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user