Store payment address of profiles

This commit is contained in:
AsamK 2022-05-17 20:09:26 +02:00
parent c3425979dd
commit e844abcad1
5 changed files with 53 additions and 20 deletions

View file

@ -1,5 +1,7 @@
package org.asamk.signal.manager.helper; package org.asamk.signal.manager.helper;
import com.google.protobuf.InvalidProtocolBufferException;
import org.asamk.signal.manager.SignalDependencies; import org.asamk.signal.manager.SignalDependencies;
import org.asamk.signal.manager.config.ServiceConfig; import org.asamk.signal.manager.config.ServiceConfig;
import org.asamk.signal.manager.storage.SignalAccount; import org.asamk.signal.manager.storage.SignalAccount;
@ -23,6 +25,7 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException; import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import org.whispersystems.signalservice.api.services.ProfileService; import org.whispersystems.signalservice.api.services.ProfileService;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -138,13 +141,20 @@ public final class ProfileHelper {
: avatar.isPresent() : avatar.isPresent()
? AvatarUploadParams.forAvatar(streamDetails) ? AvatarUploadParams.forAvatar(streamDetails)
: AvatarUploadParams.unchanged(false); : AvatarUploadParams.unchanged(false);
final var paymentsAddress = Optional.ofNullable(newProfile.getPaymentAddress()).map(data -> {
try {
return SignalServiceProtos.PaymentAddress.parseFrom(data);
} catch (InvalidProtocolBufferException e) {
return null;
}
});
final var avatarPath = dependencies.getAccountManager() final var avatarPath = dependencies.getAccountManager()
.setVersionedProfile(account.getAci(), .setVersionedProfile(account.getAci(),
account.getProfileKey(), account.getProfileKey(),
newProfile.getInternalServiceName(), newProfile.getInternalServiceName(),
newProfile.getAbout() == null ? "" : newProfile.getAbout(), newProfile.getAbout() == null ? "" : newProfile.getAbout(),
newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(), newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(),
Optional.empty(), paymentsAddress,
avatarUploadParams, avatarUploadParams,
List.of(/* TODO */)); List.of(/* TODO */));
builder.withAvatarUrlPath(avatarPath.orElse(null)); builder.withAvatarUrlPath(avatarPath.orElse(null));

View file

@ -757,6 +757,7 @@ public class SignalAccount implements Closeable {
profile.getAbout(), profile.getAbout(),
profile.getAboutEmoji(), profile.getAboutEmoji(),
null, null,
null,
profile.isUnrestrictedUnidentifiedAccess() profile.isUnrestrictedUnidentifiedAccess()
? Profile.UnidentifiedAccessMode.UNRESTRICTED ? Profile.UnidentifiedAccessMode.UNRESTRICTED
: profile.getUnidentifiedAccess() != null : profile.getUnidentifiedAccess() != null

View file

@ -20,6 +20,8 @@ public class Profile {
private final String avatarUrlPath; private final String avatarUrlPath;
private final byte[] paymentAddress;
private final UnidentifiedAccessMode unidentifiedAccessMode; private final UnidentifiedAccessMode unidentifiedAccessMode;
private final Set<Capability> capabilities; private final Set<Capability> capabilities;
@ -31,6 +33,7 @@ public class Profile {
final String about, final String about,
final String aboutEmoji, final String aboutEmoji,
final String avatarUrlPath, final String avatarUrlPath,
final byte[] paymentAddress,
final UnidentifiedAccessMode unidentifiedAccessMode, final UnidentifiedAccessMode unidentifiedAccessMode,
final Set<Capability> capabilities final Set<Capability> capabilities
) { ) {
@ -40,6 +43,7 @@ public class Profile {
this.about = about; this.about = about;
this.aboutEmoji = aboutEmoji; this.aboutEmoji = aboutEmoji;
this.avatarUrlPath = avatarUrlPath; this.avatarUrlPath = avatarUrlPath;
this.paymentAddress = paymentAddress;
this.unidentifiedAccessMode = unidentifiedAccessMode; this.unidentifiedAccessMode = unidentifiedAccessMode;
this.capabilities = capabilities; this.capabilities = capabilities;
} }
@ -51,6 +55,7 @@ public class Profile {
about = builder.about; about = builder.about;
aboutEmoji = builder.aboutEmoji; aboutEmoji = builder.aboutEmoji;
avatarUrlPath = builder.avatarUrlPath; avatarUrlPath = builder.avatarUrlPath;
paymentAddress = builder.paymentAddress;
unidentifiedAccessMode = builder.unidentifiedAccessMode; unidentifiedAccessMode = builder.unidentifiedAccessMode;
capabilities = builder.capabilities; capabilities = builder.capabilities;
} }
@ -67,6 +72,7 @@ public class Profile {
builder.about = copy.getAbout(); builder.about = copy.getAbout();
builder.aboutEmoji = copy.getAboutEmoji(); builder.aboutEmoji = copy.getAboutEmoji();
builder.avatarUrlPath = copy.getAvatarUrlPath(); builder.avatarUrlPath = copy.getAvatarUrlPath();
builder.paymentAddress = copy.getPaymentAddress();
builder.unidentifiedAccessMode = copy.getUnidentifiedAccessMode(); builder.unidentifiedAccessMode = copy.getUnidentifiedAccessMode();
builder.capabilities = copy.getCapabilities(); builder.capabilities = copy.getCapabilities();
return builder; return builder;
@ -118,6 +124,10 @@ public class Profile {
return avatarUrlPath; return avatarUrlPath;
} }
public byte[] getPaymentAddress() {
return paymentAddress;
}
public UnidentifiedAccessMode getUnidentifiedAccessMode() { public UnidentifiedAccessMode getUnidentifiedAccessMode() {
return unidentifiedAccessMode; return unidentifiedAccessMode;
} }
@ -190,6 +200,7 @@ public class Profile {
private String about; private String about;
private String aboutEmoji; private String aboutEmoji;
private String avatarUrlPath; private String avatarUrlPath;
private byte[] paymentAddress;
private UnidentifiedAccessMode unidentifiedAccessMode = UnidentifiedAccessMode.UNKNOWN; private UnidentifiedAccessMode unidentifiedAccessMode = UnidentifiedAccessMode.UNKNOWN;
private Set<Capability> capabilities = Collections.emptySet(); private Set<Capability> capabilities = Collections.emptySet();
private long lastUpdateTimestamp = 0; private long lastUpdateTimestamp = 0;
@ -240,5 +251,10 @@ public class Profile {
lastUpdateTimestamp = val; lastUpdateTimestamp = val;
return this; return this;
} }
public Builder withPaymentAddress(final byte[] val) {
paymentAddress = val;
return this;
}
} }
} }

