Add phone-number-sharing field to versioned profile
Co-authored-by: Katherine <katherine@signal.org>
This commit is contained in:
parent
3b509bf820
commit
9d3d4a3698
|
@ -163,9 +163,9 @@ public class ProfileController {
|
||||||
public Response setProfile(@Auth AuthenticatedAccount auth, @NotNull @Valid CreateProfileRequest request) {
|
public Response setProfile(@Auth AuthenticatedAccount auth, @NotNull @Valid CreateProfileRequest request) {
|
||||||
|
|
||||||
final Optional<VersionedProfile> currentProfile = profilesManager.get(auth.getAccount().getUuid(),
|
final Optional<VersionedProfile> currentProfile = profilesManager.get(auth.getAccount().getUuid(),
|
||||||
request.getVersion());
|
request.version());
|
||||||
|
|
||||||
if (request.getPaymentAddress() != null && request.getPaymentAddress().length != 0) {
|
if (request.paymentAddress() != null && request.paymentAddress().length != 0) {
|
||||||
final boolean hasDisallowedPrefix =
|
final boolean hasDisallowedPrefix =
|
||||||
dynamicConfigurationManager.getConfiguration().getPaymentsConfiguration().getDisallowedPrefixes().stream()
|
dynamicConfigurationManager.getConfiguration().getPaymentsConfiguration().getDisallowedPrefixes().stream()
|
||||||
.anyMatch(prefix -> auth.getAccount().getNumber().startsWith(prefix));
|
.anyMatch(prefix -> auth.getAccount().getNumber().startsWith(prefix));
|
||||||
|
@ -189,13 +189,14 @@ public class ProfileController {
|
||||||
|
|
||||||
profilesManager.set(auth.getAccount().getUuid(),
|
profilesManager.set(auth.getAccount().getUuid(),
|
||||||
new VersionedProfile(
|
new VersionedProfile(
|
||||||
request.getVersion(),
|
request.version(),
|
||||||
request.getName(),
|
request.name(),
|
||||||
avatar,
|
avatar,
|
||||||
request.getAboutEmoji(),
|
request.aboutEmoji(),
|
||||||
request.getAbout(),
|
request.about(),
|
||||||
request.getPaymentAddress(),
|
request.paymentAddress(),
|
||||||
request.getCommitment().serialize()));
|
request.phoneNumberSharing(),
|
||||||
|
request.commitment().serialize()));
|
||||||
|
|
||||||
if (request.getAvatarChange() != CreateProfileRequest.AvatarChange.UNCHANGED) {
|
if (request.getAvatarChange() != CreateProfileRequest.AvatarChange.UNCHANGED) {
|
||||||
currentAvatar.ifPresent(s -> s3client.deleteObject(DeleteObjectRequest.builder()
|
currentAvatar.ifPresent(s -> s3client.deleteObject(DeleteObjectRequest.builder()
|
||||||
|
@ -204,13 +205,13 @@ public class ProfileController {
|
||||||
.build()));
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<AccountBadge> updatedBadges = request.getBadges()
|
final List<AccountBadge> updatedBadges = request.badges()
|
||||||
.map(badges -> ProfileHelper.mergeBadgeIdsWithExistingAccountBadges(clock, badgeConfigurationMap, badges, auth.getAccount().getBadges()))
|
.map(badges -> ProfileHelper.mergeBadgeIdsWithExistingAccountBadges(clock, badgeConfigurationMap, badges, auth.getAccount().getBadges()))
|
||||||
.orElseGet(() -> auth.getAccount().getBadges());
|
.orElseGet(() -> auth.getAccount().getBadges());
|
||||||
|
|
||||||
accountsManager.update(auth.getAccount(), a -> {
|
accountsManager.update(auth.getAccount(), a -> {
|
||||||
a.setBadges(clock, updatedBadges);
|
a.setBadges(clock, updatedBadges);
|
||||||
a.setCurrentProfileVersion(request.getVersion());
|
a.setCurrentProfileVersion(request.version());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (request.getAvatarChange() == CreateProfileRequest.AvatarChange.UPDATE) {
|
if (request.getAvatarChange() == CreateProfileRequest.AvatarChange.UPDATE) {
|
||||||
|
@ -411,6 +412,7 @@ public class ProfileController {
|
||||||
final byte[] about = maybeProfile.map(VersionedProfile::about).orElse(null);
|
final byte[] about = maybeProfile.map(VersionedProfile::about).orElse(null);
|
||||||
final byte[] aboutEmoji = maybeProfile.map(VersionedProfile::aboutEmoji).orElse(null);
|
final byte[] aboutEmoji = maybeProfile.map(VersionedProfile::aboutEmoji).orElse(null);
|
||||||
final String avatar = maybeProfile.map(VersionedProfile::avatar).orElse(null);
|
final String avatar = maybeProfile.map(VersionedProfile::avatar).orElse(null);
|
||||||
|
final byte[] phoneNumberSharing = maybeProfile.map(VersionedProfile::phoneNumberSharing).orElse(null);
|
||||||
|
|
||||||
// Allow requests where either the version matches the latest version on Account or the latest version on Account
|
// Allow requests where either the version matches the latest version on Account or the latest version on Account
|
||||||
// is empty to read the payment address.
|
// is empty to read the payment address.
|
||||||
|
@ -421,7 +423,7 @@ public class ProfileController {
|
||||||
|
|
||||||
return new VersionedProfileResponse(
|
return new VersionedProfileResponse(
|
||||||
buildBaseProfileResponseForAccountIdentity(account, isSelf, containerRequestContext),
|
buildBaseProfileResponseForAccountIdentity(account, isSelf, containerRequestContext),
|
||||||
name, about, aboutEmoji, avatar, paymentAddress);
|
name, about, aboutEmoji, avatar, paymentAddress, phoneNumberSharing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BaseProfileResponse buildBaseProfileResponseForAccountIdentity(final Account account,
|
private BaseProfileResponse buildBaseProfileResponseForAccountIdentity(final Account account,
|
||||||
|
|
|
@ -10,91 +10,62 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCommitment;
|
import org.signal.libsignal.zkgroup.profiles.ProfileKeyCommitment;
|
||||||
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
||||||
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
||||||
|
|
||||||
public class CreateProfileRequest {
|
public record CreateProfileRequest(
|
||||||
|
@JsonProperty
|
||||||
|
@NotNull
|
||||||
|
@JsonDeserialize(using = ProfileKeyCommitmentAdapter.Deserializing.class)
|
||||||
|
@JsonSerialize(using = ProfileKeyCommitmentAdapter.Serializing.class)
|
||||||
|
ProfileKeyCommitment commitment,
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@NotEmpty
|
@NotEmpty
|
||||||
private String version;
|
String version,
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
@ExactlySize({81, 285})
|
@ExactlySize({81, 285})
|
||||||
private byte[] name;
|
byte[] name,
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private boolean avatar;
|
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private boolean sameAvatar;
|
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
@ExactlySize({0, 60})
|
@ExactlySize({0, 60})
|
||||||
private byte[] aboutEmoji;
|
byte[] aboutEmoji,
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
@ExactlySize({0, 156, 282, 540})
|
@ExactlySize({0, 156, 282, 540})
|
||||||
private byte[] about;
|
byte[] about,
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
@ExactlySize({0, 582})
|
@ExactlySize({0, 582})
|
||||||
private byte[] paymentAddress;
|
byte[] paymentAddress,
|
||||||
|
|
||||||
|
@JsonProperty("avatar")
|
||||||
|
boolean hasAvatar,
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@Nullable
|
boolean sameAvatar,
|
||||||
private List<String> badgeIds;
|
|
||||||
|
@JsonProperty("badgeIds")
|
||||||
|
Optional<List<String>> badges,
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@NotNull
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ProfileKeyCommitmentAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
@JsonSerialize(using = ProfileKeyCommitmentAdapter.Serializing.class)
|
@ExactlySize({0, 29})
|
||||||
private ProfileKeyCommitment commitment;
|
byte[] phoneNumberSharing
|
||||||
|
) {
|
||||||
public CreateProfileRequest() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public CreateProfileRequest(
|
|
||||||
final ProfileKeyCommitment commitment, final String version, final byte[] name, final byte[] aboutEmoji, final byte[] about,
|
|
||||||
final byte[] paymentAddress, final boolean wantsAvatar, final boolean sameAvatar, final List<String> badgeIds) {
|
|
||||||
this.commitment = commitment;
|
|
||||||
this.version = version;
|
|
||||||
this.name = name;
|
|
||||||
this.aboutEmoji = aboutEmoji;
|
|
||||||
this.about = about;
|
|
||||||
this.paymentAddress = paymentAddress;
|
|
||||||
this.avatar = wantsAvatar;
|
|
||||||
this.sameAvatar = sameAvatar;
|
|
||||||
this.badgeIds = badgeIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileKeyCommitment getCommitment() {
|
|
||||||
return commitment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAvatar() {
|
|
||||||
return avatar;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum AvatarChange {
|
public enum AvatarChange {
|
||||||
UNCHANGED,
|
UNCHANGED,
|
||||||
|
@ -112,19 +83,4 @@ public class CreateProfileRequest {
|
||||||
return AvatarChange.UNCHANGED;
|
return AvatarChange.UNCHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getAboutEmoji() {
|
|
||||||
return aboutEmoji;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getAbout() {
|
|
||||||
return about;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getPaymentAddress() {
|
|
||||||
return paymentAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<List<String>> getBadges() {
|
|
||||||
return Optional.ofNullable(badgeIds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
||||||
|
|
||||||
|
// Note, this class cannot be converted into a record because @JsonUnwrapped does not work with records.
|
||||||
|
// https://github.com/FasterXML/jackson-databind/issues/1467
|
||||||
public class VersionedProfileResponse {
|
public class VersionedProfileResponse {
|
||||||
|
|
||||||
@JsonUnwrapped
|
@JsonUnwrapped
|
||||||
|
@ -39,6 +41,11 @@ public class VersionedProfileResponse {
|
||||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
private byte[] paymentAddress;
|
private byte[] paymentAddress;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
|
private byte[] phoneNumberSharing;
|
||||||
|
|
||||||
public VersionedProfileResponse() {
|
public VersionedProfileResponse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +54,8 @@ public class VersionedProfileResponse {
|
||||||
final byte[] about,
|
final byte[] about,
|
||||||
final byte[] aboutEmoji,
|
final byte[] aboutEmoji,
|
||||||
final String avatar,
|
final String avatar,
|
||||||
final byte[] paymentAddress) {
|
final byte[] paymentAddress,
|
||||||
|
final byte[] phoneNumberSharing) {
|
||||||
|
|
||||||
this.baseProfileResponse = baseProfileResponse;
|
this.baseProfileResponse = baseProfileResponse;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -55,6 +63,7 @@ public class VersionedProfileResponse {
|
||||||
this.aboutEmoji = aboutEmoji;
|
this.aboutEmoji = aboutEmoji;
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
this.paymentAddress = paymentAddress;
|
this.paymentAddress = paymentAddress;
|
||||||
|
this.phoneNumberSharing = phoneNumberSharing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseProfileResponse getBaseProfileResponse() {
|
public BaseProfileResponse getBaseProfileResponse() {
|
||||||
|
@ -80,4 +89,8 @@ public class VersionedProfileResponse {
|
||||||
public byte[] getPaymentAddress() {
|
public byte[] getPaymentAddress() {
|
||||||
return paymentAddress;
|
return paymentAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getPhoneNumberSharing() {
|
||||||
|
return phoneNumberSharing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ public class ProfileGrpcHelper {
|
||||||
maybeProfile.map(VersionedProfile::about).map(ByteString::copyFrom).ifPresent(responseBuilder::setAbout);
|
maybeProfile.map(VersionedProfile::about).map(ByteString::copyFrom).ifPresent(responseBuilder::setAbout);
|
||||||
maybeProfile.map(VersionedProfile::aboutEmoji).map(ByteString::copyFrom).ifPresent(responseBuilder::setAboutEmoji);
|
maybeProfile.map(VersionedProfile::aboutEmoji).map(ByteString::copyFrom).ifPresent(responseBuilder::setAboutEmoji);
|
||||||
maybeProfile.map(VersionedProfile::avatar).ifPresent(responseBuilder::setAvatar);
|
maybeProfile.map(VersionedProfile::avatar).ifPresent(responseBuilder::setAvatar);
|
||||||
|
maybeProfile.map(VersionedProfile::phoneNumberSharing).map(ByteString::copyFrom).ifPresent(responseBuilder::setPhoneNumberSharing);
|
||||||
|
|
||||||
// Allow requests where either the version matches the latest version on Account or the latest version on Account
|
// Allow requests where either the version matches the latest version on Account or the latest version on Account
|
||||||
// is empty to read the payment address.
|
// is empty to read the payment address.
|
||||||
|
|
|
@ -141,6 +141,7 @@ public class ProfileGrpcService extends ReactorProfileGrpc.ProfileImplBase {
|
||||||
request.getAboutEmoji().toByteArray(),
|
request.getAboutEmoji().toByteArray(),
|
||||||
request.getAbout().toByteArray(),
|
request.getAbout().toByteArray(),
|
||||||
request.getPaymentAddress().toByteArray(),
|
request.getPaymentAddress().toByteArray(),
|
||||||
|
request.getPhoneNumberSharing().toByteArray(),
|
||||||
request.getCommitment().toByteArray())));
|
request.getCommitment().toByteArray())));
|
||||||
|
|
||||||
final List<Mono<?>> updates = new ArrayList<>(2);
|
final List<Mono<?>> updates = new ArrayList<>(2);
|
||||||
|
|
|
@ -62,6 +62,9 @@ public class Profiles {
|
||||||
// Payment address; byte array
|
// Payment address; byte array
|
||||||
private static final String ATTR_PAYMENT_ADDRESS = "P";
|
private static final String ATTR_PAYMENT_ADDRESS = "P";
|
||||||
|
|
||||||
|
// Phone number sharing setting; byte array
|
||||||
|
private static final String ATTR_PHONE_NUMBER_SHARING = "S";
|
||||||
|
|
||||||
// Commitment; byte array
|
// Commitment; byte array
|
||||||
private static final String ATTR_COMMITMENT = "C";
|
private static final String ATTR_COMMITMENT = "C";
|
||||||
|
|
||||||
|
@ -71,7 +74,8 @@ public class Profiles {
|
||||||
"#avatar", ATTR_AVATAR,
|
"#avatar", ATTR_AVATAR,
|
||||||
"#about", ATTR_ABOUT,
|
"#about", ATTR_ABOUT,
|
||||||
"#aboutEmoji", ATTR_EMOJI,
|
"#aboutEmoji", ATTR_EMOJI,
|
||||||
"#paymentAddress", ATTR_PAYMENT_ADDRESS);
|
"#paymentAddress", ATTR_PAYMENT_ADDRESS,
|
||||||
|
"#phoneNumberSharing", ATTR_PHONE_NUMBER_SHARING);
|
||||||
|
|
||||||
private static final Timer SET_PROFILES_TIMER = Metrics.timer(name(Profiles.class, "set"));
|
private static final Timer SET_PROFILES_TIMER = Metrics.timer(name(Profiles.class, "set"));
|
||||||
private static final Timer GET_PROFILE_TIMER = Metrics.timer(name(Profiles.class, "get"));
|
private static final Timer GET_PROFILE_TIMER = Metrics.timer(name(Profiles.class, "get"));
|
||||||
|
@ -154,6 +158,12 @@ public class Profiles {
|
||||||
deletedAttributes.add("paymentAddress");
|
deletedAttributes.add("paymentAddress");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (profile.phoneNumberSharing() != null) {
|
||||||
|
updatedAttributes.add("phoneNumberSharing");
|
||||||
|
} else {
|
||||||
|
deletedAttributes.add("phoneNumberSharing");
|
||||||
|
}
|
||||||
|
|
||||||
final StringBuilder updateExpressionBuilder = new StringBuilder(
|
final StringBuilder updateExpressionBuilder = new StringBuilder(
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment)");
|
"SET #commitment = if_not_exists(#commitment, :commitment)");
|
||||||
|
|
||||||
|
@ -201,6 +211,9 @@ public class Profiles {
|
||||||
expressionValues.put(":paymentAddress", AttributeValues.fromByteArray(profile.paymentAddress()));
|
expressionValues.put(":paymentAddress", AttributeValues.fromByteArray(profile.paymentAddress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (profile.phoneNumberSharing() != null) {
|
||||||
|
expressionValues.put(":phoneNumberSharing", AttributeValues.fromByteArray(profile.phoneNumberSharing()));
|
||||||
|
}
|
||||||
return expressionValues;
|
return expressionValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +248,7 @@ public class Profiles {
|
||||||
getBytes(item, ATTR_EMOJI),
|
getBytes(item, ATTR_EMOJI),
|
||||||
getBytes(item, ATTR_ABOUT),
|
getBytes(item, ATTR_ABOUT),
|
||||||
getBytes(item, ATTR_PAYMENT_ADDRESS),
|
getBytes(item, ATTR_PAYMENT_ADDRESS),
|
||||||
|
getBytes(item, ATTR_PHONE_NUMBER_SHARING),
|
||||||
AttributeValues.getByteArray(item, ATTR_COMMITMENT, null));
|
AttributeValues.getByteArray(item, ATTR_COMMITMENT, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,10 @@
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.storage;
|
package org.whispersystems.textsecuregcm.storage;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
|
import org.whispersystems.textsecuregcm.util.ByteArrayAdapter;
|
||||||
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
import org.whispersystems.textsecuregcm.util.ByteArrayBase64WithPaddingAdapter;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public record VersionedProfile (String version,
|
public record VersionedProfile (String version,
|
||||||
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayBase64WithPaddingAdapter.Serializing.class)
|
||||||
|
@ -33,6 +29,10 @@ public record VersionedProfile (String version,
|
||||||
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64WithPaddingAdapter.Deserializing.class)
|
||||||
byte[] paymentAddress,
|
byte[] paymentAddress,
|
||||||
|
|
||||||
|
@JsonSerialize(using = ByteArrayAdapter.Serializing.class)
|
||||||
|
@JsonDeserialize(using = ByteArrayAdapter.Deserializing.class)
|
||||||
|
byte[] phoneNumberSharing,
|
||||||
|
|
||||||
@JsonSerialize(using = ByteArrayAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ByteArrayAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayAdapter.Deserializing.class)
|
||||||
byte[] commitment) {}
|
byte[] commitment) {}
|
||||||
|
|
|
@ -132,6 +132,10 @@ message SetProfileRequest {
|
||||||
* A list of badge IDs associated with the profile.
|
* A list of badge IDs associated with the profile.
|
||||||
*/
|
*/
|
||||||
repeated string badge_ids = 7;
|
repeated string badge_ids = 7;
|
||||||
|
/**
|
||||||
|
* The ciphertext of the phone-number sharing setting on the profile. 29-byte encrypted boolean.
|
||||||
|
*/
|
||||||
|
bytes phone_number_sharing = 8;
|
||||||
/**
|
/**
|
||||||
* The profile key commitment. Used to issue a profile key credential response.
|
* The profile key commitment. Used to issue a profile key credential response.
|
||||||
* Must be set on the request.
|
* Must be set on the request.
|
||||||
|
@ -189,6 +193,10 @@ message GetVersionedProfileResponse {
|
||||||
* The ciphertext of the MobileCoin wallet ID on the profile.
|
* The ciphertext of the MobileCoin wallet ID on the profile.
|
||||||
*/
|
*/
|
||||||
bytes payment_address = 5;
|
bytes payment_address = 5;
|
||||||
|
/**
|
||||||
|
* The ciphertext of the phone-number sharing setting on the profile.
|
||||||
|
*/
|
||||||
|
bytes phone_number_sharing = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message GetUnversionedProfileRequest {
|
message GetUnversionedProfileRequest {
|
||||||
|
|
|
@ -227,10 +227,11 @@ class ProfileControllerTest {
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] about = TestRandomUtil.nextBytes(156);
|
final byte[] about = TestRandomUtil.nextBytes(156);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
|
|
||||||
when(profilesManager.get(eq(AuthHelper.VALID_UUID), eq("someversion"))).thenReturn(Optional.empty());
|
when(profilesManager.get(eq(AuthHelper.VALID_UUID), eq("someversion"))).thenReturn(Optional.empty());
|
||||||
when(profilesManager.get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion"))).thenReturn(Optional.of(new VersionedProfile(
|
when(profilesManager.get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion"))).thenReturn(Optional.of(new VersionedProfile(
|
||||||
"validversion", name, "profiles/validavatar", emoji, about, null, "validcommitmnet".getBytes())));
|
"validversion", name, "profiles/validavatar", emoji, about, null, phoneNumberSharing, "validcommitment".getBytes())));
|
||||||
|
|
||||||
clearInvocations(rateLimiter);
|
clearInvocations(rateLimiter);
|
||||||
clearInvocations(accountsManager);
|
clearInvocations(accountsManager);
|
||||||
|
@ -419,7 +420,7 @@ class ProfileControllerTest {
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion",
|
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion",
|
||||||
name, null, null,
|
name, null, null,
|
||||||
null, true, false, List.of()), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
|
null, true, false, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
|
||||||
|
|
||||||
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
||||||
|
|
||||||
|
@ -446,7 +447,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion", name,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion", name,
|
||||||
null, null, null, true, false, List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
null, null, null, true, false, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(422);
|
assertThat(response.getStatus()).isEqualTo(422);
|
||||||
}
|
}
|
||||||
|
@ -456,6 +457,7 @@ class ProfileControllerTest {
|
||||||
void testSetProfileWithoutAvatarUpload() throws InvalidInputException {
|
void testSetProfileWithoutAvatarUpload() throws InvalidInputException {
|
||||||
final ProfileKeyCommitment commitment = new ProfileKey(new byte[32]).getCommitment(new ServiceId.Aci(AuthHelper.VALID_UUID));
|
final ProfileKeyCommitment commitment = new ProfileKey(new byte[32]).getCommitment(new ServiceId.Aci(AuthHelper.VALID_UUID));
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
|
|
||||||
clearInvocations(AuthHelper.VALID_ACCOUNT_TWO);
|
clearInvocations(AuthHelper.VALID_ACCOUNT_TWO);
|
||||||
|
|
||||||
|
@ -464,7 +466,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, null, null,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, null, null,
|
||||||
null, false, false, List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
null, false, false, Optional.of(List.of()), phoneNumberSharing), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -482,6 +484,7 @@ class ProfileControllerTest {
|
||||||
assertThat(profileArgumentCaptor.getValue().name()).isEqualTo(name);
|
assertThat(profileArgumentCaptor.getValue().name()).isEqualTo(name);
|
||||||
assertThat(profileArgumentCaptor.getValue().aboutEmoji()).isNull();
|
assertThat(profileArgumentCaptor.getValue().aboutEmoji()).isNull();
|
||||||
assertThat(profileArgumentCaptor.getValue().about()).isNull();
|
assertThat(profileArgumentCaptor.getValue().about()).isNull();
|
||||||
|
assertThat(profileArgumentCaptor.getValue().phoneNumberSharing()).isEqualTo(phoneNumberSharing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +499,7 @@ class ProfileControllerTest {
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion",
|
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion",
|
||||||
name, null, null,
|
name, null, null,
|
||||||
null, true, false, List.of()), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
|
null, true, false, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
|
||||||
|
|
||||||
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
||||||
|
|
||||||
|
@ -522,7 +525,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
||||||
null, null, null, false, false, List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
null, null, null, false, false, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -552,7 +555,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
||||||
null, null, null, true, true, List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
null, null, null, true, true, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -583,7 +586,7 @@ class ProfileControllerTest {
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
||||||
null, null,
|
null, null,
|
||||||
null, false, true, List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
null, false, true, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
||||||
|
|
||||||
|
@ -610,7 +613,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", name,
|
||||||
null, null, null, true, true, List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
null, null, null, true, true, Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -642,7 +645,7 @@ class ProfileControllerTest {
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(
|
.put(Entity.entity(
|
||||||
new CreateProfileRequest(commitment, "validversion", name,
|
new CreateProfileRequest(commitment, "validversion", name,
|
||||||
null, null, null, true, false, List.of()),
|
null, null, null, true, false, Optional.of(List.of()), null),
|
||||||
MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
|
MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
|
||||||
|
|
||||||
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
||||||
|
@ -675,7 +678,7 @@ class ProfileControllerTest {
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(
|
.put(Entity.entity(
|
||||||
new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null,
|
new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null,
|
||||||
false, false, List.of()),
|
false, false, Optional.of(List.of()), null),
|
||||||
MediaType.APPLICATION_JSON_TYPE))) {
|
MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
@ -715,7 +718,7 @@ class ProfileControllerTest {
|
||||||
.put(Entity.entity(
|
.put(Entity.entity(
|
||||||
new CreateProfileRequest(commitment, "yetanotherversion", name,
|
new CreateProfileRequest(commitment, "yetanotherversion", name,
|
||||||
null, null, paymentAddress, false, false,
|
null, null, paymentAddress, false, false,
|
||||||
List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -757,7 +760,7 @@ class ProfileControllerTest {
|
||||||
.put(Entity.entity(
|
.put(Entity.entity(
|
||||||
new CreateProfileRequest(commitment, "yetanotherversion", name,
|
new CreateProfileRequest(commitment, "yetanotherversion", name,
|
||||||
null, null, paymentAddress, false, false,
|
null, null, paymentAddress, false, false,
|
||||||
List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(403);
|
assertThat(response.getStatus()).isEqualTo(403);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -776,6 +779,7 @@ class ProfileControllerTest {
|
||||||
final ProfileKeyCommitment commitment = new ProfileKey(new byte[32]).getCommitment(new ServiceId.Aci(AuthHelper.VALID_UUID));
|
final ProfileKeyCommitment commitment = new ProfileKey(new byte[32]).getCommitment(new ServiceId.Aci(AuthHelper.VALID_UUID));
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
|
|
||||||
clearInvocations(AuthHelper.VALID_ACCOUNT_TWO);
|
clearInvocations(AuthHelper.VALID_ACCOUNT_TWO);
|
||||||
|
|
||||||
|
@ -783,6 +787,7 @@ class ProfileControllerTest {
|
||||||
.thenReturn(Optional.of(
|
.thenReturn(Optional.of(
|
||||||
new VersionedProfile("1", name, null, null, null,
|
new VersionedProfile("1", name, null, null, null,
|
||||||
existingPaymentAddressOnProfile ? TestRandomUtil.nextBytes(582) : null,
|
existingPaymentAddressOnProfile ? TestRandomUtil.nextBytes(582) : null,
|
||||||
|
phoneNumberSharing,
|
||||||
commitment.serialize())));
|
commitment.serialize())));
|
||||||
|
|
||||||
|
|
||||||
|
@ -793,7 +798,7 @@ class ProfileControllerTest {
|
||||||
.put(Entity.entity(
|
.put(Entity.entity(
|
||||||
new CreateProfileRequest(commitment, "yetanotherversion", name,
|
new CreateProfileRequest(commitment, "yetanotherversion", name,
|
||||||
null, null, paymentAddress, false, false,
|
null, null, paymentAddress, false, false,
|
||||||
List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
if (existingPaymentAddressOnProfile) {
|
if (existingPaymentAddressOnProfile) {
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
@ -823,14 +828,49 @@ class ProfileControllerTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetProfilePhoneNumberSharing() throws Exception {
|
||||||
|
final ProfileKeyCommitment commitment = new ProfileKey(new byte[32]).getCommitment(new ServiceId.Aci(AuthHelper.VALID_UUID));
|
||||||
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
|
|
||||||
|
clearInvocations(AuthHelper.VALID_ACCOUNT_TWO);
|
||||||
|
|
||||||
|
try (final Response response = resources.getJerseyTest()
|
||||||
|
.target("/v1/profile/")
|
||||||
|
.request()
|
||||||
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
|
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, null, null,
|
||||||
|
null, false, false, Optional.of(List.of()), phoneNumberSharing), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
|
||||||
|
final ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
|
||||||
|
|
||||||
|
verify(profilesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO), eq("anotherversion"));
|
||||||
|
verify(profilesManager, times(1)).set(eq(AuthHelper.VALID_UUID_TWO), profileArgumentCaptor.capture());
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(s3client);
|
||||||
|
|
||||||
|
assertThat(profileArgumentCaptor.getValue().commitment()).isEqualTo(commitment.serialize());
|
||||||
|
assertThat(profileArgumentCaptor.getValue().avatar()).isNull();
|
||||||
|
assertThat(profileArgumentCaptor.getValue().version()).isEqualTo("anotherversion");
|
||||||
|
assertThat(profileArgumentCaptor.getValue().name()).isEqualTo(name);
|
||||||
|
assertThat(profileArgumentCaptor.getValue().aboutEmoji()).isNull();
|
||||||
|
assertThat(profileArgumentCaptor.getValue().about()).isNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testGetProfileByVersion() throws RateLimitExceededException {
|
void testGetProfileByVersion() throws RateLimitExceededException {
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] about = TestRandomUtil.nextBytes(156);
|
final byte[] about = TestRandomUtil.nextBytes(156);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
|
|
||||||
when(profilesManager.get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion"))).thenReturn(Optional.of(new VersionedProfile(
|
when(profilesManager.get(eq(AuthHelper.VALID_UUID_TWO), eq("validversion"))).thenReturn(Optional.of(new VersionedProfile(
|
||||||
"validversion", name, "profiles/validavatar", emoji, about, null, "validcommitmnet".getBytes())));
|
"validversion", name, "profiles/validavatar", emoji, about, null, phoneNumberSharing, "validcommitment".getBytes())));
|
||||||
|
|
||||||
final VersionedProfileResponse profile = resources.getJerseyTest()
|
final VersionedProfileResponse profile = resources.getJerseyTest()
|
||||||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
|
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
|
||||||
|
@ -843,6 +883,7 @@ class ProfileControllerTest {
|
||||||
assertThat(profile.getAbout()).containsExactly(about);
|
assertThat(profile.getAbout()).containsExactly(about);
|
||||||
assertThat(profile.getAboutEmoji()).containsExactly(emoji);
|
assertThat(profile.getAboutEmoji()).containsExactly(emoji);
|
||||||
assertThat(profile.getAvatar()).isEqualTo("profiles/validavatar");
|
assertThat(profile.getAvatar()).isEqualTo("profiles/validavatar");
|
||||||
|
assertThat(profile.getPhoneNumberSharing()).containsExactly(phoneNumberSharing);
|
||||||
assertThat(profile.getBaseProfileResponse().getCapabilities().gv1Migration()).isTrue();
|
assertThat(profile.getBaseProfileResponse().getCapabilities().gv1Migration()).isTrue();
|
||||||
assertThat(profile.getBaseProfileResponse().getUuid()).isEqualTo(new AciServiceIdentifier(AuthHelper.VALID_UUID_TWO));
|
assertThat(profile.getBaseProfileResponse().getUuid()).isEqualTo(new AciServiceIdentifier(AuthHelper.VALID_UUID_TWO));
|
||||||
assertThat(profile.getBaseProfileResponse().getBadges()).hasSize(1).element(0).has(new Condition<>(
|
assertThat(profile.getBaseProfileResponse().getBadges()).hasSize(1).element(0).has(new Condition<>(
|
||||||
|
@ -869,7 +910,7 @@ class ProfileControllerTest {
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(
|
.put(Entity.entity(
|
||||||
new CreateProfileRequest(commitment, "someversion", name, null, null, paymentAddress, false, false,
|
new CreateProfileRequest(commitment, "someversion", name, null, null, paymentAddress, false, false,
|
||||||
List.of()), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of()), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -882,7 +923,7 @@ class ProfileControllerTest {
|
||||||
void testGetProfileReturnsNoPaymentAddressIfCurrentVersionMismatch() {
|
void testGetProfileReturnsNoPaymentAddressIfCurrentVersionMismatch() {
|
||||||
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
||||||
when(profilesManager.get(AuthHelper.VALID_UUID_TWO, "validversion")).thenReturn(
|
when(profilesManager.get(AuthHelper.VALID_UUID_TWO, "validversion")).thenReturn(
|
||||||
Optional.of(new VersionedProfile(null, null, null, null, null, paymentAddress, null)));
|
Optional.of(new VersionedProfile(null, null, null, null, null, paymentAddress, null, null)));
|
||||||
|
|
||||||
{
|
{
|
||||||
final VersionedProfileResponse profile = resources.getJerseyTest()
|
final VersionedProfileResponse profile = resources.getJerseyTest()
|
||||||
|
@ -959,7 +1000,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
||||||
List.of("TEST2")), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of("TEST2")), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -982,7 +1023,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
||||||
List.of("TEST3", "TEST2")), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of("TEST3", "TEST2")), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -1008,7 +1049,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
||||||
List.of("TEST2", "TEST3")), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of("TEST2", "TEST3")), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
@ -1034,7 +1075,7 @@ class ProfileControllerTest {
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||||
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", name, emoji, about, null, false, false,
|
||||||
List.of("TEST1")), MediaType.APPLICATION_JSON_TYPE))) {
|
Optional.of(List.of("TEST1")), null), MediaType.APPLICATION_JSON_TYPE))) {
|
||||||
|
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
assertThat(response.hasEntity()).isFalse();
|
assertThat(response.hasEntity()).isFalse();
|
||||||
|
|
|
@ -218,6 +218,7 @@ public class ProfileGrpcServiceTest extends SimpleBaseGrpcTest<ProfileGrpcServic
|
||||||
final byte[] validAboutEmoji = new byte[60];
|
final byte[] validAboutEmoji = new byte[60];
|
||||||
final byte[] validAbout = new byte[540];
|
final byte[] validAbout = new byte[540];
|
||||||
final byte[] validPaymentAddress = new byte[582];
|
final byte[] validPaymentAddress = new byte[582];
|
||||||
|
final byte[] validPhoneNumberSharing = new byte[29];
|
||||||
|
|
||||||
final SetProfileRequest request = SetProfileRequest.newBuilder()
|
final SetProfileRequest request = SetProfileRequest.newBuilder()
|
||||||
.setVersion(VERSION)
|
.setVersion(VERSION)
|
||||||
|
@ -226,6 +227,7 @@ public class ProfileGrpcServiceTest extends SimpleBaseGrpcTest<ProfileGrpcServic
|
||||||
.setAboutEmoji(ByteString.copyFrom(validAboutEmoji))
|
.setAboutEmoji(ByteString.copyFrom(validAboutEmoji))
|
||||||
.setAbout(ByteString.copyFrom(validAbout))
|
.setAbout(ByteString.copyFrom(validAbout))
|
||||||
.setPaymentAddress(ByteString.copyFrom(validPaymentAddress))
|
.setPaymentAddress(ByteString.copyFrom(validPaymentAddress))
|
||||||
|
.setPhoneNumberSharing(ByteString.copyFrom(validPhoneNumberSharing))
|
||||||
.setCommitment(ByteString.copyFrom(commitment))
|
.setCommitment(ByteString.copyFrom(commitment))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -244,6 +246,7 @@ public class ProfileGrpcServiceTest extends SimpleBaseGrpcTest<ProfileGrpcServic
|
||||||
assertThat(profile.aboutEmoji()).isEqualTo(validAboutEmoji);
|
assertThat(profile.aboutEmoji()).isEqualTo(validAboutEmoji);
|
||||||
assertThat(profile.about()).isEqualTo(validAbout);
|
assertThat(profile.about()).isEqualTo(validAbout);
|
||||||
assertThat(profile.paymentAddress()).isEqualTo(validPaymentAddress);
|
assertThat(profile.paymentAddress()).isEqualTo(validPaymentAddress);
|
||||||
|
assertThat(profile.phoneNumberSharing()).isEqualTo(validPhoneNumberSharing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class ProfilesManagerTest {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
||||||
null, "somecommitment".getBytes());
|
null, null, "somecommitment".getBytes());
|
||||||
|
|
||||||
when(commands.hget(eq("profiles::" + uuid), eq("someversion"))).thenReturn(null);
|
when(commands.hget(eq("profiles::" + uuid), eq("someversion"))).thenReturn(null);
|
||||||
when(profiles.get(eq(uuid), eq("someversion"))).thenReturn(Optional.of(profile));
|
when(profiles.get(eq(uuid), eq("someversion"))).thenReturn(Optional.of(profile));
|
||||||
|
@ -133,7 +133,7 @@ public class ProfilesManagerTest {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
||||||
null, "somecommitment".getBytes());
|
null, null, "somecommitment".getBytes());
|
||||||
|
|
||||||
when(asyncCommands.hget(eq("profiles::" + uuid), eq("someversion"))).thenReturn(MockRedisFuture.completedFuture(null));
|
when(asyncCommands.hget(eq("profiles::" + uuid), eq("someversion"))).thenReturn(MockRedisFuture.completedFuture(null));
|
||||||
when(asyncCommands.hset(eq("profiles::" + uuid), eq("someversion"), anyString())).thenReturn(MockRedisFuture.completedFuture(null));
|
when(asyncCommands.hset(eq("profiles::" + uuid), eq("someversion"), anyString())).thenReturn(MockRedisFuture.completedFuture(null));
|
||||||
|
@ -157,7 +157,7 @@ public class ProfilesManagerTest {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
||||||
null, "somecommitment".getBytes());
|
null, null, "somecommitment".getBytes());
|
||||||
|
|
||||||
when(commands.hget(eq("profiles::" + uuid), eq("someversion"))).thenThrow(new RedisException("Connection lost"));
|
when(commands.hget(eq("profiles::" + uuid), eq("someversion"))).thenThrow(new RedisException("Connection lost"));
|
||||||
when(profiles.get(eq(uuid), eq("someversion"))).thenReturn(Optional.of(profile));
|
when(profiles.get(eq(uuid), eq("someversion"))).thenReturn(Optional.of(profile));
|
||||||
|
@ -180,7 +180,7 @@ public class ProfilesManagerTest {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
||||||
null, "somecommitment".getBytes());
|
null, null, "somecommitment".getBytes());
|
||||||
|
|
||||||
when(asyncCommands.hget(eq("profiles::" + uuid), eq("someversion"))).thenReturn(MockRedisFuture.failedFuture(new RedisException("Connection lost")));
|
when(asyncCommands.hget(eq("profiles::" + uuid), eq("someversion"))).thenReturn(MockRedisFuture.failedFuture(new RedisException("Connection lost")));
|
||||||
when(asyncCommands.hset(eq("profiles::" + uuid), eq("someversion"), anyString())).thenReturn(MockRedisFuture.completedFuture(null));
|
when(asyncCommands.hset(eq("profiles::" + uuid), eq("someversion"), anyString())).thenReturn(MockRedisFuture.completedFuture(null));
|
||||||
|
@ -204,7 +204,7 @@ public class ProfilesManagerTest {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
||||||
null, "somecommitment".getBytes());
|
null, null, "somecommitment".getBytes());
|
||||||
|
|
||||||
profilesManager.set(uuid, profile);
|
profilesManager.set(uuid, profile);
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ public class ProfilesManagerTest {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
final VersionedProfile profile = new VersionedProfile("someversion", name, "someavatar", null, null,
|
||||||
null, "somecommitment".getBytes());
|
null, null, "somecommitment".getBytes());
|
||||||
|
|
||||||
when(asyncCommands.hset(eq("profiles::" + uuid), eq("someversion"), anyString())).thenReturn(MockRedisFuture.completedFuture(null));
|
when(asyncCommands.hset(eq("profiles::" + uuid), eq("someversion"), anyString())).thenReturn(MockRedisFuture.completedFuture(null));
|
||||||
when(profiles.setAsync(eq(uuid), eq(profile))).thenReturn(CompletableFuture.completedFuture(null));
|
when(profiles.setAsync(eq(uuid), eq(profile))).thenReturn(CompletableFuture.completedFuture(null));
|
||||||
|
|
|
@ -48,8 +48,9 @@ public class ProfilesTest {
|
||||||
final byte[] validAboutEmoji = TestRandomUtil.nextBytes(60);
|
final byte[] validAboutEmoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] validAbout = TestRandomUtil.nextBytes(156);
|
final byte[] validAbout = TestRandomUtil.nextBytes(156);
|
||||||
final String avatar = "profiles/" + ProfileTestHelper.generateRandomBase64FromByteArray(16);
|
final String avatar = "profiles/" + ProfileTestHelper.generateRandomBase64FromByteArray(16);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
|
|
||||||
validProfile = new VersionedProfile(version, name, avatar, validAboutEmoji, validAbout, null, commitment);
|
validProfile = new VersionedProfile(version, name, avatar, validAboutEmoji, validAbout, null, phoneNumberSharing, commitment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -92,10 +93,11 @@ public class ProfilesTest {
|
||||||
final byte[] differentEmoji = TestRandomUtil.nextBytes(60);
|
final byte[] differentEmoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] differentAbout = TestRandomUtil.nextBytes(156);
|
final byte[] differentAbout = TestRandomUtil.nextBytes(156);
|
||||||
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
VersionedProfile updatedProfile = new VersionedProfile(version, name, differentAvatar,
|
VersionedProfile updatedProfile = new VersionedProfile(version, name, differentAvatar,
|
||||||
differentEmoji, differentAbout, paymentAddress, commitment);
|
differentEmoji, differentAbout, paymentAddress, phoneNumberSharing, commitment);
|
||||||
|
|
||||||
profiles.set(ACI, updatedProfile);
|
profiles.set(ACI, updatedProfile);
|
||||||
|
|
||||||
|
@ -115,7 +117,7 @@ public class ProfilesTest {
|
||||||
final byte[] name = TestRandomUtil.nextBytes(81);
|
final byte[] name = TestRandomUtil.nextBytes(81);
|
||||||
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
VersionedProfile profile = new VersionedProfile(version, name, null, null, null, null,
|
VersionedProfile profile = new VersionedProfile(version, name, null, null, null, null, null,
|
||||||
commitment);
|
commitment);
|
||||||
profiles.set(ACI, profile);
|
profiles.set(ACI, profile);
|
||||||
|
|
||||||
|
@ -147,10 +149,11 @@ public class ProfilesTest {
|
||||||
final byte[] differentEmoji = TestRandomUtil.nextBytes(60);
|
final byte[] differentEmoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] differentAbout = TestRandomUtil.nextBytes(156);
|
final byte[] differentAbout = TestRandomUtil.nextBytes(156);
|
||||||
final String differentAvatar = "profiles/" + ProfileTestHelper.generateRandomBase64FromByteArray(16);
|
final String differentAvatar = "profiles/" + ProfileTestHelper.generateRandomBase64FromByteArray(16);
|
||||||
|
final byte[] differentPhoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
final byte[] differentCommitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] differentCommitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
VersionedProfile updated = new VersionedProfile(validProfile.version(), differentName, differentAvatar, differentEmoji, differentAbout, null,
|
VersionedProfile updated = new VersionedProfile(validProfile.version(), differentName, differentAvatar, differentEmoji, differentAbout, null,
|
||||||
differentCommitment);
|
differentPhoneNumberSharing, differentCommitment);
|
||||||
profiles.set(ACI, updated);
|
profiles.set(ACI, updated);
|
||||||
|
|
||||||
retrieved = profiles.get(ACI, updated.version());
|
retrieved = profiles.get(ACI, updated.version());
|
||||||
|
@ -160,6 +163,7 @@ public class ProfilesTest {
|
||||||
assertThat(retrieved.get().about()).isEqualTo(updated.about());
|
assertThat(retrieved.get().about()).isEqualTo(updated.about());
|
||||||
assertThat(retrieved.get().aboutEmoji()).isEqualTo(updated.aboutEmoji());
|
assertThat(retrieved.get().aboutEmoji()).isEqualTo(updated.aboutEmoji());
|
||||||
assertThat(retrieved.get().avatar()).isEqualTo(updated.avatar());
|
assertThat(retrieved.get().avatar()).isEqualTo(updated.avatar());
|
||||||
|
assertThat(retrieved.get().phoneNumberSharing()).isEqualTo(updated.phoneNumberSharing());
|
||||||
|
|
||||||
// Commitment should be unchanged after an overwrite
|
// Commitment should be unchanged after an overwrite
|
||||||
assertThat(retrieved.get().commitment()).isEqualTo(validProfile.commitment());
|
assertThat(retrieved.get().commitment()).isEqualTo(validProfile.commitment());
|
||||||
|
@ -183,8 +187,8 @@ public class ProfilesTest {
|
||||||
final byte[] commitmentTwo = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] commitmentTwo = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
VersionedProfile profileOne = new VersionedProfile(versionOne, nameOne, avatarOne, null, null,
|
VersionedProfile profileOne = new VersionedProfile(versionOne, nameOne, avatarOne, null, null,
|
||||||
null, commitmentOne);
|
null, null, commitmentOne);
|
||||||
VersionedProfile profileTwo = new VersionedProfile(versionTwo, nameTwo, avatarTwo, aboutEmoji, about, null, commitmentTwo);
|
VersionedProfile profileTwo = new VersionedProfile(versionTwo, nameTwo, avatarTwo, aboutEmoji, about, null, null, commitmentTwo);
|
||||||
|
|
||||||
profiles.set(ACI, profileOne);
|
profiles.set(ACI, profileOne);
|
||||||
profiles.set(ACI, profileTwo);
|
profiles.set(ACI, profileTwo);
|
||||||
|
@ -236,8 +240,8 @@ public class ProfilesTest {
|
||||||
final byte[] commitmentTwo = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] commitmentTwo = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
VersionedProfile profileOne = new VersionedProfile(versionOne, nameOne, avatarOne, null, null,
|
VersionedProfile profileOne = new VersionedProfile(versionOne, nameOne, avatarOne, null, null,
|
||||||
null, commitmentOne);
|
null, null, commitmentOne);
|
||||||
VersionedProfile profileTwo = new VersionedProfile(versionTwo, nameTwo, avatarTwo, aboutEmoji, about, null, commitmentTwo);
|
VersionedProfile profileTwo = new VersionedProfile(versionTwo, nameTwo, avatarTwo, aboutEmoji, about, null, null, commitmentTwo);
|
||||||
|
|
||||||
profiles.set(ACI, profileOne);
|
profiles.set(ACI, profileOne);
|
||||||
profiles.set(ACI, profileTwo);
|
profiles.set(ACI, profileTwo);
|
||||||
|
@ -266,32 +270,37 @@ public class ProfilesTest {
|
||||||
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] about = TestRandomUtil.nextBytes(156);
|
final byte[] about = TestRandomUtil.nextBytes(156);
|
||||||
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, commitment),
|
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, phoneNumberSharing, commitment),
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji, #paymentAddress = :paymentAddress"),
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji, #paymentAddress = :paymentAddress, #phoneNumberSharing = :phoneNumberSharing"),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, emoji, about, null, commitment),
|
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, null, commitment),
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji REMOVE #paymentAddress"),
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji, #paymentAddress = :paymentAddress REMOVE #phoneNumberSharing"),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, emoji, null, null, commitment),
|
new VersionedProfile(version, name, avatar, emoji, about, null, null, commitment),
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #aboutEmoji = :aboutEmoji REMOVE #about, #paymentAddress"),
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #about = :about, #aboutEmoji = :aboutEmoji REMOVE #paymentAddress, #phoneNumberSharing"),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, null, null, null, commitment),
|
new VersionedProfile(version, name, avatar, emoji, null, null, null, commitment),
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar REMOVE #about, #aboutEmoji, #paymentAddress"),
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar, #aboutEmoji = :aboutEmoji REMOVE #about, #paymentAddress, #phoneNumberSharing"),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, null, null, null, null, commitment),
|
new VersionedProfile(version, name, avatar, null, null, null, null, commitment),
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name REMOVE #avatar, #about, #aboutEmoji, #paymentAddress"),
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name, #avatar = :avatar REMOVE #about, #aboutEmoji, #paymentAddress, #phoneNumberSharing"),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, null, null, null, null, null, commitment),
|
new VersionedProfile(version, name, null, null, null, null, null, commitment),
|
||||||
"SET #commitment = if_not_exists(#commitment, :commitment) REMOVE #name, #avatar, #about, #aboutEmoji, #paymentAddress")
|
"SET #commitment = if_not_exists(#commitment, :commitment), #name = :name REMOVE #avatar, #about, #aboutEmoji, #paymentAddress, #phoneNumberSharing"),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile(version, null, null, null, null, null, null, commitment),
|
||||||
|
"SET #commitment = if_not_exists(#commitment, :commitment) REMOVE #name, #avatar, #about, #aboutEmoji, #paymentAddress, #phoneNumberSharing")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,11 +317,23 @@ public class ProfilesTest {
|
||||||
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
final byte[] emoji = TestRandomUtil.nextBytes(60);
|
||||||
final byte[] about = TestRandomUtil.nextBytes(156);
|
final byte[] about = TestRandomUtil.nextBytes(156);
|
||||||
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
final byte[] paymentAddress = TestRandomUtil.nextBytes(582);
|
||||||
|
final byte[] phoneNumberSharing = TestRandomUtil.nextBytes(29);
|
||||||
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
final byte[] commitment = new ProfileKey(TestRandomUtil.nextBytes(32)).getCommitment(new ServiceId.Aci(ACI)).serialize();
|
||||||
|
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, commitment),
|
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, phoneNumberSharing, commitment),
|
||||||
|
Map.of(
|
||||||
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
|
":name", AttributeValues.fromByteArray(name),
|
||||||
|
":avatar", AttributeValues.fromString(avatar),
|
||||||
|
":aboutEmoji", AttributeValues.fromByteArray(emoji),
|
||||||
|
":about", AttributeValues.fromByteArray(about),
|
||||||
|
":paymentAddress", AttributeValues.fromByteArray(paymentAddress),
|
||||||
|
":phoneNumberSharing", AttributeValues.fromByteArray(phoneNumberSharing))),
|
||||||
|
|
||||||
|
Arguments.of(
|
||||||
|
new VersionedProfile(version, name, avatar, emoji, about, paymentAddress, null, commitment),
|
||||||
Map.of(
|
Map.of(
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
":name", AttributeValues.fromByteArray(name),
|
":name", AttributeValues.fromByteArray(name),
|
||||||
|
@ -322,7 +343,7 @@ public class ProfilesTest {
|
||||||
":paymentAddress", AttributeValues.fromByteArray(paymentAddress))),
|
":paymentAddress", AttributeValues.fromByteArray(paymentAddress))),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, emoji, about, null, commitment),
|
new VersionedProfile(version, name, avatar, emoji, about, null, null, commitment),
|
||||||
Map.of(
|
Map.of(
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
":name", AttributeValues.fromByteArray(name),
|
":name", AttributeValues.fromByteArray(name),
|
||||||
|
@ -331,7 +352,7 @@ public class ProfilesTest {
|
||||||
":about", AttributeValues.fromByteArray(about))),
|
":about", AttributeValues.fromByteArray(about))),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, emoji, null, null, commitment),
|
new VersionedProfile(version, name, avatar, emoji, null, null, null, commitment),
|
||||||
Map.of(
|
Map.of(
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
":name",AttributeValues.fromByteArray(name),
|
":name",AttributeValues.fromByteArray(name),
|
||||||
|
@ -339,20 +360,20 @@ public class ProfilesTest {
|
||||||
":aboutEmoji", AttributeValues.fromByteArray(emoji))),
|
":aboutEmoji", AttributeValues.fromByteArray(emoji))),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, avatar, null, null, null, commitment),
|
new VersionedProfile(version, name, avatar, null, null, null, null, commitment),
|
||||||
Map.of(
|
Map.of(
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
":name", AttributeValues.fromByteArray(name),
|
":name", AttributeValues.fromByteArray(name),
|
||||||
":avatar", AttributeValues.fromString(avatar))),
|
":avatar", AttributeValues.fromString(avatar))),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, name, null, null, null, null, commitment),
|
new VersionedProfile(version, name, null, null, null, null, null, commitment),
|
||||||
Map.of(
|
Map.of(
|
||||||
":commitment", AttributeValues.fromByteArray(commitment),
|
":commitment", AttributeValues.fromByteArray(commitment),
|
||||||
":name", AttributeValues.fromByteArray(name))),
|
":name", AttributeValues.fromByteArray(name))),
|
||||||
|
|
||||||
Arguments.of(
|
Arguments.of(
|
||||||
new VersionedProfile(version, null, null, null, null, null, commitment),
|
new VersionedProfile(version, null, null, null, null, null, null, commitment),
|
||||||
Map.of(":commitment", AttributeValues.fromByteArray(commitment)))
|
Map.of(":commitment", AttributeValues.fromByteArray(commitment)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue