minor username api refinements
This commit is contained in:
parent
67343f6bdc
commit
0188d314ce
|
@ -91,7 +91,7 @@ public class AccountTest {
|
||||||
final ConfirmUsernameHashRequest confirmUsernameHashRequest = new ConfirmUsernameHashRequest(
|
final ConfirmUsernameHashRequest confirmUsernameHashRequest = new ConfirmUsernameHashRequest(
|
||||||
reservedUsername.getHash(),
|
reservedUsername.getHash(),
|
||||||
reservedUsername.generateProof(),
|
reservedUsername.generateProof(),
|
||||||
new EncryptedUsername("cluck cluck i'm a parrot".getBytes())
|
"cluck cluck i'm a parrot".getBytes()
|
||||||
);
|
);
|
||||||
// try unauthorized
|
// try unauthorized
|
||||||
Operations
|
Operations
|
||||||
|
|
|
@ -354,11 +354,11 @@ public class AccountController {
|
||||||
final Account account = accounts.confirmReservedUsernameHash(
|
final Account account = accounts.confirmReservedUsernameHash(
|
||||||
auth.getAccount(),
|
auth.getAccount(),
|
||||||
confirmRequest.usernameHash(),
|
confirmRequest.usernameHash(),
|
||||||
Optional.ofNullable(confirmRequest.encryptedUsername()).map(EncryptedUsername::usernameLinkEncryptedValue).orElse(null));
|
confirmRequest.encryptedUsername());
|
||||||
final UUID linkHandle = account.getUsernameLinkHandle();
|
final UUID linkHandle = account.getUsernameLinkHandle();
|
||||||
return new UsernameHashResponse(
|
return new UsernameHashResponse(
|
||||||
account.getUsernameHash().orElseThrow(() -> new IllegalStateException("Could not get username after setting")),
|
account.getUsernameHash().orElseThrow(() -> new IllegalStateException("Could not get username after setting")),
|
||||||
linkHandle == null ? null : new UsernameLinkHandle(linkHandle));
|
linkHandle);
|
||||||
} catch (final UsernameReservationNotFoundException e) {
|
} catch (final UsernameReservationNotFoundException e) {
|
||||||
throw new WebApplicationException(Status.CONFLICT);
|
throw new WebApplicationException(Status.CONFLICT);
|
||||||
} catch (final UsernameHashNotAvailableException e) {
|
} catch (final UsernameHashNotAvailableException e) {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.entities;
|
package org.whispersystems.textsecuregcm.entities;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -27,8 +27,10 @@ public record ConfirmUsernameHashRequest(
|
||||||
@JsonDeserialize(using = ByteArrayBase64UrlAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64UrlAdapter.Deserializing.class)
|
||||||
byte[] zkProof,
|
byte[] zkProof,
|
||||||
|
|
||||||
@Schema(description = "The encrypted username to be stored for username links")
|
@Schema(type = "string", description = "The url-safe base64-encoded encrypted username to be stored for username links")
|
||||||
@Nullable
|
@Nullable
|
||||||
@Valid
|
@JsonSerialize(using = ByteArrayBase64UrlAdapter.Serializing.class)
|
||||||
EncryptedUsername encryptedUsername
|
@JsonDeserialize(using = ByteArrayBase64UrlAdapter.Deserializing.class)
|
||||||
|
@Size(min = 1, max = 128)
|
||||||
|
byte[] encryptedUsername
|
||||||
) {}
|
) {}
|
||||||
|
|
|
@ -5,8 +5,18 @@
|
||||||
|
|
||||||
package org.whispersystems.textsecuregcm.entities;
|
package org.whispersystems.textsecuregcm.entities;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
import org.whispersystems.textsecuregcm.util.ByteArrayBase64UrlAdapter;
|
||||||
|
|
||||||
public record EncryptedUsername(@NotNull @Size(min = 1, max = 128) byte[] usernameLinkEncryptedValue) {
|
public record EncryptedUsername(
|
||||||
|
@JsonSerialize(using = ByteArrayBase64UrlAdapter.Serializing.class)
|
||||||
|
@JsonDeserialize(using = ByteArrayBase64UrlAdapter.Deserializing.class)
|
||||||
|
@NotNull
|
||||||
|
@Size(min = 1, max = 128)
|
||||||
|
@Schema(type = "string", description = "the URL-safe base64 encoding of the encrypted username")
|
||||||
|
byte[] usernameLinkEncryptedValue) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import org.whispersystems.textsecuregcm.controllers.AccountController;
|
import org.whispersystems.textsecuregcm.controllers.AccountController;
|
||||||
import org.whispersystems.textsecuregcm.util.ByteArrayBase64UrlAdapter;
|
import org.whispersystems.textsecuregcm.util.ByteArrayBase64UrlAdapter;
|
||||||
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
import org.whispersystems.textsecuregcm.util.ExactlySize;
|
||||||
|
import java.util.UUID;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ public record UsernameHashResponse(
|
||||||
@JsonSerialize(using = ByteArrayBase64UrlAdapter.Serializing.class)
|
@JsonSerialize(using = ByteArrayBase64UrlAdapter.Serializing.class)
|
||||||
@JsonDeserialize(using = ByteArrayBase64UrlAdapter.Deserializing.class)
|
@JsonDeserialize(using = ByteArrayBase64UrlAdapter.Deserializing.class)
|
||||||
@ExactlySize(AccountController.USERNAME_HASH_LENGTH)
|
@ExactlySize(AccountController.USERNAME_HASH_LENGTH)
|
||||||
@Schema(description = "The hash of the confirmed username, as supplied in the request")
|
@Schema(type = "string", description = "The hash of the confirmed username, as supplied in the request")
|
||||||
byte[] usernameHash,
|
byte[] usernameHash,
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Valid
|
@Valid
|
||||||
@Schema(description = "A handle that can be included in username links to retrieve the stored encrypted username")
|
@Schema(type = "string", description = "A handle that can be included in username links to retrieve the stored encrypted username")
|
||||||
UsernameLinkHandle usernameLinkHandle
|
UUID usernameLinkHandle
|
||||||
) {}
|
) {}
|
||||||
|
|
|
@ -7,6 +7,11 @@ package org.whispersystems.textsecuregcm.entities;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
|
||||||
public record UsernameLinkHandle(@NotNull UUID usernameLinkHandle) {
|
public record UsernameLinkHandle(
|
||||||
|
@Schema(description = "A handle that can be included in username links to retrieve the stored encrypted username")
|
||||||
|
@NotNull
|
||||||
|
UUID usernameLinkHandle) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -639,12 +639,12 @@ class AccountControllerTest {
|
||||||
.target("/v1/accounts/username_hash/confirm")
|
.target("/v1/accounts/username_hash/confirm")
|
||||||
.request()
|
.request()
|
||||||
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, new EncryptedUsername(ENCRYPTED_USERNAME_1))));
|
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, ENCRYPTED_USERNAME_1)));
|
||||||
assertThat(response.getStatus()).isEqualTo(200);
|
assertThat(response.getStatus()).isEqualTo(200);
|
||||||
|
|
||||||
final UsernameHashResponse respEntity = response.readEntity(UsernameHashResponse.class);
|
final UsernameHashResponse respEntity = response.readEntity(UsernameHashResponse.class);
|
||||||
assertArrayEquals(respEntity.usernameHash(), USERNAME_HASH_1);
|
assertArrayEquals(respEntity.usernameHash(), USERNAME_HASH_1);
|
||||||
assertEquals(respEntity.usernameLinkHandle().usernameLinkHandle(), uuid);
|
assertEquals(respEntity.usernameLinkHandle(), uuid);
|
||||||
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,7 +680,7 @@ class AccountControllerTest {
|
||||||
.target("/v1/accounts/username_hash/confirm")
|
.target("/v1/accounts/username_hash/confirm")
|
||||||
.request()
|
.request()
|
||||||
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, new EncryptedUsername(ENCRYPTED_USERNAME_1))));
|
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, ENCRYPTED_USERNAME_1)));
|
||||||
assertThat(response.getStatus()).isEqualTo(409);
|
assertThat(response.getStatus()).isEqualTo(409);
|
||||||
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
||||||
}
|
}
|
||||||
|
@ -695,7 +695,7 @@ class AccountControllerTest {
|
||||||
.target("/v1/accounts/username_hash/confirm")
|
.target("/v1/accounts/username_hash/confirm")
|
||||||
.request()
|
.request()
|
||||||
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, new EncryptedUsername(ENCRYPTED_USERNAME_1))));
|
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, ENCRYPTED_USERNAME_1)));
|
||||||
assertThat(response.getStatus()).isEqualTo(410);
|
assertThat(response.getStatus()).isEqualTo(410);
|
||||||
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
||||||
}
|
}
|
||||||
|
@ -727,7 +727,7 @@ class AccountControllerTest {
|
||||||
.target("/v1/accounts/username_hash/confirm")
|
.target("/v1/accounts/username_hash/confirm")
|
||||||
.request()
|
.request()
|
||||||
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.json(new ConfirmUsernameHashRequest(usernameHash, ZK_PROOF, new EncryptedUsername(ENCRYPTED_USERNAME_1))));
|
.put(Entity.json(new ConfirmUsernameHashRequest(usernameHash, ZK_PROOF, ENCRYPTED_USERNAME_1)));
|
||||||
assertThat(response.getStatus()).isEqualTo(422);
|
assertThat(response.getStatus()).isEqualTo(422);
|
||||||
verifyNoInteractions(usernameZkProofVerifier);
|
verifyNoInteractions(usernameZkProofVerifier);
|
||||||
}
|
}
|
||||||
|
@ -740,7 +740,7 @@ class AccountControllerTest {
|
||||||
.target("/v1/accounts/username_hash/confirm")
|
.target("/v1/accounts/username_hash/confirm")
|
||||||
.request()
|
.request()
|
||||||
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header(HttpHeaders.AUTHORIZATION, AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, new EncryptedUsername(ENCRYPTED_USERNAME_1))));
|
.put(Entity.json(new ConfirmUsernameHashRequest(USERNAME_HASH_1, ZK_PROOF, ENCRYPTED_USERNAME_1)));
|
||||||
assertThat(response.getStatus()).isEqualTo(422);
|
assertThat(response.getStatus()).isEqualTo(422);
|
||||||
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
verify(usernameZkProofVerifier).verifyProof(ZK_PROOF, USERNAME_HASH_1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue