Support for advertising payment addresses on profile

This commit is contained in:
Moxie Marlinspike 2020-04-02 12:45:24 -07:00
parent 3432529f9c
commit 95f0ce1816
10 changed files with 221 additions and 22 deletions

View File

@ -55,6 +55,7 @@ import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.storage.PaymentAddressList;
import org.whispersystems.textsecuregcm.storage.PendingAccountsManager; import org.whispersystems.textsecuregcm.storage.PendingAccountsManager;
import org.whispersystems.textsecuregcm.storage.UsernamesManager; import org.whispersystems.textsecuregcm.storage.UsernamesManager;
import org.whispersystems.textsecuregcm.util.Constants; import org.whispersystems.textsecuregcm.util.Constants;
@ -514,6 +515,16 @@ public class AccountController {
return Response.ok().build(); return Response.ok().build();
} }
@Timed
@PUT
@Path("/payments")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void setPayments(@Auth Account account, @Valid PaymentAddressList payments) {
account.setPayments(payments.getPayments());
accounts.update(account);
}
private CaptchaRequirement requiresCaptcha(String number, String transport, String forwardedFor, private CaptchaRequirement requiresCaptcha(String number, String transport, String forwardedFor,
String requester, String requester,
Optional<String> captchaToken, Optional<String> captchaToken,
@ -608,6 +619,7 @@ public class AccountController {
setAccountRegistrationLockFromAttributes(account, accountAttributes); setAccountRegistrationLockFromAttributes(account, accountAttributes);
account.setUnidentifiedAccessKey(accountAttributes.getUnidentifiedAccessKey()); account.setUnidentifiedAccessKey(accountAttributes.getUnidentifiedAccessKey());
account.setUnrestrictedUnidentifiedAccess(accountAttributes.isUnrestrictedUnidentifiedAccess()); account.setUnrestrictedUnidentifiedAccess(accountAttributes.isUnrestrictedUnidentifiedAccess());
account.setPayments(accountAttributes.getPayments());
if (accounts.create(account)) { if (accounts.create(account)) {
newUserMeter.mark(); newUserMeter.mark();

View File

@ -200,7 +200,9 @@ public class ProfileController {
accountProfile.get().isUnrestrictedUnidentifiedAccess(), accountProfile.get().isUnrestrictedUnidentifiedAccess(),
new UserCapabilities(accountProfile.get().isUuidAddressingSupported(), accountProfile.get().isGroupsV2Supported()), new UserCapabilities(accountProfile.get().isUuidAddressingSupported(), accountProfile.get().isGroupsV2Supported()),
username.orElse(null), username.orElse(null),
null, credential.orElse(null))); null,
credential.orElse(null),
accountProfile.get().getPayments()));
} catch (InvalidInputException e) { } catch (InvalidInputException e) {
logger.info("Bad profile request", e); logger.info("Bad profile request", e);
throw new WebApplicationException(Response.Status.BAD_REQUEST); throw new WebApplicationException(Response.Status.BAD_REQUEST);
@ -236,7 +238,9 @@ public class ProfileController {
accountProfile.get().isUnrestrictedUnidentifiedAccess(), accountProfile.get().isUnrestrictedUnidentifiedAccess(),
new UserCapabilities(accountProfile.get().isUuidAddressingSupported(), accountProfile.get().isGroupsV2Supported()), new UserCapabilities(accountProfile.get().isUuidAddressingSupported(), accountProfile.get().isGroupsV2Supported()),
username, username,
accountProfile.get().getUuid(), null); accountProfile.get().getUuid(),
null,
accountProfile.get().getPayments());
} }
private Optional<ProfileKeyCredentialResponse> getProfileCredential(Optional<String> encodedProfileCredentialRequest, private Optional<ProfileKeyCredentialResponse> getProfileCredential(Optional<String> encodedProfileCredentialRequest,
@ -307,7 +311,9 @@ public class ProfileController {
accountProfile.get().isUnrestrictedUnidentifiedAccess(), accountProfile.get().isUnrestrictedUnidentifiedAccess(),
new UserCapabilities(accountProfile.get().isUuidAddressingSupported(), accountProfile.get().isGroupsV2Supported()), new UserCapabilities(accountProfile.get().isUuidAddressingSupported(), accountProfile.get().isGroupsV2Supported()),
username.orElse(null), username.orElse(null),
null, null); null,
null,
accountProfile.get().getPayments());
} }

View File

