diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppMarketPlaceMapper.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppMarketPlaceMapper.java index 18c1fcdf04f..c738a8c6874 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppMarketPlaceMapper.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/apps/AppMarketPlaceMapper.java @@ -8,6 +8,7 @@ import org.openmetadata.schema.entity.app.AppType; import org.openmetadata.schema.entity.app.CreateAppMarketPlaceDefinitionReq; import org.openmetadata.schema.entity.services.ingestionPipelines.PipelineServiceClientResponse; import org.openmetadata.sdk.PipelineServiceClientInterface; +import org.openmetadata.service.apps.NativeApplication; import org.openmetadata.service.mapper.EntityMapper; import org.openmetadata.service.util.JsonUtils; @@ -29,6 +30,7 @@ public class AppMarketPlaceMapper .withSupportEmail(create.getSupportEmail()) .withPrivacyPolicyUrl(create.getPrivacyPolicyUrl()) .withClassName(create.getClassName()) + .withClassName(validateAppClass(create.getClassName())) .withAppType(create.getAppType()) .withAgentType(create.getAgentType()) .withScheduleType(create.getScheduleType()) @@ -49,16 +51,30 @@ public class AppMarketPlaceMapper return app; } + private String validateAppClass(String className) { + className = + Objects.requireNonNull(className, "AppMarketPlaceDefinition.className cannot be null"); + if (!className.startsWith("org.openmetadata.") && !className.startsWith("io.collate.")) { + throw new BadRequestException( + "Only classes from org.openmetadata or io.collate packages are allowed: " + className); + } + try { + Class clazz = Class.forName(className); + if (!NativeApplication.class.isAssignableFrom(clazz)) { + throw new BadRequestException( + "AppMarketPlaceDefinition.className must be a subclass of NativeApplication: " + + className); + } + return className; + } catch (ClassNotFoundException e) { + throw new BadRequestException( + "AppMarketPlaceDefinition.className class not found: " + className); + } + } + private void validateApplication(AppMarketPlaceDefinition app) { try { JsonUtils.validateJsonSchema(app, AppMarketPlaceDefinition.class); - Class.forName( - Objects.requireNonNull( - app.getClassName(), "AppMarketPlaceDefinition.className cannot be null")); - } catch (ClassNotFoundException e) { - throw new BadRequestException( - "Application Cannot be registered, because the Class cannot be found on the Classpath: " - + app.getEventSubscriptions()); } catch (ConstraintViolationException | NullPointerException e) { throw new BadRequestException( "Application Cannot be registered, because the AppMarketPlaceDefinition is not valid: " @@ -69,7 +85,7 @@ public class AppMarketPlaceMapper if (response.getCode() != 200) { throw new BadRequestException( String.format( - "Application Cannot be registered, Error from Pipeline Service Client. Status Code : %s , Reponse : %s", + "Application Cannot be registered, Error from Pipeline Service Client. Status Code : %s , Response : %s", response.getCode(), JsonUtils.pojoToJson(response))); } }