mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 13:07:58 +01:00
Ensure details are included on all gRPC error statuses
This commit is contained in:
@@ -34,26 +34,6 @@ public final class GrpcTestUtils {
|
||||
// noop
|
||||
}
|
||||
|
||||
public static void setupAuthenticatedExtension(
|
||||
final GrpcServerExtension extension,
|
||||
final MockAuthenticationInterceptor mockAuthenticationInterceptor,
|
||||
final MockRequestAttributesInterceptor mockRequestAttributesInterceptor,
|
||||
final UUID authenticatedAci,
|
||||
final byte authenticatedDeviceId,
|
||||
final BindableService service) {
|
||||
mockAuthenticationInterceptor.setAuthenticatedDevice(authenticatedAci, authenticatedDeviceId);
|
||||
extension.getServiceRegistry()
|
||||
.addService(ServerInterceptors.intercept(service, new ValidatingInterceptor(), mockRequestAttributesInterceptor, mockAuthenticationInterceptor, new ErrorMappingInterceptor()));
|
||||
}
|
||||
|
||||
public static void setupUnauthenticatedExtension(
|
||||
final GrpcServerExtension extension,
|
||||
final MockRequestAttributesInterceptor mockRequestAttributesInterceptor,
|
||||
final BindableService service) {
|
||||
extension.getServiceRegistry()
|
||||
.addService(ServerInterceptors.intercept(service, new ValidatingInterceptor(), mockRequestAttributesInterceptor, new ErrorMappingInterceptor()));
|
||||
}
|
||||
|
||||
public static void assertStatusException(final Status expected, final Executable serviceCall) {
|
||||
final StatusRuntimeException exception = Assertions.assertThrows(StatusRuntimeException.class, serviceCall);
|
||||
assertEquals(expected.getCode(), exception.getStatus().getCode());
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.grpc;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.grpc.Status;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -34,6 +35,7 @@ import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -302,4 +304,13 @@ public class KeyTransparencyGrpcServiceTest extends SimpleBaseGrpcTest<KeyTransp
|
||||
.setEntryPosition(entryPosition)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ServerInterceptor> customizeInterceptors(List<ServerInterceptor> serverInterceptors) {
|
||||
return serverInterceptors.stream()
|
||||
// For now, don't validate conformance of KeyTransparency errors since they are forwarded directly from a
|
||||
// backing service
|
||||
.filter(interceptor -> !(interceptor instanceof ErrorConformanceInterceptor))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ class MessagesAnonymousGrpcServiceTest extends
|
||||
|
||||
when(spamChecker.checkForIndividualRecipientSpamGrpc(any(), any(), any(), any()))
|
||||
.thenReturn(new SpamCheckResult<>(
|
||||
Optional.of(GrpcResponse.withStatusException(Status.RESOURCE_EXHAUSTED.asRuntimeException())),
|
||||
Optional.of(GrpcResponse.withStatusException(GrpcExceptions.rateLimitExceeded(null))),
|
||||
Optional.empty()));
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
@@ -793,7 +793,7 @@ class MessagesAnonymousGrpcServiceTest extends
|
||||
|
||||
when(spamChecker.checkForMultiRecipientSpamGrpc(any()))
|
||||
.thenReturn(new SpamCheckResult<>(
|
||||
Optional.of(GrpcResponse.withStatusException(Status.RESOURCE_EXHAUSTED.asRuntimeException())),
|
||||
Optional.of(GrpcResponse.withStatusException(GrpcExceptions.rateLimitExceeded(null))),
|
||||
Optional.empty()));
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
@@ -1052,7 +1052,7 @@ class MessagesAnonymousGrpcServiceTest extends
|
||||
|
||||
when(spamChecker.checkForIndividualRecipientSpamGrpc(any(), any(), any(), any()))
|
||||
.thenReturn(new SpamCheckResult<>(
|
||||
Optional.of(GrpcResponse.withStatusException(Status.RESOURCE_EXHAUSTED.asRuntimeException())),
|
||||
Optional.of(GrpcResponse.withStatusException(GrpcExceptions.rateLimitExceeded(null))),
|
||||
Optional.empty()));
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
@@ -1334,8 +1334,8 @@ class MessagesAnonymousGrpcServiceTest extends
|
||||
.build();
|
||||
|
||||
when(spamChecker.checkForMultiRecipientSpamGrpc(any()))
|
||||
.thenReturn(new SpamCheckResult<>(Optional.of(
|
||||
GrpcResponse.withStatusException(Status.RESOURCE_EXHAUSTED.asRuntimeException())),
|
||||
.thenReturn(new SpamCheckResult<>(
|
||||
Optional.of(GrpcResponse.withStatusException(GrpcExceptions.rateLimitExceeded(null))),
|
||||
Optional.empty()));
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
|
||||
@@ -359,7 +359,7 @@ class MessagesGrpcServiceTest extends SimpleBaseGrpcTest<MessagesGrpcService, Me
|
||||
|
||||
when(spamChecker.checkForIndividualRecipientSpamGrpc(any(), any(), any(), any()))
|
||||
.thenReturn(new SpamCheckResult<>(
|
||||
Optional.of(GrpcResponse.withStatusException(Status.RESOURCE_EXHAUSTED.asRuntimeException())),
|
||||
Optional.of(GrpcResponse.withStatusException(GrpcExceptions.rateLimitExceeded(null))),
|
||||
Optional.empty()));
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
|
||||
@@ -17,6 +17,7 @@ import static org.whispersystems.textsecuregcm.grpc.GrpcTestUtils.assertStatusEx
|
||||
|
||||
import com.google.common.net.InetAddresses;
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.grpc.Status;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
@@ -593,4 +594,13 @@ public class ProfileAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<ProfileA
|
||||
Arguments.of(IdentityType.IDENTITY_TYPE_ACI, CredentialType.CREDENTIAL_TYPE_EXPIRING_PROFILE_KEY, true)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ServerInterceptor> customizeInterceptors(List<ServerInterceptor> serverInterceptors) {
|
||||
return serverInterceptors.stream()
|
||||
// For now, don't validate error conformance because the profiles gRPC service has not been converted to the
|
||||
// updated error model
|
||||
.filter(interceptor -> !(interceptor instanceof ErrorConformanceInterceptor))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ import com.google.common.net.InetAddresses;
|
||||
import com.google.i18n.phonenumbers.PhoneNumberUtil;
|
||||
import com.google.i18n.phonenumbers.Phonenumber;
|
||||
import com.google.protobuf.ByteString;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.grpc.Status;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Clock;
|
||||
@@ -753,4 +756,13 @@ public class ProfileGrpcServiceTest extends SimpleBaseGrpcTest<ProfileGrpcServic
|
||||
Arguments.of(IdentityType.IDENTITY_TYPE_ACI, CredentialType.CREDENTIAL_TYPE_EXPIRING_PROFILE_KEY, true)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ServerInterceptor> customizeInterceptors(List<ServerInterceptor> serverInterceptors) {
|
||||
return serverInterceptors.stream()
|
||||
// For now, don't validate error conformance because the profiles gRPC service has not been converted to the
|
||||
// updated error model
|
||||
.filter(interceptor -> !(interceptor instanceof ErrorConformanceInterceptor))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,12 @@ import static java.util.Objects.requireNonNull;
|
||||
|
||||
import io.grpc.BindableService;
|
||||
import io.grpc.Channel;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.grpc.ServerInterceptors;
|
||||
import io.grpc.stub.AbstractBlockingStub;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -113,9 +116,18 @@ public abstract class SimpleBaseGrpcTest<SERVICE extends BindableService, STUB e
|
||||
protected void baseSetup() {
|
||||
mocksCloseable = MockitoAnnotations.openMocks(this);
|
||||
service = requireNonNull(createServiceBeforeEachTest(), "created service must not be `null`");
|
||||
GrpcTestUtils.setupAuthenticatedExtension(
|
||||
GRPC_SERVER_EXTENSION_AUTHENTICATED, mockAuthenticationInterceptor, mockRequestAttributesInterceptor, AUTHENTICATED_ACI, AUTHENTICATED_DEVICE_ID, service);
|
||||
GrpcTestUtils.setupUnauthenticatedExtension(GRPC_SERVER_EXTENSION_UNAUTHENTICATED, mockRequestAttributesInterceptor, service);
|
||||
|
||||
mockAuthenticationInterceptor.setAuthenticatedDevice(AUTHENTICATED_ACI, AUTHENTICATED_DEVICE_ID);
|
||||
final List<ServerInterceptor> authenticatedInterceptors =
|
||||
List.of(new ValidatingInterceptor(), mockRequestAttributesInterceptor, mockAuthenticationInterceptor, new ErrorMappingInterceptor(), new ErrorConformanceInterceptor());
|
||||
GRPC_SERVER_EXTENSION_AUTHENTICATED
|
||||
.getServiceRegistry()
|
||||
.addService(ServerInterceptors.intercept(service, customizeInterceptors(authenticatedInterceptors)));
|
||||
|
||||
final List<ServerInterceptor> unauthenticatedInterceptors =
|
||||
List.of(new ValidatingInterceptor(), mockRequestAttributesInterceptor, new ErrorMappingInterceptor(), new ErrorConformanceInterceptor());
|
||||
GRPC_SERVER_EXTENSION_UNAUTHENTICATED.getServiceRegistry()
|
||||
.addService(ServerInterceptors.intercept(service, customizeInterceptors(unauthenticatedInterceptors)));
|
||||
try {
|
||||
authenticatedServiceStub = createStub(GRPC_SERVER_EXTENSION_AUTHENTICATED.getChannel());
|
||||
unauthenticatedServiceStub = createStub(GRPC_SERVER_EXTENSION_UNAUTHENTICATED.getChannel());
|
||||
@@ -152,4 +164,8 @@ public abstract class SimpleBaseGrpcTest<SERVICE extends BindableService, STUB e
|
||||
protected MockAuthenticationInterceptor getMockAuthenticationInterceptor() {
|
||||
return mockAuthenticationInterceptor;
|
||||
}
|
||||
|
||||
protected List<ServerInterceptor> customizeInterceptors(List<ServerInterceptor> serverInterceptors) {
|
||||
return serverInterceptors;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user