Return an empty response if somebody requests a profile key credential with a non-existent version

This commit is contained in:
Jon Chambers 2021-12-16 10:23:40 -05:00 committed by Jon Chambers
parent b2f0ace9db
commit a87b84fbe2
4 changed files with 62 additions and 16 deletions

View File

@ -296,12 +296,13 @@ public class ProfileController {
final boolean isSelf,
final ContainerRequestContext containerRequestContext) {
final VersionedProfile profile =
profilesManager.get(account.getUuid(), version).orElseThrow(NotFoundException::new);
final ProfileKeyCredentialResponse profileKeyCredentialResponse = profilesManager.get(account.getUuid(), version)
.map(profile -> getProfileCredential(encodedCredentialRequest, profile, account.getUuid()))
.orElse(null);
return new ProfileKeyCredentialProfileResponse(
buildVersionedProfileResponse(account, version, isSelf, containerRequestContext),
getProfileCredential(encodedCredentialRequest, profile, account.getUuid()));
profileKeyCredentialResponse);
}
private PniCredentialProfileResponse buildPniCredentialProfileResponse(final Account account,
@ -309,12 +310,13 @@ public class ProfileController {
final String encodedCredentialRequest,
final ContainerRequestContext containerRequestContext) {
final VersionedProfile profile =
profilesManager.get(account.getUuid(), version).orElseThrow(NotFoundException::new);
final PniCredentialResponse pniCredentialResponse = profilesManager.get(account.getUuid(), version)
.map(profile -> getPniCredential(encodedCredentialRequest, profile, account.getUuid(), account.getPhoneNumberIdentifier()))
.orElse(null);
return new PniCredentialProfileResponse(
buildVersionedProfileResponse(account, version, true, containerRequestContext),
getPniCredential(encodedCredentialRequest, profile, account.getUuid(), account.getPhoneNumberIdentifier()));
pniCredentialResponse);
}
private VersionedProfileResponse buildVersionedProfileResponse(final Account account,

View File

@ -5,32 +5,31 @@
package org.whispersystems.textsecuregcm.entities;
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.JsonSerialize;
import org.signal.zkgroup.profiles.PniCredentialResponse;
import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;
import org.signal.zkgroup.profiles.PniCredentialResponse;
public class PniCredentialProfileResponse extends CredentialProfileResponse {
@JsonProperty
@JsonSerialize(using = PniCredentialResponseAdapter.Serializing.class)
@JsonDeserialize(using = PniCredentialResponseAdapter.Deserializing.class)
@Nullable
private PniCredentialResponse pniCredential;
public PniCredentialProfileResponse() {
}
public PniCredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse,
final PniCredentialResponse pniCredential) {
@Nullable final PniCredentialResponse pniCredential) {
super(versionedProfileResponse);
this.pniCredential = pniCredential;
}
@Nullable
public PniCredentialResponse getPniCredential() {
return pniCredential;
}

View File

@ -5,33 +5,31 @@
package org.whispersystems.textsecuregcm.entities;
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.JsonSerialize;
import org.signal.zkgroup.profiles.PniCredentialResponse;
import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;
public class ProfileKeyCredentialProfileResponse extends CredentialProfileResponse {
@JsonProperty
@JsonSerialize(using = ProfileKeyCredentialResponseAdapter.Serializing.class)
@JsonDeserialize(using = ProfileKeyCredentialResponseAdapter.Deserializing.class)
@Nullable
private ProfileKeyCredentialResponse credential;
public ProfileKeyCredentialProfileResponse() {
}
public ProfileKeyCredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse,
final ProfileKeyCredentialResponse credential) {
@Nullable final ProfileKeyCredentialResponse credential) {
super(versionedProfileResponse);
this.credential = credential;
}
@Nullable
public ProfileKeyCredentialResponse getCredential() {
return credential;
}

View File

@ -768,6 +768,29 @@ class ProfileControllerTest {
);
}
@Test
void testGetProfileWithProfileKeyCredentialVersionNotFound() throws VerificationFailedException {
final Account account = mock(Account.class);
when(account.getUuid()).thenReturn(AuthHelper.VALID_UUID);
when(account.getCurrentProfileVersion()).thenReturn(Optional.of("version"));
when(account.isEnabled()).thenReturn(true);
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
when(profilesManager.get(any(), any())).thenReturn(Optional.empty());
final ProfileKeyCredentialProfileResponse profile = resources.getJerseyTest()
.target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, "version-that-does-not-exist", "credential-request"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(ProfileKeyCredentialProfileResponse.class);
assertThat(profile.getVersionedProfileResponse().getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID);
assertThat(profile.getCredential()).isNull();
verify(zkProfileOperations, never()).issueProfileKeyCredential(any(), any(), any());
verify(zkProfileOperations, never()).issuePniCredential(any(), any(), any(), any());
}
@Test
void testGetProfileWithPniCredential() throws InvalidInputException, VerificationFailedException {
final String version = "version";
@ -866,6 +889,30 @@ class ProfileControllerTest {
verify(zkProfileOperations, never()).issuePniCredential(any(), any(), any(), any());
}
@Test
void testGetProfileWithPniCredentialVersionNotFound() throws VerificationFailedException {
final Account account = mock(Account.class);
when(account.getUuid()).thenReturn(AuthHelper.VALID_UUID);
when(account.getCurrentProfileVersion()).thenReturn(Optional.of("version"));
when(account.isEnabled()).thenReturn(true);
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
when(profilesManager.get(any(), any())).thenReturn(Optional.empty());
final PniCredentialProfileResponse profile = resources.getJerseyTest()
.target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, "version-that-does-not-exist", "credential-request"))
.queryParam("credentialType", "pni")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(PniCredentialProfileResponse.class);
assertThat(profile.getVersionedProfileResponse().getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID);
assertThat(profile.getPniCredential()).isNull();
verify(zkProfileOperations, never()).issueProfileKeyCredential(any(), any(), any());
verify(zkProfileOperations, never()).issuePniCredential(any(), any(), any(), any());
}
@Test
void testSetProfileBadgesMissingFromRequest() throws InvalidInputException {
ProfileKeyCommitment commitment = new ProfileKey(new byte[32]).getCommitment(AuthHelper.VALID_UUID);