mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-01 16:26:39 +00:00
Remove siteIds and build associations from user role chnages
This commit is contained in:
@@ -11,6 +11,7 @@ import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { addTargets } from "../client/targets";
|
||||
import { getUniqueSiteResourceName } from "@server/db/names";
|
||||
import { rebuildSiteClientAssociations } from "@server/lib/rebuildSiteClientAssociations";
|
||||
|
||||
const createSiteResourceParamsSchema = z
|
||||
.object({
|
||||
@@ -29,7 +30,8 @@ const createSiteResourceSchema = z
|
||||
destination: z.string().min(1),
|
||||
enabled: z.boolean().default(true),
|
||||
alias: z.string().optional()
|
||||
}).strict()
|
||||
})
|
||||
.strict()
|
||||
.refine(
|
||||
(data) => {
|
||||
if (data.mode === "port") {
|
||||
@@ -145,61 +147,75 @@ export async function createSiteResource(
|
||||
|
||||
const niceId = await getUniqueSiteResourceName(orgId);
|
||||
|
||||
// Create the site resource
|
||||
const [newSiteResource] = await db
|
||||
.insert(siteResources)
|
||||
.values({
|
||||
siteId,
|
||||
niceId,
|
||||
orgId,
|
||||
name,
|
||||
mode,
|
||||
protocol: mode === "port" ? protocol : null,
|
||||
proxyPort: mode === "port" ? proxyPort : null,
|
||||
destinationPort: mode === "port" ? destinationPort : null,
|
||||
destination,
|
||||
enabled,
|
||||
alias: alias || null
|
||||
})
|
||||
.returning();
|
||||
let newSiteResource: SiteResource | undefined;
|
||||
await db.transaction(async (trx) => {
|
||||
// Create the site resource
|
||||
[newSiteResource] = await trx
|
||||
.insert(siteResources)
|
||||
.values({
|
||||
siteId,
|
||||
niceId,
|
||||
orgId,
|
||||
name,
|
||||
mode,
|
||||
protocol: mode === "port" ? protocol : null,
|
||||
proxyPort: mode === "port" ? proxyPort : null,
|
||||
destinationPort: mode === "port" ? destinationPort : null,
|
||||
destination,
|
||||
enabled,
|
||||
alias: alias || null
|
||||
})
|
||||
.returning();
|
||||
|
||||
const adminRole = await db
|
||||
.select()
|
||||
.from(roles)
|
||||
.where(and(eq(roles.isAdmin, true), eq(roles.orgId, orgId)))
|
||||
.limit(1);
|
||||
|
||||
if (adminRole.length === 0) {
|
||||
return next(
|
||||
createHttpError(HttpCode.NOT_FOUND, `Admin role not found`)
|
||||
);
|
||||
}
|
||||
|
||||
await db.insert(roleSiteResources).values({
|
||||
roleId: adminRole[0].roleId,
|
||||
siteResourceId: newSiteResource.siteResourceId
|
||||
});
|
||||
|
||||
// Only add targets for port mode
|
||||
if (mode === "port" && protocol && proxyPort && destinationPort) {
|
||||
const [newt] = await db
|
||||
const [adminRole] = await trx
|
||||
.select()
|
||||
.from(newts)
|
||||
.where(eq(newts.siteId, site.siteId))
|
||||
.from(roles)
|
||||
.where(and(eq(roles.isAdmin, true), eq(roles.orgId, orgId)))
|
||||
.limit(1);
|
||||
|
||||
if (!newt) {
|
||||
if (!adminRole) {
|
||||
return next(
|
||||
createHttpError(HttpCode.NOT_FOUND, "Newt not found")
|
||||
createHttpError(HttpCode.NOT_FOUND, `Admin role not found`)
|
||||
);
|
||||
}
|
||||
|
||||
await addTargets(
|
||||
newt.newtId,
|
||||
destination,
|
||||
destinationPort,
|
||||
protocol,
|
||||
proxyPort
|
||||
await trx.insert(roleSiteResources).values({
|
||||
roleId: adminRole.roleId,
|
||||
siteResourceId: newSiteResource.siteResourceId
|
||||
});
|
||||
|
||||
// Only add targets for port mode
|
||||
if (mode === "port" && protocol && proxyPort && destinationPort) {
|
||||
const [newt] = await trx
|
||||
.select()
|
||||
.from(newts)
|
||||
.where(eq(newts.siteId, site.siteId))
|
||||
.limit(1);
|
||||
|
||||
if (!newt) {
|
||||
return next(
|
||||
createHttpError(HttpCode.NOT_FOUND, "Newt not found")
|
||||
);
|
||||
}
|
||||
|
||||
await addTargets(
|
||||
newt.newtId,
|
||||
destination,
|
||||
destinationPort,
|
||||
protocol,
|
||||
proxyPort
|
||||
);
|
||||
}
|
||||
|
||||
await rebuildSiteClientAssociations(newSiteResource, trx); // we need to call this because we added to the admin role
|
||||
});
|
||||
|
||||
if (!newSiteResource) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"Site resource creation failed"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,14 @@ import { fromError } from "zod-validation-error";
|
||||
import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { removeTargets } from "../client/targets";
|
||||
import { rebuildSiteClientAssociations } from "@server/lib/rebuildSiteClientAssociations";
|
||||
|
||||
const deleteSiteResourceParamsSchema = z
|
||||
.object({
|
||||
siteResourceId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
siteResourceId: z
|
||||
.string()
|
||||
.transform(Number)
|
||||
.pipe(z.number().int().positive()),
|
||||
siteId: z.string().transform(Number).pipe(z.number().int().positive()),
|
||||
orgId: z.string()
|
||||
})
|
||||
@@ -40,7 +44,9 @@ export async function deleteSiteResource(
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
try {
|
||||
const parsedParams = deleteSiteResourceParamsSchema.safeParse(req.params);
|
||||
const parsedParams = deleteSiteResourceParamsSchema.safeParse(
|
||||
req.params
|
||||
);
|
||||
if (!parsedParams.success) {
|
||||
return next(
|
||||
createHttpError(
|
||||
@@ -66,53 +72,61 @@ export async function deleteSiteResource(
|
||||
const [existingSiteResource] = await db
|
||||
.select()
|
||||
.from(siteResources)
|
||||
.where(and(
|
||||
eq(siteResources.siteResourceId, siteResourceId),
|
||||
eq(siteResources.siteId, siteId),
|
||||
eq(siteResources.orgId, orgId)
|
||||
))
|
||||
.where(and(eq(siteResources.siteResourceId, siteResourceId)))
|
||||
.limit(1);
|
||||
|
||||
if (!existingSiteResource) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.NOT_FOUND,
|
||||
"Site resource not found"
|
||||
)
|
||||
createHttpError(HttpCode.NOT_FOUND, "Site resource not found")
|
||||
);
|
||||
}
|
||||
|
||||
// Delete the site resource
|
||||
await db
|
||||
.delete(siteResources)
|
||||
.where(and(
|
||||
eq(siteResources.siteResourceId, siteResourceId),
|
||||
eq(siteResources.siteId, siteId),
|
||||
eq(siteResources.orgId, orgId)
|
||||
));
|
||||
await db.transaction(async (trx) => {
|
||||
// Delete the site resource
|
||||
await trx
|
||||
.delete(siteResources)
|
||||
.where(
|
||||
and(
|
||||
eq(siteResources.siteResourceId, siteResourceId),
|
||||
eq(siteResources.siteId, siteId),
|
||||
eq(siteResources.orgId, orgId)
|
||||
)
|
||||
);
|
||||
|
||||
// Only remove targets for port mode
|
||||
if (existingSiteResource.mode === "port" && existingSiteResource.protocol && existingSiteResource.proxyPort && existingSiteResource.destinationPort) {
|
||||
const [newt] = await db
|
||||
.select()
|
||||
.from(newts)
|
||||
.where(eq(newts.siteId, site.siteId))
|
||||
.limit(1);
|
||||
// Only remove targets for port mode
|
||||
if (
|
||||
existingSiteResource.mode === "port" &&
|
||||
existingSiteResource.protocol &&
|
||||
existingSiteResource.proxyPort &&
|
||||
existingSiteResource.destinationPort
|
||||
) {
|
||||
const [newt] = await trx
|
||||
.select()
|
||||
.from(newts)
|
||||
.where(eq(newts.siteId, site.siteId))
|
||||
.limit(1);
|
||||
|
||||
if (!newt) {
|
||||
return next(createHttpError(HttpCode.NOT_FOUND, "Newt not found"));
|
||||
if (!newt) {
|
||||
return next(
|
||||
createHttpError(HttpCode.NOT_FOUND, "Newt not found")
|
||||
);
|
||||
}
|
||||
|
||||
await removeTargets(
|
||||
newt.newtId,
|
||||
existingSiteResource.destination,
|
||||
existingSiteResource.destinationPort,
|
||||
existingSiteResource.protocol,
|
||||
existingSiteResource.proxyPort
|
||||
);
|
||||
}
|
||||
|
||||
await removeTargets(
|
||||
newt.newtId,
|
||||
existingSiteResource.destination,
|
||||
existingSiteResource.destinationPort,
|
||||
existingSiteResource.protocol,
|
||||
existingSiteResource.proxyPort
|
||||
);
|
||||
}
|
||||
await rebuildSiteClientAssociations(existingSiteResource, trx);
|
||||
});
|
||||
|
||||
logger.info(`Deleted site resource ${siteResourceId} for site ${siteId}`);
|
||||
logger.info(
|
||||
`Deleted site resource ${siteResourceId} for site ${siteId}`
|
||||
);
|
||||
|
||||
return response(res, {
|
||||
data: { message: "Site resource deleted successfully" },
|
||||
@@ -123,6 +137,11 @@ export async function deleteSiteResource(
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error("Error deleting site resource:", error);
|
||||
return next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "Failed to delete site resource"));
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"Failed to delete site resource"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { eq, and, ne } from "drizzle-orm";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { rebuildSiteClientAssociations } from "@server/lib/rebuildSiteClientAssociations";
|
||||
|
||||
const setSiteResourceRolesBodySchema = z
|
||||
.object({
|
||||
@@ -62,7 +63,9 @@ export async function setSiteResourceRoles(
|
||||
|
||||
const { roleIds } = parsedBody.data;
|
||||
|
||||
const parsedParams = setSiteResourceRolesParamsSchema.safeParse(req.params);
|
||||
const parsedParams = setSiteResourceRolesParamsSchema.safeParse(
|
||||
req.params
|
||||
);
|
||||
if (!parsedParams.success) {
|
||||
return next(
|
||||
createHttpError(
|
||||
@@ -136,6 +139,8 @@ export async function setSiteResourceRoles(
|
||||
.returning()
|
||||
)
|
||||
);
|
||||
|
||||
await rebuildSiteClientAssociations(siteResource, trx);
|
||||
});
|
||||
|
||||
return response(res, {
|
||||
@@ -152,4 +157,3 @@ export async function setSiteResourceRoles(
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { db } from "@server/db";
|
||||
import { db, siteResources } from "@server/db";
|
||||
import { userSiteResources } from "@server/db";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
@@ -9,6 +9,7 @@ import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { rebuildSiteClientAssociations } from "@server/lib/rebuildSiteClientAssociations";
|
||||
|
||||
const setSiteResourceUsersBodySchema = z
|
||||
.object({
|
||||
@@ -74,6 +75,22 @@ export async function setSiteResourceUsers(
|
||||
|
||||
const { siteResourceId } = parsedParams.data;
|
||||
|
||||
// get the site resource
|
||||
const [siteResource] = await db
|
||||
.select()
|
||||
.from(siteResources)
|
||||
.where(eq(siteResources.siteResourceId, siteResourceId))
|
||||
.limit(1);
|
||||
|
||||
if (!siteResource) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.INTERNAL_SERVER_ERROR,
|
||||
"Site resource not found"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await db.transaction(async (trx) => {
|
||||
await trx
|
||||
.delete(userSiteResources)
|
||||
@@ -87,6 +104,8 @@ export async function setSiteResourceUsers(
|
||||
.returning()
|
||||
)
|
||||
);
|
||||
|
||||
await rebuildSiteClientAssociations(siteResource, trx);
|
||||
});
|
||||
|
||||
return response(res, {
|
||||
|
||||
Reference in New Issue
Block a user