Refactor: separate the various types of profile responses
This commit is contained in:
parent
4ea7278c6f
commit
66845d7080
|
@ -8,6 +8,8 @@ package org.whispersystems.textsecuregcm.auth;
|
|||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
|
||||
import javax.ws.rs.NotAuthorizedException;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.security.MessageDigest;
|
||||
|
@ -36,9 +38,9 @@ public class OptionalAccess {
|
|||
}
|
||||
|
||||
if (requestAccount.isPresent()) {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
throw new NotFoundException();
|
||||
} else {
|
||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||
throw new NotAuthorizedException(Response.Status.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
|
@ -56,7 +58,7 @@ public class OptionalAccess {
|
|||
|
||||
//noinspection ConstantConditions
|
||||
if (requestAccount.isPresent() && (targetAccount.isEmpty() || (targetAccount.isPresent() && !targetAccount.get().isEnabled()))) {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
if (accessKey.isPresent() && targetAccount.isPresent() && targetAccount.get().isEnabled() && targetAccount.get().isUnrestrictedUnidentifiedAccess()) {
|
||||
|
@ -72,7 +74,7 @@ public class OptionalAccess {
|
|||
return;
|
||||
}
|
||||
|
||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||
throw new NotAuthorizedException(Response.Status.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import javax.ws.rs.DefaultValue;
|
|||
import javax.ws.rs.ForbiddenException;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.HeaderParam;
|
||||
import javax.ws.rs.NotAuthorizedException;
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
@ -63,9 +65,13 @@ import org.whispersystems.textsecuregcm.configuration.BadgeConfiguration;
|
|||
import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.CreateProfileRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.Profile;
|
||||
import org.whispersystems.textsecuregcm.entities.CredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.PniCredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.ProfileAvatarUploadAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.ProfileKeyCredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.BaseProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.UserCapabilities;
|
||||
import org.whispersystems.textsecuregcm.entities.VersionedProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.s3.PolicySigner;
|
||||
import org.whispersystems.textsecuregcm.s3.PostPolicyGenerator;
|
||||
|
@ -196,23 +202,28 @@ public class ProfileController {
|
|||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{uuid}/{version}")
|
||||
public Profile getProfile(
|
||||
public VersionedProfileResponse getProfile(
|
||||
@Auth Optional<AuthenticatedAccount> auth,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
@PathParam("uuid") UUID uuid,
|
||||
@PathParam("version") String version)
|
||||
throws RateLimitExceededException {
|
||||
return getVersionedProfile(auth.map(AuthenticatedAccount::getAccount), accessKey,
|
||||
getAcceptableLanguagesForRequest(containerRequestContext), uuid,
|
||||
version, Optional.empty(), Optional.empty());
|
||||
|
||||
final Optional<Account> maybeRequester = auth.map(AuthenticatedAccount::getAccount);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, uuid);
|
||||
|
||||
return buildVersionedProfileResponse(targetAccount,
|
||||
version,
|
||||
isSelfProfileRequest(maybeRequester, uuid),
|
||||
containerRequestContext);
|
||||
}
|
||||
|
||||
@Timed
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{uuid}/{version}/{credentialRequest}")
|
||||
public Profile getProfile(
|
||||
public CredentialProfileResponse getProfile(
|
||||
@Auth Optional<AuthenticatedAccount> auth,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
|
@ -221,134 +232,140 @@ public class ProfileController {
|
|||
@PathParam("credentialRequest") String credentialRequest,
|
||||
@QueryParam("credentialType") @DefaultValue(PROFILE_KEY_CREDENTIAL_TYPE) String credentialType)
|
||||
throws RateLimitExceededException {
|
||||
return getVersionedProfile(auth.map(AuthenticatedAccount::getAccount), accessKey,
|
||||
getAcceptableLanguagesForRequest(containerRequestContext), uuid,
|
||||
version, Optional.of(credentialRequest), Optional.of(credentialType));
|
||||
}
|
||||
|
||||
private Profile getVersionedProfile(
|
||||
Optional<Account> requestAccount,
|
||||
Optional<Anonymous> accessKey,
|
||||
List<Locale> acceptableLanguages,
|
||||
UUID uuid,
|
||||
String version,
|
||||
Optional<String> credentialRequest,
|
||||
Optional<String> credentialType)
|
||||
throws RateLimitExceededException {
|
||||
if (requestAccount.isEmpty() && accessKey.isEmpty()) {
|
||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||
}
|
||||
final Optional<Account> maybeRequester = auth.map(AuthenticatedAccount::getAccount);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, uuid);
|
||||
final boolean isSelf = isSelfProfileRequest(maybeRequester, uuid);
|
||||
|
||||
boolean isSelf = false;
|
||||
if (requestAccount.isPresent()) {
|
||||
UUID authedUuid = requestAccount.get().getUuid();
|
||||
rateLimiters.getProfileLimiter().validate(authedUuid);
|
||||
isSelf = uuid.equals(authedUuid);
|
||||
}
|
||||
switch (credentialType) {
|
||||
case PROFILE_KEY_CREDENTIAL_TYPE -> {
|
||||
return buildProfileKeyCredentialProfileResponse(targetAccount,
|
||||
version,
|
||||
credentialRequest,
|
||||
isSelf,
|
||||
containerRequestContext);
|
||||
}
|
||||
|
||||
Optional<Account> accountProfile = accountsManager.getByAccountIdentifier(uuid);
|
||||
OptionalAccess.verify(requestAccount, accessKey, accountProfile);
|
||||
|
||||
assert accountProfile.isPresent();
|
||||
|
||||
Optional<String> username = accountProfile.flatMap(Account::getUsername);
|
||||
Optional<VersionedProfile> profile = profilesManager.get(uuid, version);
|
||||
|
||||
String name = profile.map(VersionedProfile::getName).orElse(null);
|
||||
String about = profile.map(VersionedProfile::getAbout).orElse(null);
|
||||
String aboutEmoji = profile.map(VersionedProfile::getAboutEmoji).orElse(null);
|
||||
String avatar = profile.map(VersionedProfile::getAvatar).orElse(null);
|
||||
Optional<String> currentProfileVersion = accountProfile.get().getCurrentProfileVersion();
|
||||
|
||||
// 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.
|
||||
final String paymentAddress = profile
|
||||
.filter(p -> currentProfileVersion.map(v -> v.equals(version)).orElse(true))
|
||||
.map(VersionedProfile::getPaymentAddress)
|
||||
.orElse(null);
|
||||
|
||||
final ProfileKeyCredentialResponse profileKeyCredentialResponse;
|
||||
final PniCredentialResponse pniCredentialResponse;
|
||||
|
||||
if (credentialRequest.isPresent() && credentialType.isPresent() && profile.isPresent()) {
|
||||
if (PNI_CREDENTIAL_TYPE.equals(credentialType.get())) {
|
||||
case PNI_CREDENTIAL_TYPE -> {
|
||||
if (!isSelf) {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
||||
profileKeyCredentialResponse = null;
|
||||
pniCredentialResponse = getPniCredential(credentialRequest.get(),
|
||||
profile.get(),
|
||||
requestAccount.get().getUuid(),
|
||||
requestAccount.get().getPhoneNumberIdentifier());
|
||||
} else if (PROFILE_KEY_CREDENTIAL_TYPE.equals(credentialType.get())) {
|
||||
profileKeyCredentialResponse = getProfileCredential(credentialRequest.get(),
|
||||
profile.get(),
|
||||
uuid);
|
||||
|
||||
pniCredentialResponse = null;
|
||||
} else {
|
||||
throw new BadRequestException();
|
||||
return buildPniCredentialProfileResponse(targetAccount,
|
||||
version,
|
||||
credentialRequest,
|
||||
containerRequestContext);
|
||||
}
|
||||
} else {
|
||||
profileKeyCredentialResponse = null;
|
||||
pniCredentialResponse = null;
|
||||
}
|
||||
|
||||
return new Profile(
|
||||
name,
|
||||
about,
|
||||
aboutEmoji,
|
||||
avatar,
|
||||
paymentAddress,
|
||||
accountProfile.get().getIdentityKey(),
|
||||
UnidentifiedAccessChecksum.generateFor(accountProfile.get().getUnidentifiedAccessKey()),
|
||||
accountProfile.get().isUnrestrictedUnidentifiedAccess(),
|
||||
UserCapabilities.createForAccount(accountProfile.get()),
|
||||
username.orElse(null),
|
||||
null,
|
||||
profileBadgeConverter.convert(acceptableLanguages, accountProfile.get().getBadges(), isSelf),
|
||||
profileKeyCredentialResponse,
|
||||
pniCredentialResponse);
|
||||
default -> throw new BadRequestException();
|
||||
}
|
||||
}
|
||||
|
||||
// Although clients should generally be using versioned profiles wherever possible, there are still a few lingering
|
||||
// use cases for getting profiles without a version (e.g. getting a contact's unidentified access key checksum).
|
||||
@Timed
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{identifier}")
|
||||
public BaseProfileResponse getUnversionedProfile(
|
||||
@Auth Optional<AuthenticatedAccount> auth,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
@HeaderParam("User-Agent") String userAgent,
|
||||
@PathParam("identifier") UUID identifier,
|
||||
@QueryParam("ca") boolean useCaCertificate)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
final Optional<Account> maybeRequester = auth.map(AuthenticatedAccount::getAccount);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, identifier);
|
||||
|
||||
return buildBaseProfileResponse(targetAccount,
|
||||
isSelfProfileRequest(maybeRequester, identifier),
|
||||
containerRequestContext);
|
||||
}
|
||||
|
||||
private ProfileKeyCredentialProfileResponse buildProfileKeyCredentialProfileResponse(final Account account,
|
||||
final String version,
|
||||
final String encodedCredentialRequest,
|
||||
final boolean isSelf,
|
||||
final ContainerRequestContext containerRequestContext) {
|
||||
|
||||
final VersionedProfile profile =
|
||||
profilesManager.get(account.getUuid(), version).orElseThrow(NotFoundException::new);
|
||||
|
||||
return new ProfileKeyCredentialProfileResponse(
|
||||
buildVersionedProfileResponse(account, version, isSelf, containerRequestContext),
|
||||
getProfileCredential(encodedCredentialRequest, profile, account.getUuid()));
|
||||
}
|
||||
|
||||
private PniCredentialProfileResponse buildPniCredentialProfileResponse(final Account account,
|
||||
final String version,
|
||||
final String encodedCredentialRequest,
|
||||
final ContainerRequestContext containerRequestContext) {
|
||||
|
||||
final VersionedProfile profile =
|
||||
profilesManager.get(account.getUuid(), version).orElseThrow(NotFoundException::new);
|
||||
|
||||
return new PniCredentialProfileResponse(
|
||||
buildVersionedProfileResponse(account, version, true, containerRequestContext),
|
||||
getPniCredential(encodedCredentialRequest, profile, account.getUuid(), account.getPhoneNumberIdentifier()));
|
||||
}
|
||||
|
||||
private VersionedProfileResponse buildVersionedProfileResponse(final Account account,
|
||||
final String version,
|
||||
final boolean isSelf,
|
||||
final ContainerRequestContext containerRequestContext) {
|
||||
|
||||
final Optional<VersionedProfile> maybeProfile = profilesManager.get(account.getUuid(), version);
|
||||
|
||||
final String name = maybeProfile.map(VersionedProfile::getName).orElse(null);
|
||||
final String about = maybeProfile.map(VersionedProfile::getAbout).orElse(null);
|
||||
final String aboutEmoji = maybeProfile.map(VersionedProfile::getAboutEmoji).orElse(null);
|
||||
final String avatar = maybeProfile.map(VersionedProfile::getAvatar).orElse(null);
|
||||
|
||||
// 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.
|
||||
final String paymentAddress = maybeProfile
|
||||
.filter(p -> account.getCurrentProfileVersion().map(v -> v.equals(version)).orElse(true))
|
||||
.map(VersionedProfile::getPaymentAddress)
|
||||
.orElse(null);
|
||||
|
||||
return new VersionedProfileResponse(buildBaseProfileResponse(account, isSelf, containerRequestContext),
|
||||
name, about, aboutEmoji, avatar, paymentAddress);
|
||||
}
|
||||
|
||||
private BaseProfileResponse buildBaseProfileResponse(final Account account,
|
||||
final boolean isSelf,
|
||||
final ContainerRequestContext containerRequestContext) {
|
||||
|
||||
return new BaseProfileResponse(account.getIdentityKey(),
|
||||
UnidentifiedAccessChecksum.generateFor(account.getUnidentifiedAccessKey()),
|
||||
account.isUnrestrictedUnidentifiedAccess(),
|
||||
UserCapabilities.createForAccount(account),
|
||||
profileBadgeConverter.convert(
|
||||
getAcceptableLanguagesForRequest(containerRequestContext),
|
||||
account.getBadges(),
|
||||
isSelf),
|
||||
isSelf ? account.getUsername().orElse(null) : null,
|
||||
account.getUuid());
|
||||
}
|
||||
|
||||
@Timed
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/username/{username}")
|
||||
public Profile getProfileByUsername(
|
||||
public BaseProfileResponse getProfileByUsername(
|
||||
@Auth AuthenticatedAccount auth,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
@PathParam("username") String username)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
rateLimiters.getUsernameLookupLimiter().validate(auth.getAccount().getUuid());
|
||||
|
||||
username = username.toLowerCase();
|
||||
final Account targetAccount = accountsManager.getByUsername(username).orElseThrow(NotFoundException::new);
|
||||
final boolean isSelf = auth.getAccount().getUuid().equals(targetAccount.getUuid());
|
||||
|
||||
final Account accountProfile = accountsManager.getByUsername(username)
|
||||
.orElseThrow(() -> new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build()));
|
||||
|
||||
final boolean isSelf = auth.getAccount().getUuid().equals(accountProfile.getUuid());
|
||||
|
||||
return new Profile(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
accountProfile.getIdentityKey(),
|
||||
UnidentifiedAccessChecksum.generateFor(accountProfile.getUnidentifiedAccessKey()),
|
||||
accountProfile.isUnrestrictedUnidentifiedAccess(),
|
||||
UserCapabilities.createForAccount(accountProfile),
|
||||
username,
|
||||
accountProfile.getUuid(),
|
||||
profileBadgeConverter.convert(
|
||||
getAcceptableLanguagesForRequest(containerRequestContext),
|
||||
accountProfile.getBadges(),
|
||||
isSelf),
|
||||
null,
|
||||
null);
|
||||
return buildBaseProfileResponse(targetAccount, isSelf, containerRequestContext);
|
||||
}
|
||||
|
||||
private ProfileKeyCredentialResponse getProfileCredential(final String encodedProfileCredentialRequest,
|
||||
|
@ -379,57 +396,6 @@ public class ProfileController {
|
|||
}
|
||||
}
|
||||
|
||||
// Although clients should generally be using versioned profiles wherever possible, there are still a few lingering
|
||||
// use cases for getting profiles without a version (e.g. getting a contact's unidentified access key checksum).
|
||||
@Timed
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{identifier}")
|
||||
public Profile getUnversionedProfile(
|
||||
@Auth Optional<AuthenticatedAccount> auth,
|
||||
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
@HeaderParam("User-Agent") String userAgent,
|
||||
@PathParam("identifier") UUID identifier,
|
||||
@QueryParam("ca") boolean useCaCertificate)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
if (auth.isEmpty() && accessKey.isEmpty()) {
|
||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
boolean isSelf = false;
|
||||
if (auth.isPresent()) {
|
||||
UUID authedUuid = auth.get().getAccount().getUuid();
|
||||
rateLimiters.getProfileLimiter().validate(authedUuid);
|
||||
isSelf = authedUuid.equals(identifier);
|
||||
}
|
||||
|
||||
Optional<Account> accountProfile = accountsManager.getByAccountIdentifier(identifier);
|
||||
OptionalAccess.verify(auth.map(AuthenticatedAccount::getAccount), accessKey, accountProfile);
|
||||
|
||||
Optional<String> username = accountProfile.flatMap(Account::getUsername);
|
||||
|
||||
return new Profile(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
accountProfile.get().getIdentityKey(),
|
||||
UnidentifiedAccessChecksum.generateFor(accountProfile.get().getUnidentifiedAccessKey()),
|
||||
accountProfile.get().isUnrestrictedUnidentifiedAccess(),
|
||||
UserCapabilities.createForAccount(accountProfile.get()),
|
||||
username.orElse(null),
|
||||
null,
|
||||
profileBadgeConverter.convert(
|
||||
getAcceptableLanguagesForRequest(containerRequestContext),
|
||||
accountProfile.get().getBadges(),
|
||||
isSelf),
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
private ProfileAvatarUploadAttributes generateAvatarUploadForm(String objectName) {
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
Pair<String, String> policy = policyGenerator.createFor(now, objectName, 10 * 1024 * 1024);
|
||||
|
@ -497,4 +463,42 @@ public class ProfileController {
|
|||
|
||||
return new ArrayList<>(result.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the requester has permission to view the profile of the account identified by the given ACI.
|
||||
*
|
||||
* @param maybeRequester the authenticated account requesting the profile, if any
|
||||
* @param maybeAccessKey an anonymous access key for the target account
|
||||
* @param targetUuid the ACI of the target account
|
||||
*
|
||||
* @return the target account
|
||||
*
|
||||
* @throws RateLimitExceededException if the requester must wait before requesting the target account's profile
|
||||
* @throws NotFoundException if no account was found for the target ACI
|
||||
* @throws NotAuthorizedException if the requester is not authorized to receive the target account's profile or if the
|
||||
* requester was not authenticated and did not present an anonymous access key
|
||||
*/
|
||||
private Account verifyPermissionToReceiveProfile(final Optional<Account> maybeRequester,
|
||||
final Optional<Anonymous> maybeAccessKey,
|
||||
final UUID targetUuid) throws RateLimitExceededException {
|
||||
|
||||
if (maybeRequester.isEmpty() && maybeAccessKey.isEmpty()) {
|
||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if (maybeRequester.isPresent()) {
|
||||
rateLimiters.getProfileLimiter().validate(maybeRequester.get().getUuid());
|
||||
}
|
||||
|
||||
final Optional<Account> maybeTargetAccount = accountsManager.getByAccountIdentifier(targetUuid);
|
||||
|
||||
OptionalAccess.verify(maybeRequester, maybeAccessKey, maybeTargetAccount);
|
||||
assert maybeTargetAccount.isPresent();
|
||||
|
||||
return maybeTargetAccount.get();
|
||||
}
|
||||
|
||||
private boolean isSelfProfileRequest(final Optional<Account> maybeRequester, final UUID targetUuid) {
|
||||
return maybeRequester.map(requester -> requester.getUuid().equals(targetUuid)).orElse(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BaseProfileResponse {
|
||||
|
||||
@JsonProperty
|
||||
private String identityKey;
|
||||
|
||||
@JsonProperty
|
||||
private String unidentifiedAccess;
|
||||
|
||||
@JsonProperty
|
||||
private boolean unrestrictedUnidentifiedAccess;
|
||||
|
||||
@JsonProperty
|
||||
private UserCapabilities capabilities;
|
||||
|
||||
@JsonProperty
|
||||
private List<Badge> badges;
|
||||
|
||||
@JsonProperty
|
||||
private String username;
|
||||
|
||||
@JsonProperty
|
||||
private UUID uuid;
|
||||
|
||||
public BaseProfileResponse() {
|
||||
}
|
||||
|
||||
public BaseProfileResponse(final String identityKey,
|
||||
final String unidentifiedAccess,
|
||||
final boolean unrestrictedUnidentifiedAccess,
|
||||
final UserCapabilities capabilities,
|
||||
final List<Badge> badges,
|
||||
@Nullable final String username,
|
||||
final UUID uuid) {
|
||||
|
||||
this.identityKey = identityKey;
|
||||
this.unidentifiedAccess = unidentifiedAccess;
|
||||
this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
|
||||
this.capabilities = capabilities;
|
||||
this.badges = badges;
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getIdentityKey() {
|
||||
return identityKey;
|
||||
}
|
||||
|
||||
public String getUnidentifiedAccess() {
|
||||
return unidentifiedAccess;
|
||||
}
|
||||
|
||||
public boolean isUnrestrictedUnidentifiedAccess() {
|
||||
return unrestrictedUnidentifiedAccess;
|
||||
}
|
||||
|
||||
public UserCapabilities getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
public List<Badge> getBadges() {
|
||||
return badges;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
|
||||
public abstract class CredentialProfileResponse {
|
||||
|
||||
@JsonUnwrapped
|
||||
private VersionedProfileResponse versionedProfileResponse;
|
||||
|
||||
protected CredentialProfileResponse() {
|
||||
}
|
||||
|
||||
protected CredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse) {
|
||||
this.versionedProfileResponse = versionedProfileResponse;
|
||||
}
|
||||
|
||||
public VersionedProfileResponse getVersionedProfileResponse() {
|
||||
return versionedProfileResponse;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
public class PniCredentialProfileResponse extends CredentialProfileResponse {
|
||||
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = PniCredentialResponseAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = PniCredentialResponseAdapter.Deserializing.class)
|
||||
private PniCredentialResponse pniCredential;
|
||||
|
||||
public PniCredentialProfileResponse() {
|
||||
}
|
||||
|
||||
public PniCredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse,
|
||||
final PniCredentialResponse pniCredential) {
|
||||
|
||||
super(versionedProfileResponse);
|
||||
this.pniCredential = pniCredential;
|
||||
}
|
||||
|
||||
public PniCredentialResponse getPniCredential() {
|
||||
return pniCredential;
|
||||
}
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013-2020 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.signal.zkgroup.profiles.PniCredentialResponse;
|
||||
import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
|
||||
|
||||
public class Profile {
|
||||
|
||||
@JsonProperty
|
||||
private String identityKey;
|
||||
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
private String about;
|
||||
|
||||
@JsonProperty
|
||||
private String aboutEmoji;
|
||||
|
||||
@JsonProperty
|
||||
private String avatar;
|
||||
|
||||
@JsonProperty
|
||||
private String paymentAddress;
|
||||
|
||||
@JsonProperty
|
||||
private String unidentifiedAccess;
|
||||
|
||||
@JsonProperty
|
||||
private boolean unrestrictedUnidentifiedAccess;
|
||||
|
||||
@JsonProperty
|
||||
private UserCapabilities capabilities;
|
||||
|
||||
@JsonProperty
|
||||
private String username;
|
||||
|
||||
@JsonProperty
|
||||
private UUID uuid;
|
||||
|
||||
@JsonProperty
|
||||
private List<Badge> badges;
|
||||
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = ProfileKeyCredentialResponseAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = ProfileKeyCredentialResponseAdapter.Deserializing.class)
|
||||
private ProfileKeyCredentialResponse credential;
|
||||
|
||||
@JsonProperty
|
||||
@JsonSerialize(using = PniCredentialResponseAdapter.Serializing.class)
|
||||
@JsonDeserialize(using = PniCredentialResponseAdapter.Deserializing.class)
|
||||
private PniCredentialResponse pniCredential;
|
||||
|
||||
public Profile() {}
|
||||
|
||||
public Profile(
|
||||
String name, String about, String aboutEmoji, String avatar, String paymentAddress, String identityKey,
|
||||
String unidentifiedAccess, boolean unrestrictedUnidentifiedAccess, UserCapabilities capabilities, String username,
|
||||
UUID uuid, List<Badge> badges, ProfileKeyCredentialResponse credential, PniCredentialResponse pniCredential)
|
||||
{
|
||||
this.name = name;
|
||||
this.about = about;
|
||||
this.aboutEmoji = aboutEmoji;
|
||||
this.avatar = avatar;
|
||||
this.paymentAddress = paymentAddress;
|
||||
this.identityKey = identityKey;
|
||||
this.unidentifiedAccess = unidentifiedAccess;
|
||||
this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
|
||||
this.capabilities = capabilities;
|
||||
this.username = username;
|
||||
this.uuid = uuid;
|
||||
this.badges = badges;
|
||||
this.credential = credential;
|
||||
this.pniCredential = pniCredential;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String getIdentityKey() {
|
||||
return identityKey;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAbout() {
|
||||
return about;
|
||||
}
|
||||
|
||||
public String getAboutEmoji() {
|
||||
return aboutEmoji;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public String getPaymentAddress() {
|
||||
return paymentAddress;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String getUnidentifiedAccess() {
|
||||
return unidentifiedAccess;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public boolean isUnrestrictedUnidentifiedAccess() {
|
||||
return unrestrictedUnidentifiedAccess;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public UserCapabilities getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public List<Badge> getBadges() {
|
||||
return badges;
|
||||
}
|
||||
|
||||
public ProfileKeyCredentialResponse getCredential() {
|
||||
return credential;
|
||||
}
|
||||
|
||||
public PniCredentialResponse getPniCredential() {
|
||||
return pniCredential;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
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)
|
||||
private ProfileKeyCredentialResponse credential;
|
||||
|
||||
public ProfileKeyCredentialProfileResponse() {
|
||||
}
|
||||
|
||||
public ProfileKeyCredentialProfileResponse(final VersionedProfileResponse versionedProfileResponse,
|
||||
final ProfileKeyCredentialResponse credential) {
|
||||
|
||||
super(versionedProfileResponse);
|
||||
this.credential = credential;
|
||||
}
|
||||
|
||||
public ProfileKeyCredentialResponse getCredential() {
|
||||
return credential;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VersionedProfileResponse {
|
||||
|
||||
@JsonUnwrapped
|
||||
private BaseProfileResponse baseProfileResponse;
|
||||
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
private String about;
|
||||
|
||||
@JsonProperty
|
||||
private String aboutEmoji;
|
||||
|
||||
@JsonProperty
|
||||
private String avatar;
|
||||
|
||||
@JsonProperty
|
||||
private String paymentAddress;
|
||||
|
||||
public VersionedProfileResponse() {
|
||||
}
|
||||
|
||||
public VersionedProfileResponse(final BaseProfileResponse baseProfileResponse,
|
||||
final String name,
|
||||
final String about,
|
||||
final String aboutEmoji,
|
||||
final String avatar,
|
||||
final String paymentAddress) {
|
||||
|
||||
this.baseProfileResponse = baseProfileResponse;
|
||||
this.name = name;
|
||||
this.about = about;
|
||||
this.aboutEmoji = aboutEmoji;
|
||||
this.avatar = avatar;
|
||||
this.paymentAddress = paymentAddress;
|
||||
}
|
||||
|
||||
public BaseProfileResponse getBaseProfileResponse() {
|
||||
return baseProfileResponse;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getAbout() {
|
||||
return about;
|
||||
}
|
||||
|
||||
public String getAboutEmoji() {
|
||||
return aboutEmoji;
|
||||
}
|
||||
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public String getPaymentAddress() {
|
||||
return paymentAddress;
|
||||
}
|
||||
}
|
|
@ -73,9 +73,12 @@ import org.whispersystems.textsecuregcm.controllers.ProfileController;
|
|||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
import org.whispersystems.textsecuregcm.entities.Badge;
|
||||
import org.whispersystems.textsecuregcm.entities.BadgeSvg;
|
||||
import org.whispersystems.textsecuregcm.entities.BaseProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.CreateProfileRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.Profile;
|
||||
import org.whispersystems.textsecuregcm.entities.PniCredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.ProfileAvatarUploadAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.ProfileKeyCredentialProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.VersionedProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.s3.PolicySigner;
|
||||
|
@ -209,16 +212,14 @@ class ProfileControllerTest {
|
|||
|
||||
@Test
|
||||
void testProfileGetByUuid() throws RateLimitExceededException {
|
||||
Profile profile= resources.getJerseyTest()
|
||||
BaseProfileResponse profile = resources.getJerseyTest()
|
||||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(BaseProfileResponse.class);
|
||||
|
||||
assertThat(profile.getIdentityKey()).isEqualTo("bar");
|
||||
assertThat(profile.getName()).isNull();
|
||||
assertThat(profile.getAvatar()).isNull();
|
||||
assertThat(profile.getUsername()).isEqualTo("n00bkiller");
|
||||
assertThat(profile.getUsername()).isNull();
|
||||
assertThat(profile.getBadges()).hasSize(1).element(0).has(new Condition<>(
|
||||
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));
|
||||
|
||||
|
@ -228,16 +229,14 @@ class ProfileControllerTest {
|
|||
|
||||
@Test
|
||||
void testProfileGetByUsername() throws RateLimitExceededException {
|
||||
Profile profile= resources.getJerseyTest()
|
||||
BaseProfileResponse profile = resources.getJerseyTest()
|
||||
.target("/v1/profile/username/n00bkiller")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(BaseProfileResponse.class);
|
||||
|
||||
assertThat(profile.getIdentityKey()).isEqualTo("bar");
|
||||
assertThat(profile.getName()).isNull();
|
||||
assertThat(profile.getAvatar()).isNull();
|
||||
assertThat(profile.getUsername()).isEqualTo("n00bkiller");
|
||||
assertThat(profile.getUsername()).isNull();
|
||||
assertThat(profile.getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO);
|
||||
assertThat(profile.getBadges()).hasSize(1).element(0).has(new Condition<>(
|
||||
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));
|
||||
|
@ -295,11 +294,11 @@ class ProfileControllerTest {
|
|||
|
||||
@Test
|
||||
void testProfileCapabilities() {
|
||||
Profile profile= resources.getJerseyTest()
|
||||
BaseProfileResponse profile = resources.getJerseyTest()
|
||||
.target("/v1/profile/" + AuthHelper.VALID_UUID)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(BaseProfileResponse.class);
|
||||
|
||||
assertThat(profile.getCapabilities().isGv2()).isTrue();
|
||||
assertThat(profile.getCapabilities().isGv1Migration()).isTrue();
|
||||
|
@ -311,7 +310,7 @@ class ProfileControllerTest {
|
|||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO)
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||
.get(Profile.class);
|
||||
.get(BaseProfileResponse.class);
|
||||
|
||||
assertThat(profile.getCapabilities().isGv2()).isFalse();
|
||||
assertThat(profile.getCapabilities().isGv1Migration()).isFalse();
|
||||
|
@ -538,22 +537,22 @@ class ProfileControllerTest {
|
|||
|
||||
@Test
|
||||
void testGetProfileByVersion() throws RateLimitExceededException {
|
||||
Profile profile = resources.getJerseyTest()
|
||||
VersionedProfileResponse profile = resources.getJerseyTest()
|
||||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(VersionedProfileResponse.class);
|
||||
|
||||
assertThat(profile.getIdentityKey()).isEqualTo("bar");
|
||||
assertThat(profile.getBaseProfileResponse().getIdentityKey()).isEqualTo("bar");
|
||||
assertThat(profile.getName()).isEqualTo("validname");
|
||||
assertThat(profile.getAbout()).isEqualTo("about");
|
||||
assertThat(profile.getAboutEmoji()).isEqualTo("emoji");
|
||||
assertThat(profile.getAvatar()).isEqualTo("profiles/validavatar");
|
||||
assertThat(profile.getCapabilities().isGv2()).isFalse();
|
||||
assertThat(profile.getCapabilities().isGv1Migration()).isFalse();
|
||||
assertThat(profile.getUsername()).isEqualTo("n00bkiller");
|
||||
assertThat(profile.getUuid()).isNull();
|
||||
assertThat(profile.getBadges()).hasSize(1).element(0).has(new Condition<>(
|
||||
assertThat(profile.getBaseProfileResponse().getCapabilities().isGv2()).isFalse();
|
||||
assertThat(profile.getBaseProfileResponse().getCapabilities().isGv1Migration()).isFalse();
|
||||
assertThat(profile.getBaseProfileResponse().getUsername()).isNull();
|
||||
assertThat(profile.getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID_TWO);
|
||||
assertThat(profile.getBaseProfileResponse().getBadges()).hasSize(1).element(0).has(new Condition<>(
|
||||
badge -> "Test Badge".equals(badge.getName()), "has badge with expected name"));
|
||||
|
||||
verify(accountsManager, times(1)).getByAccountIdentifier(eq(AuthHelper.VALID_UUID_TWO));
|
||||
|
@ -587,11 +586,11 @@ class ProfileControllerTest {
|
|||
void testGetProfileReturnsNoPaymentAddressIfCurrentVersionMismatch() {
|
||||
when(profilesManager.get(AuthHelper.VALID_UUID_TWO, "validversion")).thenReturn(
|
||||
Optional.of(new VersionedProfile(null, null, null, null, null, "paymentaddress", null)));
|
||||
Profile profile = resources.getJerseyTest()
|
||||
VersionedProfileResponse profile = resources.getJerseyTest()
|
||||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(VersionedProfileResponse.class);
|
||||
assertThat(profile.getPaymentAddress()).isEqualTo("paymentaddress");
|
||||
|
||||
when(profileAccount.getCurrentProfileVersion()).thenReturn(Optional.of("validversion"));
|
||||
|
@ -599,7 +598,7 @@ class ProfileControllerTest {
|
|||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(VersionedProfileResponse.class);
|
||||
assertThat(profile.getPaymentAddress()).isEqualTo("paymentaddress");
|
||||
|
||||
when(profileAccount.getCurrentProfileVersion()).thenReturn(Optional.of("someotherversion"));
|
||||
|
@ -607,7 +606,7 @@ class ProfileControllerTest {
|
|||
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(VersionedProfileResponse.class);
|
||||
assertThat(profile.getPaymentAddress()).isNull();
|
||||
}
|
||||
|
||||
|
@ -747,15 +746,14 @@ class ProfileControllerTest {
|
|||
when(zkProfileOperations.issueProfileKeyCredential(credentialRequest, AuthHelper.VALID_UUID, profileKeyCommitment))
|
||||
.thenReturn(credentialResponse);
|
||||
|
||||
final Profile profile = resources.getJerseyTest()
|
||||
final ProfileKeyCredentialProfileResponse profile = resources.getJerseyTest()
|
||||
.target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, Hex.encodeHexString(credentialRequest.serialize())))
|
||||
.request()
|
||||
.headers(authHeaders)
|
||||
.get(Profile.class);
|
||||
.get(ProfileKeyCredentialProfileResponse.class);
|
||||
|
||||
assertThat(profile.getUuid()).isNull();
|
||||
assertThat(profile.getVersionedProfileResponse().getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID);
|
||||
assertThat(profile.getCredential()).isEqualTo(credentialResponse);
|
||||
assertThat(profile.getPniCredential()).isNull();
|
||||
|
||||
verify(zkProfileOperations).issueProfileKeyCredential(credentialRequest, AuthHelper.VALID_UUID, profileKeyCommitment);
|
||||
verify(zkProfileOperations, never()).issuePniCredential(any(), any(), any(), any());
|
||||
|
@ -809,15 +807,14 @@ class ProfileControllerTest {
|
|||
when(zkProfileOperations.issuePniCredential(credentialRequest, AuthHelper.VALID_UUID, AuthHelper.VALID_PNI, profileKeyCommitment))
|
||||
.thenReturn(credentialResponse);
|
||||
|
||||
final Profile profile = resources.getJerseyTest()
|
||||
final PniCredentialProfileResponse profile = resources.getJerseyTest()
|
||||
.target(String.format("/v1/profile/%s/%s/%s", AuthHelper.VALID_UUID, version, Hex.encodeHexString(credentialRequest.serialize())))
|
||||
.queryParam("credentialType", "pni")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(Profile.class);
|
||||
.get(PniCredentialProfileResponse.class);
|
||||
|
||||
assertThat(profile.getUuid()).isNull();
|
||||
assertThat(profile.getCredential()).isNull();
|
||||
assertThat(profile.getVersionedProfileResponse().getBaseProfileResponse().getUuid()).isEqualTo(AuthHelper.VALID_UUID);
|
||||
assertThat(profile.getPniCredential()).isEqualTo(credentialResponse);
|
||||
|
||||
verify(zkProfileOperations, never()).issueProfileKeyCredential(any(), any(), any());
|
||||
|
|
Loading…
Reference in New Issue