@ -21,6 +21,9 @@ import com.google.common.annotations.VisibleForTesting;
import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.Length;
import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.Device.DeviceCapabilities; import org.whispersystems.textsecuregcm.storage.Device.DeviceCapabilities;
import org.whispersystems.textsecuregcm.storage.PaymentAddress;
import java.util.List;
public class AccountAttributes { public class AccountAttributes {
@ -49,6 +52,9 @@ public class AccountAttributes {
@JsonProperty @JsonProperty
private boolean unrestrictedUnidentifiedAccess; private boolean unrestrictedUnidentifiedAccess;
@JsonProperty
private List<PaymentAddress> payments;
@JsonProperty @JsonProperty
private DeviceCapabilities capabilities; private DeviceCapabilities capabilities;
@ -56,17 +62,18 @@ public class AccountAttributes {
@VisibleForTesting @VisibleForTesting
public AccountAttributes(String signalingKey, boolean fetchesMessages, int registrationId, String pin) { public AccountAttributes(String signalingKey, boolean fetchesMessages, int registrationId, String pin) {
this(signalingKey, fetchesMessages, registrationId, null, pin, null); this(signalingKey, fetchesMessages, registrationId, null, pin, null, null);
} }
@VisibleForTesting @VisibleForTesting
public AccountAttributes(String signalingKey, boolean fetchesMessages, int registrationId, String name, String pin, String registrationLock) { public AccountAttributes(String signalingKey, boolean fetchesMessages, int registrationId, String name, String pin, String registrationLock, List<PaymentAddress> payments) {
this.signalingKey = signalingKey; this.signalingKey = signalingKey;
this.fetchesMessages = fetchesMessages; this.fetchesMessages = fetchesMessages;
this.registrationId = registrationId; this.registrationId = registrationId;
this.name = name; this.name = name;
this.pin = pin; this.pin = pin;
this.registrationLock = registrationLock; this.registrationLock = registrationLock;
this.payments = payments;
} }
public String getSignalingKey() { public String getSignalingKey() {
@ -104,4 +111,8 @@ public class AccountAttributes {
public DeviceCapabilities getCapabilities() { public DeviceCapabilities getCapabilities() {
return capabilities; return capabilities;
} }
public List<PaymentAddress> getPayments() {
return payments;
}
} }

View File

@ -6,7 +6,9 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse; import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
import org.whispersystems.textsecuregcm.storage.PaymentAddress;
import java.util.List;
import java.util.UUID; import java.util.UUID;
public class Profile { public class Profile {
@ -35,6 +37,9 @@ public class Profile {
@JsonProperty @JsonProperty
private UUID uuid; private UUID uuid;
@JsonProperty
private List<PaymentAddress> payments;
@JsonProperty @JsonProperty
@JsonSerialize(using = ProfileKeyCredentialResponseAdapter.Serializing.class) @JsonSerialize(using = ProfileKeyCredentialResponseAdapter.Serializing.class)
@JsonDeserialize(using = ProfileKeyCredentialResponseAdapter.Deserializing.class) @JsonDeserialize(using = ProfileKeyCredentialResponseAdapter.Deserializing.class)
@ -45,7 +50,8 @@ public class Profile {
public Profile(String name, String avatar, String identityKey, public Profile(String name, String avatar, String identityKey,
String unidentifiedAccess, boolean unrestrictedUnidentifiedAccess, String unidentifiedAccess, boolean unrestrictedUnidentifiedAccess,
UserCapabilities capabilities, String username, UUID uuid, UserCapabilities capabilities, String username, UUID uuid,
ProfileKeyCredentialResponse credential) ProfileKeyCredentialResponse credential,
List<PaymentAddress> payments)
{ {
this.name = name; this.name = name;
this.avatar = avatar; this.avatar = avatar;
@ -55,6 +61,7 @@ public class Profile {
this.capabilities = capabilities; this.capabilities = capabilities;
this.username = username; this.username = username;
this.uuid = uuid; this.uuid = uuid;
this.payments = payments;
this.credential = credential; this.credential = credential;
} }
@ -97,4 +104,9 @@ public class Profile {
public UUID getUuid() { public UUID getUuid() {
return uuid; return uuid;
} }
@VisibleForTesting
public List<PaymentAddress> getPayments() {
return payments;
}
} }

View File

@ -26,6 +26,7 @@ import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock;
import javax.security.auth.Subject; import javax.security.auth.Subject;
import java.security.Principal; import java.security.Principal;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -52,10 +53,10 @@ public class Account implements Principal {
private String avatar; private String avatar;
@JsonProperty @JsonProperty
private String avatarDigest; private String pin;
@JsonProperty @JsonProperty
private String pin; private List<PaymentAddress> payments;
@JsonProperty @JsonProperty
private String registrationLock; private String registrationLock;
@ -224,14 +225,6 @@ public class Account implements Principal {
this.avatar = avatar; this.avatar = avatar;
} }
public String getAvatarDigest() {
return avatarDigest;
}
public void setAvatarDigest(String avatarDigest) {
this.avatarDigest = avatarDigest;
}
public void setPin(String pin) { public void setPin(String pin) {
this.pin = pin; this.pin = pin;
} }
@ -261,6 +254,14 @@ public class Account implements Principal {
this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess; this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
} }
public List<PaymentAddress> getPayments() {
return payments;
}
public void setPayments(List<PaymentAddress> payments) {
this.payments = payments;
}
public boolean isFor(AmbiguousIdentifier identifier) { public boolean isFor(AmbiguousIdentifier identifier) {
if (identifier.hasUuid()) return identifier.getUuid().equals(uuid); if (identifier.hasUuid()) return identifier.getUuid().equals(uuid);
else if (identifier.hasNumber()) return identifier.getNumber().equals(number); else if (identifier.hasNumber()) return identifier.getNumber().equals(number);

View File

@ -0,0 +1,51 @@
package org.whispersystems.textsecuregcm.storage;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.RegEx;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.Objects;
public class PaymentAddress {
@JsonProperty
@NotEmpty
@Size(max = 256)
private String address;
@JsonProperty
@NotEmpty
@Size(min = 88, max = 88)
private String signature;
public PaymentAddress() {}
public PaymentAddress(String address, String signature) {
this.address = address;
this.signature = signature;
}
public String getSignature() {
return signature;
}
public String getAddress() {
return address;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PaymentAddress that = (PaymentAddress) o;
return Objects.equals(address, that.address) && Objects.equals(signature, that.signature);
}
@Override
public int hashCode() {
return Objects.hash(address, signature);
}
}

View File

@ -0,0 +1,27 @@
package org.whispersystems.textsecuregcm.storage;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
public class PaymentAddressList {
@JsonProperty
@NotNull
@Valid
private List<PaymentAddress> payments;
public PaymentAddressList() {
}
public PaymentAddressList(List<PaymentAddress> payments) {
this.payments = payments;
}
public List<PaymentAddress> getPayments() {
return payments;
}
}

View File

@ -40,6 +40,8 @@ import org.whispersystems.textsecuregcm.storage.AbusiveHostRules;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.storage.PaymentAddress;
import org.whispersystems.textsecuregcm.storage.PaymentAddressList;
import org.whispersystems.textsecuregcm.storage.PendingAccountsManager; import org.whispersystems.textsecuregcm.storage.PendingAccountsManager;
import org.whispersystems.textsecuregcm.storage.UsernamesManager; import org.whispersystems.textsecuregcm.storage.UsernamesManager;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper; import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
@ -53,6 +55,7 @@ import java.io.IOException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -577,7 +580,7 @@ public class AccountControllerTest {
.target(String.format("/v1/accounts/code/%s", "666666")) .target(String.format("/v1/accounts/code/%s", "666666"))
.request() .request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar")) .header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, Hex.toStringCondensed(registration_lock_key)), .put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, Hex.toStringCondensed(registration_lock_key), null),
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
assertThat(result.getUuid()).isNotNull(); assertThat(result.getUuid()).isNotNull();
@ -593,7 +596,7 @@ public class AccountControllerTest {
.target(String.format("/v1/accounts/code/%s", "666666")) .target(String.format("/v1/accounts/code/%s", "666666"))
.request() .request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar")) .header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, Hex.toStringCondensed(registration_lock_key)), .put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, Hex.toStringCondensed(registration_lock_key), null),
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
assertThat(result.getUuid()).isNotNull(); assertThat(result.getUuid()).isNotNull();
@ -627,7 +630,7 @@ public class AccountControllerTest {
.target(String.format("/v1/accounts/code/%s", "666666")) .target(String.format("/v1/accounts/code/%s", "666666"))
.request() .request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar")) .header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, null), .put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, null, null),
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
assertThat(result.getUuid()).isNotNull(); assertThat(result.getUuid()).isNotNull();
@ -783,6 +786,78 @@ public class AccountControllerTest {
assertThat(pinCapture.getValue().length()).isEqualTo(40); assertThat(pinCapture.getValue().length()).isEqualTo(40);
} }
@Test
public void testSetPayments() {
PaymentAddress paymentAddress = new PaymentAddress("some address", "V15Pf5JsFcQF6AtlM3vo3OhGEgFwTh8G3iDDvShpr8QzoJmFQ+a2xb3PoXRmGF60DLq1RR2o8Fgw+f953mKvNA==");
Response response =
resources.getJerseyTest()
.target("/v1/accounts/payments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.put(Entity.json(new PaymentAddressList(List.of(paymentAddress))));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.VALID_ACCOUNT, times(1)).setPayments(eq(List.of(paymentAddress)));
}
@Test
public void testSetPaymentsUnauthorized() {
PaymentAddress paymentAddress = new PaymentAddress("an address", "V15Pf5JsFcQF6AtlM3vo3OhGEgFwTh8G3iDDvShpr8QzoJmFQ+a2xb3PoXRmGF60DLq1RR2o8Fgw+f953mKvNA==");
Response response =
resources.getJerseyTest()
.target("/v1/accounts/payments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.INVALID_UUID.toString(), AuthHelper.INVALID_PASSWORD))
.put(Entity.json(new PaymentAddressList(List.of(paymentAddress))));
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
public void testSetPaymentsInvalidSignature() {
PaymentAddress paymentAddress = new PaymentAddress("some address", "123456789012345678901234567890123");
Response response =
resources.getJerseyTest()
.target("/v1/accounts/payments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.put(Entity.json(new PaymentAddressList(List.of(paymentAddress))));
assertThat(response.getStatus()).isEqualTo(422);
}
@Test
public void testSetPaymentsEmptyAddress() {
PaymentAddress paymentAddress = new PaymentAddress(null, "V15Pf5JsFcQF6AtlM3vo3OhGEgFwTh8G3iDDvShpr8QzoJmFQ+a2xb3PoXRmGF60DLq1RR2o8Fgw+f953mKvNA==");
Response response =
resources.getJerseyTest()
.target("/v1/accounts/payments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.put(Entity.json(new PaymentAddressList(List.of(paymentAddress))));
assertThat(response.getStatus()).isEqualTo(422);
}
@Test
public void testSetPaymentsEmptySignature() {
PaymentAddress paymentAddress = new PaymentAddress("some address", null);
Response response =
resources.getJerseyTest()
.target("/v1/accounts/payments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.put(Entity.json(new PaymentAddressList(List.of(paymentAddress))));
assertThat(response.getStatus()).isEqualTo(422);
}
@Test @Test
public void testSetPinUnauthorized() throws Exception { public void testSetPinUnauthorized() throws Exception {

View File

@ -212,7 +212,7 @@ public class DeviceControllerTest {
.target("/v1/devices/5678901") .target("/v1/devices/5678901")
.request() .request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1")) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.put(Entity.entity(new AccountAttributes("keykeykeykey", false, 1234, "this is a really long name that is longer than 80 characters it's so long that it's even longer than 204 characters. that's a lot of characters. we're talking lots and lots and lots of characters. 12345678", null, null), .put(Entity.entity(new AccountAttributes("keykeykeykey", false, 1234, "this is a really long name that is longer than 80 characters it's so long that it's even longer than 204 characters. that's a lot of characters. we're talking lots and lots and lots of characters. 12345678", null, null, null),
MediaType.APPLICATION_JSON_TYPE)); MediaType.APPLICATION_JSON_TYPE));
assertEquals(response.getStatus(), 422); assertEquals(response.getStatus(), 422);

View File

@ -28,6 +28,7 @@ import org.whispersystems.textsecuregcm.s3.PolicySigner;
import org.whispersystems.textsecuregcm.s3.PostPolicyGenerator; import org.whispersystems.textsecuregcm.s3.PostPolicyGenerator;
import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.PaymentAddress;
import org.whispersystems.textsecuregcm.storage.ProfilesManager; import org.whispersystems.textsecuregcm.storage.ProfilesManager;
import org.whispersystems.textsecuregcm.storage.UsernamesManager; import org.whispersystems.textsecuregcm.storage.UsernamesManager;
import org.whispersystems.textsecuregcm.storage.VersionedProfile; import org.whispersystems.textsecuregcm.storage.VersionedProfile;
@ -37,6 +38,7 @@ import org.whispersystems.textsecuregcm.util.SystemMapper;
import javax.ws.rs.client.Entity; import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
@ -87,17 +89,16 @@ public class ProfileControllerTest {
when(profileAccount.getIdentityKey()).thenReturn("bar"); when(profileAccount.getIdentityKey()).thenReturn("bar");
when(profileAccount.getProfileName()).thenReturn("baz"); when(profileAccount.getProfileName()).thenReturn("baz");
when(profileAccount.getAvatar()).thenReturn("profiles/bang"); when(profileAccount.getAvatar()).thenReturn("profiles/bang");
when(profileAccount.getAvatarDigest()).thenReturn("buh");
when(profileAccount.getUuid()).thenReturn(AuthHelper.VALID_UUID_TWO); when(profileAccount.getUuid()).thenReturn(AuthHelper.VALID_UUID_TWO);
when(profileAccount.isEnabled()).thenReturn(true); when(profileAccount.isEnabled()).thenReturn(true);
when(profileAccount.isUuidAddressingSupported()).thenReturn(false); when(profileAccount.isUuidAddressingSupported()).thenReturn(false);
when(profileAccount.getPayments()).thenReturn(List.of(new PaymentAddress("mc", "12345678901234567890123456789012")));
Account capabilitiesAccount = mock(Account.class); Account capabilitiesAccount = mock(Account.class);
when(capabilitiesAccount.getIdentityKey()).thenReturn("barz"); when(capabilitiesAccount.getIdentityKey()).thenReturn("barz");
when(capabilitiesAccount.getProfileName()).thenReturn("bazz"); when(capabilitiesAccount.getProfileName()).thenReturn("bazz");
when(capabilitiesAccount.getAvatar()).thenReturn("profiles/bangz"); when(capabilitiesAccount.getAvatar()).thenReturn("profiles/bangz");
when(capabilitiesAccount.getAvatarDigest()).thenReturn("buz");
when(capabilitiesAccount.isEnabled()).thenReturn(true); when(capabilitiesAccount.isEnabled()).thenReturn(true);
when(capabilitiesAccount.isUuidAddressingSupported()).thenReturn(true); when(capabilitiesAccount.isUuidAddressingSupported()).thenReturn(true);
@ -133,6 +134,7 @@ public class ProfileControllerTest {
assertThat(profile.getName()).isEqualTo("baz"); assertThat(profile.getName()).isEqualTo("baz");
assertThat(profile.getAvatar()).isEqualTo("profiles/bang"); assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getUsername()).isEqualTo("n00bkiller"); assertThat(profile.getUsername()).isEqualTo("n00bkiller");
assertThat(profile.getPayments()).isEqualTo(List.of(new PaymentAddress("mc", "12345678901234567890123456789012")));
verify(accountsManager, times(1)).get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(AuthHelper.VALID_UUID_TWO))); verify(accountsManager, times(1)).get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(AuthHelper.VALID_UUID_TWO)));
verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO)); verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));
@ -150,6 +152,7 @@ public class ProfileControllerTest {
assertThat(profile.getIdentityKey()).isEqualTo("bar"); assertThat(profile.getIdentityKey()).isEqualTo("bar");
assertThat(profile.getName()).isEqualTo("baz"); assertThat(profile.getName()).isEqualTo("baz");
assertThat(profile.getAvatar()).isEqualTo("profiles/bang"); assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getPayments()).isEqualTo(List.of(new PaymentAddress("mc", "12345678901234567890123456789012")));
assertThat(profile.getCapabilities().isUuid()).isFalse(); assertThat(profile.getCapabilities().isUuid()).isFalse();
assertThat(profile.getUsername()).isNull(); assertThat(profile.getUsername()).isNull();
assertThat(profile.getUuid()).isNull();; assertThat(profile.getUuid()).isNull();;
@ -171,6 +174,7 @@ public class ProfileControllerTest {
assertThat(profile.getName()).isEqualTo("baz"); assertThat(profile.getName()).isEqualTo("baz");
assertThat(profile.getAvatar()).isEqualTo("profiles/bang"); assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getUsername()).isEqualTo("n00bkiller"); assertThat(profile.getUsername()).isEqualTo("n00bkiller");
assertThat(profile.getPayments()).isEqualTo(List.of(new PaymentAddress("mc", "12345678901234567890123456789012")));
assertThat(profile.getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO); assertThat(profile.getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO);
verify(accountsManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO)); verify(accountsManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));