Add a counter for cases where clients use both an authenticated identity and UAK when fetching profiles
This commit is contained in:
parent
144c4c9223
commit
f62f79c95c
|
@ -97,6 +97,7 @@ import org.whispersystems.websocket.auth.Mutable;
|
|||
import org.whispersystems.websocket.auth.ReadOnly;
|
||||
import software.amazon.awssdk.services.s3.S3Client;
|
||||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
@Path("/v1/profile")
|
||||
|
@ -123,6 +124,7 @@ public class ProfileController {
|
|||
private static final String EXPIRING_PROFILE_KEY_CREDENTIAL_TYPE = "expiringProfileKey";
|
||||
|
||||
private static final String VERSION_NOT_FOUND_COUNTER_NAME = name(ProfileController.class, "versionNotFound");
|
||||
private static final String DUPLICATE_AUTHENTICATION_COUNTER_NAME = name(ProfileController.class, "duplicateAuthentication");
|
||||
|
||||
public ProfileController(
|
||||
Clock clock,
|
||||
|
@ -230,11 +232,12 @@ public class ProfileController {
|
|||
@HeaderParam(HeaderUtils.UNIDENTIFIED_ACCESS_KEY) Optional<Anonymous> accessKey,
|
||||
@Context ContainerRequestContext containerRequestContext,
|
||||
@PathParam("identifier") AciServiceIdentifier accountIdentifier,
|
||||
@PathParam("version") String version)
|
||||
@PathParam("version") String version,
|
||||
@HeaderParam(HttpHeaders.USER_AGENT) String userAgent)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
final Optional<Account> maybeRequester = auth.map(AuthenticatedDevice::getAccount);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, accountIdentifier);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, accountIdentifier, "getVersionedProfile", userAgent);
|
||||
|
||||
return buildVersionedProfileResponse(targetAccount,
|
||||
version,
|
||||
|
@ -253,7 +256,8 @@ public class ProfileController {
|
|||
@PathParam("identifier") AciServiceIdentifier accountIdentifier,
|
||||
@PathParam("version") String version,
|
||||
@PathParam("credentialRequest") String credentialRequest,
|
||||
@QueryParam("credentialType") String credentialType)
|
||||
@QueryParam("credentialType") String credentialType,
|
||||
@HeaderParam(HttpHeaders.USER_AGENT) String userAgent)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
if (!EXPIRING_PROFILE_KEY_CREDENTIAL_TYPE.equals(credentialType)) {
|
||||
|
@ -261,7 +265,7 @@ public class ProfileController {
|
|||
}
|
||||
|
||||
final Optional<Account> maybeRequester = auth.map(AuthenticatedDevice::getAccount);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, accountIdentifier);
|
||||
final Account targetAccount = verifyPermissionToReceiveProfile(maybeRequester, accessKey, accountIdentifier, "credentialRequest", userAgent);
|
||||
final boolean isSelf = maybeRequester.map(requester -> ProfileHelper.isSelfProfileRequest(requester.getUuid(), accountIdentifier)).orElse(false);
|
||||
|
||||
return buildExpiringProfileKeyCredentialProfileResponse(targetAccount,
|
||||
|
@ -303,7 +307,7 @@ public class ProfileController {
|
|||
}
|
||||
} else {
|
||||
targetAccount = verifyPermissionToReceiveProfile(
|
||||
maybeRequester, accessKey.filter(ignored -> identifier.identityType() == IdentityType.ACI), identifier);
|
||||
maybeRequester, accessKey.filter(ignored -> identifier.identityType() == IdentityType.ACI), identifier, "getUnversionedProfile", userAgent);
|
||||
}
|
||||
return switch (identifier.identityType()) {
|
||||
case ACI -> buildBaseProfileResponseForAccountIdentity(targetAccount,
|
||||
|
@ -386,7 +390,7 @@ public class ProfileController {
|
|||
profileKeyCredentialResponse = ProfileHelper.getExpiringProfileKeyCredential(HexFormat.of().parseHex(encodedCredentialRequest),
|
||||
profile, new ServiceId.Aci(account.getUuid()), zkProfileOperations);
|
||||
} catch (VerificationFailedException | InvalidInputException e) {
|
||||
throw new BadRequestException(Response.status(Response.Status.BAD_REQUEST).build(), e);
|
||||
throw new BadRequestException(e);
|
||||
}
|
||||
return profileKeyCredentialResponse;
|
||||
})
|
||||
|
@ -474,7 +478,15 @@ public class ProfileController {
|
|||
*/
|
||||
private Account verifyPermissionToReceiveProfile(final Optional<Account> maybeRequester,
|
||||
final Optional<Anonymous> maybeAccessKey,
|
||||
final ServiceIdentifier accountIdentifier) throws RateLimitExceededException {
|
||||
final ServiceIdentifier accountIdentifier,
|
||||
final String endpoint,
|
||||
@Nullable final String userAgent) throws RateLimitExceededException {
|
||||
|
||||
if (maybeRequester.isPresent() && maybeAccessKey.isPresent()) {
|
||||
Metrics.counter(DUPLICATE_AUTHENTICATION_COUNTER_NAME,
|
||||
Tags.of(UserAgentTagUtil.getPlatformTag(userAgent), io.micrometer.core.instrument.Tag.of("endpoint", endpoint)))
|
||||
.increment();
|
||||
}
|
||||
|
||||
if (maybeRequester.isPresent()) {
|
||||
rateLimiters.getProfileLimiter().validate(maybeRequester.get().getUuid());
|
||||
|
|
Loading…
Reference in New Issue