Merge "b/163140302 Add schema validation for x-security-fresh extension"
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtendedValidator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtendedValidator.java
index 32a24a9..18400b8 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtendedValidator.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtendedValidator.java
@@ -1,11 +1,14 @@
package com.apigee.security.oas.extendedvalidator;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.flogger.FluentLogger;
import javax.inject.Inject;
import org.openapi4j.parser.model.v3.OpenApi3;
final class BaseExtendedValidator implements ExtendedValidator {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final TraversalHelperFactory traversalHelperFactory;
@Inject
@@ -17,5 +20,9 @@
public void validate(OpenApi3 openApiSpec) {
TraversalHelper traversalHelper = traversalHelperFactory.create(ImmutableList.of());
traversalHelper.sendOpenApiTraversal(openApiSpec);
+ ImmutableSet<Extension> extensions = traversalHelper.traverse();
+
+ // TODO(b/161441872) : Add extension validation logic
+ logger.atInfo().log("%s", extensions);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionSchemaValidator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionSchemaValidator.java
index b576fb9..c6ad87c 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionSchemaValidator.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionSchemaValidator.java
@@ -1,5 +1,6 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.ErrorMessage.INVALID_SCHEMA;
import static com.apigee.security.oas.extendedvalidator.ExtensionName.valueOfExtensionName;
import static com.apigee.security.oas.extendedvalidator.ExtensionValidators.defaultErrors;
import static com.apigee.security.oas.extendedvalidator.ExtensionValidators.prepareNamedPath;
@@ -83,7 +84,8 @@
JsonSchema schema = getJsonSchemaFromUrl(schemaUrl);
Set<ValidationMessage> errors = schema.validate(extension.getExtensionContent());
- return toExtensionValidationMessages(errors, "INVALID_SCHEMA", prepareNamedPath(extension));
+ return toExtensionValidationMessages(
+ errors, INVALID_SCHEMA.getErrorType(), prepareNamedPath(extension));
} catch (URISyntaxException e) {
String errorMessage = "Failed to validate extension schema";
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionScopeValidator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionScopeValidator.java
new file mode 100644
index 0000000..8ff013a
--- /dev/null
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionScopeValidator.java
@@ -0,0 +1,94 @@
+package com.apigee.security.oas.extendedvalidator;
+
+import static com.apigee.security.oas.extendedvalidator.ErrorMessage.X_SECURITY_ALLOW_SCOPE_ERROR;
+import static com.apigee.security.oas.extendedvalidator.ErrorMessage.X_SECURITY_TYPE_DEFINITIONS_SCOPE_ERROR;
+import static com.apigee.security.oas.extendedvalidator.ErrorMessage.X_SECURITY_TYPE_SCOPE_ERROR;
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.X_SECURITY_ALLOW;
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.X_SECURITY_TYPE;
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.X_SECURITY_TYPE_DEFINITIONS;
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.valueOfExtensionName;
+import static com.apigee.security.oas.extendedvalidator.ExtensionValidators.defaultErrors;
+import static com.apigee.security.oas.extendedvalidator.ExtensionValidators.fetchExtensionParent;
+import static com.apigee.security.oas.extendedvalidator.ExtensionValidators.prepareNamedPath;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.flogger.FluentLogger;
+import java.util.Optional;
+import org.openapi4j.parser.model.OpenApiSchema;
+import org.openapi4j.parser.model.v3.OpenApi3;
+import org.openapi4j.parser.model.v3.Operation;
+import org.openapi4j.parser.model.v3.Parameter;
+import org.openapi4j.parser.model.v3.Schema;
+
+final class BaseExtensionScopeValidator implements ExtensionScopeValidator {
+
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+ private static final ImmutableMap<ExtensionName, ErrorMessage> errorMessages =
+ Maps.immutableEnumMap(
+ ImmutableMap.of(
+ X_SECURITY_TYPE, X_SECURITY_TYPE_SCOPE_ERROR,
+ X_SECURITY_ALLOW, X_SECURITY_ALLOW_SCOPE_ERROR,
+ X_SECURITY_TYPE_DEFINITIONS, X_SECURITY_TYPE_DEFINITIONS_SCOPE_ERROR));
+
+ private static final ImmutableMap<ExtensionName, ImmutableSet<Class<? extends OpenApiSchema>>>
+ allowedParentsMap =
+ Maps.immutableEnumMap(
+ ImmutableMap.of(
+ X_SECURITY_TYPE, ImmutableSet.of(Schema.class, Parameter.class),
+ X_SECURITY_ALLOW, ImmutableSet.of(Operation.class),
+ X_SECURITY_TYPE_DEFINITIONS, ImmutableSet.of(OpenApi3.class)));
+
+ /**
+ * Validates the scope of an supported {@link Extension} by contrasting it against its appropriate
+ * scope.
+ *
+ * <p>An invalid scoped Extension will return {@code INVALID_SCOPE} {@link
+ * ExtensionValidationMessage}.
+ */
+ @Override
+ public ImmutableSet<ExtensionValidationMessage> validate(Extension extension) {
+ Optional<ExtensionName> extensionNameOptional =
+ valueOfExtensionName(extension.getExtensionName());
+ ImmutableSet.Builder<ExtensionValidationMessage> errors = ImmutableSet.builder();
+
+ extensionNameOptional.ifPresentOrElse(
+ extensionNameEnum -> errors.addAll(validateExtensionScope(extension, extensionNameEnum)),
+ () -> errors.addAll(defaultErrors(extension)));
+
+ logger.atInfo().log("Scope Errors(%s) : %s", prepareNamedPath(extension), errors);
+
+ return errors.build();
+ }
+
+ /**
+ * Checks whether {@link Extension} exists under an allowed parent class.
+ *
+ * <p>A parent class is allowed if {@link Extension} has an entry in {@link
+ * BaseExtensionScopeValidator#allowedParentsMap} with it.
+ */
+ private static ImmutableSet<ExtensionValidationMessage> validateExtensionScope(
+ Extension extension, ExtensionName extensionNameEnum) {
+
+ Optional<Class<? extends OpenApiSchema>> extensionParent = fetchExtensionParent(extension);
+
+ if (extensionParent.isPresent()
+ && allowedParentsMap.get(extensionNameEnum).contains(extensionParent.get())) {
+ return ImmutableSet.of();
+ }
+
+ return ImmutableSet.of(prepareInvalidScopeValidationMessage(extension, extensionNameEnum));
+ }
+
+ private static ExtensionValidationMessage prepareInvalidScopeValidationMessage(
+ Extension extension, ExtensionName extensionNameEnum) {
+
+ ErrorMessage errorMessageEnum = errorMessages.get(extensionNameEnum);
+ return ExtensionValidationMessage.builder()
+ .setType(errorMessageEnum.getErrorType())
+ .setMessage(errorMessageEnum.getErrorMessage())
+ .setPath(prepareNamedPath(extension))
+ .build();
+ }
+}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionValidationIntegrator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionValidationIntegrator.java
index 055b696..1fc861e 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionValidationIntegrator.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseExtensionValidationIntegrator.java
@@ -1,13 +1,20 @@
package com.apigee.security.oas.extendedvalidator;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import java.util.Optional;
+import org.openapi4j.parser.model.OpenApiSchema;
final class BaseExtensionValidationIntegrator extends ExtensionValidationIntegrator {
// TODO(b/161441872): Inject ExtensionValidationIntegrator member dependencies.
@Override
- public void validateExtensions(ImmutableMap<String, Object> extensions) {
+ public void validateExtensions(
+ ImmutableMap<String, Object> extensions,
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath) {
// TODO(b/161441872): Add validation logic here.
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalCoordinator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalCoordinator.java
index b08fc02..b2b2769 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalCoordinator.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalCoordinator.java
@@ -1,6 +1,8 @@
package com.apigee.security.oas.extendedvalidator;
+import com.google.common.collect.ImmutableSet;
import java.util.ArrayDeque;
+import java.util.Optional;
/** Executes {@linkplain Traversal TraversalCommands} in a depth first (right to left) fashion. */
final class BaseTraversalCoordinator implements TraversalCoordinator {
@@ -8,10 +10,15 @@
private final ArrayDeque<TraversalCommand> stack = new ArrayDeque<>();
@Override
- public void traverse() {
+ public ImmutableSet<Extension> traverse() {
+ ImmutableSet.Builder<Extension> setBuilder = new ImmutableSet.Builder<>();
+
while (!stack.isEmpty()) {
- stack.pop().traverse();
+ Optional.ofNullable(stack.pop().traverse())
+ .ifPresent(extensions -> setBuilder.addAll(extensions));
}
+
+ return setBuilder.build();
}
@Override
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java
index 58e4e14..f160c01 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/BaseTraversalHelper.java
@@ -2,6 +2,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -47,6 +48,11 @@
}
@Override
+ public ImmutableSet<Extension> traverse() {
+ return coordinator.traverse();
+ }
+
+ @Override
public void sendCallbackTraversals(ImmutableMap<String, Callback> callbackMap) {
Optional.ofNullable(callbackMap)
.ifPresent(
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/CallbackTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/CallbackTraversal.java
index 7ed41fc..c00db58 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/CallbackTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/CallbackTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -13,26 +16,25 @@
@Inject
CallbackTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Callback openApiSchemaObj,
@Assisted String name) {
- super(
- traversalHelperFactory,
- extensionValidationIntegrator,
- traversalPath,
- openApiSchemaObj,
- name);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj, name);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendPathTraversals(
Immutables.toImmutableMap(openApiSchemaObj.getCallbackPaths()));
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ContactTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ContactTraversal.java
index 9c6691f..3c07fb6 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ContactTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ContactTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,15 +17,16 @@
@Inject
ContactTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Contact openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), getUpdatedTraversalPath());
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ErrorMessage.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ErrorMessage.java
new file mode 100644
index 0000000..40b6c53
--- /dev/null
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ErrorMessage.java
@@ -0,0 +1,30 @@
+package com.apigee.security.oas.extendedvalidator;
+
+/** Stores information of {@link Extension} validation errors for ease of use. */
+enum ErrorMessage {
+ UNSUPPORTED_EXTENSION("UNSUPPORTED_EXTENSION", "extension is not binded to a validator."),
+ X_SECURITY_TYPE_SCOPE_ERROR(
+ "INVALID_SCOPE", "extension should be under a schema or parameter object."),
+ X_SECURITY_ALLOW_SCOPE_ERROR(
+ "INVALID_SCOPE",
+ "extension should be under a paths operation object like get, post, patch, etc."),
+ X_SECURITY_TYPE_DEFINITIONS_SCOPE_ERROR(
+ "INVALID_SCOPE", "extension should be on the top-level scope."),
+ INVALID_SCHEMA("INVALID_SCHEMA", "extension has an invalid schema.");
+
+ private final String errorType;
+ private final String errorMessage;
+
+ ErrorMessage(String errorType, String errorMessage) {
+ this.errorType = errorType;
+ this.errorMessage = errorMessage;
+ }
+
+ String getErrorType() {
+ return errorType;
+ }
+
+ String getErrorMessage() {
+ return errorMessage;
+ }
+}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtendedValidatorModule.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtendedValidatorModule.java
index f7b0dc0..8237d03 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtendedValidatorModule.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtendedValidatorModule.java
@@ -2,6 +2,7 @@
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
+import javax.inject.Singleton;
/**
* Configures the bindings of inner components to be installed in the {@link
@@ -15,7 +16,7 @@
bind(ExtensionValidationIntegrator.class).to(BaseExtensionValidationIntegrator.class);
- bind(TraversalCoordinator.class).to(BaseTraversalCoordinator.class);
+ bind(TraversalCoordinator.class).to(BaseTraversalCoordinator.class).in(Singleton.class);
install(
new FactoryModuleBuilder()
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionModule.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionModule.java
index 70c3f7a..bd083e2 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionModule.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionModule.java
@@ -19,6 +19,7 @@
.build(ExtensionFactory.class));
bind(ExtensionSchemaValidator.class).to(BaseExtensionSchemaValidator.class);
+ bind(ExtensionScopeValidator.class).to(BaseExtensionScopeValidator.class);
}
@Provides
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionScopeValidator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionScopeValidator.java
new file mode 100644
index 0000000..bb0e888
--- /dev/null
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionScopeValidator.java
@@ -0,0 +1,9 @@
+package com.apigee.security.oas.extendedvalidator;
+
+/**
+ * Validates that {@link Extension} exists in a valid scope.
+ *
+ * <p>A valid scope of {@link Extension} is a defined {@link Class}<? extends {@link
+ * org.openapi4j.parser.model.OpenApiSchema}> object that it is allowed to exist under.
+ */
+interface ExtensionScopeValidator extends ExtensionValidator {}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidationIntegrator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidationIntegrator.java
index 26fcaed..c38c062 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidationIntegrator.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidationIntegrator.java
@@ -1,6 +1,10 @@
package com.apigee.security.oas.extendedvalidator;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import java.util.Optional;
+import org.openapi4j.parser.model.OpenApiSchema;
/** Carries out the process of validating ApiSecurityTool's OpenApi extensions. */
public abstract class ExtensionValidationIntegrator {
@@ -11,5 +15,8 @@
* Validates extensions from a mapping of extension {@linkplain String name} to extension
* {@linkplain Object content}.
*/
- abstract void validateExtensions(ImmutableMap<String, Object> extensions);
+ abstract void validateExtensions(
+ ImmutableMap<String, Object> extensions,
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath);
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidators.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidators.java
index d380ca7..1d85f31 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidators.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExtensionValidators.java
@@ -1,5 +1,7 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.ErrorMessage.UNSUPPORTED_EXTENSION;
+
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.networknt.schema.ValidationMessage;
@@ -72,11 +74,15 @@
return ImmutableSet.copyOf(updatedErrors);
}
- // TODO(b/162938113) : Create validation error type and message constants.
/** Prepares {@link ExtensionValidationMessage} for extensions without validators. */
static ImmutableSet<ExtensionValidationMessage> defaultErrors(Extension extension) {
- String errorType = "UNSUPPORTED_EXTENSION";
- String errorMessage = extension.getExtensionName() + " is not binded to the validator.";
+ String errorType = UNSUPPORTED_EXTENSION.getErrorType();
+ String errorMessage =
+ new StringBuilder()
+ .append(extension.getExtensionName())
+ .append(" ")
+ .append(UNSUPPORTED_EXTENSION.getErrorMessage())
+ .toString();
String path = prepareNamedPath(extension);
return ImmutableSet.of(
ExtensionValidationMessage.builder()
@@ -86,5 +92,16 @@
.build());
}
+ static Optional<Class<? extends OpenApiSchema>> fetchExtensionParent(Extension extension) {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> extensionPath =
+ extension.getExtensionPath();
+
+ if (extensionPath.isEmpty()) {
+ return Optional.empty();
+ }
+
+ return Optional.of(extensionPath.get(extensionPath.size() - 1).getKey());
+ }
+
private ExtensionValidators() {}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java
index 47b08ab..072ac6d 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ExternalDocsTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -15,16 +18,17 @@
@Inject
ExternalDocsTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted ExternalDocs openApiSchemaObj,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
traversalPath) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), getUpdatedTraversalPath());
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java
index 5d89df2..d1df744 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/InfoTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,20 +17,24 @@
@Inject
InfoTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Info openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendContactTraversal(openApiSchemaObj.getContact());
traversalHelper.sendLicenseTraversal(openApiSchemaObj.getLicense());
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/LicenseTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/LicenseTraversal.java
index e3b20f0..2e6116f 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/LicenseTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/LicenseTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,15 +17,16 @@
@Inject
LicenseTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted License openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), getUpdatedTraversalPath());
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java
index 07b547f..c2ff58f 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversal.java
@@ -4,8 +4,12 @@
import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
+import java.util.Map;
+import java.util.Optional;
import javax.inject.Inject;
+import org.openapi4j.parser.model.OpenApiSchema;
import org.openapi4j.parser.model.v3.OpenApi3;
/** A {@link Traversal} that traverses an {@link OpenApi3} object. */
@@ -15,23 +19,28 @@
@Inject
OpenApiSpecificationTraversal(
TraversalHelperFactory factory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted OpenApi3 openApiSchemaObj) {
- super(factory, extensionValidationIntegrator, ImmutableList.of(), openApiSchemaObj);
+ super(factory, extensionFactory, ImmutableList.of(), openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendExternalDocsTraversal(openApiSchemaObj.getExternalDocs());
traversalHelper.sendInfoTraversal(openApiSchemaObj.getInfo());
traversalHelper.sendServerTraversals(toImmutableList(openApiSchemaObj.getServers()));
traversalHelper.sendTagTraversals(toImmutableList(openApiSchemaObj.getTags()));
traversalHelper.sendPathTraversals(toImmutableMap(openApiSchemaObj.getPaths()));
- // TODO(b/162682119): Send OpenApiSpecification SecurityRequirements to TraversalHelper.
+ traversalHelper.sendSecurityRequirementTraversals(
+ toImmutableList(openApiSchemaObj.getSecurityRequirements()));
// TODO(b/162677159): Send Components traversal.
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java
index 22ed41d..4d89636 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/OperationTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,24 +17,20 @@
@Inject
OperationTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Operation openApiSchemaObj,
@Assisted String name) {
- super(
- traversalHelperFactory,
- extensionValidationIntegrator,
- traversalPath,
- openApiSchemaObj,
- name);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj, name);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendExternalDocsTraversal(openApiSchemaObj.getExternalDocs());
traversalHelper.sendCallbackTraversals(
@@ -43,5 +42,8 @@
Immutables.toImmutableMap(openApiSchemaObj.getResponses()));
traversalHelper.sendSecurityRequirementTraversals(
Immutables.toImmutableList(openApiSchemaObj.getSecurityRequirements()));
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java
index 869fcb7..02f9f28 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ParameterTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -13,18 +16,20 @@
@Inject
ParameterTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Parameter openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
// TODO(b/162897637): Send MediaType Traversal
// TODO(b/162942899): Send Example Traversal
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), getUpdatedTraversalPath());
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/PathTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/PathTraversal.java
index 5ba0797..e6da1ce 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/PathTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/PathTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,29 +17,28 @@
@Inject
PathTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Path openApiSchemaObj,
@Assisted String name) {
- super(
- traversalHelperFactory,
- extensionValidationIntegrator,
- traversalPath,
- openApiSchemaObj,
- name);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj, name);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendParameterTraversals(
Immutables.toImmutableList(openApiSchemaObj.getParameters()));
traversalHelper.sendServerTraversals(Immutables.toImmutableList(openApiSchemaObj.getServers()));
traversalHelper.sendOperationTraversals(
Immutables.toImmutableMap(openApiSchemaObj.getOperations()));
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ResponseTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ResponseTraversal.java
index d214ada..17370b6 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ResponseTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ResponseTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,23 +17,20 @@
@Inject
ResponseTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Response openApiSchemaObj,
@Assisted String name) {
- super(
- traversalHelperFactory,
- extensionValidationIntegrator,
- traversalPath,
- openApiSchemaObj,
- name);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj, name);
}
@Override
- public void traverse() {
+ public ImmutableSet<Extension> traverse() {
// TODO(b/162897637): Send MediaType Traversals.
// TODO(b/162949105): Send Header Traversals.
// TODO(b/162949106): Send Link Traversals.
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), getUpdatedTraversalPath());
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/SecurityRequirementTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/SecurityRequirementTraversal.java
index 78f614e..ce8f0cd 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/SecurityRequirementTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/SecurityRequirementTraversal.java
@@ -1,6 +1,7 @@
package com.apigee.security.oas.extendedvalidator;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,15 +15,16 @@
@Inject
SecurityRequirementTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted SecurityRequirement openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ // SecurityRequirement object cannot have extensions.
+ return ImmutableSet.of();
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java
index c464d7a..160ee27 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerTraversal.java
@@ -3,6 +3,7 @@
import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -16,19 +17,23 @@
@Inject
ServerTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Server openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendServerVariableTraversals(toImmutableMap(openApiSchemaObj.getVariables()));
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerVariableTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerVariableTraversal.java
index d1284ef..ddb7e27 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerVariableTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/ServerVariableTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -15,21 +18,17 @@
@Inject
ServerVariableTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted ServerVariable openApiSchemaObj,
@Assisted String name) {
- super(
- traversalHelperFactory,
- extensionValidationIntegrator,
- traversalPath,
- openApiSchemaObj,
- name);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj, name);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), getUpdatedTraversalPath());
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java
index c6e9a40..5a21d2c 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TagTraversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import static com.apigee.security.oas.extendedvalidator.Immutables.toImmutableMap;
+
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.assistedinject.Assisted;
import java.util.Map;
import java.util.Optional;
@@ -14,19 +17,23 @@
@Inject
TagTraversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
@Assisted
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
@Assisted Tag openApiSchemaObj) {
- super(traversalHelperFactory, extensionValidationIntegrator, traversalPath, openApiSchemaObj);
+ super(traversalHelperFactory, extensionFactory, traversalPath, openApiSchemaObj);
}
@Override
- public void traverse() {
- // TODO(b/161441872): Process extensions.
+ public ImmutableSet<Extension> traverse() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ updatedTraversalPath = getUpdatedTraversalPath();
- TraversalHelper traversalHelper = traversalHelperFactory.create(getUpdatedTraversalPath());
+ TraversalHelper traversalHelper = traversalHelperFactory.create(updatedTraversalPath);
traversalHelper.sendExternalDocsTraversal(openApiSchemaObj.getExternalDocs());
+
+ return generateExtensions(
+ toImmutableMap(openApiSchemaObj.getExtensions()), updatedTraversalPath);
}
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java
index 37ebd51..0c3986f 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/Traversal.java
@@ -1,6 +1,9 @@
package com.apigee.security.oas.extendedvalidator;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import java.util.AbstractMap;
import java.util.ArrayDeque;
import java.util.Map;
@@ -11,19 +14,20 @@
abstract class Traversal<T extends OpenApiSchema> {
protected final T openApiSchemaObj;
- protected final ExtensionValidationIntegrator extensionValidationIntegrator;
+ protected final ExtensionFactory extensionFactory;
protected final TraversalHelperFactory traversalHelperFactory;
private final ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
traversalPath;
private final Optional<String> name;
+ private final ObjectMapper objectMapper = new ObjectMapper();
Traversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
T openApiSchemaObj) {
this.traversalHelperFactory = traversalHelperFactory;
- this.extensionValidationIntegrator = extensionValidationIntegrator;
+ this.extensionFactory = extensionFactory;
this.traversalPath = traversalPath;
this.openApiSchemaObj = openApiSchemaObj;
this.name = Optional.empty();
@@ -31,12 +35,12 @@
Traversal(
TraversalHelperFactory traversalHelperFactory,
- ExtensionValidationIntegrator extensionValidationIntegrator,
+ ExtensionFactory extensionFactory,
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath,
T openApiSchemaObj,
String name) {
this.traversalHelperFactory = traversalHelperFactory;
- this.extensionValidationIntegrator = extensionValidationIntegrator;
+ this.extensionFactory = extensionFactory;
this.traversalPath = traversalPath;
this.openApiSchemaObj = openApiSchemaObj;
this.name = Optional.of(name);
@@ -50,4 +54,20 @@
new AbstractMap.SimpleImmutableEntry<>(openApiSchemaObj.getClass(), name));
return ImmutableList.copyOf(updatedTraversalPath);
}
+
+ protected ImmutableSet<Extension> generateExtensions(
+ ImmutableMap<String, Object> extensions,
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> traversalPath) {
+ ImmutableSet.Builder<Extension> setBuilder = new ImmutableSet.Builder<>();
+
+ Optional.ofNullable(extensions)
+ .orElse(ImmutableMap.of())
+ .forEach(
+ (name, content) ->
+ setBuilder.add(
+ extensionFactory.create(
+ name, objectMapper.valueToTree(content), traversalPath)));
+
+ return setBuilder.build();
+ }
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommand.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommand.java
index 257eb80..a2f5d9a 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommand.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCommand.java
@@ -1,8 +1,10 @@
package com.apigee.security.oas.extendedvalidator;
+import com.google.common.collect.ImmutableSet;
+
/** Used in conjunction with {@link Traversal} to traverse an OpenApi4j object. */
public interface TraversalCommand {
- /** Starts traversal logic. */
- void traverse();
+ /** Starts traversal logic and collects {@link Extension extensions}. */
+ ImmutableSet<Extension> traverse();
}
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCoordinator.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCoordinator.java
index bb15592..0aa8568 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCoordinator.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalCoordinator.java
@@ -1,13 +1,18 @@
package com.apigee.security.oas.extendedvalidator;
+import com.google.common.collect.ImmutableSet;
+
/**
* A {@link TraversalCoordinator} serves as the coordinator for otherwise interdependent {@linkplain
* TraversalCommand TraversalCommands}.
*/
public interface TraversalCoordinator {
- /** Traverses handled {@linkplain Traversal TraversalCommands}. */
- void traverse();
+ /**
+ * Traverses handled {@linkplain Traversal TraversalCommands} and returns {@link Extension
+ * extensions} found.
+ */
+ ImmutableSet<Extension> traverse();
/**
* Handles given {@link Traversal} in accordance with {@linkplain TraversalCoordinator
diff --git a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java
index 1f6ea32..680b896 100644
--- a/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java
+++ b/oas-core/src/main/java/com/apigee/security/oas/extendedvalidator/TraversalHelper.java
@@ -2,6 +2,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
import org.openapi4j.parser.model.v3.Callback;
import org.openapi4j.parser.model.v3.Contact;
import org.openapi4j.parser.model.v3.ExternalDocs;
@@ -47,4 +48,6 @@
void sendServerVariableTraversals(ImmutableMap<String, ServerVariable> serverVariables);
void sendTagTraversals(ImmutableList<Tag> tagList);
+
+ ImmutableSet<Extension> traverse();
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseExtensionScopeValidatorTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseExtensionScopeValidatorTest.java
new file mode 100644
index 0000000..aab22ec
--- /dev/null
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/BaseExtensionScopeValidatorTest.java
@@ -0,0 +1,154 @@
+package com.apigee.security.oas.extendedvalidator;
+
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.X_SECURITY_ALLOW;
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.X_SECURITY_TYPE;
+import static com.apigee.security.oas.extendedvalidator.ExtensionName.X_SECURITY_TYPE_DEFINITIONS;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
+import org.openapi4j.parser.model.OpenApiSchema;
+import org.openapi4j.parser.model.v3.OpenApi3;
+import org.openapi4j.parser.model.v3.Operation;
+import org.openapi4j.parser.model.v3.Parameter;
+import org.openapi4j.parser.model.v3.Path;
+
+@RunWith(JUnit4.class)
+public class BaseExtensionScopeValidatorTest {
+
+ @Rule public final MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+
+ @Mock private Extension extension;
+
+ private ExtensionValidator validator;
+
+ /** Setting up injector and scope validator instances. */
+ @Before
+ public void setup() {
+ Injector injector = Guice.createInjector(new ExtendedValidatorMainModule());
+ validator = injector.getInstance(ExtensionScopeValidator.class);
+ }
+
+ private static ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
+ createPathList(Class<? extends OpenApiSchema>[] pathClasses) {
+ ArrayList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> list = new ArrayList<>();
+ for (Class<? extends OpenApiSchema> pathClass : pathClasses) {
+ list.add(new SimpleImmutableEntry<>(pathClass, Optional.empty()));
+ }
+
+ return ImmutableList.copyOf(list);
+ }
+
+ @Test
+ public void validate_unsupportedExtension_returnsUnsupportedExtensionErrorType() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ ImmutableList.of();
+ when(extension.getExtensionName()).thenReturn("x-unsupported");
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension))
+ .hasSize(1)
+ .first()
+ .extracting(ExtensionValidationMessage::type)
+ .isEqualTo("UNSUPPORTED_EXTENSION");
+ }
+
+ @Test
+ public void validate_emptyPathSecurityTypeExtension_returnsInvalidScopeErrorType() {
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_TYPE.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(ImmutableList.of());
+
+ assertThat(validator.validate(extension))
+ .hasSize(1)
+ .first()
+ .extracting(ExtensionValidationMessage::type)
+ .isEqualTo("INVALID_SCOPE");
+ }
+
+ @Test
+ public void validate_validScopeSecurityTypeExtension_returnsEmptyErrorSet() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ createPathList(new Class[] {Path.class, Operation.class, Parameter.class});
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_TYPE.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension)).isEmpty();
+ }
+
+ @Test
+ public void validate_invalidScopeSecurityTypeExtension_returnsInvalidScopeErrorType() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ createPathList(new Class[] {Path.class});
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_TYPE.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension))
+ .hasSize(1)
+ .first()
+ .extracting(ExtensionValidationMessage::type)
+ .isEqualTo("INVALID_SCOPE");
+ }
+
+ @Test
+ public void validate_validScopeSecurityAllowExtension_returnsEmptyErrorSet() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ createPathList(new Class[] {Path.class, Operation.class});
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_ALLOW.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension)).isEmpty();
+ }
+
+ @Test
+ public void validate_invalidScopeSecurityAllowExtension_returnsInvalidScopeErrorTypes() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ createPathList(new Class[] {Path.class});
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_ALLOW.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension))
+ .hasSize(1)
+ .first()
+ .extracting(ExtensionValidationMessage::type)
+ .isEqualTo("INVALID_SCOPE");
+ }
+
+ @Test
+ public void validate_validScopeSecurityTypeDefinitionsExtension_returnsEmptyErrorSet() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ createPathList(new Class[] {OpenApi3.class});
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_TYPE_DEFINITIONS.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension)).isEmpty();
+ }
+
+ @Test
+ public void validate_invalidScopeSecurityTypeDefinitionsExtension_returnsInvalidScopeErrorType() {
+ ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> path =
+ createPathList(new Class[] {OpenApi3.class, Path.class});
+ when(extension.getExtensionName()).thenReturn(X_SECURITY_TYPE_DEFINITIONS.getExtensionName());
+ when(extension.getExtensionPath()).thenReturn(path);
+
+ assertThat(validator.validate(extension))
+ .hasSize(1)
+ .first()
+ .extracting(ExtensionValidationMessage::type)
+ .isEqualTo("INVALID_SCOPE");
+ }
+}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/CallbackTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/CallbackTraversalTest.java
index dc4944d..1acb831 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/CallbackTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/CallbackTraversalTest.java
@@ -1,12 +1,16 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -28,21 +32,18 @@
private CallbackTraversal callbackTraversal;
@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+ @Mock private ExtensionFactory extensionFactory;
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
@Mock private Callback callback;
+ @Mock private Extension extension;
/** Sets up live and mocked instances for testing. */
@Before
public void setup() {
callbackTraversal =
new CallbackTraversal(
- traversalHelperFactory,
- extensionValidationIntegrator,
- ImmutableList.of(),
- callback,
- "name");
+ traversalHelperFactory, extensionFactory, ImmutableList.of(), callback, "name");
when(callback.getCallbackPaths()).thenReturn(callbackPaths);
@@ -64,4 +65,20 @@
verify(traversalHelper, atLeastOnce()).sendPathTraversals(any());
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(callback.getExtensions()).thenReturn(Map.of("x-callback", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(callbackTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(callback.getExtensions()).thenReturn(Map.of());
+
+ assertThat(callbackTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java
index 462db49..17b5e8c 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/InfoTraversalTest.java
@@ -1,10 +1,14 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -25,7 +29,8 @@
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
+ @Mock private Extension extension;
@Mock private Info info;
private final License license = new License();
@@ -37,8 +42,7 @@
@Before
public void setup() {
infoTraversal =
- new InfoTraversal(
- traversalHelperFactory, extensionValidationIntegrator, ImmutableList.of(), info);
+ new InfoTraversal(traversalHelperFactory, extensionFactory, ImmutableList.of(), info);
when(info.getContact()).thenReturn(contact);
when(info.getLicense()).thenReturn(license);
@@ -59,4 +63,20 @@
verify(traversalHelper).sendLicenseTraversal(license);
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(info.getExtensions()).thenReturn(Map.of("x-info", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(infoTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(info.getExtensions()).thenReturn(Map.of());
+
+ assertThat(infoTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java
index efe1ae1..f1375a0 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OpenApiSpecificationTraversalTest.java
@@ -1,12 +1,16 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -20,6 +24,7 @@
import org.openapi4j.parser.model.v3.Info;
import org.openapi4j.parser.model.v3.OpenApi3;
import org.openapi4j.parser.model.v3.Path;
+import org.openapi4j.parser.model.v3.SecurityRequirement;
import org.openapi4j.parser.model.v3.Server;
import org.openapi4j.parser.model.v3.Tag;
@@ -30,8 +35,9 @@
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
@Mock private OpenApi3 openApiSpec;
+ @Mock private Extension extension;
private final Info info = new Info();
private final ExternalDocs externalDocs = new ExternalDocs();
@@ -42,6 +48,9 @@
private final ImmutableMap<String, Path> paths =
ImmutableMap.of("one", new Path(), "two", new Path(), "three", new Path());
+ private final ImmutableList<SecurityRequirement> securityRequirements =
+ ImmutableList.of(
+ new SecurityRequirement(), new SecurityRequirement(), new SecurityRequirement());
private OpenApiSpecificationTraversal openApiSpecificationTraversal;
@@ -49,14 +58,14 @@
@Before
public void setup() {
openApiSpecificationTraversal =
- new OpenApiSpecificationTraversal(
- traversalHelperFactory, extensionValidationIntegrator, openApiSpec);
+ new OpenApiSpecificationTraversal(traversalHelperFactory, extensionFactory, openApiSpec);
when(openApiSpec.getServers()).thenReturn(servers);
when(openApiSpec.getTags()).thenReturn(tags);
when(openApiSpec.getInfo()).thenReturn(info);
when(openApiSpec.getExternalDocs()).thenReturn(externalDocs);
when(openApiSpec.getPaths()).thenReturn(paths);
+ when(openApiSpec.getSecurityRequirements()).thenReturn(securityRequirements);
when(traversalHelperFactory.create(any(ImmutableList.class))).thenReturn(traversalHelper);
}
@@ -92,6 +101,22 @@
}
@Test
+ public void traverse_sendsSecurityRequirementsToTraversalHelper() {
+ openApiSpecificationTraversal.traverse();
+
+ verify(traversalHelper).sendSecurityRequirementTraversals(securityRequirements);
+ }
+
+ @Test
+ public void traverse_nullSecurityRequirementsMember_doesNotFail() {
+ when(openApiSpec.getSecurityRequirements()).thenReturn(null);
+
+ openApiSpecificationTraversal.traverse();
+
+ verify(traversalHelper, atLeastOnce()).sendSecurityRequirementTraversals(any());
+ }
+
+ @Test
public void traverse_sendsServersToTraversalHelper() {
openApiSpecificationTraversal.traverse();
@@ -122,4 +147,20 @@
verify(traversalHelper, atLeastOnce()).sendTagTraversals(any());
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(openApiSpec.getExtensions()).thenReturn(Map.of("x-openapi", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(openApiSpecificationTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(openApiSpec.getExtensions()).thenReturn(Map.of());
+
+ assertThat(openApiSpecificationTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java
index 5e4436e..1bd3800 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/OperationTraversalTest.java
@@ -1,12 +1,16 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -31,7 +35,8 @@
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
+ @Mock private Extension extension;
@Mock private Operation operation;
private final ExternalDocs externalDocs = new ExternalDocs();
@@ -53,7 +58,6 @@
/** Sets up live and mocked instances for testing. */
@Before
public void setup() {
-
when(operation.getExternalDocs()).thenReturn(externalDocs);
when(operation.getServers()).thenReturn(servers);
when(operation.getParameters()).thenReturn(parameters);
@@ -63,11 +67,7 @@
operationTraversal =
new OperationTraversal(
- traversalHelperFactory,
- extensionValidationIntegrator,
- ImmutableList.of(),
- operation,
- "name");
+ traversalHelperFactory, extensionFactory, ImmutableList.of(), operation, "name");
when(traversalHelperFactory.create(any(ImmutableList.class))).thenReturn(traversalHelper);
}
@@ -158,4 +158,20 @@
verify(traversalHelper, atLeastOnce()).sendServerTraversals(any());
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(operation.getExtensions()).thenReturn(Map.of("x-operation", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(operationTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(operation.getExtensions()).thenReturn(Map.of());
+
+ assertThat(operationTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/PathTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/PathTraversalTest.java
index 042f0a4..3bc0518 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/PathTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/PathTraversalTest.java
@@ -1,12 +1,16 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -37,7 +41,8 @@
@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
+ @Mock private Extension extension;
@Mock private Path path;
/** Sets up live and mocked instances for testing. */
@@ -45,11 +50,7 @@
public void setup() {
pathTraversal =
new PathTraversal(
- traversalHelperFactory,
- extensionValidationIntegrator,
- ImmutableList.of(),
- path,
- "name");
+ traversalHelperFactory, extensionFactory, ImmutableList.of(), path, "name");
when(path.getOperations()).thenReturn(operations);
when(path.getParameters()).thenReturn(parameters);
@@ -105,4 +106,20 @@
verify(traversalHelper, atLeastOnce()).sendServerTraversals(any());
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(path.getExtensions()).thenReturn(Map.of("x-path", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(pathTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(path.getExtensions()).thenReturn(Map.of());
+
+ assertThat(pathTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java
index 5887005..b77c054 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/ServerTraversalTest.java
@@ -1,12 +1,16 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -26,7 +30,8 @@
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
+ @Mock private Extension extension;
@Mock private Server server;
@Mock private ServerVariable serverVariable;
@@ -37,8 +42,7 @@
@Before
public void setup() {
serverTraversal =
- new ServerTraversal(
- traversalHelperFactory, extensionValidationIntegrator, ImmutableList.of(), server);
+ new ServerTraversal(traversalHelperFactory, extensionFactory, ImmutableList.of(), server);
serverVariables =
ImmutableMap.of(
@@ -66,4 +70,20 @@
verify(traversalHelper, atLeastOnce()).sendServerVariableTraversals(any());
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(server.getExtensions()).thenReturn(Map.of("x-server", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(serverTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(server.getExtensions()).thenReturn(Map.of());
+
+ assertThat(serverTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java
index ab86592..54ec074 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TagTraversalTest.java
@@ -1,10 +1,14 @@
package com.apigee.security.oas.extendedvalidator;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableList;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -24,7 +28,8 @@
@Mock private TraversalHelperFactory traversalHelperFactory;
@Mock private TraversalHelper traversalHelper;
- @Mock private ExtensionValidationIntegrator extensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
+ @Mock private Extension extension;
@Mock private Tag tag;
private final ExternalDocs externalDocs = new ExternalDocs();
@@ -35,8 +40,7 @@
@Before
public void setup() {
tagTraversal =
- new TagTraversal(
- traversalHelperFactory, extensionValidationIntegrator, ImmutableList.of(), tag);
+ new TagTraversal(traversalHelperFactory, extensionFactory, ImmutableList.of(), tag);
when(tag.getExternalDocs()).thenReturn(externalDocs);
when(traversalHelperFactory.create(any(ImmutableList.class))).thenReturn(traversalHelper);
@@ -48,4 +52,20 @@
verify(traversalHelper).sendExternalDocsTraversal(externalDocs);
}
+
+ @Test
+ public void traverse_withExtensions_returnsGeneratedExtensions() {
+ when(tag.getExtensions()).thenReturn(Map.of("x-tag", ""));
+ when(extensionFactory.create(anyString(), any(JsonNode.class), any(ImmutableList.class)))
+ .thenReturn(extension);
+
+ assertThat(tagTraversal.traverse()).hasSize(1).containsOnlyOnce(extension);
+ }
+
+ @Test
+ public void traverse_withoutExtensions_returnsEmptyExtensionsImmutableList() {
+ when(tag.getExtensions()).thenReturn(Map.of());
+
+ assertThat(tagTraversal.traverse()).isEmpty();
+ }
}
diff --git a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalTest.java b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalTest.java
index e99a7d3..9df32b5 100644
--- a/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalTest.java
+++ b/oas-core/src/test/java/com/apigee/security/oas/extendedvalidator/TraversalTest.java
@@ -23,7 +23,7 @@
@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
@Mock private TraversalHelperFactory traversalHelperFactory;
- @Mock private ExtensionValidationIntegrator baseExtensionValidationIntegrator;
+ @Mock private ExtensionFactory extensionFactory;
@Test
public void instantiate_traversal_addsTraversalsOpenApiObjClassToTraversalPath() {
@@ -31,11 +31,7 @@
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>> prevTraversalPath =
ImmutableList.copyOf(new ArrayDeque<>());
InfoTraversal traversal =
- new InfoTraversal(
- traversalHelperFactory,
- baseExtensionValidationIntegrator,
- prevTraversalPath,
- new Info());
+ new InfoTraversal(traversalHelperFactory, extensionFactory, prevTraversalPath, new Info());
ImmutableList<Map.Entry<Class<? extends OpenApiSchema>, Optional<String>>>
updatedTraversalPath = traversal.getUpdatedTraversalPath();