Retire `AmbiguousIdentifier`

This commit is contained in:
Jon Chambers 2021-08-27 13:40:46 -04:00 committed by GitHub
parent 1f815b49dd
commit d1735c7e57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 899 additions and 906 deletions

View File

@ -1,61 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.auth;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
import javax.annotation.Nullable;
import java.util.UUID;
import static com.codahale.metrics.MetricRegistry.name;
public class AmbiguousIdentifier {
private final UUID uuid;
private final String number;
private static final String REQUEST_COUNTER_NAME = name(AmbiguousIdentifier.class, "request");
public AmbiguousIdentifier(String target) {
if (target.startsWith("+")) {
this.uuid = null;
this.number = target;
} else {
this.uuid = UUID.fromString(target);
this.number = null;
}
}
public UUID getUuid() {
return uuid;
}
public String getNumber() {
return number;
}
public boolean hasUuid() {
return uuid != null;
}
public boolean hasNumber() {
return number != null;
}
@Override
public String toString() {
return hasUuid() ? uuid.toString() : number;
}
public void incrementRequestCounter(final String context, @Nullable final String userAgent) {
Metrics.counter(REQUEST_COUNTER_NAME, Tags.of(
Tag.of("type", hasUuid() ? "uuid" : "e164"),
Tag.of("context", context),
UserAgentTagUtil.getPlatformTag(userAgent))).increment();
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.auth;
import org.whispersystems.textsecuregcm.util.Util;
import java.io.IOException;
import java.util.Base64;
public class AuthorizationHeader {
private final AmbiguousIdentifier identifier;
private final long deviceId;
private final String password;
private AuthorizationHeader(AmbiguousIdentifier identifier, long deviceId, String password) {
this.identifier = identifier;
this.deviceId = deviceId;
this.password = password;
}
public static AuthorizationHeader fromUserAndPassword(String user, String password) throws InvalidAuthorizationHeaderException {
try {
String[] numberAndId = user.split("\\.");
return new AuthorizationHeader(new AmbiguousIdentifier(numberAndId[0]),
numberAndId.length > 1 ? Long.parseLong(numberAndId[1]) : 1,
password);
} catch (NumberFormatException nfe) {
throw new InvalidAuthorizationHeaderException(nfe);
}
}
public static AuthorizationHeader fromFullHeader(String header) throws InvalidAuthorizationHeaderException {
try {
if (header == null) {
throw new InvalidAuthorizationHeaderException("Null header");
}
String[] headerParts = header.split(" ");
if (headerParts == null || headerParts.length < 2) {
throw new InvalidAuthorizationHeaderException("Invalid authorization header: " + header);
}
if (!"Basic".equals(headerParts[0])) {
throw new InvalidAuthorizationHeaderException("Unsupported authorization method: " + headerParts[0]);
}
String concatenatedValues = new String(Base64.getDecoder().decode(headerParts[1]));
if (Util.isEmpty(concatenatedValues)) {
throw new InvalidAuthorizationHeaderException("Bad decoded value: " + concatenatedValues);
}
String[] credentialParts = concatenatedValues.split(":");
if (credentialParts == null || credentialParts.length < 2) {
throw new InvalidAuthorizationHeaderException("Badly formated credentials: " + concatenatedValues);
}
return fromUserAndPassword(credentialParts[0], credentialParts[1]);
} catch (IllegalArgumentException e) {
throw new InvalidAuthorizationHeaderException(e);
}
}
public AmbiguousIdentifier getIdentifier() {
return identifier;
}
public long getDeviceId() {
return deviceId;
}
public String getPassword() {
return password;
}
}

View File

@ -15,11 +15,13 @@ import java.time.Clock;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.storage.RefreshingAccountAndDeviceSupplier;
import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.util.Util;
public class BaseAccountAuthenticator {
@ -28,7 +30,6 @@ public class BaseAccountAuthenticator {
private static final String AUTHENTICATION_SUCCEEDED_TAG_NAME = "succeeded";
private static final String AUTHENTICATION_FAILURE_REASON_TAG_NAME = "reason";
private static final String AUTHENTICATION_ENABLED_REQUIRED_TAG_NAME = "enabledRequired";
private static final String AUTHENTICATION_CREDENTIAL_TYPE_TAG_NAME = "credentialType";
private static final String DAYS_SINCE_LAST_SEEN_DISTRIBUTION_NAME = name(BaseAccountAuthenticator.class, "daysSinceLastSeen");
private static final String IS_PRIMARY_DEVICE_TAG = "isPrimary";
@ -46,24 +47,45 @@ public class BaseAccountAuthenticator {
this.clock = clock;
}
static Pair<String, Long> getIdentifierAndDeviceId(final String basicUsername) {
final String identifier;
final long deviceId;
final int deviceIdSeparatorIndex = basicUsername.indexOf('.');
if (deviceIdSeparatorIndex == -1) {
identifier = basicUsername;
deviceId = Device.MASTER_ID;
} else {
identifier = basicUsername.substring(0, deviceIdSeparatorIndex);
deviceId = Long.parseLong(basicUsername.substring(deviceIdSeparatorIndex + 1));
}
return new Pair<>(identifier, deviceId);
}
public Optional<AuthenticatedAccount> authenticate(BasicCredentials basicCredentials, boolean enabledRequired) {
boolean succeeded = false;
String failureReason = null;
String credentialType = null;
try {
AuthorizationHeader authorizationHeader = AuthorizationHeader.fromUserAndPassword(basicCredentials.getUsername(),
basicCredentials.getPassword());
Optional<Account> account = accountsManager.get(authorizationHeader.getIdentifier());
final UUID accountUuid;
final long deviceId;
{
final Pair<String, Long> identifierAndDeviceId = getIdentifierAndDeviceId(basicCredentials.getUsername());
credentialType = authorizationHeader.getIdentifier().hasNumber() ? "e164" : "uuid";
accountUuid = UUID.fromString(identifierAndDeviceId.first());
deviceId = identifierAndDeviceId.second();
}
Optional<Account> account = accountsManager.get(accountUuid);
if (account.isEmpty()) {
failureReason = "noSuchAccount";
return Optional.empty();
}
Optional<Device> device = account.get().getDevice(authorizationHeader.getDeviceId());
Optional<Device> device = account.get().getDevice(deviceId);
if (device.isEmpty()) {
failureReason = "noSuchDevice";
@ -102,10 +124,6 @@ public class BaseAccountAuthenticator {
tags = tags.and(AUTHENTICATION_FAILURE_REASON_TAG_NAME, failureReason);
}
if (StringUtils.isNotBlank(credentialType)) {
tags = tags.and(AUTHENTICATION_CREDENTIAL_TYPE_TAG_NAME, credentialType);
}
Metrics.counter(AUTHENTICATION_COUNTER_NAME, tags).increment();
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.auth;
import java.util.Base64;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.util.Pair;
public class BasicAuthorizationHeader {
private final String username;
private final long deviceId;
private final String password;
private BasicAuthorizationHeader(final String username, final long deviceId, final String password) {
this.username = username;
this.deviceId = deviceId;
this.password = password;
}
public static BasicAuthorizationHeader fromString(final String header) throws InvalidAuthorizationHeaderException {
try {
if (StringUtils.isBlank(header)) {
throw new InvalidAuthorizationHeaderException("Blank header");
}
final int spaceIndex = header.indexOf(' ');
if (spaceIndex == -1) {
throw new InvalidAuthorizationHeaderException("Invalid authorization header: " + header);
}
final String authorizationType = header.substring(0, spaceIndex);
if (!"Basic".equals(authorizationType)) {
throw new InvalidAuthorizationHeaderException("Unsupported authorization method: " + authorizationType);
}
final String credentials;
try {
credentials = new String(Base64.getDecoder().decode(header.substring(spaceIndex + 1)));
} catch (final IndexOutOfBoundsException e) {
throw new InvalidAuthorizationHeaderException("Missing credentials");
}
if (StringUtils.isEmpty(credentials)) {
throw new InvalidAuthorizationHeaderException("Bad decoded value: " + credentials);
}
final int credentialSeparatorIndex = credentials.indexOf(':');
if (credentialSeparatorIndex == -1) {
throw new InvalidAuthorizationHeaderException("Badly-formatted credentials: " + credentials);
}
final String usernameComponent = credentials.substring(0, credentialSeparatorIndex);
final String username;
final long deviceId;
{
final Pair<String, Long> identifierAndDeviceId =
BaseAccountAuthenticator.getIdentifierAndDeviceId(usernameComponent);
username = identifierAndDeviceId.first();
deviceId = identifierAndDeviceId.second();
}
final String password = credentials.substring(credentialSeparatorIndex + 1);
if (StringUtils.isAnyBlank(username, password)) {
throw new InvalidAuthorizationHeaderException("Username or password were blank");
}
return new BasicAuthorizationHeader(username, deviceId, password);
} catch (final IllegalArgumentException | IndexOutOfBoundsException e) {
throw new InvalidAuthorizationHeaderException(e);
}
}
public String getUsername() {
return username;
}
public long getDeviceId() {
return deviceId;
}
public String getPassword() {
return password;
}
}

View File

@ -5,12 +5,15 @@
package org.whispersystems.textsecuregcm.auth;
public class InvalidAuthorizationHeaderException extends Exception {
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
public class InvalidAuthorizationHeaderException extends WebApplicationException {
public InvalidAuthorizationHeaderException(String s) {
super(s);
super(s, Status.UNAUTHORIZED);
}
public InvalidAuthorizationHeaderException(Exception e) {
super(e);
super(e, Status.UNAUTHORIZED);
}
}

View File

@ -41,11 +41,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.AuthorizationHeader;
import org.whispersystems.textsecuregcm.auth.BasicAuthorizationHeader;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException;
import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
import org.whispersystems.textsecuregcm.auth.TurnToken;
@ -326,79 +325,70 @@ public class AccountController {
@Produces(MediaType.APPLICATION_JSON)
@Path("/code/{verification_code}")
public AccountCreationResult verifyAccount(@PathParam("verification_code") String verificationCode,
@HeaderParam("Authorization") String authorizationHeader,
@HeaderParam("X-Signal-Agent") String signalAgent,
@HeaderParam("User-Agent") String userAgent,
@QueryParam("transfer") Optional<Boolean> availableForTransfer,
@Valid AccountAttributes accountAttributes)
@HeaderParam("Authorization") BasicAuthorizationHeader authorizationHeader,
@HeaderParam("X-Signal-Agent") String signalAgent,
@HeaderParam("User-Agent") String userAgent,
@QueryParam("transfer") Optional<Boolean> availableForTransfer,
@Valid AccountAttributes accountAttributes)
throws RateLimitExceededException, InterruptedException {
try {
AuthorizationHeader header = AuthorizationHeader.fromFullHeader(authorizationHeader);
String number = header.getIdentifier().getNumber();
String password = header.getPassword();
if (number == null) {
throw new WebApplicationException(400);
}
String number = authorizationHeader.getUsername();
String password = authorizationHeader.getPassword();
rateLimiters.getVerifyLimiter().validate(number);
rateLimiters.getVerifyLimiter().validate(number);
Optional<StoredVerificationCode> storedVerificationCode = pendingAccounts.getCodeForNumber(number);
Optional<StoredVerificationCode> storedVerificationCode = pendingAccounts.getCodeForNumber(number);
if (storedVerificationCode.isEmpty() || !storedVerificationCode.get().isValid(verificationCode)) {
throw new WebApplicationException(Response.status(403).build());
}
storedVerificationCode.flatMap(StoredVerificationCode::getTwilioVerificationSid)
.ifPresent(smsSender::reportVerificationSucceeded);
Optional<Account> existingAccount = accounts.get(number);
Optional<StoredRegistrationLock> existingRegistrationLock = existingAccount.map(Account::getRegistrationLock);
Optional<ExternalServiceCredentials> existingBackupCredentials = existingAccount.map(Account::getUuid)
.map(uuid -> backupServiceCredentialGenerator.generateFor(uuid.toString()));
if (existingRegistrationLock.isPresent() && existingRegistrationLock.get().requiresClientRegistrationLock()) {
rateLimiters.getVerifyLimiter().clear(number);
if (!Util.isEmpty(accountAttributes.getRegistrationLock())) {
rateLimiters.getPinLimiter().validate(number);
}
if (!existingRegistrationLock.get().verify(accountAttributes.getRegistrationLock())) {
throw new WebApplicationException(Response.status(423)
.entity(new RegistrationLockFailure(existingRegistrationLock.get().getTimeRemaining(),
existingRegistrationLock.get().needsFailureCredentials() ? existingBackupCredentials.orElseThrow() : null))
.build());
}
rateLimiters.getPinLimiter().clear(number);
}
if (availableForTransfer.orElse(false) && existingAccount.map(Account::isTransferSupported).orElse(false)) {
throw new WebApplicationException(Response.status(409).build());
}
Account account = accounts.create(number, password, signalAgent, accountAttributes);
{
metricRegistry.meter(name(AccountController.class, "verify", Util.getCountryCode(number))).mark();
final List<Tag> tags = new ArrayList<>();
tags.add(Tag.of(COUNTRY_CODE_TAG_NAME, Util.getCountryCode(number)));
tags.add(UserAgentTagUtil.getPlatformTag(userAgent));
tags.add(Tag.of(VERIFY_EXPERIMENT_TAG_NAME, String.valueOf(storedVerificationCode.get().getTwilioVerificationSid().isPresent())));
Metrics.counter(ACCOUNT_VERIFY_COUNTER_NAME, tags).increment();
Metrics.timer(name(AccountController.class, "verifyDuration"), tags)
.record(Instant.now().toEpochMilli() - storedVerificationCode.get().getTimestamp(), TimeUnit.MILLISECONDS);
}
return new AccountCreationResult(account.getUuid(), existingAccount.map(Account::isStorageSupported).orElse(false));
} catch (InvalidAuthorizationHeaderException e) {
logger.info("Bad Authorization Header", e);
throw new WebApplicationException(Response.status(401).build());
if (storedVerificationCode.isEmpty() || !storedVerificationCode.get().isValid(verificationCode)) {
throw new WebApplicationException(Response.status(403).build());
}
storedVerificationCode.flatMap(StoredVerificationCode::getTwilioVerificationSid)
.ifPresent(smsSender::reportVerificationSucceeded);
Optional<Account> existingAccount = accounts.get(number);
Optional<StoredRegistrationLock> existingRegistrationLock = existingAccount.map(Account::getRegistrationLock);
Optional<ExternalServiceCredentials> existingBackupCredentials = existingAccount.map(Account::getUuid)
.map(uuid -> backupServiceCredentialGenerator.generateFor(uuid.toString()));
if (existingRegistrationLock.isPresent() && existingRegistrationLock.get().requiresClientRegistrationLock()) {
rateLimiters.getVerifyLimiter().clear(number);
if (!Util.isEmpty(accountAttributes.getRegistrationLock())) {
rateLimiters.getPinLimiter().validate(number);
}
if (!existingRegistrationLock.get().verify(accountAttributes.getRegistrationLock())) {
throw new WebApplicationException(Response.status(423)
.entity(new RegistrationLockFailure(existingRegistrationLock.get().getTimeRemaining(),
existingRegistrationLock.get().needsFailureCredentials() ? existingBackupCredentials.orElseThrow() : null))
.build());
}
rateLimiters.getPinLimiter().clear(number);
}
if (availableForTransfer.orElse(false) && existingAccount.map(Account::isTransferSupported).orElse(false)) {
throw new WebApplicationException(Response.status(409).build());
}
Account account = accounts.create(number, password, signalAgent, accountAttributes);
{
metricRegistry.meter(name(AccountController.class, "verify", Util.getCountryCode(number))).mark();
final List<Tag> tags = new ArrayList<>();
tags.add(Tag.of(COUNTRY_CODE_TAG_NAME, Util.getCountryCode(number)));
tags.add(UserAgentTagUtil.getPlatformTag(userAgent));
tags.add(Tag.of(VERIFY_EXPERIMENT_TAG_NAME, String.valueOf(storedVerificationCode.get().getTwilioVerificationSid().isPresent())));
Metrics.counter(ACCOUNT_VERIFY_COUNTER_NAME, tags).increment();
Metrics.timer(name(AccountController.class, "verifyDuration"), tags)
.record(Instant.now().toEpochMilli() - storedVerificationCode.get().getTimestamp(), TimeUnit.MILLISECONDS);
}
return new AccountCreationResult(account.getUuid(), existingAccount.map(Account::isStorageSupported).orElse(false));
}
@Timed

View File

@ -24,12 +24,9 @@ import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.AuthorizationHeader;
import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException;
import org.whispersystems.textsecuregcm.auth.BasicAuthorizationHeader;
import org.whispersystems.textsecuregcm.auth.StoredVerificationCode;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
import org.whispersystems.textsecuregcm.entities.DeviceInfo;
@ -51,8 +48,6 @@ import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil;
@Path("/v1/devices")
public class DeviceController {
private final Logger logger = LoggerFactory.getLogger(DeviceController.class);
private static final int MAX_DEVICES = 6;
private final StoredVerificationCodeManager pendingDevices;
@ -149,55 +144,52 @@ public class DeviceController {
@Consumes(MediaType.APPLICATION_JSON)
@Path("/{verification_code}")
public DeviceResponse verifyDeviceToken(@PathParam("verification_code") String verificationCode,
@HeaderParam("Authorization") String authorizationHeader,
@HeaderParam("User-Agent") String userAgent,
@Valid AccountAttributes accountAttributes)
@HeaderParam("Authorization") BasicAuthorizationHeader authorizationHeader,
@HeaderParam("User-Agent") String userAgent,
@Valid AccountAttributes accountAttributes)
throws RateLimitExceededException, DeviceLimitExceededException
{
try {
AuthorizationHeader header = AuthorizationHeader.fromFullHeader(authorizationHeader);
String number = header.getIdentifier().getNumber();
String password = header.getPassword();
if (number == null) throw new WebApplicationException(400);
String number = authorizationHeader.getUsername();
String password = authorizationHeader.getPassword();
rateLimiters.getVerifyDeviceLimiter().validate(number);
rateLimiters.getVerifyDeviceLimiter().validate(number);
Optional<StoredVerificationCode> storedVerificationCode = pendingDevices.getCodeForNumber(number);
Optional<StoredVerificationCode> storedVerificationCode = pendingDevices.getCodeForNumber(number);
if (!storedVerificationCode.isPresent() || !storedVerificationCode.get().isValid(verificationCode)) {
throw new WebApplicationException(Response.status(403).build());
}
if (!storedVerificationCode.isPresent() || !storedVerificationCode.get().isValid(verificationCode)) {
throw new WebApplicationException(Response.status(403).build());
}
Optional<Account> account = accounts.get(number);
Optional<Account> account = accounts.get(number);
if (!account.isPresent()) {
throw new WebApplicationException(Response.status(403).build());
}
if (!account.isPresent()) {
throw new WebApplicationException(Response.status(403).build());
}
int maxDeviceLimit = MAX_DEVICES;
int maxDeviceLimit = MAX_DEVICES;
if (maxDeviceConfiguration.containsKey(account.get().getNumber())) {
maxDeviceLimit = maxDeviceConfiguration.get(account.get().getNumber());
}
if (maxDeviceConfiguration.containsKey(account.get().getNumber())) {
maxDeviceLimit = maxDeviceConfiguration.get(account.get().getNumber());
}
if (account.get().getEnabledDeviceCount() >= maxDeviceLimit) {
throw new DeviceLimitExceededException(account.get().getDevices().size(), MAX_DEVICES);
}
if (account.get().getEnabledDeviceCount() >= maxDeviceLimit) {
throw new DeviceLimitExceededException(account.get().getDevices().size(), MAX_DEVICES);
}
final DeviceCapabilities capabilities = accountAttributes.getCapabilities();
if (capabilities != null && isCapabilityDowngrade(account.get(), capabilities, userAgent)) {
throw new WebApplicationException(Response.status(409).build());
}
final DeviceCapabilities capabilities = accountAttributes.getCapabilities();
if (capabilities != null && isCapabilityDowngrade(account.get(), capabilities, userAgent)) {
throw new WebApplicationException(Response.status(409).build());
}
Device device = new Device();
device.setName(accountAttributes.getName());
device.setAuthenticationCredentials(new AuthenticationCredentials(password));
device.setFetchesMessages(accountAttributes.getFetchesMessages());
device.setRegistrationId(accountAttributes.getRegistrationId());
device.setLastSeen(Util.todayInMillis());
device.setCreated(System.currentTimeMillis());
device.setCapabilities(accountAttributes.getCapabilities());
Device device = new Device();
device.setName(accountAttributes.getName());
device.setAuthenticationCredentials(new AuthenticationCredentials(password));
device.setFetchesMessages(accountAttributes.getFetchesMessages());
device.setRegistrationId(accountAttributes.getRegistrationId());
device.setLastSeen(Util.todayInMillis());
device.setCreated(System.currentTimeMillis());
device.setCapabilities(accountAttributes.getCapabilities());
accounts.update(account.get(), a -> {
device.setId(a.getNextDeviceId());
@ -205,13 +197,9 @@ public class DeviceController {
a.addDevice(device);
});
pendingDevices.remove(number);
pendingDevices.remove(number);
return new DeviceResponse(device.getId());
} catch (InvalidAuthorizationHeaderException e) {
logger.info("Bad Authorization Header", e);
throw new WebApplicationException(Response.status(401).build());
}
return new DeviceResponse(device.getId());
}
@Timed

View File

@ -15,6 +15,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import javax.validation.Valid;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@ -26,7 +27,6 @@ import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.Anonymous;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
@ -63,7 +63,6 @@ public class KeysController {
private static final String SOURCE_COUNTRY_TAG_NAME = "sourceCountry";
private static final String INTERNATIONAL_TAG_NAME = "international";
private static final String PREKEY_TARGET_IDENTIFIER_TAG_NAME = "identifierType";
public KeysController(RateLimiters rateLimiters, KeysDynamoDb keysDynamoDb, AccountsManager accounts,
PreKeyRateLimiter preKeyRateLimiter,
@ -119,20 +118,18 @@ public class KeysController {
@Produces(MediaType.APPLICATION_JSON)
public Response getDeviceKeys(@Auth Optional<AuthenticatedAccount> auth,
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
@PathParam("identifier") AmbiguousIdentifier targetName,
@PathParam("identifier") UUID targetUuid,
@PathParam("device_id") String deviceId,
@HeaderParam("User-Agent") String userAgent)
throws RateLimitExceededException, RateLimitChallengeException, ServerRejectedException {
targetName.incrementRequestCounter("getDeviceKeys", userAgent);
if (auth.isEmpty() && accessKey.isEmpty()) {
if (!auth.isPresent() && !accessKey.isPresent()) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
final Optional<Account> account = auth.map(AuthenticatedAccount::getAccount);
Optional<Account> target = accounts.get(targetName);
Optional<Account> target = accounts.get(targetUuid);
OptionalAccess.verify(account, accessKey, target, deviceId);
assert (target.isPresent());
@ -143,8 +140,7 @@ public class KeysController {
Metrics.counter(PREKEY_REQUEST_COUNTER_NAME, Tags.of(
SOURCE_COUNTRY_TAG_NAME, sourceCountryCode,
INTERNATIONAL_TAG_NAME, String.valueOf(!sourceCountryCode.equals(targetCountryCode)),
PREKEY_TARGET_IDENTIFIER_TAG_NAME, targetName.hasNumber() ? "number" : "uuid"
INTERNATIONAL_TAG_NAME, String.valueOf(!sourceCountryCode.equals(targetCountryCode))
)).increment();
}

View File

@ -65,7 +65,6 @@ import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.Anonymous;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.CombinedUnidentifiedSenderAccessKeys;
@ -154,7 +153,6 @@ public class MessageController {
private static final String EPHEMERAL_TAG_NAME = "ephemeral";
private static final String SENDER_TYPE_TAG_NAME = "senderType";
private static final String SENDER_COUNTRY_TAG_NAME = "senderCountry";
private static final String DESTINATION_TYPE_TAG_NAME = "destinationType";
private static final long MAX_MESSAGE_SIZE = DataSize.kibibytes(256).toBytes();
@ -202,17 +200,15 @@ public class MessageController {
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
@HeaderParam("User-Agent") String userAgent,
@HeaderParam("X-Forwarded-For") String forwardedFor,
@PathParam("destination") AmbiguousIdentifier destinationName,
@PathParam("destination") UUID destinationUuid,
@Valid IncomingMessageList messages)
throws RateLimitExceededException, RateLimitChallengeException {
destinationName.incrementRequestCounter("sendMessage", userAgent);
if (source.isEmpty() && accessKey.isEmpty()) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
if (source.isPresent() && !source.get().getAccount().isFor(destinationName)) {
if (source.isPresent() && !source.get().getAccount().getUuid().equals(destinationUuid)) {
assert source.get().getAccount().getMasterDevice().isPresent();
final Device masterDevice = source.get().getAccount().getMasterDevice().get();
@ -227,7 +223,7 @@ public class MessageController {
final String senderType;
if (source.isPresent() && !source.get().getAccount().isFor(destinationName)) {
if (source.isPresent() && !source.get().getAccount().getUuid().equals(destinationUuid)) {
identifiedMeter.mark();
senderType = "identified";
} else if (source.isEmpty()) {
@ -257,12 +253,12 @@ public class MessageController {
}
try {
boolean isSyncMessage = source.isPresent() && source.get().getAccount().isFor(destinationName);
boolean isSyncMessage = source.isPresent() && source.get().getAccount().getUuid().equals(destinationUuid);
Optional<Account> destination;
if (!isSyncMessage) {
destination = accountsManager.get(destinationName);
destination = accountsManager.get(destinationUuid);
} else {
destination = source.map(AuthenticatedAccount::getAccount);
}
@ -270,7 +266,7 @@ public class MessageController {
OptionalAccess.verify(source.map(AuthenticatedAccount::getAccount), accessKey, destination);
assert (destination.isPresent());
if (source.isPresent() && !source.get().getAccount().isFor(destinationName)) {
if (source.isPresent() && !source.get().getAccount().getUuid().equals(destinationUuid)) {
rateLimiters.getMessagesLimiter().validate(source.get().getAccount().getUuid(), destination.get().getUuid());
final String senderCountryCode = Util.getCountryCode(source.get().getAccount().getNumber());
@ -320,8 +316,7 @@ public class MessageController {
final List<Tag> tags = List.of(UserAgentTagUtil.getPlatformTag(userAgent),
Tag.of(EPHEMERAL_TAG_NAME, String.valueOf(messages.isOnline())),
Tag.of(SENDER_TYPE_TAG_NAME, senderType),
Tag.of(DESTINATION_TYPE_TAG_NAME, destinationName.hasNumber() ? "e164" : "uuid"));
Tag.of(SENDER_TYPE_TAG_NAME, senderType));
for (IncomingMessage incomingMessage : messages.getMessages()) {
Optional<Device> destinationDevice = destination.get().getDevice(incomingMessage.getDestinationDeviceId());

View File

@ -39,7 +39,6 @@ import org.signal.zkgroup.profiles.ProfileKeyCredentialResponse;
import org.signal.zkgroup.profiles.ServerZkProfileOperations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.Anonymous;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
@ -339,12 +338,10 @@ public class ProfileController {
public Profile getProfile(@Auth Optional<AuthenticatedAccount> auth,
@HeaderParam(OptionalAccess.UNIDENTIFIED) Optional<Anonymous> accessKey,
@HeaderParam("User-Agent") String userAgent,
@PathParam("identifier") AmbiguousIdentifier identifier,
@PathParam("identifier") UUID identifier,
@QueryParam("ca") boolean useCaCertificate)
throws RateLimitExceededException {
identifier.incrementRequestCounter("getProfile", userAgent);
if (auth.isEmpty() && accessKey.isEmpty()) {
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
@ -356,12 +353,7 @@ public class ProfileController {
Optional<Account> accountProfile = accountsManager.get(identifier);
OptionalAccess.verify(auth.map(AuthenticatedAccount::getAccount), accessKey, accountProfile);
Optional<String> username = Optional.empty();
if (!identifier.hasNumber()) {
//noinspection OptionalGetWithoutIsPresent
username = usernamesManager.get(accountProfile.get().getUuid());
}
Optional<String> username = usernamesManager.get(accountProfile.get().getUuid());
return new Profile(accountProfile.get().getProfileName(),
null,

View File

@ -14,7 +14,6 @@ import java.util.Set;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
@ -335,14 +334,6 @@ public class Account {
this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
}
public boolean isFor(AmbiguousIdentifier identifier) {
requireNotStale();
if (identifier.hasUuid()) return identifier.getUuid().equals(uuid);
else if (identifier.hasNumber()) return identifier.getNumber().equals(number);
else throw new AssertionError();
}
public boolean isDiscoverableByPhoneNumber() {
requireNotStale();

View File

@ -36,7 +36,6 @@ import net.logstash.logback.argument.StructuredArguments;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.controllers.AccountController;
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
@ -373,12 +372,6 @@ public class AccountsManager {
});
}
public Optional<Account> get(AmbiguousIdentifier identifier) {
if (identifier.hasNumber()) return get(identifier.getNumber());
else if (identifier.hasUuid()) return get(identifier.getUuid());
else throw new AssertionError();
}
public Optional<Account> get(String number) {
try (Timer.Context ignored = getByNumberTimer.time()) {
Optional<Account> account = redisGet(number);

View File

@ -0,0 +1,344 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.auth;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.time.Clock;
import java.time.Instant;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
import io.dropwizard.auth.basic.BasicCredentials;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.BaseAccountAuthenticator;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.tests.util.AccountsHelper;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
import org.whispersystems.textsecuregcm.util.Pair;
class BaseAccountAuthenticatorTest {
private final Random random = new Random(867_5309L);
private final long today = 1590451200000L;
private final long yesterday = today - 86_400_000L;
private final long oldTime = yesterday - 86_400_000L;
private final long currentTime = today + 68_000_000L;
private AccountsManager accountsManager;
private BaseAccountAuthenticator baseAccountAuthenticator;
private Clock clock;
private Account acct1;
private Account acct2;
private Account oldAccount;
@BeforeEach
void setup() {
accountsManager = mock(AccountsManager.class);
clock = mock(Clock.class);
baseAccountAuthenticator = new BaseAccountAuthenticator(accountsManager, clock);
acct1 = new Account("+14088675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
null, null, null, false, 0, null, yesterday, 0, null, 0, null)), null);
acct2 = new Account("+14098675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
null, null, null, false, 0, null, yesterday, 0, null, 0, null)), null);
oldAccount = new Account("+14108675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
null, null, null, false, 0, null, oldTime, 0, null, 0, null)), null);
AccountsHelper.setupMockUpdate(accountsManager);
}
@Test
void testUpdateLastSeenMiddleOfDay() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(currentTime));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct1), any(), anyLong());
verify(accountsManager).updateDeviceLastSeen(eq(acct2), eq(device2), anyLong());
assertThat(device1.getLastSeen()).isEqualTo(yesterday);
assertThat(device2.getLastSeen()).isEqualTo(today);
assertThat(acct1).isSameAs(updatedAcct1);
assertThat(acct2).isNotSameAs(updatedAcct2);
}
@Test
void testUpdateLastSeenStartOfDay() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(today));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct1), any(), anyLong());
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct2), any(), anyLong());
assertThat(device1.getLastSeen()).isEqualTo(yesterday);
assertThat(device2.getLastSeen()).isEqualTo(yesterday);
assertThat(acct1).isSameAs(updatedAcct1);
assertThat(acct2).isSameAs(updatedAcct2);
}
@Test
void testUpdateLastSeenEndOfDay() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(today + 86_400_000L - 1));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
verify(accountsManager).updateDeviceLastSeen(eq(acct1), eq(device1), anyLong());
verify(accountsManager).updateDeviceLastSeen(eq(acct2), eq(device2), anyLong());
assertThat(device1.getLastSeen()).isEqualTo(today);
assertThat(device2.getLastSeen()).isEqualTo(today);
assertThat(updatedAcct1).isNotSameAs(acct1);
assertThat(updatedAcct2).isNotSameAs(acct2);
}
@Test
void testNeverWriteYesterday() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(today));
final Device device = oldAccount.getDevices().stream().findFirst().get();
baseAccountAuthenticator.updateLastSeen(oldAccount, device);
verify(accountsManager).updateDeviceLastSeen(eq(oldAccount), eq(device), anyLong());
assertThat(device.getLastSeen()).isEqualTo(today);
}
@Test
void testAuthenticate() {
final UUID uuid = UUID.randomUUID();
final long deviceId = 1;
final String password = "12345";
final Account account = mock(Account.class);
final Device device = mock(Device.class);
final AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(clock.instant()).thenReturn(Instant.now());
when(accountsManager.get(uuid)).thenReturn(Optional.of(account));
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
when(device.isEnabled()).thenReturn(true);
when(device.getAuthenticationCredentials()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
final Optional<AuthenticatedAccount> maybeAuthenticatedAccount =
baseAccountAuthenticator.authenticate(new BasicCredentials(uuid.toString(), password), true);
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(device);
}
@Test
void testAuthenticateNonDefaultDevice() {
final UUID uuid = UUID.randomUUID();
final long deviceId = 2;
final String password = "12345";
final Account account = mock(Account.class);
final Device device = mock(Device.class);
final AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(clock.instant()).thenReturn(Instant.now());
when(accountsManager.get(uuid)).thenReturn(Optional.of(account));
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
when(device.isEnabled()).thenReturn(true);
when(device.getAuthenticationCredentials()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
final Optional<AuthenticatedAccount> maybeAuthenticatedAccount =
baseAccountAuthenticator.authenticate(new BasicCredentials(uuid + "." + deviceId, password), true);
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(device);
}
@ParameterizedTest
@ValueSource(booleans = {true, false})
void testAuthenticateEnabledRequired(final boolean enabledRequired) {
final UUID uuid = UUID.randomUUID();
final long deviceId = 1;
final String password = "12345";
final Account account = mock(Account.class);
final Device device = mock(Device.class);
final AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(clock.instant()).thenReturn(Instant.now());
when(accountsManager.get(uuid)).thenReturn(Optional.of(account));
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(false);
when(device.getId()).thenReturn(deviceId);
when(device.isEnabled()).thenReturn(false);
when(device.getAuthenticationCredentials()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
final Optional<AuthenticatedAccount> maybeAuthenticatedAccount =
baseAccountAuthenticator.authenticate(new BasicCredentials(uuid.toString(), password), enabledRequired);
if (enabledRequired) {
assertThat(maybeAuthenticatedAccount).isEmpty();
} else {
assertThat(maybeAuthenticatedAccount).isPresent();
assertThat(maybeAuthenticatedAccount.get().getAccount().getUuid()).isEqualTo(uuid);
assertThat(maybeAuthenticatedAccount.get().getAuthenticatedDevice()).isEqualTo(device);
}
}
@Test
void testAuthenticateAccountNotFound() {
assertThat(baseAccountAuthenticator.authenticate(new BasicCredentials(UUID.randomUUID().toString(), "password"), true))
.isEmpty();
}
@Test
void testAuthenticateDeviceNotFound() {
final UUID uuid = UUID.randomUUID();
final long deviceId = 1;
final String password = "12345";
final Account account = mock(Account.class);
final Device device = mock(Device.class);
final AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(clock.instant()).thenReturn(Instant.now());
when(accountsManager.get(uuid)).thenReturn(Optional.of(account));
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
when(device.isEnabled()).thenReturn(true);
when(device.getAuthenticationCredentials()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
final Optional<AuthenticatedAccount> maybeAuthenticatedAccount =
baseAccountAuthenticator.authenticate(new BasicCredentials(uuid + "." + (deviceId + 1), password), true);
assertThat(maybeAuthenticatedAccount).isEmpty();
verify(account).getDevice(deviceId + 1);
}
@Test
void testAuthenticateIncorrectPassword() {
final UUID uuid = UUID.randomUUID();
final long deviceId = 1;
final String password = "12345";
final Account account = mock(Account.class);
final Device device = mock(Device.class);
final AuthenticationCredentials credentials = mock(AuthenticationCredentials.class);
when(clock.instant()).thenReturn(Instant.now());
when(accountsManager.get(uuid)).thenReturn(Optional.of(account));
when(account.getUuid()).thenReturn(uuid);
when(account.getDevice(deviceId)).thenReturn(Optional.of(device));
when(account.isEnabled()).thenReturn(true);
when(device.getId()).thenReturn(deviceId);
when(device.isEnabled()).thenReturn(true);
when(device.getAuthenticationCredentials()).thenReturn(credentials);
when(credentials.verify(password)).thenReturn(true);
final String incorrectPassword = password + "incorrect";
final Optional<AuthenticatedAccount> maybeAuthenticatedAccount =
baseAccountAuthenticator.authenticate(new BasicCredentials(uuid.toString(), incorrectPassword), true);
assertThat(maybeAuthenticatedAccount).isEmpty();
verify(credentials).verify(incorrectPassword);
}
@ParameterizedTest
@MethodSource
void testAuthenticateMalformedCredentials(final String username) {
final Optional<AuthenticatedAccount> maybeAuthenticatedAccount = assertDoesNotThrow(
() -> baseAccountAuthenticator.authenticate(new BasicCredentials(username, "password"), true));
assertThat(maybeAuthenticatedAccount).isEmpty();
verify(accountsManager, never()).get(any(UUID.class));
}
private static Stream<String> testAuthenticateMalformedCredentials() {
return Stream.of(
"",
".4",
"This is definitely not a valid UUID",
UUID.randomUUID() + ".");
}
@ParameterizedTest
@MethodSource
void testGetIdentifierAndDeviceId(final String username, final String expectedIdentifier, final long expectedDeviceId) {
final Pair<String, Long> identifierAndDeviceId = BaseAccountAuthenticator.getIdentifierAndDeviceId(username);
assertEquals(expectedIdentifier, identifierAndDeviceId.first());
assertEquals(expectedDeviceId, identifierAndDeviceId.second());
}
private static Stream<Arguments> testGetIdentifierAndDeviceId() {
return Stream.of(
Arguments.of("", "", Device.MASTER_ID),
Arguments.of("test", "test", Device.MASTER_ID),
Arguments.of("test.7", "test", 7));
}
@ParameterizedTest
@ValueSource(strings = {
".",
".....",
"test.7.8",
"test."
})
void testGetIdentifierAndDeviceIdMalformed(final String malformedUsername) {
assertThrows(IllegalArgumentException.class,
() -> BaseAccountAuthenticator.getIdentifierAndDeviceId(malformedUsername));
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.auth;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.whispersystems.textsecuregcm.storage.Device;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
class BasicAuthorizationHeaderTest {
@Test
void fromString() throws InvalidAuthorizationHeaderException {
{
final BasicAuthorizationHeader header =
BasicAuthorizationHeader.fromString("Basic YWxhZGRpbjpvcGVuc2VzYW1l");
assertEquals("aladdin", header.getUsername());
assertEquals("opensesame", header.getPassword());
assertEquals(Device.MASTER_ID, header.getDeviceId());
}
{
final BasicAuthorizationHeader header = BasicAuthorizationHeader.fromString("Basic " +
Base64.getEncoder().encodeToString("username.7:password".getBytes(StandardCharsets.UTF_8)));
assertEquals("username", header.getUsername());
assertEquals("password", header.getPassword());
assertEquals(7, header.getDeviceId());
}
}
@ParameterizedTest
@MethodSource
void fromStringMalformed(final String header) {
assertThrows(InvalidAuthorizationHeaderException.class,
() -> BasicAuthorizationHeader.fromString(header));
}
private static Stream<String> fromStringMalformed() {
return Stream.of(
null,
"",
" ",
"Obviously not a valid authorization header",
"Digest YWxhZGRpbjpvcGVuc2VzYW1l",
"Basic",
"Basic ",
"Basic &&&&&&",
"Basic " + Base64.getEncoder().encodeToString("".getBytes(StandardCharsets.UTF_8)),
"Basic " + Base64.getEncoder().encodeToString(":".getBytes(StandardCharsets.UTF_8)),
"Basic " + Base64.getEncoder().encodeToString("test".getBytes(StandardCharsets.UTF_8)),
"Basic " + Base64.getEncoder().encodeToString("test.".getBytes(StandardCharsets.UTF_8)),
"Basic " + Base64.getEncoder().encodeToString("test.:".getBytes(StandardCharsets.UTF_8)),
"Basic " + Base64.getEncoder().encodeToString("test.:password".getBytes(StandardCharsets.UTF_8)),
"Basic " + Base64.getEncoder().encodeToString(":password".getBytes(StandardCharsets.UTF_8)));
}
}

View File

@ -63,7 +63,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(pushChallengeJson));
assertEquals(200, response.getStatus());
@ -82,7 +82,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(pushChallengeJson));
assertEquals(413, response.getStatus());
@ -100,7 +100,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("X-Forwarded-For", "10.0.0.1")
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(recaptchaChallengeJson));
assertEquals(200, response.getStatus());
@ -121,7 +121,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("X-Forwarded-For", "10.0.0.1")
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(recaptchaChallengeJson));
assertEquals(413, response.getStatus());
@ -138,7 +138,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(recaptchaChallengeJson));
assertEquals(400, response.getStatus());
@ -154,7 +154,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("X-Forwarded-For", "10.0.0.1")
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(unrecognizedJson));
assertEquals(400, response.getStatus());
@ -167,7 +167,7 @@ class ChallengeControllerTest {
{
final Response response = EXTENSION.target("/v1/challenge/push")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(Entity.text(""));
assertEquals(200, response.getStatus());
@ -178,7 +178,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge/push")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.post(Entity.text(""));
assertEquals(404, response.getStatus());
@ -193,7 +193,7 @@ class ChallengeControllerTest {
final Response response = EXTENSION.target("/v1/challenge")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(unrecognizedJson));
assertEquals(422, response.getStatus());

View File

@ -1,133 +0,0 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.tests.auth;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.time.Clock;
import java.time.Instant;
import java.util.Random;
import java.util.Set;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.auth.BaseAccountAuthenticator;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.tests.util.AccountsHelper;
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
class BaseAccountAuthenticatorTest {
private final Random random = new Random(867_5309L);
private final long today = 1590451200000L;
private final long yesterday = today - 86_400_000L;
private final long oldTime = yesterday - 86_400_000L;
private final long currentTime = today + 68_000_000L;
private AccountsManager accountsManager;
private BaseAccountAuthenticator baseAccountAuthenticator;
private Clock clock;
private Account acct1;
private Account acct2;
private Account oldAccount;
@BeforeEach
void setup() {
accountsManager = mock(AccountsManager.class);
clock = mock(Clock.class);
baseAccountAuthenticator = new BaseAccountAuthenticator(accountsManager, clock);
acct1 = new Account("+14088675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
null, null, null, false, 0, null, yesterday, 0, null, 0, null)), null);
acct2 = new Account("+14098675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
null, null, null, false, 0, null, yesterday, 0, null, 0, null)), null);
oldAccount = new Account("+14108675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
null, null, null, false, 0, null, oldTime, 0, null, 0, null)), null);
AccountsHelper.setupMockUpdate(accountsManager);
}
@Test
void testUpdateLastSeenMiddleOfDay() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(currentTime));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct1), any(), anyLong());
verify(accountsManager).updateDeviceLastSeen(eq(acct2), eq(device2), anyLong());
assertThat(device1.getLastSeen()).isEqualTo(yesterday);
assertThat(device2.getLastSeen()).isEqualTo(today);
assertThat(acct1).isSameAs(updatedAcct1);
assertThat(acct2).isNotSameAs(updatedAcct2);
}
@Test
void testUpdateLastSeenStartOfDay() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(today));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct1), any(), anyLong());
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct2), any(), anyLong());
assertThat(device1.getLastSeen()).isEqualTo(yesterday);
assertThat(device2.getLastSeen()).isEqualTo(yesterday);
assertThat(acct1).isSameAs(updatedAcct1);
assertThat(acct2).isSameAs(updatedAcct2);
}
@Test
void testUpdateLastSeenEndOfDay() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(today + 86_400_000L - 1));
final Device device1 = acct1.getDevices().stream().findFirst().get();
final Device device2 = acct2.getDevices().stream().findFirst().get();
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
verify(accountsManager).updateDeviceLastSeen(eq(acct1), eq(device1), anyLong());
verify(accountsManager).updateDeviceLastSeen(eq(acct2), eq(device2), anyLong());
assertThat(device1.getLastSeen()).isEqualTo(today);
assertThat(device2.getLastSeen()).isEqualTo(today);
assertThat(updatedAcct1).isNotSameAs(acct1);
assertThat(updatedAcct2).isNotSameAs(acct2);
}
@Test
void testNeverWriteYesterday() {
when(clock.instant()).thenReturn(Instant.ofEpochMilli(today));
final Device device = oldAccount.getDevices().stream().findFirst().get();
baseAccountAuthenticator.updateLastSeen(oldAccount, device);
verify(accountsManager).updateDeviceLastSeen(eq(oldAccount), eq(device), anyLong());
assertThat(device.getLastSeen()).isEqualTo(today);
}
}

