Add a require.proto presence annotation

This commit is contained in:
ravi-signal
2024-05-30 16:21:28 -05:00
parent cea2abcf6e
commit afa1899dc9
6 changed files with 191 additions and 108 deletions

View File

@@ -21,6 +21,7 @@ import org.whispersystems.textsecuregcm.grpc.validators.EnumSpecifiedFieldValida
import org.whispersystems.textsecuregcm.grpc.validators.ExactlySizeFieldValidator;
import org.whispersystems.textsecuregcm.grpc.validators.FieldValidator;
import org.whispersystems.textsecuregcm.grpc.validators.NonEmptyFieldValidator;
import org.whispersystems.textsecuregcm.grpc.validators.PresentFieldValidator;
import org.whispersystems.textsecuregcm.grpc.validators.RangeFieldValidator;
import org.whispersystems.textsecuregcm.grpc.validators.SizeFieldValidator;
@@ -28,6 +29,7 @@ public class ValidatingInterceptor implements ServerInterceptor {
private final Map<String, FieldValidator> fieldValidators = Map.of(
"org.signal.chat.require.nonEmpty", new NonEmptyFieldValidator(),
"org.signal.chat.require.present", new PresentFieldValidator(),
"org.signal.chat.require.specified", new EnumSpecifiedFieldValidator(),
"org.signal.chat.require.e164", new E164FieldValidator(),
"org.signal.chat.require.exactlySize", new ExactlySizeFieldValidator(),

View File

@@ -12,6 +12,7 @@ import static org.whispersystems.textsecuregcm.grpc.validators.ValidatorUtils.in
import com.google.protobuf.ByteString;
import com.google.protobuf.Descriptors;
import com.google.protobuf.GeneratedMessageV3;
import com.google.protobuf.Message;
import io.grpc.Status;
import io.grpc.StatusException;
import java.util.Set;
@@ -91,7 +92,10 @@ public abstract class BaseFieldValidator<T> implements FieldValidator {
validateBytesValue(extensionValueTyped, (ByteString) msg.getField(fd));
case ENUM ->
validateEnumValue(extensionValueTyped, (Descriptors.EnumValueDescriptor) msg.getField(fd));
case FLOAT, DOUBLE, BOOL, MESSAGE, GROUP -> {
case MESSAGE -> {
validateMessageValue(extensionValueTyped, (Message) msg.getField(fd));
}
case FLOAT, DOUBLE, BOOL, GROUP -> {
// at this moment, there are no validations specific to these types of fields
}
}
@@ -140,6 +144,12 @@ public abstract class BaseFieldValidator<T> implements FieldValidator {
throw internalError("`validateEnumValue` method needs to be implemented");
}
protected void validateMessageValue(
final T extensionValue,
final Message message) throws StatusException {
throw internalError("`validateMessageValue` method needs to be implemented");
}
protected static boolean requireFlagExtension(final Object extensionValue) throws StatusException {
if (extensionValue instanceof Boolean flagIsOn && flagIsOn) {
return true;

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.grpc.validators;
import static org.whispersystems.textsecuregcm.grpc.validators.ValidatorUtils.invalidArgument;
import com.google.protobuf.Descriptors;
import com.google.protobuf.Message;
import io.grpc.StatusException;
import java.util.Set;
public class PresentFieldValidator extends BaseFieldValidator<Boolean> {
public PresentFieldValidator() {
super("present",
Set.of(Descriptors.FieldDescriptor.Type.MESSAGE),
MissingOptionalAction.FAIL,
true);
}
@Override
protected Boolean resolveExtensionValue(final Object extensionValue) throws StatusException {
return requireFlagExtension(extensionValue);
}
@Override
protected void validateMessageValue(final Boolean extensionValue, final Message msg) throws StatusException {
if (msg == null) {
throw invalidArgument("message expected to be present");
}
}
}