feature: Changes backend creation to use checks, and to automatically enable.

This commit is contained in:
greysoh 2024-04-27 16:12:59 -04:00
parent f7f2fc7826
commit 5bfbf5cb05
No known key found for this signature in database
GPG key ID: FE0F173B8FC01571
5 changed files with 105 additions and 45 deletions

View file

@ -4,9 +4,7 @@ import { PrismaClient } from '@prisma/client';
import Fastify from "fastify";
import type { ServerOptions, SessionToken, RouteOptions } from "./libs/types.js";
import type { BackendBaseClass } from "./backendimpl/base.js";
import { backendProviders } from "./backendimpl/index.js";
import type { BackendBaseClass } from "./backendimpl/base.js";``
import { route as getPermissions } from "./routes/getPermissions.js";
@ -22,7 +20,7 @@ import { route as userCreate } from "./routes/user/create.js";
import { route as userRemove } from "./routes/user/remove.js";
import { route as userLookup } from "./routes/user/lookup.js";
import { route as userLogin } from "./routes/user/login.js";
import { connect } from "node:http2";
import { backendInit } from "./libs/backendInit.js";
const prisma = new PrismaClient();
@ -64,45 +62,9 @@ const createdBackends = await prisma.desinationProvider.findMany();
for (const backend of createdBackends) {
console.log(`Running init steps for ID '${backend.id}' (${backend.name})`);
const init = await backendInit(backend, backends, prisma);
const ourProvider = backendProviders[backend.backend];
if (!ourProvider) {
console.log(" - Error: Invalid backend recieved!");
continue;
}
console.log(" - Initializing backend...");
backends[backend.id] = new ourProvider(backend.connectionDetails);
const ourBackend = backends[backend.id];
if (!await ourBackend.start()) {
console.log(" - Error initializing backend!");
console.log(" - " + ourBackend.logs.join("\n - "));
continue;
}
console.log(" - Initializing clients...");
const clients = await prisma.forwardRule.findMany({
where: {
destProviderID: backend.id,
enabled: true
}
});
for (const client of clients) {
if (client.protocol != "tcp" && client.protocol != "udp") {
console.error(` - Error: Client with ID of '${client.id}' has an invalid protocol! (must be either TCP or UDP)`);
continue;
}
ourBackend.addConnection(client.sourceIP, client.sourcePort, client.destPort, client.protocol);
}
console.log("Init successful.");
if (init) console.log("Init successful.");
}
console.log("Done.");

53
src/libs/backendInit.ts Normal file
View file

@ -0,0 +1,53 @@
import type { PrismaClient } from "@prisma/client";
import type { BackendBaseClass } from "../backendimpl/base.js";
import { backendProviders } from "../backendimpl/index.js";
type Backend = {
id: number;
name: string;
description: string | null;
backend: string;
connectionDetails: string;
};
export async function backendInit(backend: Backend, backends: Record<number, BackendBaseClass>, prisma: PrismaClient): Promise<boolean> {
const ourProvider = backendProviders[backend.backend];
if (!ourProvider) {
console.log(" - Error: Invalid backend recieved!");
return false;
}
console.log(" - Initializing backend...");
backends[backend.id] = new ourProvider(backend.connectionDetails);
const ourBackend = backends[backend.id];
if (!await ourBackend.start()) {
console.log(" - Error initializing backend!");
console.log(" - " + ourBackend.logs.join("\n - "));
return false;
}
console.log(" - Initializing clients...");
const clients = await prisma.forwardRule.findMany({
where: {
destProviderID: backend.id,
enabled: true
}
});
for (const client of clients) {
if (client.protocol != "tcp" && client.protocol != "udp") {
console.error(` - Error: Client with ID of '${client.id}' has an invalid protocol! (must be either TCP or UDP)`);
continue;
}
ourBackend.addConnection(client.sourceIP, client.sourcePort, client.destPort, client.protocol);
}
return true;
}

View file

@ -1,11 +1,15 @@
import { hasPermissionByToken } from "../../libs/permissions.js";
import type { RouteOptions } from "../../libs/types.js";
import { backendProviders } from "../../backendimpl/index.js";
import { backendInit } from "../../libs/backendInit.js";
export function route(routeOptions: RouteOptions) {
const {
fastify,
prisma,
tokens
tokens,
backends
} = routeOptions;
function hasPermission(token: string, permissionList: string[]): Promise<boolean> {
@ -47,6 +51,21 @@ export function route(routeOptions: RouteOptions) {
});
};
if (!backendProviders[body.backend]) {
return res.status(400).send({
error: "Unknown/unsupported/deprecated backend!"
});
};
const connectionDetails = JSON.stringify(body.connectionDetails);
const connectionDetailsValidityCheck = backendProviders[body.backend].checkParametersBackendInstance(connectionDetails);
if (!connectionDetailsValidityCheck.success) {
return res.status(400).send({
error: connectionDetailsValidityCheck.message ?? "Unknown error while attempting to parse connectionDetails (it's on your side)"
});
};
const backend = await prisma.desinationProvider.create({
data: {
name: body.name,
@ -57,6 +76,16 @@ export function route(routeOptions: RouteOptions) {
}
});
const init = await backendInit(backend, backends, prisma);
if (!init) {
// TODO: better error code
return res.status(504).send({
error: "Backend is created, but failed to initalize correctly",
id: backend.id
});
}
return {
success: true,
id: backend.id

View file

@ -5,7 +5,8 @@ export function route(routeOptions: RouteOptions) {
const {
fastify,
prisma,
tokens
tokens,
backends
} = routeOptions;
function hasPermission(token: string, permissionList: string[]): Promise<boolean> {
@ -42,6 +43,21 @@ export function route(routeOptions: RouteOptions) {
});
};
if (!backends[body.id]) {
return res.status(400).send({
error: "Backend not found"
});
};
// Unload the backend
if (!await backends[body.id].stop()) {
return res.status(400).send({
error: "Failed to stop backend! Please report this issue."
})
}
delete backends[body.id];
await prisma.desinationProvider.delete({
where: {
id: body.id

View file

@ -20,7 +20,7 @@ export function route(routeOptions: RouteOptions) {
required: ["email", "password"],
properties: {
email: { type: "string" },
email: { type: "string" },
password: { type: "string" }
}
}