Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: service credentials id check #391

Merged
merged 5 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions content/pages/editMetadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@
"required": true
},
{
"name": "serviceSD",
"label": "Service Self-Description",
"placeholder": "e.g. https://file.com/service-self-description.json",
"help": "Please enter the URL to a valid service self-description and click \"ADD FILE\" to validate the data. This file URL and its content will be publicly available after publishing",
"type": "serviceSD"
"name": "serviceCredential",
"label": "Service Credential",
"placeholder": "e.g. https://file.com/service-credential.json",
"help": "Please enter the URL to a valid service credential and click \"ADD FILE\" to validate the data. This file URL and its content will be publicly available after publishing",
"type": "serviceCredential"
},
{
"name": "tags",
Expand Down
17 changes: 2 additions & 15 deletions content/pages/verify.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
{
"title": "Service Self-Description Verifier",
"description": "Visualize and verify service self-descriptions via DID.",
"title": "Service Credential Verifier",
"description": "Visualize and verify service credentials via DID.",
"input": {
"label": "Enter a valid did:op",
"placeholder": "did:op:87152E582e3B05Cc6940E9763b9e0c22eA812448",
"buttonLabel": "Verify"
},
"serviceSDSection": {
"title": "Service Self-Description",
"badgeLabel": "Verified Self-Description"
},
"errorSection": {
"title": "Validation Errors",
"badgeLabel": "Invalid Self-Description"
},
"errorList": {
"invalidDid": "The provided DID:OP does not refer to any DDO.",
"noServiceSD": "The requested DDO does not contain a service self-description.",
"default": "An unexpected error occurred. Please try again later."
}
}
10 changes: 5 additions & 5 deletions content/publish/form.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"required": true
},
{
"name": "serviceSD",
"label": "Service Self-Description",
"placeholder": "e.g. https://file.com/service-self-description.json",
"help": "Please enter the URL to a valid service self-description and click \"ADD FILE\" to validate the data. This file URL and its content will be publicly available after publishing",
"type": "serviceSD"
"name": "serviceCredential",
"label": "Service Credential",
"placeholder": "e.g. https://file.com/service-credential.json",
"help": "Please enter the URL to a valid service credential and click \"ADD FILE\" to validate the data. This file URL and its content will be publicly available after publishing",
"type": "serviceCredential"
},
{
"name": "tags",
Expand Down
82 changes: 48 additions & 34 deletions src/@context/Asset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import { assetStateToString } from '@utils/assetState'
import { isValidDid } from '@utils/ddo'
import { useAddressConfig } from '@hooks/useAddressConfig'
import {
getPublisherFromServiceSD,
getServiceSD,
verifyRawServiceSD
getPublisherFromServiceCredential,
getServiceCredential,
verifyRawServiceCredential
} from '@components/Publish/_utils'

export interface AssetProviderValue {
Expand All @@ -37,9 +37,10 @@ export interface AssetProviderValue {
oceanConfig: Config
loading: boolean
assetState: string
isVerifyingSD: boolean
isServiceSDVerified: boolean
serviceSDVersion: string
isVerifyingServiceCredential: boolean
isServiceCredentialVerified: boolean
serviceCredentialIdMatch?: boolean
serviceCredentialVersion: string
verifiedServiceProviderName: string
fetchAsset: (token?: CancelToken) => Promise<void>
}
Expand Down Expand Up @@ -68,9 +69,14 @@ function AssetProvider({
const [isAssetNetwork, setIsAssetNetwork] = useState<boolean>()
const [oceanConfig, setOceanConfig] = useState<Config>()
const [assetState, setAssetState] = useState<string>()
const [isVerifyingSD, setIsVerifyingSD] = useState(false)
const [isServiceSDVerified, setIsServiceSDVerified] = useState<boolean>()
const [serviceSDVersion, setServiceSDVersion] = useState<string>()
const [isVerifyingServiceCredential, setIsVerifyingServiceCredential] =
useState(false)
const [isServiceCredentialVerified, setIsServiceCredentialVerified] =
useState<boolean>()
const [serviceCredentialIdMatch, setServiceCredentialIdMatch] =
useState<boolean>()
const [serviceCredentialVersion, setServiceCredentialVersion] =
useState<string>()
const [verifiedServiceProviderName, setVerifiedServiceProviderName] =
useState<string>()

Expand Down Expand Up @@ -162,43 +168,50 @@ function AssetProvider({
}, [asset?.chainId, asset?.services, accountId, did])

// -----------------------------------
// Helper: Get and set asset Self-Description state
// Helper: Get and set asset Service Credential state
// -----------------------------------
const checkServiceSD = useCallback(
const checkServiceCredential = useCallback(
async (asset: AssetExtended): Promise<void> => {
if (!asset) return
setIsVerifyingSD(true)
setIsVerifyingServiceCredential(true)

try {
const { additionalInformation } = asset.metadata
const serviceSD = additionalInformation?.gaiaXInformation?.serviceSD
const serviceCredential =
additionalInformation?.gaiaXInformation?.serviceSD

if (!serviceSD || !Object.keys(serviceSD)?.length) {
setIsServiceSDVerified(false)
setServiceSDVersion(undefined)
if (!serviceCredential || !Object.keys(serviceCredential)?.length) {
setIsServiceCredentialVerified(false)
setServiceCredentialIdMatch(false)
setServiceCredentialVersion(undefined)
setVerifiedServiceProviderName(undefined)
return
}

const serviceSDContent = serviceSD?.url
? await getServiceSD(serviceSD?.url)
: serviceSD?.raw
const serviceCredentialContent = serviceCredential?.url
? await getServiceCredential(serviceCredential?.url)
: serviceCredential?.raw

const { verified, complianceApiVersion } = await verifyRawServiceSD(
serviceSDContent
)
const { verified, complianceApiVersion, idMatch } =
await verifyRawServiceCredential(serviceCredentialContent, asset.id)

setIsServiceSDVerified(verified && !!serviceSDContent)
setServiceSDVersion(complianceApiVersion)
const serviceProviderName = getPublisherFromServiceSD(serviceSDContent)
setIsServiceCredentialVerified(verified && !!serviceCredentialContent)
setServiceCredentialIdMatch(
verified && !!serviceCredentialContent && idMatch
)
setServiceCredentialVersion(complianceApiVersion)
const serviceProviderName = getPublisherFromServiceCredential(
serviceCredentialContent
)
setVerifiedServiceProviderName(serviceProviderName)
} catch (error) {
setIsServiceSDVerified(false)
setServiceSDVersion(undefined)
setIsServiceCredentialVerified(false)
setServiceCredentialIdMatch(false)
setServiceCredentialVersion(undefined)
setVerifiedServiceProviderName(undefined)
LoggerInstance.error(error)
} finally {
setIsVerifyingSD(false)
setIsVerifyingServiceCredential(false)
}
},
[]
Expand Down Expand Up @@ -269,13 +282,13 @@ function AssetProvider({
}, [asset])

// -----------------------------------
// Set Asset Self-Description state
// Set Asset Service Credential state
// -----------------------------------
useEffect(() => {
if (!asset) return

checkServiceSD(asset)
}, [asset, checkServiceSD])
checkServiceCredential(asset)
}, [asset, checkServiceCredential])

return (
<AssetContext.Provider
Expand All @@ -294,9 +307,10 @@ function AssetProvider({
isOwner,
oceanConfig,
assetState,
isVerifyingSD,
isServiceSDVerified,
serviceSDVersion,
isVerifyingServiceCredential,
isServiceCredentialVerified,
serviceCredentialIdMatch,
serviceCredentialVersion,
verifiedServiceProviderName
} as AssetProviderValue
}
Expand Down
6 changes: 6 additions & 0 deletions src/@types/gaia-x/2210/ServiceCredential.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface ServiceCredential {
raw?: string
url?: string
isVerified?: boolean
idMatch?: boolean
}
5 changes: 0 additions & 5 deletions src/@types/gaia-x/2210/ServiceSD.d.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import Loader from '@components/@shared/atoms/Loader'
import styles from './index.module.css'
import {
getFormattedCodeString,
getServiceSD,
signServiceSD,
getServiceCredential,
signServiceCredential,
storeRawServiceSD,
verifyRawServiceSD
verifyRawServiceCredential
} from '@components/Publish/_utils'
import URLInput from '../URLInput'
import FileInfo from '../FilesInput/Info'

const serviceSelfDescriptionOptions = [
const serviceCredentialOptions = [
{
name: 'url',
checked: false,
Expand All @@ -30,18 +30,19 @@ const serviceSelfDescriptionOptions = [
}
]

export default function ServiceSD(props: InputProps): ReactElement {
export default function ServiceCredential(props: InputProps): ReactElement {
const [field, meta, helpers] = useField(props.name)
const [userSelection, setUserSelection] = useState<string>()
const [isVerified, setIsVerified] = useState(false)
const [isLoading, setIsLoading] = useState(false)
const [rawServiceSDPreview, setRawServiceSDPreview] = useState<string>()
const [rawServiceCredentialPreview, setRawServiceCredentialPreview] =
useState<string>()

const validateUrl = async (url: string): Promise<string> => {
try {
setIsLoading(true)
const serviceSD = await getServiceSD(url)
const { verified } = await verifyRawServiceSD(serviceSD)
const serviceCredential = await getServiceCredential(url)
const { verified } = await verifyRawServiceCredential(serviceCredential)
setIsVerified(verified)

if (!verified) {
Expand All @@ -50,15 +51,15 @@ export default function ServiceSD(props: InputProps): ReactElement {
)
return
}
if (!serviceSD) {
if (!serviceCredential) {
toast.error(
'The linked file is not accessible. Please verify your service provider allows access from this domain and try again.'
)
return
}

helpers.setValue({ url, isVerified: verified })
toast.success('Great! The provided service self-description looks good.')
toast.success('Great! The provided service credential looks good.')
} catch (error) {
toast.error('Could not fetch file info. Please check URL and try again')
console.error(error.message)
Expand All @@ -67,31 +68,34 @@ export default function ServiceSD(props: InputProps): ReactElement {
}
}

const verifyRawBody = async (rawServiceSD: string) => {
const verifyRawBody = async (rawServiceCredential: string) => {
try {
setIsLoading(true)

const parsedServiceSD = JSON.parse(rawServiceSD)
const signedServiceSD = parsedServiceSD?.complianceCredential
? parsedServiceSD
: await signServiceSD(parsedServiceSD)
const parsedServiceCredential = JSON.parse(rawServiceCredential)
const signedServiceCredential =
parsedServiceCredential?.complianceCredential
? parsedServiceCredential
: await signServiceCredential(parsedServiceCredential)

const { verified, storedSdUrl } = await storeRawServiceSD(signedServiceSD)
const { verified, storedSdUrl } = await storeRawServiceSD(
signedServiceCredential
)
setIsVerified(verified)

if (!verified) {
toast.error(
'The data you entered appears to be invalid. Please check the provided service self-description and try again'
'The data you entered appears to be invalid. Please check the provided service credential and try again'
)
return
}

setRawServiceSDPreview(signedServiceSD)
setRawServiceCredentialPreview(signedServiceCredential)
helpers.setValue({ url: storedSdUrl })
toast.success('Great! The provided service self-description looks good.')
toast.success('Great! The provided service credential looks good.')
} catch (error) {
toast.error(
'Something went wrong. Please check the provided service self-description and try again'
'Something went wrong. Please check the provided service credential and try again'
)
console.error(error.message)
} finally {
Expand Down
6 changes: 3 additions & 3 deletions src/components/@shared/FormInput/InputElement/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import ContainerInput from '@shared/FormInput/InputElement/ContainerInput'
import TagsAutoComplete from './TagsAutoComplete'
import TabsFile from '@shared/atoms/TabsFile'
import { extensions, oceanTheme } from '@utils/codemirror'
import ServiceSD from './ServiceSD'
import ServiceCredential from './ServiceCredential'

const cx = classNames.bind(styles)

Expand Down Expand Up @@ -176,8 +176,8 @@ const InputElement = forwardRef(
)
case 'files':
return <FilesInput {...field} form={form} {...props} />
case 'serviceSD':
return <ServiceSD {...field} {...props} />
case 'serviceCredential':
return <ServiceCredential {...field} {...props} />
case 'container':
return <ContainerInput {...field} {...props} />
case 'providerUrl':
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.container {
margin-top: var(--spacer);
}

.header {
display: flex;
justify-content: space-between;
Expand All @@ -9,6 +13,10 @@
position: relative;
}

.markdownContainer pre {
margin-top: 0;
}

.copyContainer {
position: absolute;
top: calc(var(--spacer) / 2);
Expand Down
Loading