Skip to content

Commit

Permalink
TEA layout and duplication bug fixes (#44)
Browse files Browse the repository at this point in the history
* chore: skeleton Transparency Exchange API
* fix(build): remove dup class
* fix(build): add exports
* feat: Prisma models
* fix(build): remove space
* feat: refactor axios calls
* fix: lastObserved on update
* fix: duplication bugs

---------

Co-authored-by: Christopher Langton <[email protected]>
  • Loading branch information
0x73746F66 and chrisdlangton authored Sep 25, 2024
1 parent a1bb5fd commit 663e5d7
Show file tree
Hide file tree
Showing 26 changed files with 709 additions and 315 deletions.
16 changes: 10 additions & 6 deletions functions/cdx/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ export async function onRequestPost(context) {
return Response.json({ ok: false, error: { message: 'CDX is missing necessary fields.' } })
}
console.log(cdx)
const cdxStr = JSON.stringify(cdx)
const cdxId = await hex(cdxStr)
// const cdxStr = JSON.stringify(cdx) //TODO: Add to TEA
const componentsJSON = JSON.stringify(cdx.components)
const dependenciesJSON = JSON.stringify(cdx.dependencies)
const cdxId = await hex(cdx.metadata?.component?.name + componentsJSON + dependenciesJSON)
const cdxData = {
cdxId,
source: 'upload',
Expand All @@ -47,8 +49,8 @@ export async function onRequestPost(context) {
createdAt: (new Date(cdx.metadata.timestamp)).getTime(),
toolName: cdx.metadata.tools.map(t => `${t?.vendor} ${t?.name} ${t?.version}`.trim()).join(', '),
externalReferencesJSON: JSON.stringify(cdx.metadata.component?.externalReferences || []),
componentsJSON: JSON.stringify(cdx.components),
dependenciesJSON: JSON.stringify(cdx.dependencies),
componentsJSON,
dependenciesJSON,
}
const info = await prisma.cdx.upsert({
where: {
Expand Down Expand Up @@ -107,7 +109,9 @@ export async function onRequestPost(context) {
const originalFinding = await prisma.findings.findFirst({
where: {
findingId,
AND: { cdxId },
AND: {
memberEmail: session.memberEmail
},
}
})
let finding;
Expand Down Expand Up @@ -143,7 +147,7 @@ export async function onRequestPost(context) {
findingKey: finding.id,
},
data: {
modifiedAt: vexData.lastObserved
lastObserved: vexData.lastObserved
},
})
} else {
Expand Down
4 changes: 2 additions & 2 deletions functions/enrich/[findingKey].js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export async function onRequestGet(context) {
// MissionWellbeingImpact

const { searchParams } = new URL(request.url)
const seen = parseInt(searchParams.get('seen'), 10) || 1
const seen = parseInt(searchParams.get('seen'), 10) || 0
let { analysisState = 'in_triage', triageAutomated = 0, triagedAt = null, seenAt = null } = finding?.triage || {}
if (
(cvssVector && (
Expand All @@ -130,7 +130,7 @@ export async function onRequestGet(context) {
triagedAt = new Date().getTime()
}
}
if (seen === 1 && !seenAt) {
if (seen === 1) {
seenAt = new Date().getTime()
}
if (!finding?.triage) {
Expand Down
11 changes: 7 additions & 4 deletions functions/github/repos/[org]/[repo]/spdx.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ export async function onRequestGet(context) {

const process = async (prisma, session, repoName, content) => {
const spdx = content.sbom
const relationshipsJSON = JSON.stringify(spdx.relationships)
const spdxStr = JSON.stringify(spdx)
const spdxId = await hex(spdxStr)
const spdxId = await hex(spdx.name + relationshipsJSON)
const spdxData = {
spdxId,
source: 'GitHub',
Expand All @@ -118,7 +119,7 @@ const process = async (prisma, session, repoName, content) => {
toolName: spdx.creationInfo.creators.join(', '),
documentDescribes: spdx.documentDescribes.join(','),
packagesJSON: JSON.stringify(spdx.packages),
relationshipsJSON: JSON.stringify(spdx.relationships),
relationshipsJSON,
comment: spdx.creationInfo?.comment || '',
}
const findingIds = []
Expand Down Expand Up @@ -175,7 +176,9 @@ const process = async (prisma, session, repoName, content) => {
const originalFinding = await prisma.findings.findFirst({
where: {
findingId,
AND: { spdxId },
AND: {
memberEmail: session.memberEmail
},
}
})
let finding;
Expand Down Expand Up @@ -212,7 +215,7 @@ const process = async (prisma, session, repoName, content) => {
findingKey: finding.id,
},
data: {
modifiedAt: vexData.lastObserved
lastObserved: vexData.lastObserved
},
})
} else {
Expand Down
6 changes: 4 additions & 2 deletions functions/spdx/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ export async function onRequestPost(context) {
const originalFinding = await prisma.findings.findFirst({
where: {
findingId,
AND: { spdxId },
AND: {
memberEmail: session.memberEmail
},
}
})
let finding;
Expand Down Expand Up @@ -143,7 +145,7 @@ export async function onRequestPost(context) {
findingKey: finding.id,
},
data: {
modifiedAt: vexData.lastObserved
lastObserved: vexData.lastObserved
},
})
} else {
Expand Down
43 changes: 43 additions & 0 deletions functions/v0.2.0/collection/[collectionId].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Collection } from "@/tea";
import { PrismaD1 } from '@prisma/adapter-d1';
import { PrismaClient } from '@prisma/client';

/**
* If only the serialNumber parameter is supplied, retrieve the latest version of the BOM from the repository.
* If providing serialNumber and version, a specific version of the BOM will be retrieved.
* Supports HTTP content negotiation for all CycloneDX BOM formats and versions.
* If original is true, returns the original, unmodified BOM.
*
* curl -X GET 'http://localhost:8000/v1/bom?serialNumber=urn%3Auuid%3A3e671687-395b-41f5-a30f-a58921a69b79' -H 'accept: application/vnd.cyclonedx+json; version=1.4'
*/
export async function onRequestGet(context) {
const {
request, // same as existing Worker API
env, // same as existing Worker API
params, // if filename includes [id] or [[path]]
waitUntil, // same as ctx.waitUntil in existing Worker API
next, // used for middleware or to fetch assets
data, // arbitrary space for passing data between middlewares
} = context
try {
const adapter = new PrismaD1(env.d1db)
const prisma = new PrismaClient({
adapter,
transactionOptions: {
maxWait: 1500, // default: 2000
timeout: 2000, // default: 5000
},
})
params.collectionId // id assigned in the system to the specific collection as returned by collection element

// const member = await prisma.members.findFirst({
// where: {
// email: verificationResult.session.memberEmail,
// },
// })
// return Response.json([]) // [ Collection ]
} catch (err) {
console.error(err)
// return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED })
}
}
48 changes: 48 additions & 0 deletions functions/v0.2.0/leaf/[tei].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Visibility, CollectionEl } from "@/tea";
import { PrismaD1 } from '@prisma/adapter-d1';
import { PrismaClient } from '@prisma/client';

/**
* If only the serialNumber parameter is supplied, retrieve the latest version of the BOM from the repository.
* If providing serialNumber and version, a specific version of the BOM will be retrieved.
* Supports HTTP content negotiation for all CycloneDX BOM formats and versions.
* If original is true, returns the original, unmodified BOM.
*
* curl -X GET 'http://localhost:8000/v1/bom?serialNumber=urn%3Auuid%3A3e671687-395b-41f5-a30f-a58921a69b79' -H 'accept: application/vnd.cyclonedx+json; version=1.4'
*/
export async function onRequestGet(context) {
const {
request, // same as existing Worker API
env, // same as existing Worker API
params, // if filename includes [id] or [[path]]
waitUntil, // same as ctx.waitUntil in existing Worker API
next, // used for middleware or to fetch assets
data, // arbitrary space for passing data between middlewares
} = context
try {
const adapter = new PrismaD1(env.d1db)
const prisma = new PrismaClient({
adapter,
transactionOptions: {
maxWait: 1500, // default: 2000
timeout: 2000, // default: 5000
},
})
params.tei // TEI unique leaf index
const { searchParams } = new URL(request.url)
const visibility = searchParams.get('visibility') // Used to specify whether we list public or private components
if (visibility && ![Visibility.ALLAVAILABLE, Visibility.PUBLICONLY].includes(visibility)) {
return Response(null, { status: 422, statusText: `Invalid value provided: visibility=${visibility}` })
}

// const member = await prisma.members.findFirst({
// where: {
// email: verificationResult.session.memberEmail,
// },
// })
// return Response.json([]) // [ CollectionEl ]
} catch (err) {
console.error(err)
// return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED })
}
}
48 changes: 48 additions & 0 deletions functions/v0.2.0/product/[tei].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Visibility, Product } from "@/tea";
import { PrismaD1 } from '@prisma/adapter-d1';
import { PrismaClient } from '@prisma/client';

/**
* If only the serialNumber parameter is supplied, retrieve the latest version of the BOM from the repository.
* If providing serialNumber and version, a specific version of the BOM will be retrieved.
* Supports HTTP content negotiation for all CycloneDX BOM formats and versions.
* If original is true, returns the original, unmodified BOM.
*
* curl -X GET 'http://localhost:8000/v1/bom?serialNumber=urn%3Auuid%3A3e671687-395b-41f5-a30f-a58921a69b79' -H 'accept: application/vnd.cyclonedx+json; version=1.4'
*/
export async function onRequestGet(context) {
const {
request, // same as existing Worker API
env, // same as existing Worker API
params, // if filename includes [id] or [[path]]
waitUntil, // same as ctx.waitUntil in existing Worker API
next, // used for middleware or to fetch assets
data, // arbitrary space for passing data between middlewares
} = context
try {
const adapter = new PrismaD1(env.d1db)
const prisma = new PrismaClient({
adapter,
transactionOptions: {
maxWait: 1500, // default: 2000
timeout: 2000, // default: 5000
},
})
params.tei // TEI unique product index
const { searchParams } = new URL(request.url)
const visibility = searchParams.get('visibility') // Used to specify whether we list public or private components
if (visibility && ![Visibility.ALLAVAILABLE, Visibility.PUBLICONLY].includes(visibility)) {
return Response(null, { status: 422, statusText: `Invalid value provided: visibility=${visibility}` })
}

// const member = await prisma.members.findFirst({
// where: {
// email: verificationResult.session.memberEmail,
// },
// })
// return Response.json([]) // [ Product ]
} catch (err) {
console.error(err)
// return Response.json({ ok: false, error: { message: err }, result: AuthResult.REVOKED })
}
}
132 changes: 0 additions & 132 deletions migrations/0000_plan_TMP.sql

This file was deleted.

Loading

0 comments on commit 663e5d7

Please sign in to comment.