From cdd5c5cf16302c877207e88313c8cd535facddfd Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 25 Feb 2021 23:03:47 +0200 Subject: [PATCH] WIP validate for dockerhub images and 3rd party images --- src/components/molecules/MetadataPreview.tsx | 6 +- src/components/pages/Publish/index.tsx | 10 ++- src/utils/metadata.ts | 65 +++++++++++++++++++- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/components/molecules/MetadataPreview.tsx b/src/components/molecules/MetadataPreview.tsx index 420c3603b..42b674ed1 100644 --- a/src/components/molecules/MetadataPreview.tsx +++ b/src/components/molecules/MetadataPreview.tsx @@ -157,7 +157,11 @@ export function MetadataAlgorithmPreview({ /> )} {values.algorithmPrivacy && ( - + )} diff --git a/src/components/pages/Publish/index.tsx b/src/components/pages/Publish/index.tsx index 38483705d..e6fc44ec7 100644 --- a/src/components/pages/Publish/index.tsx +++ b/src/components/pages/Publish/index.tsx @@ -11,11 +11,11 @@ import { initialValues as initialValuesAlgorithm, validationSchema as validationSchemaAlgorithm } from '../../../models/FormAlgoPublish' - import { transformPublishFormToMetadata, transformPublishAlgorithmFormToMetadata, - mapTimeoutStringToSeconds + mapTimeoutStringToSeconds, + validateDockerImage } from '../../../utils/metadata' import { MetadataPreview, @@ -156,10 +156,14 @@ export default function PublishPage({ ) => void ): Promise { const metadata = transformPublishAlgorithmFormToMetadata(values) - try { Logger.log('Publish Algorithm with ', metadata) + const validImage = await validateDockerImage( + values.image, + values.containerTag + ) + const ddo = await publish( (metadata as unknown) as Metadata, values.algorithmPrivacy === true ? 'compute' : 'access' diff --git a/src/utils/metadata.ts b/src/utils/metadata.ts index 014513d29..21e51786c 100644 --- a/src/utils/metadata.ts +++ b/src/utils/metadata.ts @@ -1,3 +1,5 @@ +import axios, { CancelToken, AxiosResponse } from 'axios' +import { toast } from 'react-toastify' import { MetadataMarket, MetadataPublishFormDataset, @@ -6,7 +8,7 @@ import { import { toStringNoMS } from '.' import AssetModel from '../models/Asset' import slugify from '@sindresorhus/slugify' -import { DDO, MetadataAlgorithm } from '@oceanprotocol/lib' +import { DDO, MetadataAlgorithm, Logger } from '@oceanprotocol/lib' export function transformTags(value: string): string[] { const originalTags = value?.split(',') @@ -128,6 +130,67 @@ export function transformPublishFormToMetadata( return metadata } +async function isDockerHubImageValid( + image: string, + tag: string +): Promise { + try { + const response = await axios.get( + `https://hub.docker.com/v2/repositories/${image}/tags/${tag}` + ) + if (!response || response.status !== 200 || !response.data) { + toast.error( + 'Could not fetch docker hub image info. Please check image name and tag and try again' + ) + return false + } + + return true + } catch (error) { + Logger.error(error.message) + return false + } +} + +async function is3rdPartyImageValid(imageURL: string): Promise { + try { + const response = await axios.options(imageURL) + if (!response || response.status !== 200) { + toast.error( + 'Could not fetch docker image info. Please check URL and try again' + ) + return false + } + return true + } catch (error) { + Logger.error(error.message) + return false + } +} + +function isUrl(image: string): boolean { + const pattern = new RegExp( + '^(https?:\\/\\/)?' + + '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + + '((\\d{1,3}\\.){3}\\d{1,3}))' + + '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + + '(\\?[;&a-z\\d%_.~+=-]*)?' + + '(\\#[-a-z\\d_]*)?$', + 'i' + ) + return !!pattern.test(image) +} + +export async function validateDockerImage( + dockerImage: string, + tag: string +): Promise { + const isValid = isUrl(dockerImage) + ? await is3rdPartyImageValid(dockerImage) + : await isDockerHubImageValid(dockerImage, tag) + return isValid +} + export function transformPublishAlgorithmFormToMetadata( { name,