View File

@ -932,7 +932,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "1234"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER, "bar"))
.put(Entity.entity(new AccountAttributes(), MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
verify(accountsManager).create(eq(SENDER), eq("bar"), any(), any());
@ -942,13 +942,24 @@ class AccountControllerTest {
}
}
@Test
void testVerifyCodeBadCredentials() {
final Response response = resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "1234"))
.request()
.header("Authorization", "This is not a valid authorization header")
.put(Entity.entity(new AccountAttributes(), MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
void testVerifyCodeOld() {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "1234"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_OLD, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_OLD, "bar"))
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -963,7 +974,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "1111"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER, "bar"))
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -978,7 +989,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "666666"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes(false, 3333, null, Hex.toStringCondensed(registration_lock_key), true, null),
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
@ -993,7 +1004,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "666666"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes(false, 3333, null, Hex.toStringCondensed(registration_lock_key), true, null),
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
@ -1016,7 +1027,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "666666"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class);
@ -1034,7 +1045,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "666666"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes(false, 3333, null,
Hex.toStringCondensed(new byte[32]), true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -1050,7 +1061,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "666666"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_REG_LOCK, "bar"))
.put(Entity.entity(new AccountAttributes(false, 3333, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -1075,7 +1086,7 @@ class AccountControllerTest {
.target(String.format("/v1/accounts/code/%s", "1234"))
.queryParam("transfer", true)
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_TRANSFER, "bar"))
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -1091,7 +1102,7 @@ class AccountControllerTest {
.target(String.format("/v1/accounts/code/%s", "1234"))
.queryParam("transfer", true)
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_TRANSFER, "bar"))
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -1106,7 +1117,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/accounts/code/%s", "1234"))
.request()
.header("Authorization", AuthHelper.getAuthHeader(SENDER_TRANSFER, "bar"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(SENDER_TRANSFER, "bar"))
.put(Entity.entity(new AccountAttributes(false, 2222, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -1119,7 +1130,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/registration_lock/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(new RegistrationLock("1234567890123456789012345678901234567890123456789012345678901234")));
assertThat(response.getStatus()).isEqualTo(204);
@ -1141,7 +1152,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/registration_lock/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(new RegistrationLock("313")));
assertThat(response.getStatus()).isEqualTo(422);
@ -1153,34 +1164,19 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/registration_lock/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new RegistrationLock("1234567890123456789012345678901234567890123456789012345678901234")));
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
void testSetGcmId() throws Exception {
void testSetGcmId() {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/gcm/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new GcmRegistrationId("c00lz0rz")));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.DISABLED_DEVICE, times(1)).setGcmId(eq("c00lz0rz"));
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
}
@Test
void testSetGcmIdByUuid() throws Exception {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/gcm/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID.toString(), AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new GcmRegistrationId("z000")));
assertThat(response.getStatus()).isEqualTo(204);
@ -1190,12 +1186,12 @@ class AccountControllerTest {
}
@Test
void testSetApnId() throws Exception {
void testSetApnId() {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/apn/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new ApnRegistrationId("first", "second")));
assertThat(response.getStatus()).isEqualTo(204);
@ -1206,12 +1202,12 @@ class AccountControllerTest {
}
@Test
void testSetApnIdNoVoip() throws Exception {
void testSetApnIdNoVoip() {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/apn/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new ApnRegistrationId("first", null)));
assertThat(response.getStatus()).isEqualTo(204);
@ -1221,22 +1217,6 @@ class AccountControllerTest {
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
}
@Test
void testSetApnIdByUuid() throws Exception {
Response response =
resources.getJerseyTest()
.target("/v1/accounts/apn/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID.toString(), AuthHelper.DISABLED_PASSWORD))
.put(Entity.json(new ApnRegistrationId("third", "fourth")));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.DISABLED_DEVICE, times(1)).setApnId(eq("third"));
verify(AuthHelper.DISABLED_DEVICE, times(1)).setVoipApnId(eq("fourth"));
verify(accountsManager, times(1)).updateDevice(eq(AuthHelper.DISABLED_ACCOUNT), anyLong(), any());
}
@ParameterizedTest
@ValueSource(strings = {"/v1/accounts/whoami/", "/v1/accounts/me/"})
public void testWhoAmI(final String path) {
@ -1244,7 +1224,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target(path)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(AccountCreationResult.class);
assertThat(response.getUuid()).isEqualTo(AuthHelper.VALID_UUID);
@ -1256,7 +1236,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/n00bkiller")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(200);
@ -1268,7 +1248,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/takenusername")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(409);
@ -1280,7 +1260,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/pаypal")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(400);
@ -1292,7 +1272,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/0n00bkiller")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(400);
@ -1304,7 +1284,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/n00bkiller")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(401);
@ -1316,7 +1296,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.delete();
assertThat(response.getStatus()).isEqualTo(204);
@ -1329,7 +1309,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/username/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.delete();
assertThat(response.getStatus()).isEqualTo(401);
@ -1341,7 +1321,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/attributes/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(new AccountAttributes(false, 2222, null, null, true, null)));
assertThat(response.getStatus()).isEqualTo(204);
@ -1353,7 +1333,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/attributes/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.UNDISCOVERABLE_NUMBER, AuthHelper.UNDISCOVERABLE_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.UNDISCOVERABLE_UUID, AuthHelper.UNDISCOVERABLE_PASSWORD))
.put(Entity.json(new AccountAttributes(false, 2222, null, null, true, null)));
assertThat(response.getStatus()).isEqualTo(204);
@ -1365,7 +1345,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/attributes/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json(new AccountAttributes(false, 2222, null, null, false, null)));
assertThat(response.getStatus()).isEqualTo(204);
@ -1377,7 +1357,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/me")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.delete();
assertThat(response.getStatus()).isEqualTo(204);
@ -1392,7 +1372,7 @@ class AccountControllerTest {
resources.getJerseyTest()
.target("/v1/accounts/me")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.delete();
assertThat(response.getStatus()).isEqualTo(500);

View File

@ -97,7 +97,7 @@ class AttachmentControllerTest {
AttachmentDescriptorV3 descriptor = resources.getJerseyTest()
.target("/v3/attachments/form/upload")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(AttachmentDescriptorV3.class);
assertThat(descriptor.getKey()).isNotBlank();
@ -153,7 +153,7 @@ class AttachmentControllerTest {
Response response = resources.getJerseyTest()
.target("/v3/attachments/form/upload")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
@ -164,7 +164,7 @@ class AttachmentControllerTest {
AttachmentDescriptorV2 descriptor = resources.getJerseyTest()
.target("/v2/attachments/form/upload")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(AttachmentDescriptorV2.class);
assertThat(descriptor.getKey()).isEqualTo(descriptor.getAttachmentIdString());
@ -192,7 +192,7 @@ class AttachmentControllerTest {
Response response = resources.getJerseyTest()
.target("/v2/attachments/form/upload")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
@ -204,7 +204,7 @@ class AttachmentControllerTest {
AttachmentDescriptorV1 descriptor = resources.getJerseyTest()
.target("/v1/attachments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(AttachmentDescriptorV1.class);
assertThat(descriptor.getLocation()).startsWith("https://attachment-bucket.s3-accelerate.amazonaws.com");
@ -217,7 +217,7 @@ class AttachmentControllerTest {
AttachmentDescriptorV1 descriptor = resources.getJerseyTest()
.target("/v1/attachments/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.get(AttachmentDescriptorV1.class);
assertThat(descriptor.getLocation()).startsWith("https://s3.amazonaws.com");
@ -230,7 +230,7 @@ class AttachmentControllerTest {
AttachmentUri uri = resources.getJerseyTest()
.target("/v1/attachments/1234")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(AttachmentUri.class);
assertThat(uri.getLocation().getHost()).isEqualTo("attachment-bucket.s3-accelerate.amazonaws.com");
@ -241,7 +241,7 @@ class AttachmentControllerTest {
AttachmentUri uri = resources.getJerseyTest()
.target("/v1/attachments/1234")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.get(AttachmentUri.class);
assertThat(uri.getLocation().getHost()).isEqualTo("s3.amazonaws.com");

View File

@ -79,7 +79,7 @@ class CertificateControllerTest {
DeliveryCertificate certificateObject = resources.getJerseyTest()
.target("/v1/certificate/delivery")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(DeliveryCertificate.class);
@ -105,7 +105,7 @@ class CertificateControllerTest {
.target("/v1/certificate/delivery")
.queryParam("includeUuid", "true")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(DeliveryCertificate.class);
@ -131,7 +131,7 @@ class CertificateControllerTest {
.queryParam("includeUuid", "true")
.queryParam("includeE164", "false")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(DeliveryCertificate.class);
@ -155,7 +155,7 @@ class CertificateControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/certificate/delivery")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.get();
assertEquals(response.getStatus(), 401);
@ -189,7 +189,7 @@ class CertificateControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/certificate/delivery")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertEquals(response.getStatus(), 401);
@ -200,7 +200,7 @@ class CertificateControllerTest {
GroupCredentials credentials = resources.getJerseyTest()
.target("/v1/certificate/group/" + Util.currentDaysSinceEpoch() + "/" + Util.currentDaysSinceEpoch())
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(GroupCredentials.class);
assertThat(credentials.getCredentials().size()).isEqualTo(1);
@ -215,7 +215,7 @@ class CertificateControllerTest {
GroupCredentials credentials = resources.getJerseyTest()
.target("/v1/certificate/group/" + Util.currentDaysSinceEpoch() + "/" + (Util.currentDaysSinceEpoch() + 7))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(GroupCredentials.class);
assertThat(credentials.getCredentials().size()).isEqualTo(8);
@ -233,7 +233,7 @@ class CertificateControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/certificate/group/" + Util.currentDaysSinceEpoch() + "/" + (Util.currentDaysSinceEpoch() + 8))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(400);
@ -244,7 +244,7 @@ class CertificateControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/certificate/group/" + (Util.currentDaysSinceEpoch() - 1) + "/" + (Util.currentDaysSinceEpoch() + 7))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(400);
@ -255,7 +255,7 @@ class CertificateControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/certificate/group/" + Util.currentDaysSinceEpoch() + "/" + (Util.currentDaysSinceEpoch() + 7))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);

View File

@ -104,7 +104,7 @@ class DeviceControllerTest {
@BeforeEach
void setup() throws Exception {
void setup() {
when(rateLimiters.getSmsDestinationLimiter()).thenReturn(rateLimiter);
when(rateLimiters.getVoiceDestinationLimiter()).thenReturn(rateLimiter);
when(rateLimiters.getVerifyLimiter()).thenReturn(rateLimiter);
@ -147,11 +147,11 @@ class DeviceControllerTest {
}
@Test
void validDeviceRegisterTest() throws Exception {
void validDeviceRegisterTest() {
VerificationCode deviceCode = resources.getJerseyTest()
.target("/v1/devices/provisioning/code")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(VerificationCode.class);
assertThat(deviceCode).isEqualTo(new VerificationCode(5678901));
@ -159,7 +159,7 @@ class DeviceControllerTest {
DeviceResponse response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.put(Entity.entity(new AccountAttributes(false, 1234, null,
null, true, null),
MediaType.APPLICATION_JSON_TYPE),
@ -172,22 +172,35 @@ class DeviceControllerTest {
}
@Test
void disabledDeviceRegisterTest() throws Exception {
void verifyDeviceTokenBadCredentials() {
final Response response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", "This is not a valid authorization header")
.put(Entity.entity(new AccountAttributes(false, 1234, null,
null, true, null),
MediaType.APPLICATION_JSON_TYPE));
assertEquals(401, response.getStatus());
}
@Test
void disabledDeviceRegisterTest() {
Response response = resources.getJerseyTest()
.target("/v1/devices/provisioning/code")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
void invalidDeviceRegisterTest() throws Exception {
void invalidDeviceRegisterTest() {
VerificationCode deviceCode = resources.getJerseyTest()
.target("/v1/devices/provisioning/code")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(VerificationCode.class);
assertThat(deviceCode).isEqualTo(new VerificationCode(5678901));
@ -195,7 +208,7 @@ class DeviceControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/devices/5678902")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.put(Entity.entity(new AccountAttributes(false, 1234, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -205,11 +218,11 @@ class DeviceControllerTest {
}
@Test
void oldDeviceRegisterTest() throws Exception {
void oldDeviceRegisterTest() {
Response response = resources.getJerseyTest()
.target("/v1/devices/1112223")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.put(Entity.entity(new AccountAttributes(false, 1234, null, null, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -219,11 +232,11 @@ class DeviceControllerTest {
}
@Test
void maxDevicesTest() throws Exception {
void maxDevicesTest() {
Response response = resources.getJerseyTest()
.target("/v1/devices/provisioning/code")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.get();
assertEquals(411, response.getStatus());
@ -231,11 +244,11 @@ class DeviceControllerTest {
}
@Test
void longNameTest() throws Exception {
void longNameTest() {
Response response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.put(Entity.entity(new AccountAttributes(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, true, null),
MediaType.APPLICATION_JSON_TYPE));
@ -245,13 +258,13 @@ class DeviceControllerTest {
@ParameterizedTest
@MethodSource
void deviceDowngradeCapabilitiesTest(final String userAgent, final boolean gv2, final boolean gv2_2, final boolean gv2_3, final int expectedStatus) throws Exception {
void deviceDowngradeCapabilitiesTest(final String userAgent, final boolean gv2, final boolean gv2_2, final boolean gv2_3, final int expectedStatus) {
DeviceCapabilities deviceCapabilities = new DeviceCapabilities(gv2, gv2_2, gv2_3, true, false, true, true, true);
AccountAttributes accountAttributes = new AccountAttributes(false, 1234, null, null, true, deviceCapabilities);
Response response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("User-Agent", userAgent)
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
@ -291,7 +304,7 @@ class DeviceControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("user-agent", "Signal-Android/4.68.3 Android/25")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
@ -302,7 +315,7 @@ class DeviceControllerTest {
response = resources.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
.header("user-agent", "Signal-Android/4.68.3 Android/25")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
@ -318,7 +331,7 @@ class DeviceControllerTest {
.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.42.8675309 Android/30")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409);
@ -329,7 +342,7 @@ class DeviceControllerTest {
.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.42.8675309 Android/30")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
@ -344,7 +357,7 @@ class DeviceControllerTest {
.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.42.8675309 Android/30")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(409);
@ -355,7 +368,7 @@ class DeviceControllerTest {
.getJerseyTest()
.target("/v1/devices/5678901")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getProvisioningAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.42.8675309 Android/30")
.put(Entity.entity(accountAttributes, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
@ -373,7 +386,7 @@ class DeviceControllerTest {
.getJerseyTest()
.target("/v1/devices/" + deviceId)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.42.8675309 Android/30")
.delete();

View File

@ -55,7 +55,7 @@ class DirectoryControllerTest {
resources.getJerseyTest()
.target("/v1/directory/feedback-v3/ok")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.json("{\"reason\": \"test reason\"}"));
assertThat(response.getStatusInfo().getFamily()).isEqualTo(Family.SUCCESSFUL);
}
@ -66,7 +66,7 @@ class DirectoryControllerTest {
resources.getJerseyTest()
.target("/v1/directory/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(ExternalServiceCredentials.class);
assertThat(token.getUsername()).isEqualTo(validCredentials.getUsername());
assertThat(token.getPassword()).isEqualTo(validCredentials.getPassword());
@ -78,7 +78,7 @@ class DirectoryControllerTest {
resources.getJerseyTest()
.target("/v1/directory/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
@ -91,7 +91,7 @@ class DirectoryControllerTest {
.target("/v1/directory/tokens/")
.request()
.header("Authorization",
AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER,
AuthHelper.getAuthHeader(AuthHelper.VALID_UUID,
AuthHelper.VALID_PASSWORD))
.header("X-Forwarded-For", "192.168.1.1, 1.1.1.1")
.put(Entity.entity(Collections.emptyMap(), MediaType.APPLICATION_JSON_TYPE));

View File

@ -85,7 +85,7 @@ public class DonationControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/donation/authorize-apple-pay")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(Entity.entity(request, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
@ -116,7 +116,7 @@ public class DonationControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/donation/authorize-apple-pay")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(Entity.entity(request, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(422);

View File

@ -8,7 +8,6 @@ package org.whispersystems.textsecuregcm.tests.controllers;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
@ -42,8 +41,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
@ -74,12 +71,12 @@ class KeysControllerTest {
private static final String EXISTS_NUMBER = "+14152222222";
private static final UUID EXISTS_UUID = UUID.randomUUID();
private static String NOT_EXISTS_NUMBER = "+14152222220";
private static UUID NOT_EXISTS_UUID = UUID.randomUUID();
private static final String NOT_EXISTS_NUMBER = "+14152222220";
private static final UUID NOT_EXISTS_UUID = UUID.randomUUID();
private static int SAMPLE_REGISTRATION_ID = 999;
private static int SAMPLE_REGISTRATION_ID2 = 1002;
private static int SAMPLE_REGISTRATION_ID4 = 1555;
private static final int SAMPLE_REGISTRATION_ID = 999;
private static final int SAMPLE_REGISTRATION_ID2 = 1002;
private static final int SAMPLE_REGISTRATION_ID4 = 1555;
private final PreKey SAMPLE_KEY = new PreKey(1234, "test1");
private final PreKey SAMPLE_KEY2 = new PreKey(5667, "test3");
@ -158,13 +155,9 @@ class KeysControllerTest {
when(accounts.get(EXISTS_NUMBER)).thenReturn(Optional.of(existsAccount));
when(accounts.get(EXISTS_UUID)).thenReturn(Optional.of(existsAccount));
when(accounts.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(EXISTS_NUMBER)))).thenReturn(Optional.of(existsAccount));
when(accounts.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(EXISTS_UUID)))).thenReturn(Optional.of(existsAccount));
when(accounts.get(NOT_EXISTS_NUMBER)).thenReturn(Optional.<Account>empty());
when(accounts.get(NOT_EXISTS_NUMBER)).thenReturn(Optional.empty());
when(accounts.get(NOT_EXISTS_UUID)).thenReturn(Optional.empty());
when(accounts.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(NOT_EXISTS_NUMBER)))).thenReturn(Optional.empty());
when(accounts.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(NOT_EXISTS_UUID)))).thenReturn(Optional.empty());
when(rateLimiters.getPreKeysLimiter()).thenReturn(rateLimiter);
@ -195,26 +188,12 @@ class KeysControllerTest {
}
@Test
void validKeyStatusTestByNumberV2() throws Exception {
void validKeyStatusTest() {
PreKeyCount result = resources.getJerseyTest()
.target("/v2/keys")
.request()
.header("Authorization",
AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(PreKeyCount.class);
assertThat(result.getCount()).isEqualTo(4);
verify(keysDynamoDb).getCount(eq(AuthHelper.VALID_ACCOUNT), eq(1L));
}
@Test
void validKeyStatusTestByUuidV2() throws Exception {
PreKeyCount result = resources.getJerseyTest()
.target("/v2/keys")
.request()
.header("Authorization",
AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(PreKeyCount.class);
assertThat(result.getCount()).isEqualTo(4);
@ -224,11 +203,11 @@ class KeysControllerTest {
@Test
void getSignedPreKeyV2ByNumber() throws Exception {
void getSignedPreKeyV2() {
SignedPreKey result = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(SignedPreKey.class);
assertThat(result.getSignature()).isEqualTo(VALID_DEVICE_SIGNED_KEY.getSignature());
@ -237,40 +216,12 @@ class KeysControllerTest {
}
@Test
void getSignedPreKeyV2ByUuid() throws Exception {
SignedPreKey result = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.get(SignedPreKey.class);
assertThat(result.getSignature()).isEqualTo(VALID_DEVICE_SIGNED_KEY.getSignature());
assertThat(result.getKeyId()).isEqualTo(VALID_DEVICE_SIGNED_KEY.getKeyId());
assertThat(result.getPublicKey()).isEqualTo(VALID_DEVICE_SIGNED_KEY.getPublicKey());
}
@Test
void putSignedPreKeyV2ByNumber() throws Exception {
SignedPreKey test = new SignedPreKey(9999, "fooozzz", "baaarzzz");
Response response = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(test, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(204);
verify(AuthHelper.VALID_DEVICE).setSignedPreKey(eq(test));
verify(accounts).updateDevice(eq(AuthHelper.VALID_ACCOUNT), anyLong(), any());
}
@Test
void putSignedPreKeyV2ByUuid() throws Exception {
void putSignedPreKeyV2() {
SignedPreKey test = new SignedPreKey(9998, "fooozzz", "baaarzzz");
Response response = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(test, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(204);
@ -281,73 +232,23 @@ class KeysControllerTest {
@Test
void disabledPutSignedPreKeyV2ByNumber() throws Exception {
void disabledPutSignedPreKeyV2() {
SignedPreKey test = new SignedPreKey(9999, "fooozzz", "baaarzzz");
Response response = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(test, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
void disabledPutSignedPreKeyV2ByUuid() throws Exception {
SignedPreKey test = new SignedPreKey(9999, "fooozzz", "baaarzzz");
Response response = resources.getJerseyTest()
.target("/v2/keys/signed")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID.toString(), AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(test, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(401);
}
@Test
void validSingleRequestTestV2ByNumber() throws Exception {
PreKeyResponse result = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(PreKeyResponse.class);
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
assertThat(result.getDevicesCount()).isEqualTo(1);
assertThat(result.getDevice(1).getPreKey().getKeyId()).isEqualTo(SAMPLE_KEY.getKeyId());
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
verify(keysDynamoDb).take(eq(existsAccount), eq(1L));
verifyNoMoreInteractions(keysDynamoDb);
}
@Test
void validSingleRequestTestV2ByUuid() throws Exception {
void validSingleRequestTestV2() {
PreKeyResponse result = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.get(PreKeyResponse.class);
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
assertThat(result.getDevicesCount()).isEqualTo(1);
assertThat(result.getDevice(1).getPreKey().getKeyId()).isEqualTo(SAMPLE_KEY.getKeyId());
assertThat(result.getDevice(1).getPreKey().getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
assertThat(result.getDevice(1).getSignedPreKey()).isEqualTo(existsAccount.getDevice(1).get().getSignedPreKey());
verify(keysDynamoDb).take(eq(existsAccount), eq(1L));
verifyNoMoreInteractions(keysDynamoDb);
}
@Test
void testUnidentifiedRequestByNumber() throws Exception {
PreKeyResponse result = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
.request()
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("1337".getBytes()))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(PreKeyResponse.class);
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
@ -361,9 +262,9 @@ class KeysControllerTest {
}
@Test
void testUnidentifiedRequestByUuid() throws Exception {
void testUnidentifiedRequest() {
PreKeyResponse result = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_UUID.toString()))
.target(String.format("/v2/keys/%s/1", EXISTS_UUID))
.request()
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("1337".getBytes()))
.get(PreKeyResponse.class);
@ -384,7 +285,7 @@ class KeysControllerTest {
when(existsAccount.getDevices()).thenReturn(Collections.emptySet());
Response result = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/*", EXISTS_UUID.toString()))
.target(String.format("/v2/keys/%s/*", EXISTS_UUID))
.request()
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("1337".getBytes()))
.get();
@ -394,9 +295,9 @@ class KeysControllerTest {
}
@Test
void testUnauthorizedUnidentifiedRequest() throws Exception {
void testUnauthorizedUnidentifiedRequest() {
Response response = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
.target(String.format("/v2/keys/%s/1", EXISTS_UUID))
.request()
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("9999".getBytes()))
.get();
@ -406,9 +307,9 @@ class KeysControllerTest {
}
@Test
void testMalformedUnidentifiedRequest() throws Exception {
void testMalformedUnidentifiedRequest() {
Response response = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
.target(String.format("/v2/keys/%s/1", EXISTS_UUID))
.request()
.header(OptionalAccess.UNIDENTIFIED, "$$$$$$$$$")
.get();
@ -419,61 +320,11 @@ class KeysControllerTest {
@Test
void validMultiRequestTestV2ByNumber() throws Exception {
PreKeyResponse results = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/*", EXISTS_NUMBER))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(PreKeyResponse.class);
assertThat(results.getDevicesCount()).isEqualTo(3);
assertThat(results.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
PreKey signedPreKey = results.getDevice(1).getSignedPreKey();
PreKey preKey = results.getDevice(1).getPreKey();
long registrationId = results.getDevice(1).getRegistrationId();
long deviceId = results.getDevice(1).getDeviceId();
assertThat(preKey.getKeyId()).isEqualTo(SAMPLE_KEY.getKeyId());
assertThat(preKey.getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey());
assertThat(registrationId).isEqualTo(SAMPLE_REGISTRATION_ID);
assertThat(signedPreKey.getKeyId()).isEqualTo(SAMPLE_SIGNED_KEY.getKeyId());
assertThat(signedPreKey.getPublicKey()).isEqualTo(SAMPLE_SIGNED_KEY.getPublicKey());
assertThat(deviceId).isEqualTo(1);
signedPreKey = results.getDevice(2).getSignedPreKey();
preKey = results.getDevice(2).getPreKey();
registrationId = results.getDevice(2).getRegistrationId();
deviceId = results.getDevice(2).getDeviceId();
assertThat(preKey.getKeyId()).isEqualTo(SAMPLE_KEY2.getKeyId());
assertThat(preKey.getPublicKey()).isEqualTo(SAMPLE_KEY2.getPublicKey());
assertThat(registrationId).isEqualTo(SAMPLE_REGISTRATION_ID2);
assertThat(signedPreKey.getKeyId()).isEqualTo(SAMPLE_SIGNED_KEY2.getKeyId());
assertThat(signedPreKey.getPublicKey()).isEqualTo(SAMPLE_SIGNED_KEY2.getPublicKey());
assertThat(deviceId).isEqualTo(2);
signedPreKey = results.getDevice(4).getSignedPreKey();
preKey = results.getDevice(4).getPreKey();
registrationId = results.getDevice(4).getRegistrationId();
deviceId = results.getDevice(4).getDeviceId();
assertThat(preKey.getKeyId()).isEqualTo(SAMPLE_KEY4.getKeyId());
assertThat(preKey.getPublicKey()).isEqualTo(SAMPLE_KEY4.getPublicKey());
assertThat(registrationId).isEqualTo(SAMPLE_REGISTRATION_ID4);
assertThat(signedPreKey).isNull();
assertThat(deviceId).isEqualTo(4);
verify(keysDynamoDb).take(eq(existsAccount));
verifyNoMoreInteractions(keysDynamoDb);
}
@Test
void validMultiRequestTestV2ByUuid() throws Exception {
void validMultiRequestTestV2() {
PreKeyResponse results = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/*", EXISTS_UUID.toString()))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(PreKeyResponse.class);
assertThat(results.getDevicesCount()).isEqualTo(3);
@ -520,41 +371,41 @@ class KeysControllerTest {
@Test
void invalidRequestTestV2() throws Exception {
void invalidRequestTestV2() {
Response response = resources.getJerseyTest()
.target(String.format("/v2/keys/%s", NOT_EXISTS_NUMBER))
.target(String.format("/v2/keys/%s", NOT_EXISTS_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get();
assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(404);
}
@Test
void anotherInvalidRequestTestV2() throws Exception {
void anotherInvalidRequestTestV2() {
Response response = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/22", EXISTS_NUMBER))
.target(String.format("/v2/keys/%s/22", EXISTS_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get();
assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(404);
}
@Test
void unauthorizedRequestTestV2() throws Exception {
void unauthorizedRequestTestV2() {
Response response =
resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
.target(String.format("/v2/keys/%s/1", EXISTS_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.get();
assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(401);
response =
resources.getJerseyTest()
.target(String.format("/v2/keys/%s/1", EXISTS_NUMBER))
.target(String.format("/v2/keys/%s/1", EXISTS_UUID))
.request()
.get();
@ -562,7 +413,7 @@ class KeysControllerTest {
}
@Test
void putKeysTestV2() throws Exception {
void putKeysTestV2() {
final PreKey preKey = new PreKey(31337, "foobar");
final SignedPreKey signedPreKey = new SignedPreKey(31338, "foobaz", "myvalidsig");
final String identityKey = "barbar";
@ -577,7 +428,7 @@ class KeysControllerTest {
resources.getJerseyTest()
.target("/v2/keys")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(preKeyState, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(204);
@ -596,7 +447,7 @@ class KeysControllerTest {
}
@Test
void disabledPutKeysTestV2() throws Exception {
void disabledPutKeysTestV2() {
final PreKey preKey = new PreKey(31337, "foobar");
final SignedPreKey signedPreKey = new SignedPreKey(31338, "foobaz", "myvalidsig");
final String identityKey = "barbar";
@ -611,7 +462,7 @@ class KeysControllerTest {
resources.getJerseyTest()
.target("/v2/keys")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(preKeyState, MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(204);
@ -657,7 +508,7 @@ class KeysControllerTest {
result = resources.getJerseyTest()
.target(String.format("/v2/keys/%s/*", EXISTS_UUID.toString()))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.1.2 Android/30")
.get();

View File

@ -19,7 +19,6 @@ import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@ -66,9 +65,7 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.stubbing.Answer;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
@ -156,22 +153,26 @@ class MessageControllerTest {
.build();
@BeforeEach
void setup() throws Exception {
Set<Device> singleDeviceList = new HashSet<Device>() {{
void setup() {
Set<Device> singleDeviceList = new HashSet<>() {{
add(new Device(1, null, "foo", "bar",
"isgcm", null, null, false, 111, new SignedPreKey(333, "baz", "boop"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, false, false, true, true, false,
"isgcm", null, null, false, 111, new SignedPreKey(333, "baz", "boop"), System.currentTimeMillis(),
System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, false, false, true, true, false,
false, false)));
}};
Set<Device> multiDeviceList = new HashSet<Device>() {{
Set<Device> multiDeviceList = new HashSet<>() {{
add(new Device(1, null, "foo", "bar",
"isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, false, false, true, false, false,
"isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(),
System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, false, false, true, false, false,
false, false)));
add(new Device(2, null, "foo", "bar",
"isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, false, false, true, false, false,
"isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(),
System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, false, false, true, false, false,
false, false)));
add(new Device(3, null, "foo", "bar",
"isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(false, false, false, false, false, false,
"isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31),
System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(false, false, false, false, false, false,
false, false)));
}};
@ -179,12 +180,9 @@ class MessageControllerTest {
Account multiDeviceAccount = new Account(MULTI_DEVICE_RECIPIENT, MULTI_DEVICE_UUID, multiDeviceList, "1234".getBytes());
internationalAccount = new Account(INTERNATIONAL_RECIPIENT, INTERNATIONAL_UUID, singleDeviceList, "1234".getBytes());
when(accountsManager.get(eq(SINGLE_DEVICE_RECIPIENT))).thenReturn(Optional.of(singleDeviceAccount));
when(accountsManager.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(SINGLE_DEVICE_RECIPIENT)))).thenReturn(Optional.of(singleDeviceAccount));
when(accountsManager.get(eq(MULTI_DEVICE_RECIPIENT))).thenReturn(Optional.of(multiDeviceAccount));
when(accountsManager.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(MULTI_DEVICE_RECIPIENT)))).thenReturn(Optional.of(multiDeviceAccount));
when(accountsManager.get(INTERNATIONAL_RECIPIENT)).thenReturn(Optional.of(internationalAccount));
when(accountsManager.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(INTERNATIONAL_RECIPIENT)))).thenReturn(Optional.of(internationalAccount));
when(accountsManager.get(eq(SINGLE_DEVICE_UUID))).thenReturn(Optional.of(singleDeviceAccount));
when(accountsManager.get(eq(MULTI_DEVICE_UUID))).thenReturn(Optional.of(multiDeviceAccount));
when(accountsManager.get(INTERNATIONAL_UUID)).thenReturn(Optional.of(internationalAccount));
when(rateLimiters.getMessagesLimiter()).thenReturn(rateLimiter);
@ -221,9 +219,9 @@ class MessageControllerTest {
void testSendFromDisabledAccount() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -234,9 +232,9 @@ class MessageControllerTest {
void testSingleDeviceCurrent() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -253,9 +251,9 @@ class MessageControllerTest {
void testNullMessageInList() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_null_message_in_list.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -283,9 +281,9 @@ class MessageControllerTest {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", INTERNATIONAL_RECIPIENT))
.target(String.format("/v1/messages/%s", INTERNATIONAL_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.header("X-Forwarded-For", senderHost)
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -333,9 +331,9 @@ class MessageControllerTest {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", INTERNATIONAL_RECIPIENT))
.target(String.format("/v1/messages/%s", INTERNATIONAL_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.6.4 Android/30")
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -363,9 +361,9 @@ class MessageControllerTest {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", INTERNATIONAL_RECIPIENT))
.target(String.format("/v1/messages/%s", INTERNATIONAL_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.header("User-Agent", "Signal-Android/5.1.2 Android/30")
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -385,7 +383,7 @@ class MessageControllerTest {
void testSingleDeviceCurrentUnidentified() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_UUID))
.request()
.header(OptionalAccess.UNIDENTIFIED, Base64.getEncoder().encodeToString("1234".getBytes()))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
@ -405,7 +403,7 @@ class MessageControllerTest {
void testSendBadAuth() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", SINGLE_DEVICE_UUID))
.request()
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -417,9 +415,9 @@ class MessageControllerTest {
void testMultiDeviceMissing() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", MULTI_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -436,9 +434,9 @@ class MessageControllerTest {
void testMultiDeviceExtra() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", MULTI_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_extra_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -455,9 +453,9 @@ class MessageControllerTest {
void testMultiDevice() throws Exception {
Response response =
resources.getJerseyTest()
.target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT))
.target(String.format("/v1/messages/%s", MULTI_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_multi_device.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -469,9 +467,9 @@ class MessageControllerTest {
@Test
void testRegistrationIdMismatch() throws Exception {
Response response =
resources.getJerseyTest().target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT))
resources.getJerseyTest().target(String.format("/v1/messages/%s", MULTI_DEVICE_UUID))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_registration_id.json"), IncomingMessageList.class),
MediaType.APPLICATION_JSON_TYPE));
@ -506,7 +504,7 @@ class MessageControllerTest {
OutgoingMessageEntityList response =
resources.getJerseyTest().target("/v1/messages/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.accept(MediaType.APPLICATION_JSON_TYPE)
.get(OutgoingMessageEntityList.class);
@ -543,7 +541,7 @@ class MessageControllerTest {
Response response =
resources.getJerseyTest().target("/v1/messages/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.accept(MediaType.APPLICATION_JSON_TYPE)
.get();
@ -573,7 +571,7 @@ class MessageControllerTest {
Response response = resources.getJerseyTest()
.target(String.format("/v1/messages/uuid/%s", uuid1))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.delete();
assertThat("Good Response Code", response.getStatus(), is(equalTo(204)));
@ -582,7 +580,7 @@ class MessageControllerTest {
response = resources.getJerseyTest()
.target(String.format("/v1/messages/uuid/%s", uuid2))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID.toString(), AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.delete();
assertThat("Good Response Code", response.getStatus(), is(equalTo(204)));
@ -591,7 +589,7 @@ class MessageControllerTest {
response = resources.getJerseyTest()
.target(String.format("/v1/messages/uuid/%s", uuid3))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.delete();
assertThat("Good Response Code", response.getStatus(), is(equalTo(204)));
@ -609,7 +607,7 @@ class MessageControllerTest {
resources.getJerseyTest()
.target(String.format("/v1/messages/report/%s/%s", senderNumber, messageGuid))
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.post(null);
assertThat(response.getStatus(), is(equalTo(202)));

View File

@ -61,7 +61,7 @@ class PaymentsControllerTest {
resources.getJerseyTest()
.target("/v1/payments/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(ExternalServiceCredentials.class);
assertThat(token.getUsername()).isEqualTo(validCredentials.getUsername());
@ -74,7 +74,7 @@ class PaymentsControllerTest {
resources.getJerseyTest()
.target("/v1/payments/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.INVVALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.INVALID_UUID, AuthHelper.INVALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
@ -86,7 +86,7 @@ class PaymentsControllerTest {
resources.getJerseyTest()
.target("/v1/payments/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
}
@ -97,7 +97,7 @@ class PaymentsControllerTest {
resources.getJerseyTest()
.target("/v1/payments/conversions")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(CurrencyConversionEntityList.class);

View File

@ -7,7 +7,6 @@ package org.whispersystems.textsecuregcm.tests.controllers;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
@ -35,12 +34,10 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.signal.zkgroup.InvalidInputException;
import org.signal.zkgroup.profiles.ProfileKey;
import org.signal.zkgroup.profiles.ProfileKeyCommitment;
import org.signal.zkgroup.profiles.ServerZkProfileOperations;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
@ -107,7 +104,7 @@ class ProfileControllerTest {
.build();
@BeforeEach
void setup() throws Exception {
void setup() {
reset(s3client);
AccountsHelper.setupMockUpdate(accountsManager);
@ -150,11 +147,9 @@ class ProfileControllerTest {
when(accountsManager.get(AuthHelper.VALID_UUID_TWO)).thenReturn(Optional.of(profileAccount));
when(usernamesManager.get(AuthHelper.VALID_UUID_TWO)).thenReturn(Optional.of("n00bkiller"));
when(usernamesManager.get("n00bkiller")).thenReturn(Optional.of(AuthHelper.VALID_UUID_TWO));
when(accountsManager.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(AuthHelper.VALID_NUMBER_TWO)))).thenReturn(Optional.of(profileAccount));
when(accountsManager.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(AuthHelper.VALID_UUID_TWO)))).thenReturn(Optional.of(profileAccount));
when(accountsManager.get(AuthHelper.VALID_NUMBER)).thenReturn(Optional.of(capabilitiesAccount));
when(accountsManager.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(AuthHelper.VALID_NUMBER)))).thenReturn(Optional.of(capabilitiesAccount));
when(accountsManager.get(AuthHelper.VALID_UUID)).thenReturn(Optional.of(capabilitiesAccount));
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(
@ -177,7 +172,7 @@ class ProfileControllerTest {
Profile profile= resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getIdentityKey()).isEqualTo("bar");
@ -185,38 +180,17 @@ class ProfileControllerTest {
assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getUsername()).isEqualTo("n00bkiller");
verify(accountsManager, times(1)).get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(AuthHelper.VALID_UUID_TWO)));
verify(accountsManager).get(AuthHelper.VALID_UUID_TWO);
verify(usernamesManager, times(1)).get(eq(AuthHelper.VALID_UUID_TWO));
verify(rateLimiter, times(1)).validate(AuthHelper.VALID_UUID);
}
@Test
void testProfileGetByNumber() throws RateLimitExceededException {
Profile profile= resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getIdentityKey()).isEqualTo("bar");
assertThat(profile.getName()).isEqualTo("baz");
assertThat(profile.getAvatar()).isEqualTo("profiles/bang");
assertThat(profile.getCapabilities().isGv2()).isFalse();
assertThat(profile.getCapabilities().isGv1Migration()).isFalse();
assertThat(profile.getUsername()).isNull();
assertThat(profile.getUuid()).isNull();
verify(accountsManager, times(1)).get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(AuthHelper.VALID_NUMBER_TWO)));
verifyNoMoreInteractions(usernamesManager);
verify(rateLimiter, times(1)).validate(AuthHelper.VALID_UUID);
}
@Test
void testProfileGetByUsername() throws RateLimitExceededException {
Profile profile= resources.getJerseyTest()
.target("/v1/profile/username/n00bkiller")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getIdentityKey()).isEqualTo("bar");
@ -233,7 +207,7 @@ class ProfileControllerTest {
@Test
void testProfileGetUnauthorized() {
Response response = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO)
.request()
.get();
@ -256,7 +230,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/username/n00bkillerzzzzz")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(404);
@ -269,9 +243,9 @@ class ProfileControllerTest {
@Test
void testProfileGetDisabled() {
Response response = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_NUMBER, AuthHelper.DISABLED_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.DISABLED_UUID, AuthHelper.DISABLED_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);
@ -280,9 +254,9 @@ class ProfileControllerTest {
@Test
void testProfileCapabilities() {
Profile profile= resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER)
.target("/v1/profile/" + AuthHelper.VALID_UUID)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getCapabilities().isGv2()).isTrue();
@ -292,9 +266,9 @@ class ProfileControllerTest {
profile = resources
.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_NUMBER_TWO)
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO)
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.get(Profile.class);
assertThat(profile.getCapabilities().isGv2()).isFalse();
@ -308,7 +282,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/name/123456789012345678901234567890123456789012345678901234567890123456789012")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(204);
@ -321,7 +295,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/name/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(204);
@ -334,7 +308,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/name/1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.text(""));
assertThat(response.getStatus()).isEqualTo(400);
@ -350,7 +324,7 @@ class ProfileControllerTest {
ProfileAvatarUploadAttributes uploadAttributes = resources.getJerseyTest()
.target("/v1/profile/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", null, null,
null, true), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
@ -375,7 +349,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion", "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", null, null,
null, true), MediaType.APPLICATION_JSON_TYPE));
@ -391,7 +365,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.put(Entity.entity(new CreateProfileRequest(commitment, "anotherversion", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", null, null,
null, false), MediaType.APPLICATION_JSON_TYPE));
@ -423,7 +397,7 @@ class ProfileControllerTest {
ProfileAvatarUploadAttributes uploadAttributes= resources.getJerseyTest()
.target("/v1/profile/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.put(Entity.entity(new CreateProfileRequest(commitment, "validversion", "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678", null, null,
null, true), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
@ -449,7 +423,7 @@ class ProfileControllerTest {
resources.getJerseyTest()
.target("/v1/profile/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_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, null, null, null, true), MediaType.APPLICATION_JSON_TYPE), ProfileAvatarUploadAttributes.class);
ArgumentCaptor<VersionedProfile> profileArgumentCaptor = ArgumentCaptor.forClass(VersionedProfile.class);
@ -479,7 +453,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_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, text, null, false), MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
@ -520,7 +494,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.put(Entity.entity(new CreateProfileRequest(commitment, "yetanotherversion", name, null, null, paymentAddress, false), MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
@ -558,7 +532,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.put(Entity.entity(new CreateProfileRequest(commitment, "yetanotherversion", name, null, null, paymentAddress, false), MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(403);
@ -572,7 +546,7 @@ class ProfileControllerTest {
Profile profile = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getIdentityKey()).isEqualTo("bar");
@ -607,7 +581,7 @@ class ProfileControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/profile")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.put(Entity.entity(new CreateProfileRequest(commitment, "someversion", name, null, null, paymentAddress, false), MediaType.APPLICATION_JSON_TYPE));
assertThat(response.getStatus()).isEqualTo(200);
@ -623,7 +597,7 @@ class ProfileControllerTest {
Profile profile = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getPaymentAddress()).isEqualTo("paymentaddress");
@ -631,7 +605,7 @@ class ProfileControllerTest {
profile = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getPaymentAddress()).isEqualTo("paymentaddress");
@ -639,7 +613,7 @@ class ProfileControllerTest {
profile = resources.getJerseyTest()
.target("/v1/profile/" + AuthHelper.VALID_UUID_TWO + "/validversion")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(Profile.class);
assertThat(profile.getPaymentAddress()).isNull();
}

View File

@ -87,7 +87,7 @@ class RemoteConfigControllerTest {
UserRemoteConfigList configuration = resources.getJerseyTest()
.target("/v1/config/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(UserRemoteConfigList.class);
verify(remoteConfigsManager, times(1)).getAll();
@ -121,7 +121,7 @@ class RemoteConfigControllerTest {
UserRemoteConfigList configuration = resources.getJerseyTest()
.target("/v1/config/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID_TWO, AuthHelper.VALID_PASSWORD_TWO))
.get(UserRemoteConfigList.class);
verify(remoteConfigsManager, times(1)).getAll();
@ -178,7 +178,7 @@ class RemoteConfigControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/config/")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.INVALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);

View File

@ -43,7 +43,7 @@ class SecureStorageControllerTest {
ExternalServiceCredentials credentials = resources.getJerseyTest()
.target("/v1/storage/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(ExternalServiceCredentials.class);
assertThat(credentials.getPassword()).isNotEmpty();
@ -55,7 +55,7 @@ class SecureStorageControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/storage/auth")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.INVVALID_NUMBER, AuthHelper.INVALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.INVALID_UUID, AuthHelper.INVALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(401);

View File

@ -56,7 +56,7 @@ class StickerControllerTest {
StickerPackFormUploadAttributes attributes = resources.getJerseyTest()
.target("/v1/sticker/pack/form/10")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get(StickerPackFormUploadAttributes.class);
assertThat(attributes.getPackId()).isNotNull();
@ -94,7 +94,7 @@ class StickerControllerTest {
Response response = resources.getJerseyTest()
.target("/v1/sticker/pack/form/202")
.request()
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD))
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
.get();
assertThat(response.getStatus()).isEqualTo(400);

View File

@ -5,7 +5,6 @@
package org.whispersystems.textsecuregcm.tests.util;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
@ -21,9 +20,7 @@ import java.util.Base64;
import java.util.Optional;
import java.util.Random;
import java.util.UUID;
import org.mockito.ArgumentMatcher;
import org.whispersystems.textsecuregcm.auth.AccountAuthenticator;
import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
@ -46,7 +43,7 @@ public class AuthHelper {
public static final UUID VALID_UUID_TWO = UUID.randomUUID();
public static final String VALID_PASSWORD_TWO = "baz";
public static final String INVVALID_NUMBER = "+14151111111";
public static final String INVALID_NUMBER = "+14151111111";
public static final UUID INVALID_UUID = UUID.randomUUID();
public static final String INVALID_PASSWORD = "bar";
@ -142,35 +139,15 @@ public class AuthHelper {
when(ACCOUNTS_MANAGER.get(VALID_NUMBER)).thenReturn(Optional.of(VALID_ACCOUNT));
when(ACCOUNTS_MANAGER.get(VALID_UUID)).thenReturn(Optional.of(VALID_ACCOUNT));
when(ACCOUNTS_MANAGER.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber() && identifier.getNumber().equals(VALID_NUMBER)))).thenReturn(Optional.of(VALID_ACCOUNT));
when(ACCOUNTS_MANAGER.get(argThat((ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid() && identifier.getUuid().equals(VALID_UUID)))).thenReturn(Optional.of(VALID_ACCOUNT));
when(ACCOUNTS_MANAGER.get(VALID_NUMBER_TWO)).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
when(ACCOUNTS_MANAGER.get(VALID_UUID_TWO)).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
when(ACCOUNTS_MANAGER.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber()
&& identifier.getNumber().equals(VALID_NUMBER_TWO)))).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
when(ACCOUNTS_MANAGER.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid()
&& identifier.getUuid().equals(VALID_UUID_TWO)))).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
when(ACCOUNTS_MANAGER.get(DISABLED_NUMBER)).thenReturn(Optional.of(DISABLED_ACCOUNT));
when(ACCOUNTS_MANAGER.get(DISABLED_UUID)).thenReturn(Optional.of(DISABLED_ACCOUNT));
when(ACCOUNTS_MANAGER.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber()
&& identifier.getNumber().equals(DISABLED_NUMBER)))).thenReturn(Optional.of(DISABLED_ACCOUNT));
when(ACCOUNTS_MANAGER.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid()
&& identifier.getUuid().equals(DISABLED_UUID)))).thenReturn(Optional.of(DISABLED_ACCOUNT));
when(ACCOUNTS_MANAGER.get(UNDISCOVERABLE_NUMBER)).thenReturn(Optional.of(UNDISCOVERABLE_ACCOUNT));
when(ACCOUNTS_MANAGER.get(UNDISCOVERABLE_UUID)).thenReturn(Optional.of(UNDISCOVERABLE_ACCOUNT));
when(ACCOUNTS_MANAGER.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber()
&& identifier.getNumber().equals(UNDISCOVERABLE_NUMBER)))).thenReturn(Optional.of(UNDISCOVERABLE_ACCOUNT));
when(ACCOUNTS_MANAGER.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid()
&& identifier.getUuid().equals(UNDISCOVERABLE_UUID)))).thenReturn(Optional.of(UNDISCOVERABLE_ACCOUNT));
AccountsHelper.setupMockUpdateForAuthHelper(ACCOUNTS_MANAGER);
@ -187,8 +164,16 @@ public class AuthHelper {
DisabledPermittedAuthenticatedAccount.class, disabledPermittedAccountAuthFilter));
}
public static String getAuthHeader(String number, String password) {
return "Basic " + Base64.getEncoder().encodeToString((number + ":" + password).getBytes());
public static String getAuthHeader(UUID uuid, String password) {
return getAuthHeader(uuid.toString(), password);
}
public static String getProvisioningAuthHeader(String number, String password) {
return getAuthHeader(number, password);
}
private static String getAuthHeader(String identifier, String password) {
return "Basic " + Base64.getEncoder().encodeToString((identifier + ":" + password).getBytes());
}
public static String getUnidentifiedAccessHeader(byte[] key) {
@ -220,7 +205,7 @@ public class AuthHelper {
}
public String getAuthHeader() {
return AuthHelper.getAuthHeader(number, password);
return AuthHelper.getAuthHeader(uuid, password);
}
private void setup(final AccountsManager accountsManager) {
@ -237,12 +222,6 @@ public class AuthHelper {
when(account.isEnabled()).thenReturn(true);
when(accountsManager.get(number)).thenReturn(Optional.of(account));
when(accountsManager.get(uuid)).thenReturn(Optional.of(account));
when(accountsManager.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasNumber()
&& identifier.getNumber().equals(number)))).thenReturn(Optional.of(account));
when(accountsManager.get(argThat(
(ArgumentMatcher<AmbiguousIdentifier>) identifier -> identifier != null && identifier.hasUuid()
&& identifier.getUuid().equals(uuid)))).thenReturn(Optional.of(account));
}
}