Skip to content

Commit

Permalink
Merge pull request #64 from CodeGrade/feat/list-and-delete-keys
Browse files Browse the repository at this point in the history
List and Delete API Keys from Command Line
  • Loading branch information
blerner authored Aug 12, 2024
2 parents 77f3543 + b868a0c commit 0b3bdef
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 4 deletions.
9 changes: 8 additions & 1 deletion orchestrator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,11 @@

Orca's web server is designed to receive grading jobs from Bottlenose and push them onto the grading queue accordingly.

## Running the Server
## API Key Scripts

Users running the orchestator can run the following scripts for interacting with API keys:
* `yarn generate-api-key -h <hostname>`
* `yarn list-api-keys -h <hostname>`
* `yarn delete-api-key -h <hostname> -k <apikey>`

**NOTE:** The `POSTGRES_URL` envirnoment variable _must be set_ in order to run these scripts.
2 changes: 2 additions & 0 deletions orchestrator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"private": "true",
"scripts": {
"generate-api-key": "yarn workspace @codegrade-orca/db generate-api-key",
"delete-api-key": "yarn workspace @codegrade-orca/db delete-api-key",
"list-api-keys": "yarn workspace @codegrade-orca/db list-api-keys",
"server": "yarn workspace @codegrade-orca/api start",
"server:dev": "yarn workspace @codegrade-orca/api dev",
"image-builder": "yarn workspace @codegrade-orca/image-build-service start",
Expand Down
4 changes: 3 additions & 1 deletion orchestrator/packages/db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
"scripts": {
"build": "tsc --build",
"check": "tsc --noEmit",
"generate-api-key": "ts-node src/scripts/generate-api-key.ts"
"generate-api-key": "ts-node src/scripts/generate-api-key.ts",
"list-api-keys": "ts-node src/scripts/list-api-keys.ts",
"delete-api-key": "ts-node src/scripts/delete-api-key.ts"
},
"devDependencies": {
"jest-mock-extended": "^3.0.5",
Expand Down
4 changes: 3 additions & 1 deletion orchestrator/packages/db/src/api-key-operations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ export const createAPIKey = async (hostname: string): Promise<string> =>
export const validAPIKey = async (hostname: string, value: string) =>
Boolean(await prismaInstance.apiKey.count({ where: { hostname, value } }))

const generateKey = (): string => randomBytes(KEY_LENGTH).toString('hex');
// randomBytes into hex string will return a value with double the length passed
// to randomBytes
const generateKey = (): string => randomBytes(KEY_LENGTH / 2).toString('hex');
30 changes: 30 additions & 0 deletions orchestrator/packages/db/src/scripts/delete-api-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { parseArgs } from "util";
import prismaInstance from "../prisma-instance";

const main = async () => {
const { values } = parseArgs(
{
options:
{
hostname: { type: "string", short: "h" },
key: { type: "string", short: "k" }
},
}
);
const missing = Object.entries(values).filter(([_, v]) => v === undefined).map(([k, _]) => k);
if (missing.length) {
process.stderr.write(`Missing the following options: ${missing.join(', ')}`);
process.exit(1);
}
const { hostname, key } = values;
const deletedResult = await prismaInstance.$transaction(async (tx) => await tx.apiKey.deleteMany(
{ where: { hostname, value: key } }
));
const { count } = deletedResult;
if (!count) {
process.stderr.write("The given key does not exist under the given host name.");
process.exit(1);
}
};

main();
3 changes: 2 additions & 1 deletion orchestrator/packages/db/src/scripts/generate-api-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const main = async () => {
console.error("Must provide hostname for api key generation with flag '-h'.");
process.exit(1);
}
await createAPIKey(hostname as string);
const newKey = await createAPIKey(hostname as string);
process.stdout.write(newKey + "\n");
}

main();
19 changes: 19 additions & 0 deletions orchestrator/packages/db/src/scripts/list-api-keys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { parseArgs } from "util";
import prismaInstance from "../prisma-instance";

const main = async () => {
const { values } = parseArgs({ options: { hostname: { type: "string", short: "h" } } });
const { hostname } = values;
if (!hostname) {
process.stderr.write("Must provide hostname option.");
process.exit(1);
}
const keys = await prismaInstance.apiKey.findMany({ where: { hostname } }).then((vals) => vals.map((v) => v.value));
if (!keys.length) {
process.stderr.write("No keys found under given host name.");
process.exit(0);
}
process.stdout.write(keys.join("\n") + "\n");
};

main();

0 comments on commit 0b3bdef

Please sign in to comment.