View file

@ -103,6 +103,9 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
r.profile.about, r.profile.about,
r.profile.aboutEmoji, r.profile.aboutEmoji,
r.profile.avatarUrlPath, r.profile.avatarUrlPath,
r.profile.paymentAddress == null
? null
: Base64.getDecoder().decode(r.profile.paymentAddress),
Profile.UnidentifiedAccessMode.valueOfOrUnknown(r.profile.unidentifiedAccessMode), Profile.UnidentifiedAccessMode.valueOfOrUnknown(r.profile.unidentifiedAccessMode),
r.profile.capabilities.stream() r.profile.capabilities.stream()
.map(Profile.Capability::valueOfOrNull) .map(Profile.Capability::valueOfOrNull)
@ -535,27 +538,28 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
final var base64 = Base64.getEncoder(); final var base64 = Base64.getEncoder();
var storage = new Storage(recipients.entrySet().stream().map(pair -> { var storage = new Storage(recipients.entrySet().stream().map(pair -> {
final var recipient = pair.getValue(); final var recipient = pair.getValue();
final var contact = recipient.getContact() == null final var recipientContact = recipient.getContact();
final var contact = recipientContact == null
? null ? null
: new Storage.Recipient.Contact(recipient.getContact().getName(), : new Storage.Recipient.Contact(recipientContact.getName(),
recipient.getContact().getColor(), recipientContact.getColor(),
recipient.getContact().getMessageExpirationTime(), recipientContact.getMessageExpirationTime(),
recipient.getContact().isBlocked(), recipientContact.isBlocked(),
recipient.getContact().isArchived()); recipientContact.isArchived());
final var profile = recipient.getProfile() == null final var recipientProfile = recipient.getProfile();
final var profile = recipientProfile == null
? null ? null
: new Storage.Recipient.Profile(recipient.getProfile().getLastUpdateTimestamp(), : new Storage.Recipient.Profile(recipientProfile.getLastUpdateTimestamp(),
recipient.getProfile().getGivenName(), recipientProfile.getGivenName(),
recipient.getProfile().getFamilyName(), recipientProfile.getFamilyName(),
recipient.getProfile().getAbout(), recipientProfile.getAbout(),
recipient.getProfile().getAboutEmoji(), recipientProfile.getAboutEmoji(),
recipient.getProfile().getAvatarUrlPath(), recipientProfile.getAvatarUrlPath(),
recipient.getProfile().getUnidentifiedAccessMode().name(), recipientProfile.getPaymentAddress() == null
recipient.getProfile() ? null
.getCapabilities() : base64.encodeToString(recipientProfile.getPaymentAddress()),
.stream() recipientProfile.getUnidentifiedAccessMode().name(),
.map(Enum::name) recipientProfile.getCapabilities().stream().map(Enum::name).collect(Collectors.toSet()));
.collect(Collectors.toSet()));
return new Storage.Recipient(pair.getKey().id(), return new Storage.Recipient(pair.getKey().id(),
recipient.getAddress().number().orElse(null), recipient.getAddress().number().orElse(null),
recipient.getAddress().uuid().map(UUID::toString).orElse(null), recipient.getAddress().uuid().map(UUID::toString).orElse(null),
@ -605,6 +609,7 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
String about, String about,
String aboutEmoji, String aboutEmoji,
String avatarUrlPath, String avatarUrlPath,
String paymentAddress,
String unidentifiedAccessMode, String unidentifiedAccessMode,
Set<String> capabilities Set<String> capabilities
) {} ) {}

View file

@ -32,6 +32,7 @@ public class ProfileUtils {
about, about,
aboutEmoji, aboutEmoji,
encryptedProfile.getAvatar(), encryptedProfile.getAvatar(),
encryptedProfile.getPaymentAddress(),
getUnidentifiedAccessMode(encryptedProfile, profileCipher), getUnidentifiedAccessMode(encryptedProfile, profileCipher),
getCapabilities(encryptedProfile)); getCapabilities(encryptedProfile));
} catch (InvalidCiphertextException e) { } catch (InvalidCiphertextException e) {