Skip to content

Commit

Permalink
Added repositories clickable to show black/white list
Browse files Browse the repository at this point in the history
  • Loading branch information
FredrikSorum committed Feb 19, 2025
1 parent 96cda3a commit 9bd1a30
Show file tree
Hide file tree
Showing 6 changed files with 377 additions and 162 deletions.
127 changes: 89 additions & 38 deletions api/src/get/blacklist.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,89 @@
import { FastifyReply, FastifyRequest } from "fastify"
import run from "../db.js"
import fetchBlackList from "../utils/fetchBlacklist"

export default async function blacklistIndexHandler(_: FastifyRequest, res: FastifyReply) {
try {
const result = await run(`
SELECT b.name,
COALESCE((SELECT array_agg(version) FROM blacklist_versions WHERE name = b.name), '{}'::TEXT[]) as versions,
COALESCE((SELECT array_agg(ecosystem) FROM blacklist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems,
COALESCE((SELECT array_agg(repository) FROM blacklist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories,
COALESCE((SELECT array_agg(comment) FROM blacklist_comments WHERE name = b.name), '{}'::TEXT[]) as comments
FROM blacklist b;
`, [])
if (result.rows.length === 0) {
return res.send([])
}

return res.send(result.rows)
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}

export async function blacklistHandler(req: FastifyRequest, res: FastifyReply) {
const { ecosystem, name, version } = req.params as OSVHandlerParams
if (!ecosystem || !name || !version) {
return res.status(400).send({ error: "Missing name, version, or ecosystem." })
}

try {
return fetchBlackList({name, version, ecosystem, res})
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}
import { FastifyReply, FastifyRequest } from "fastify"
import run from "../db.js"
import fetchBlackList from "../utils/fetchBlacklist"

export default async function blacklistIndexHandler(_: FastifyRequest, res: FastifyReply) {
try {
const result = await run(`
SELECT b.name,
COALESCE((SELECT array_agg(version) FROM blacklist_versions WHERE name = b.name), '{}'::TEXT[]) as versions,
COALESCE((SELECT array_agg(ecosystem) FROM blacklist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems,
COALESCE((SELECT array_agg(repository) FROM blacklist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories,
COALESCE((SELECT array_agg(comment) FROM blacklist_comments WHERE name = b.name), '{}'::TEXT[]) as comments
FROM blacklist b;
`, [])
if (result.rows.length === 0) {
return res.send([])
}

return res.send(result.rows)
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}

export async function blacklistHandler(req: FastifyRequest, res: FastifyReply) {
const { ecosystem, name, version } = req.params as OSVHandlerParams
if (!ecosystem || !name || !version) {
return res.status(400).send({ error: "Missing name, version, or ecosystem." })
}

try {
return fetchBlackList({name, version, ecosystem, res})
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}

export async function blacklistByRepositoryHandler(req: FastifyRequest, res: FastifyReply) {
const { repository } = req.query as { repository?: string };

if (!repository) {
return res.status(400).send({ error: "Missing 'repository' query parameter." });
}

try {
console.log(`Fetching blacklist data for repository: ${repository}`);

const result = await run(
`
SELECT b.name,
COALESCE(
(SELECT array_agg(version)
FROM blacklist_versions
WHERE name = b.name), '{}'::TEXT[]
) as versions,
COALESCE(
(SELECT array_agg(ecosystem)
FROM blacklist_ecosystems
WHERE name = b.name), '{}'::TEXT[]
) as ecosystems,
COALESCE(
(SELECT array_agg(repository)
FROM blacklist_repositories
WHERE name = b.name), '{}'::TEXT[]
) as repositories,
COALESCE(
(SELECT array_agg(comment)
FROM blacklist_comments
WHERE name = b.name), '{}'::TEXT[]
) as comments
FROM blacklist b
JOIN blacklist_repositories br ON b.name = br.name
WHERE br.repository = $1;
`,
[repository]
);

if (result.rows.length === 0) {
return res.status(404).send({ error: `No blacklist entries found for repository: ${repository}` });
}

return res.send(result.rows);
} catch (error) {
console.error("Database error:", error);
return res.status(500).send({ error: "Internal Server Error" });
}
}
129 changes: 90 additions & 39 deletions api/src/get/whitelist.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,90 @@
import { FastifyReply, FastifyRequest } from "fastify"
import run from "../db.js"
import fetchWhiteList from "../utils/fetchWhitelist"

export default async function whitelistIndexHandler(_: FastifyRequest, res: FastifyReply) {
try {
const result = await run(`
SELECT b.name,
COALESCE((SELECT array_agg(version) FROM whitelist_versions WHERE name = b.name), '{}'::TEXT[]) as versions,
COALESCE((SELECT array_agg(ecosystem) FROM whitelist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems,
COALESCE((SELECT array_agg(repository) FROM whitelist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories,
COALESCE((SELECT array_agg(comment) FROM whitelist_comments WHERE name = b.name), '{}'::TEXT[]) as comments
FROM whitelist b;
`, [])
if (result.rows.length === 0) {
return res.send([])
}

return res.send(result.rows)
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}

export async function whitelistHandler(req: FastifyRequest, res: FastifyReply) {
const { ecosystem, name, version } = req.params as OSVHandlerParams

if (!ecosystem || !name || !version) {
return res.status(400).send({ error: "Missing name, version, or ecosystem." })
}

try {
return fetchWhiteList({name, version, ecosystem, res})
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}
import { FastifyReply, FastifyRequest } from "fastify"
import run from "../db.js"
import fetchWhiteList from "../utils/fetchWhitelist"

export default async function whitelistIndexHandler(_: FastifyRequest, res: FastifyReply) {
try {
const result = await run(`
SELECT b.name,
COALESCE((SELECT array_agg(version) FROM whitelist_versions WHERE name = b.name), '{}'::TEXT[]) as versions,
COALESCE((SELECT array_agg(ecosystem) FROM whitelist_ecosystems WHERE name = b.name), '{}'::TEXT[]) as ecosystems,
COALESCE((SELECT array_agg(repository) FROM whitelist_repositories WHERE name = b.name), '{}'::TEXT[]) as repositories,
COALESCE((SELECT array_agg(comment) FROM whitelist_comments WHERE name = b.name), '{}'::TEXT[]) as comments
FROM whitelist b;
`, [])
if (result.rows.length === 0) {
return res.send([])
}

return res.send(result.rows)
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}

export async function whitelistHandler(req: FastifyRequest, res: FastifyReply) {
const { ecosystem, name, version } = req.params as OSVHandlerParams

if (!ecosystem || !name || !version) {
return res.status(400).send({ error: "Missing name, version, or ecosystem." })
}

try {
return fetchWhiteList({name, version, ecosystem, res})
} catch (error) {
console.error("Database error:", error)
return res.status(500).send({ error: "Internal Server Error" })
}
}

export async function whitelistByRepositoryHandler(req: FastifyRequest, res: FastifyReply) {
const { repository } = req.query as { repository?: string };

if (!repository) {
return res.status(400).send({ error: "Missing 'repository' query parameter." });
}

try {
console.log(`Fetching whitelist data for repository: ${repository}`);

const result = await run(
`
SELECT b.name,
COALESCE(
(SELECT array_agg(version)
FROM whitelist_versions
WHERE name = b.name), '{}'::TEXT[]
) as versions,
COALESCE(
(SELECT array_agg(ecosystem)
FROM whitelist_ecosystems
WHERE name = b.name), '{}'::TEXT[]
) as ecosystems,
COALESCE(
(SELECT array_agg(repository)
FROM whitelist_repositories
WHERE name = b.name), '{}'::TEXT[]
) as repositories,
COALESCE(
(SELECT array_agg(comment)
FROM whitelist_comments
WHERE name = b.name), '{}'::TEXT[]
) as comments
FROM whitelist b
JOIN whitelist_repositories br ON b.name = br.name
WHERE br.repository = $1;
`,
[repository]
);

if (result.rows.length === 0) {
return res.status(404).send({ error: `No whitelist entries found for repository: ${repository}` });
}

return res.send(result.rows);
} catch (error) {
console.error("Database error:", error);
return res.status(500).send({ error: "Internal Server Error" });
}
}
71 changes: 37 additions & 34 deletions api/src/routes.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
import indexHandler from "./get/index.js"
import osvHandler from "./get/osv.js"
import whitelistIndexHandler, { whitelistHandler } from "./get/whitelist.js"
import blacklistIndexHandler, { blacklistHandler } from "./get/blacklist.js"
import whitelistPostHandler from "./post/whitelist.js"
import blacklistPostHandler from "./post/blacklist.js"
import whitelistPutHandler from "./put/whitelist.js"
import blacklistPutHandler from "./put/blacklist.js"
import whitelistDeleteHandler from "./delete/whitelist.js"
import blacklistDeleteHandler from "./delete/blacklist.js"
import { FastifyInstance, FastifyPluginOptions } from "fastify"

export default async function apiRoutes(fastify: FastifyInstance, options: FastifyPluginOptions) {
// GET handlers
fastify.get("/", indexHandler)
fastify.get("/osv/:ecosystem/:name/:version", osvHandler)
fastify.get("/whitelist", whitelistIndexHandler)
fastify.get("/blacklist", blacklistIndexHandler)
fastify.get("/whitelist/:ecosystem/:name/:version", whitelistHandler)
fastify.get("/blacklist/:ecosystem/:name/:version", blacklistHandler)

// POST handlers
fastify.post("/whitelist", whitelistPostHandler)
fastify.post("/blacklist", blacklistPostHandler)

// PUT handlers
fastify.put("/whitelist", whitelistPutHandler)
fastify.put("/blacklist", blacklistPutHandler)

// DELETE handlers
fastify.delete("/whitelist/:name", whitelistDeleteHandler)
fastify.delete("/blacklist/:name", blacklistDeleteHandler)
}

import indexHandler from "./get/index.js"
import osvHandler from "./get/osv.js"
import whitelistIndexHandler, { whitelistHandler, whitelistByRepositoryHandler } from "./get/whitelist.js"
import blacklistIndexHandler, { blacklistHandler, blacklistByRepositoryHandler } from "./get/blacklist.js"
import whitelistPostHandler from "./post/whitelist.js"
import blacklistPostHandler from "./post/blacklist.js"
import whitelistPutHandler from "./put/whitelist.js"
import blacklistPutHandler from "./put/blacklist.js"
import whitelistDeleteHandler from "./delete/whitelist.js"
import blacklistDeleteHandler from "./delete/blacklist.js"
import { FastifyInstance, FastifyPluginOptions } from "fastify"

export default async function apiRoutes(fastify: FastifyInstance, options: FastifyPluginOptions) {
// GET handlers
fastify.get("/", indexHandler)
fastify.get("/osv/:ecosystem/:name/:version", osvHandler)
fastify.get("/whitelist", whitelistIndexHandler)
fastify.get("/blacklist", blacklistIndexHandler)
fastify.get("/whitelist/:ecosystem/:name/:version", whitelistHandler)
fastify.get("/blacklist/:ecosystem/:name/:version", blacklistHandler)
fastify.get("/whitelist/:repository", whitelistByRepositoryHandler)
fastify.get("/blacklist/:repository", blacklistByRepositoryHandler)


// POST handlers
fastify.post("/whitelist", whitelistPostHandler)
fastify.post("/blacklist", blacklistPostHandler)

// PUT handlers
fastify.put("/whitelist", whitelistPutHandler)
fastify.put("/blacklist", blacklistPutHandler)

// DELETE handlers
fastify.delete("/whitelist/:name", whitelistDeleteHandler)
fastify.delete("/blacklist/:name", blacklistDeleteHandler)
}

51 changes: 51 additions & 0 deletions ui/src/app/dashboard/repositories/config/[repo]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import Link from "next/link"
import fetchRepoConfig, { RepoWhitelistItem, RepoBlacklistItem } from "@/utils/fetchRepoConfig"

export default async function RepoConfigPage({params}: {params: Promise<{ repo: string }>}){
const repo = (await params).repo
const { whitelist, blacklist } = await fetchRepoConfig(repo)
return (
<main className="min-h-full w-full p-4">
<div className="mb-4">
<Link href="/dashboard/repositories">
<a className="text-blue-500 underline">← Back to Repositories</a>
</Link>
</div>

<h1 className="text-3xl font-bold mb-4">Repository Config: {repo}</h1>

<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<section>
<h2 className="text-2xl font-semibold mb-2">Whitelist</h2>
{whitelist.length === 0 ? (
<p>No whitelisted items.</p>
) : (
<ul className="list-disc list-inside">
{whitelist.map((item: RepoWhitelistItem) => (
<li key={item.name}>
{item.name}{" "}
{item.versions && item.versions.length > 0 && (
<span>(Versions: {item.versions.join(", ")})</span>
)}
</li>
))}
</ul>
)}
</section>

<section>
<h2 className="text-2xl font-semibold mb-2">Blacklist</h2>
{blacklist.length === 0 ? (
<p>No blacklisted items.</p>
) : (
<ul className="list-disc list-inside">
{blacklist.map((item: RepoBlacklistItem) => (
<li key={item.name}>{item.name}</li>
))}
</ul>
)}
</section>
</div>
</main>
);
}
Loading

0 comments on commit 9bd1a30

Please sign in to comment.