Read phone number sharing mode from storage

Fixes #755
This commit is contained in:
AsamK 2021-11-10 14:14:19 +01:00
parent 81a11dc977
commit 4baf0849a6
6 changed files with 155 additions and 20 deletions

View file

@ -39,6 +39,10 @@
"allDeclaredFields":true,
"allDeclaredMethods":true}
,
{
"name":"com.google.protobuf.GeneratedMessageLite",
"fields":[{"name":"unknownFields"}]}
,
{
"name":"com.google.protobuf.Internal$LongList",
"allDeclaredMethods":true}
@ -659,13 +663,19 @@
"allDeclaredConstructors":true}
,
{
"name":"org.asamk.signal.manager.configuration.ConfigurationStore$Storage",
"name":"org.asamk.signal.manager.api.PhoneNumberSharingMode",
"allDeclaredFields":true,
"queryAllDeclaredMethods":true}
,
{
"name":"org.asamk.signal.manager.storage.configuration.ConfigurationStore$Storage",
"allDeclaredFields":true,
"queryAllDeclaredMethods":true,
"queryAllDeclaredConstructors":true,
"methods":[
{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Boolean","java.lang.Boolean","java.lang.Boolean"] },
{"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Boolean","java.lang.Boolean","java.lang.Boolean","org.asamk.signal.manager.api.PhoneNumberSharingMode"] },
{"name":"linkPreviews","parameterTypes":[] },
{"name":"phoneNumberSharingMode","parameterTypes":[] },
{"name":"readReceipts","parameterTypes":[] },
{"name":"typingIndicators","parameterTypes":[] },
{"name":"unidentifiedDeliveryIndicators","parameterTypes":[] }
@ -2492,6 +2502,79 @@
{"name":"metadata_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord",
"allDeclaredFields":true}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord$PinnedConversation",
"fields":[
{"name":"identifierCase_"},
{"name":"identifier_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord$PinnedConversation$Contact",
"fields":[
{"name":"e164_"},
{"name":"uuid_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.ContactRecord",
"allDeclaredFields":true}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.GroupV2Record",
"allDeclaredFields":true}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.ManifestRecord",
"fields":[
{"name":"identifiers_"},
{"name":"version_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.ManifestRecord$Identifier",
"fields":[
{"name":"raw_"},
{"name":"type_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.Payments",
"allDeclaredFields":true}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.ReadOperation",
"fields":[{"name":"readKey_"}]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.StorageItem",
"fields":[
{"name":"key_"},
{"name":"value_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.StorageItems",
"fields":[{"name":"items_"}]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.StorageManifest",
"fields":[
{"name":"value_"},
{"name":"version_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.storage.protos.StorageRecord",
"fields":[
{"name":"recordCase_"},
{"name":"record_"}
]}
,
{
"name":"org.whispersystems.signalservice.internal.util.JsonUtil$AciDeserializer",
"methods":[{"name":"<init>","parameterTypes":[] }]}

View file

@ -0,0 +1,7 @@
package org.asamk.signal.manager.api;
public enum PhoneNumberSharingMode {
EVERYBODY,
CONTACTS,
NOBODY,
}

View file

@ -2,6 +2,7 @@ package org.asamk.signal.manager.helper;
import org.asamk.signal.manager.SignalDependencies;
import org.asamk.signal.manager.TrustLevel;
import org.asamk.signal.manager.api.PhoneNumberSharingMode;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.recipients.Contact;
@ -17,6 +18,7 @@ import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
import org.whispersystems.signalservice.api.storage.StorageId;
import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
import java.io.IOException;
@ -202,6 +204,14 @@ public class StorageHelper {
account.getConfigurationStore()
.setUnidentifiedDeliveryIndicators(accountRecord.isSealedSenderIndicatorsEnabled());
account.getConfigurationStore().setLinkPreviews(accountRecord.isLinkPreviewsEnabled());
if (accountRecord.getPhoneNumberSharingMode() != AccountRecord.PhoneNumberSharingMode.UNRECOGNIZED) {
account.getConfigurationStore()
.setPhoneNumberSharingMode(switch (accountRecord.getPhoneNumberSharingMode()) {
case EVERYBODY -> PhoneNumberSharingMode.EVERYBODY;
case NOBODY -> PhoneNumberSharingMode.NOBODY;
default -> PhoneNumberSharingMode.CONTACTS;
});
}
if (accountRecord.getProfileKey().isPresent()) {
ProfileKey profileKey;

View file

@ -1,6 +1,7 @@
package org.asamk.signal.manager.helper;
import org.asamk.signal.manager.SignalDependencies;
import org.asamk.signal.manager.api.PhoneNumberSharingMode;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
@ -37,20 +38,38 @@ public class UnidentifiedAccessHelper {
this.profileProvider = profileProvider;
}
private byte[] getSenderCertificate() {
byte[] certificate;
private byte[] getSenderCertificateFor(final RecipientId recipientId) {
final var sharingMode = account.getConfigurationStore().getPhoneNumberSharingMode();
if (sharingMode == PhoneNumberSharingMode.EVERYBODY || (
sharingMode == PhoneNumberSharingMode.CONTACTS
&& account.getContactStore().getContact(recipientId) != null
)) {
logger.debug("Using normal sender certificate for message to {}", recipientId);
return getSenderCertificate();
} else {
logger.debug("Using phone number privacy sender certificate for message to {}", recipientId);
return getSenderCertificateForPhoneNumberPrivacy();
}
}
private byte[] getSenderCertificateForPhoneNumberPrivacy() {
// TODO cache for a day
try {
if (account.isPhoneNumberShared()) {
certificate = dependencies.getAccountManager().getSenderCertificate();
} else {
certificate = dependencies.getAccountManager().getSenderCertificateForPhoneNumberPrivacy();
}
return dependencies.getAccountManager().getSenderCertificateForPhoneNumberPrivacy();
} catch (IOException e) {
logger.warn("Failed to get sender certificate, ignoring: {}", e.getMessage());
return null;
}
}
private byte[] getSenderCertificate() {
// TODO cache for a day
return certificate;
try {
return dependencies.getAccountManager().getSenderCertificate();
} catch (IOException e) {
logger.warn("Failed to get sender certificate, ignoring: {}", e.getMessage());
return null;
}
}
private byte[] getSelfUnidentifiedAccessKey() {
@ -102,7 +121,7 @@ public class UnidentifiedAccessHelper {
public Optional<UnidentifiedAccessPair> getAccessFor(RecipientId recipient) {
var recipientUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipient);
var selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey();
var selfUnidentifiedAccessCertificate = getSenderCertificate();
var selfUnidentifiedAccessCertificate = getSenderCertificateFor(recipient);
if (recipientUnidentifiedAccessKey == null
|| selfUnidentifiedAccessKey == null

View file

@ -5,8 +5,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.asamk.signal.manager.TrustLevel;
import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.configuration.ConfigurationStore;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.configuration.ConfigurationStore;
import org.asamk.signal.manager.storage.contacts.ContactsStore;
import org.asamk.signal.manager.storage.contacts.LegacyJsonContactsStore;
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
@ -987,11 +987,6 @@ public class SignalAccount implements Closeable {
return true;
}
public boolean isPhoneNumberShared() {
// TODO make configurable
return true;
}
public void finishRegistration(final ACI aci, final MasterKey masterKey, final String pin) {
this.pinMasterKey = masterKey;
this.storageManifestVersion = -1;

View file

@ -1,4 +1,6 @@
package org.asamk.signal.manager.configuration;
package org.asamk.signal.manager.storage.configuration;
import org.asamk.signal.manager.api.PhoneNumberSharingMode;
public class ConfigurationStore {
@ -8,6 +10,7 @@ public class ConfigurationStore {
private Boolean unidentifiedDeliveryIndicators;
private Boolean typingIndicators;
private Boolean linkPreviews;
private PhoneNumberSharingMode phoneNumberSharingMode;
public ConfigurationStore(final Saver saver) {
this.saver = saver;
@ -19,6 +22,7 @@ public class ConfigurationStore {
store.unidentifiedDeliveryIndicators = storage.unidentifiedDeliveryIndicators;
store.typingIndicators = storage.typingIndicators;
store.linkPreviews = storage.linkPreviews;
store.phoneNumberSharingMode = storage.phoneNumberSharingMode;
return store;
}
@ -58,12 +62,29 @@ public class ConfigurationStore {
saver.save(toStorage());
}
public PhoneNumberSharingMode getPhoneNumberSharingMode() {
return phoneNumberSharingMode;
}
public void setPhoneNumberSharingMode(final PhoneNumberSharingMode phoneNumberSharingMode) {
this.phoneNumberSharingMode = phoneNumberSharingMode;
saver.save(toStorage());
}
private Storage toStorage() {
return new Storage(readReceipts, unidentifiedDeliveryIndicators, typingIndicators, linkPreviews);
return new Storage(readReceipts,
unidentifiedDeliveryIndicators,
typingIndicators,
linkPreviews,
phoneNumberSharingMode);
}
public record Storage(
Boolean readReceipts, Boolean unidentifiedDeliveryIndicators, Boolean typingIndicators, Boolean linkPreviews
Boolean readReceipts,
Boolean unidentifiedDeliveryIndicators,
Boolean typingIndicators,
Boolean linkPreviews,
PhoneNumberSharingMode phoneNumberSharingMode
) {}
public interface Saver {